1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-24 15:49: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:
Zach Gollwitzer 2024-03-28 13:23:54 -04:00 committed by GitHub
parent 7ae25dd6df
commit f0c2d4ead0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 296 additions and 146 deletions

View file

@ -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);
};
}

View 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";
});
}
}

View file

@ -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");
}
});
}
};
}

View file

@ -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();
}
}