mirror of
https://github.com/we-promise/sure.git
synced 2026-05-30 15:59:02 +00:00
fix(goals/index): persist filter + search in URL across reloads
UX audit finding. The filter chip state and search input lived only in Stimulus values — a Behind-filter selection survived turbo morphs but vanished on F5, browser back from a goal's show page, and any deeplink share. For a family with 10+ goals filtering by "behind", every navigation reset to "all". Hydrate on `connect()`: - read `?filter=behind` → statusValue - read `?q=…` → input target Sync on every `filter()` call via `history.replaceState`: - filter=all → drop key - q empty → drop key - else preserve both Uses `replaceState` (not `pushState`) so each keystroke / chip click doesn't bloat the back-history. The page URL becomes shareable for the filtered view.
This commit is contained in:
@@ -25,7 +25,11 @@ export default class extends Controller {
|
||||
};
|
||||
|
||||
connect() {
|
||||
this.#hydrateFromUrl();
|
||||
this.syncChipState();
|
||||
if (this.statusValue !== "all" || (this.hasInputTarget && this.inputTarget.value)) {
|
||||
this.filter();
|
||||
}
|
||||
}
|
||||
|
||||
filter() {
|
||||
@@ -56,6 +60,37 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
this.updateEmptyState(visible, query, active);
|
||||
this.#syncUrl();
|
||||
}
|
||||
|
||||
#hydrateFromUrl() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const status = params.get("filter");
|
||||
if (status && this.chipTargets.some((c) => c.dataset.status === status)) {
|
||||
this.statusValue = status;
|
||||
}
|
||||
const q = params.get("q");
|
||||
if (q && this.hasInputTarget) {
|
||||
this.inputTarget.value = q;
|
||||
}
|
||||
}
|
||||
|
||||
#syncUrl() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
if (this.statusValue && this.statusValue !== "all") {
|
||||
params.set("filter", this.statusValue);
|
||||
} else {
|
||||
params.delete("filter");
|
||||
}
|
||||
const q = this.hasInputTarget ? this.inputTarget.value.trim() : "";
|
||||
if (q) {
|
||||
params.set("q", q);
|
||||
} else {
|
||||
params.delete("q");
|
||||
}
|
||||
const qs = params.toString();
|
||||
const url = qs ? `${window.location.pathname}?${qs}` : window.location.pathname;
|
||||
window.history.replaceState(window.history.state, "", url);
|
||||
}
|
||||
|
||||
updateEmptyState(visible, query, active) {
|
||||
|
||||
Reference in New Issue
Block a user