Budget page refactor: split into(All - Over Budget - On Track) (#1195)

* Optimize UI in budget

* update locales

* Optimize UI

* optimize suggested_daily_spending

* try over_budget and on_track

* update locale

* optimize

* add budgets_helper.rb

* fix

* hide no buget and no expense sub-catogory

* Optimize

* Optimize button on phone

* Fix Pipelock CI noise

* using section to render both overbudget and onTrack

* hide last ruler

* fix

* update test

---------

Co-authored-by: Juan José Mata <juanjo.mata@gmail.com>
This commit is contained in:
Tao Chen
2026-04-14 02:03:55 +08:00
committed by GitHub
parent fdc2ce1feb
commit aacbb5ef3b
17 changed files with 626 additions and 63 deletions

View File

@@ -0,0 +1,57 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["onTrack", "overBudget", "tab"];
static values = { filter: { type: String, default: "all" } };
connect() {
const filterParam = new URLSearchParams(window.location.search).get("filter");
if (this.#isValidFilter(filterParam) && filterParam !== this.filterValue) {
this.filterValue = filterParam;
} else if (filterParam && !this.#isValidFilter(filterParam)) {
this.#syncFilterParam();
}
}
setFilter(event) {
this.filterValue = event.params.filter;
this.#syncFilterParam();
}
filterValueChanged() {
const filter = this.filterValue;
if (this.hasOnTrackTarget) {
this.onTrackTarget.hidden = filter === "over_budget";
}
if (this.hasOverBudgetTarget) {
this.overBudgetTarget.hidden = filter === "on_track";
}
this.tabTargets.forEach((tab) => {
const isActive = tab.dataset.budgetFilterFilterParam === filter;
tab.classList.toggle("bg-container", isActive);
tab.classList.toggle("text-primary", isActive);
tab.classList.toggle("shadow-sm", isActive);
tab.classList.toggle("text-secondary", !isActive);
});
}
#isValidFilter(filter) {
return ["all", "over_budget", "on_track"].includes(filter);
}
#syncFilterParam() {
const url = new URL(window.location.href);
if (this.filterValue === "all") {
url.searchParams.delete("filter");
} else {
url.searchParams.set("filter", this.filterValue);
}
window.history.replaceState({}, "", url);
}
}