Commit Graph

3 Commits

Author SHA1 Message Date
Pit Friedrich 8545b06f41 fix: add a per-widget action menu (#27)
CI / build-and-test (pull_request) Successful in 2m25s
A GridStackItem now carries an overflow menu next to the grip and the
close button: refresh, maximize, duplicate, remove. Maximize and remove
are handled by the item itself; refresh and duplicate are only reported,
since what they mean depends on the widget.

Maximizing only sets a class — the item's gs-* attributes and its
gridstack node are untouched, so restoring is by definition the position
it had.

The menu sits outside the drag-handle selector, like the close button, so
opening it never starts a drag; a Playwright test drags it to prove it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69
2026-07-28 21:26:05 +02:00
Pit Friedrich df5d1a9b9b fix: add a global dashboard filter bar (#24)
CI / build-and-test (pull_request) Successful in 2m46s
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
2026-07-28 20:52:33 +02:00
Pit Friedrich 5fe159a604 fix: add a widget registry and "add widget" picker (#21)
CI / build-and-test (pull_request) Successful in 2m25s
"Widget hinzufügen" appended an empty placeholder card, so a widget closed
via its X was gone until a page reload. Widget types now live in a
WidgetRegistry (WidgetDefinition: type id, title key, default size,
content factory); the toolbar button opens a picker dialog over the
registry, and the dashboard builds its initial widgets from it too.

Chart construction moves from DashboardView into the registry factories,
which resolve translation keys through the chart component so they follow
the UI locale. Added widgets get an id of "<type>-<n>" from a
monotonically growing counter, so a closed widget's id is never handed to
a new one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69
2026-07-28 20:32:45 +02:00