Configurable user dashboard — interactive + / remove / customize widgets #46
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
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?
Trigger
m 2026-05-20 10:42:
Current state
The logged-in landing (
/or/dashboard) currently renders a fixed layout: deadline traffic lights, upcoming appointments, recent activity, all scoped to visible projects (per project CLAUDE.md > Purpose > Dashboard). Every user sees the same widgets in the same order; there's no personalisation.What m wants
+button to add widgets, anx(or drag-to-trash) to remove, a drag-to-reorder gesture. "Edit mode" toggle if necessary to avoid accidental rearrangement during normal use.Design considerations (not prescriptive — for the inventor's design pass)
Widgetshape (id, title, default size, schema for per-widget config).paliad.user_dashboard_layoutstable? A JSON blob onusers.metadata? A normalisedpaliad.user_dashboard_widgets(user_id, widget_id, position, settings jsonb)? The schema choice has implications for migration (adding a new widget type) and for reordering UX (drag updates 1 row vs. n rows).Out of scope
Acceptance
+to add a widget from the catalog, clickxto remove, drag to reorder, configure each widget's per-widget settings, and persist all of it.Role recommendation
inventor — bigger feature, design pass justified. After m's go-ahead on the design, slice plan likely 3+ slices:
Branch:
mai/<inventor>/dashboard-configurable.t-paliad-219 Slice A complete — backend storage + service + handlers + frontend widget dispatch
Branch:
mai/newton/inventor-configurable(pushed)Commits since shift-1 design:
bfd6c9aSlice A1 — migration 109 +DashboardLayoutSpec+DashboardLayoutService+WidgetCatalog(7 entries) + 18 pure-function tests + 4 live-DB tests607b58fSlice A2 — 4 HTTP endpoints (GET/PUT /api/me/dashboard-layout,POST .../reset,GET /api/dashboard-widget-catalog) + main.go wiringfdc4b14Slice A3 —DashboardServicewidened to 60d/LIMIT 40 for upcoming-deadlines+appointments + newInboxSummaryfield powered byApprovalService.PendingCountForUser/ListPendingForApprover297d20bSlice A4 — frontend: triple hydration placeholders, dashboard.tsx data-widget-key attributes + inbox-approvals section markup, dashboard.ts widget dispatcher (applyLayout+settingsFor+filterByHorizonDays+renderInbox), 5 new i18n keysVerification:
go build ./...cleango vet ./...cleango test ./internal/... -short -count=1all green (25 new tests pass)bun run buildclean — 2528 → 2533 i18n keys, scan clean__PALIAD_DASHBOARD_*__placeholders present indist/dashboard.htmlPixel-identical factory render budget: held. Every previously-visible widget keeps its DOM markup, classes, IDs, and parent. New widget (inbox-approvals) lands between agenda and activity per
WidgetCatalogorder — expected visible regression per m's Q3 pick.Design doc deviation note:
caldav_sync_log.binding_id) and 108 (caldav_mkcalendar_capability) onmainafter the design was filed. Boltzmann's gap-tolerant runner (c85c382) covers the race.paliad.user_pinned_projects+PinServicealready exist in the codebase (pre-dates this task). Slice C reduces to one PR adding the pinned-projects widget module + catalog entry.What's next:
Awaiting maria's review and merge to main before continuing to Slice B.
Slice B shipped via newton; merged at https://mgit.msbls.de/m/paliad/commit/0857c1c. Edit mode + drag/drop + autosave live after Dokploy deploy. Slice C (catalog expansion + admin firm-wide default) remaining.
Slice C shipped via newton; merged at https://mgit.msbls.de/m/paliad/commit/ca71162. m/paliad#46 complete (Slices A + B + C). Live after Dokploy deploy.