feat: global dashboard filter bar (date range, region) (#24) #36

Merged
pitfriedrich merged 1 commits from ai/issue-24-dashboard-filter-bar into main 2026-07-28 18:57:16 +00:00
Collaborator

Closes #24

Was

Der Berichtszeitraum steckte fest im Datenservice (months() = Jan–Jun), es gab keine Möglichkeit, den Inhalt des Dashboards ohne Codeänderung zu wechseln.

Änderungen

  • data/DashboardFilter — Record aus Zeitraum (MONTH / QUARTER / HALF_YEAR / YEAR) und optionaler Region. ALL_REGIONS ist ein Übersetzungs-Key statt eines null-Sonderfalls.
  • ChartDataService — jede Abfrage nimmt einen Filter; die parameterlosen Overloads sind dieselbe Abfrage unter DashboardFilter.defaults(), damit bestehende Aufrufer unverändert bleiben.
  • InMemoryChartDataService — Basis-Jahr aus 12 Monaten; der Filter schneidet eine Scheibe heraus (ein Monat = vier Wochen) und skaliert sie. Skalierung relativ zum Default-Halbjahr, das ungefilterte Dashboard zeigt also exakt die alten Zahlen. Kumulative Größen wachsen mit dem Zeitraum, ein Bestand (offene Vorgänge) und ein Durchschnitt (Ø Bestellwert) nicht.
  • widgets/DashboardContext — der kleine Event-Bus: Filterleiste setzt, Widgets abonnieren. View-State, keine Spring-Bean.
  • views/DashboardFilterBar — zwei Selects über dem Grid; kennt kein einziges Widget.
  • Update in place — Widgets werden über updateData nachgefüttert (aus #23), nicht neu gebaut; SparklineChart hat denselben Pfad bekommen, damit auch KPI-Tiles nicht blitzen. Charts hängen ihr Abo an den Detach, ein geschlossenes Widget wird nicht mehr gefüttert.
  • KpiData trägt jetzt die Zahl, das Bundle das Einheiten- und Zahlenformat (MessageFormat), weil der KPI-Wert vom Filter abhängt und trotzdem locale-formatiert bleiben muss.
  • i18n in allen drei Bundles (de/en/es): Filter-Captions, Monate Jul–Dez, Wochen 1–4, KPI-Wertmuster.

Akzeptanzkriterien

  • Filterwechsel aktualisiert alle abonnierten Widgets ohne Reload.
  • Update in place, kein Rebuild — ApexChartUpdateTest#filterChange_patchesEveryChartInPlace prüft, dass ein Filterwechsel 7 updateData-Calls und kein renderChart erzeugt.
  • Filterzustand ist nicht persistiert — dokumentiert in DashboardContext (Grid-Layout bleibt wie gehabt im localStorage).
  • Copy auf Deutsch, Keys in translations.properties, _en, _es.

Tests

./mvnw test — 46 Tests grün (inkl. Playwright-E2E). Neu: DashboardContextTest, Filter-Tests in InMemoryChartDataServiceTest und DashboardViewTest.

🤖 Generated with Claude Code

https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69

Closes #24 ## Was Der Berichtszeitraum steckte fest im Datenservice (`months()` = Jan–Jun), es gab keine Möglichkeit, den Inhalt des Dashboards ohne Codeänderung zu wechseln. ## Änderungen - **`data/DashboardFilter`** — Record aus Zeitraum (`MONTH` / `QUARTER` / `HALF_YEAR` / `YEAR`) und optionaler Region. `ALL_REGIONS` ist ein Übersetzungs-Key statt eines `null`-Sonderfalls. - **`ChartDataService`** — jede Abfrage nimmt einen Filter; die parameterlosen Overloads sind dieselbe Abfrage unter `DashboardFilter.defaults()`, damit bestehende Aufrufer unverändert bleiben. - **`InMemoryChartDataService`** — Basis-Jahr aus 12 Monaten; der Filter schneidet eine Scheibe heraus (ein Monat = vier Wochen) und skaliert sie. Skalierung relativ zum Default-Halbjahr, das ungefilterte Dashboard zeigt also exakt die alten Zahlen. Kumulative Größen wachsen mit dem Zeitraum, ein Bestand (offene Vorgänge) und ein Durchschnitt (Ø Bestellwert) nicht. - **`widgets/DashboardContext`** — der kleine Event-Bus: Filterleiste setzt, Widgets abonnieren. View-State, keine Spring-Bean. - **`views/DashboardFilterBar`** — zwei Selects über dem Grid; kennt kein einziges Widget. - **Update in place** — Widgets werden über `updateData` nachgefüttert (aus #23), nicht neu gebaut; `SparklineChart` hat denselben Pfad bekommen, damit auch KPI-Tiles nicht blitzen. Charts hängen ihr Abo an den Detach, ein geschlossenes Widget wird nicht mehr gefüttert. - **`KpiData`** trägt jetzt die Zahl, das Bundle das Einheiten- und Zahlenformat (`MessageFormat`), weil der KPI-Wert vom Filter abhängt und trotzdem locale-formatiert bleiben muss. - **i18n** in allen drei Bundles (`de`/`en`/`es`): Filter-Captions, Monate Jul–Dez, Wochen 1–4, KPI-Wertmuster. ## Akzeptanzkriterien - [x] Filterwechsel aktualisiert alle abonnierten Widgets ohne Reload. - [x] Update in place, kein Rebuild — `ApexChartUpdateTest#filterChange_patchesEveryChartInPlace` prüft, dass ein Filterwechsel 7 `updateData`-Calls und kein `renderChart` erzeugt. - [x] Filterzustand ist **nicht** persistiert — dokumentiert in `DashboardContext` (Grid-Layout bleibt wie gehabt im `localStorage`). - [x] Copy auf Deutsch, Keys in `translations.properties`, `_en`, `_es`. ## Tests `./mvnw test` — 46 Tests grün (inkl. Playwright-E2E). Neu: `DashboardContextTest`, Filter-Tests in `InMemoryChartDataServiceTest` und `DashboardViewTest`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69
claude-bot added 1 commit 2026-07-28 18:52:53 +00:00
fix: add a global dashboard filter bar (#24)
CI / build-and-test (pull_request) Successful in 2m46s
df5d1a9b9b
The reporting period was baked into the data service, so nothing could
change what the dashboard shows without editing code.

- DashboardFilter (period + optional region) parameterises every
  ChartDataService query; the no-arg overloads are the default filter.
- DashboardContext is the bus between the new DashboardFilterBar and the
  widgets: charts subscribe in WidgetRegistry, KPI tiles in DashboardView.
- Updates go through updateData, so widgets patch in place instead of
  being rebuilt; SparklineChart gained the same path.
- KpiData carries the number, the bundle the unit and number pattern, so
  a KPI value can follow the filter and stay locale-formatted.
- Filter state is deliberately not persisted, unlike the grid layout.

Closes #24

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69
pitfriedrich merged commit cff232070d into main 2026-07-28 18:57:16 +00:00
pitfriedrich deleted branch ai/issue-24-dashboard-filter-bar 2026-07-28 18:57:17 +00:00
Sign in to join this conversation.