mirror of
https://github.com/maybe-finance/maybe.git
synced 2025-07-24 07:39:39 +02:00
Implement transaction filtering UI (#578)
* Rough sketch of implementation * Consolidate auto submit controller * Store ransack params in session * Improve how summary is calculated for txns * Implement filters UI
This commit is contained in:
parent
7ae25dd6df
commit
f0c2d4ead0
20 changed files with 296 additions and 146 deletions
|
@ -1,31 +1,26 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
|
||||
get cssInputSelector() {
|
||||
return 'input:not(.no-auto-submit), textarea:not(.no-auto-submit)';
|
||||
}
|
||||
|
||||
get inputElements() {
|
||||
return this.element.querySelectorAll(this.cssInputSelector);
|
||||
}
|
||||
|
||||
get selectElements() {
|
||||
return this.element.querySelectorAll('select:not(.no-auto-submit)');
|
||||
}
|
||||
// By default, auto-submit is "opt-in" to avoid unexpected behavior. Each `auto` target
|
||||
// will trigger a form submission when the input event is triggered.
|
||||
static targets = ["auto"];
|
||||
|
||||
connect() {
|
||||
[...this.inputElements, ...this.selectElements].forEach(el => el.addEventListener('change', this.handler));
|
||||
this.autoTargets.forEach((element) => {
|
||||
element.addEventListener("input", this.handleInput);
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
[...this.inputElements, ...this.selectElements].forEach(el => el.removeEventListener('change', this.handler));
|
||||
}
|
||||
|
||||
handler = (e) => {
|
||||
console.log(e);
|
||||
this.element.requestSubmit();
|
||||
this.autoTargets.forEach((element) => {
|
||||
element.removeEventListener("input", this.handleInput);
|
||||
});
|
||||
}
|
||||
|
||||
handleInput = () => {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
this.element.requestSubmit();
|
||||
}, 500);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
16
app/javascript/controllers/list_filter_controller.js
Normal file
16
app/javascript/controllers/list_filter_controller.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
// Basic functionality to filter a list based on a provided text attribute.
|
||||
export default class extends Controller {
|
||||
static targets = ["input", "list"];
|
||||
|
||||
filter() {
|
||||
const filterValue = this.inputTarget.value.toLowerCase();
|
||||
const items = this.listTarget.querySelectorAll(".filterable-item");
|
||||
|
||||
items.forEach((item) => {
|
||||
const text = item.getAttribute("data-filter-name").toLowerCase();
|
||||
item.style.display = text.includes(filterValue) ? "" : "none";
|
||||
});
|
||||
}
|
||||
}
|
|
@ -21,15 +21,17 @@ export default class extends Controller {
|
|||
|
||||
onTurboLoad = () => {
|
||||
this.updateClasses(this.defaultTabValue);
|
||||
}
|
||||
};
|
||||
|
||||
updateClasses = (selectedId) => {
|
||||
this.btnTargets.forEach((btn) => btn.classList.remove(this.activeClass));
|
||||
this.btnTargets.forEach((btn) =>
|
||||
btn.classList.remove(...this.activeClasses)
|
||||
);
|
||||
this.tabTargets.forEach((tab) => tab.classList.add("hidden"));
|
||||
|
||||
this.btnTargets.forEach((btn) => {
|
||||
if (btn.dataset.id === selectedId) {
|
||||
btn.classList.add(this.activeClass);
|
||||
btn.classList.add(...this.activeClasses);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -38,5 +40,5 @@ export default class extends Controller {
|
|||
tab.classList.remove("hidden");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["search", "date"]
|
||||
|
||||
connect() {
|
||||
this.timeout = null
|
||||
}
|
||||
|
||||
search() {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
this.submitForm();
|
||||
}, 300); // Debounce time in milliseconds
|
||||
}
|
||||
|
||||
submitForm() {
|
||||
const formData = new FormData(this.searchTarget.form);
|
||||
const searchParams = new URLSearchParams(formData).toString();
|
||||
const newUrl = `${window.location.pathname}?${searchParams}`;
|
||||
|
||||
history.pushState({}, '', newUrl);
|
||||
this.searchTarget.form.requestSubmit();
|
||||
}
|
||||
|
||||
afterSubmit() {
|
||||
this.searchTarget.focus();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue