feat: widget registry and "add widget" picker (#21) #35
Reference in New Issue
Block a user
Delete Branch "ai/issue-21-widget-registry-picker"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #21
Problem
DashboardView.addWidget()only ever appended a placeholder card ("Frei platzierbare Karte."). Combined with the closable widgets from #14 this was lossy: a widget closed via its X could not be brought back without a full page reload.Change
widgets/WidgetDefinition— record: stabletypeid, i18ntitleKey, defaultwidth/height,Supplier<Component>factory.widgets/WidgetRegistry—@Serviceholding the definitions in registration order (revenue-trendline,revenue-monthbar,revenue-regionpie). The chart construction moves here out ofDashboardView; factories pull their numbers fromChartDataService(#20) and resolve translation keys through the chart component, so they follow the current UI locale without the registry being aComponent.DashboardView— "Widget hinzufügen" opens a pickerDialoglisting the registered types instead of appending a placeholder. The initial widgets are built from the registry as well (keeping their existing ids and placement, so persisted layouts still match).<type>-<n>from a counter that only ever grows and is shared across types, so a closed widget's id is never handed to a new widget — otherwise the new one would inherit the closed one's saved position.gridstack.pickerTitlein all three bundles; the now-unusedgridstack.widget/gridstack.widgetTextplaceholder keys are removed. Card titles reuse the existingcard.*keys.Tests
./mvnw test— 31 tests green (incl. the Playwright e2e ones).New/updated in
DashboardViewTest: picking a type adds a widget that renders a real chart; a closed widget can be re-added and gets a fresh id; adding the same type twice yields distinct ids; the picker lists every registered type.WidgetRegistryTestcovers ordering,require()on an unknown type, and re-registration (the factories need a Vaadin UI for translations, so they are exercised through the view test).Note on scope
The diff is ~320 added lines, above the ~200-line guideline in
CLAUDE.md. About a third is tests and Javadoc, and the registry + picker are hard to land separately without leaving the picker referring to a registry nothing uses. Flagging it rather than splitting after the fact — say the word and I'll cut it into "registry only" and "picker" PRs.🤖 Generated with Claude Code
https://claude.ai/code/session_0124BiJikbhbiEsNfJxdWM69