feat(dashboards): SPA widget view surface for saved layouts (PMS-472) #331
No reviewers
Labels
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
psa-systems/mokosh-apps!331
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/PMS-472-dashboard-view-surface"
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?
PMS-453 phase 1 stored a per-user
layoutJSONB but the SPA treated itas opaque. PMS-472 ships the read-only view surface: a typed schema
(
DashboardLayout { widgets: [{ widget_key, grid_col, grid_row, grid_col_span, grid_row_span, filter_scope? }] }), a forward-compatiblewidget catalog (
tickets_by_status,time_this_week,sla_at_risk,open_invoices,recent_audit_log), and a new/dashboards/:id/viewroute that renders each widget into a 12-column CSS grid cell at the
encoded coordinates.
The existing
/dashboardentrypoint now hitsGET /dashboards/defaultfirst; if the caller has pinned a saved row, the saved layout renders
through the new pipeline. Without a pin, the v1 hardcoded dashboard
keeps rendering verbatim so nothing regresses for users who never
visited
/dashboards.Widget bodies are placeholder copy in this slice. PMS-487 layers the
editor (add / reposition / save) and the per-widget data fetches on
top of this catalog.
Acceptance criteria:
the layout encodes (
render_widget+grid_style).GET /api/v1/dashboards/default(DefaultDashboardPage).ticket split.
#PMS-472
PMS-453 phase 1 stored a per-user `layout` JSONB but the SPA treated it as opaque. PMS-472 ships the read-only view surface: a typed schema (`DashboardLayout { widgets: [{ widget_key, grid_col, grid_row, grid_col_span, grid_row_span, filter_scope? }] }`), a forward-compatible widget catalog (`tickets_by_status`, `time_this_week`, `sla_at_risk`, `open_invoices`, `recent_audit_log`), and a new `/dashboards/:id/view` route that renders each widget into a 12-column CSS grid cell at the encoded coordinates. The existing `/dashboard` entrypoint now hits `GET /dashboards/default` first; if the caller has pinned a saved row, the saved layout renders through the new pipeline. Without a pin, the v1 hardcoded dashboard keeps rendering verbatim so nothing regresses for users who never visited `/dashboards`. Widget bodies are placeholder copy in this slice. PMS-487 layers the editor (add / reposition / save) and the per-widget data fetches on top of this catalog. Acceptance criteria: - The SPA renders a saved dashboard's widgets in the grid positions the layout encodes (`render_widget` + `grid_style`). - The pinned-default dashboard loads on app boot via `GET /api/v1/dashboards/default` (`DefaultDashboardPage`). - Editor + add-widget round-trip deferred to PMS-487 per the original ticket split. #PMS-472PMS-472 shipped the read-only view surface for a saved dashboard's layout. PMS-487 layers the editor and replaces the placeholder widget bodies with real data fetches against existing PSA endpoints. Editor (toggled via an "Edit layout" button on SavedDashboardViewPage): - Per-widget number inputs for grid_col / grid_row / grid_col_span / grid_row_span. Number inputs are the v1 shape - drag-and-drop is nicer UX but locks the project into a heavy dnd dependency the PMS-487 AC explicitly does not require. - "Add widget" panel listing every catalog key as a button; click appends a row to the in-memory draft with sensible defaults (col=1, row=next-after-max, col_span=6, row_span=1). - "Save layout" PATCHes `/dashboards/{id}` with `{layout: ...}` and refetches the row on success. - "Cancel" reverts the draft to the persisted layout. Per-widget bodies: - tickets_by_status: open-by-priority from `/reports/dashboard`. - time_this_week: minutes since Monday from `/time-entries`. - sla_at_risk: at-risk + breached from `/reports/dashboard`. - open_invoices: count + total from `/invoices?status=sent&per_page=50`. - recent_audit_log: last 5 rows of `/audit-log`. Acceptance criteria: - "Edit layout" toggle on SavedDashboardViewPage swaps into editor. - User can add widgets from the catalog, change grid coords, save through `PATCH /dashboards/{id}` (UpdateLayoutBody + on_save). - Each catalog widget renders real data via its own per-widget fetch. - The pinned-default dashboard loads via `GET /dashboards/default` (DefaultDashboardPage, unchanged from PMS-472). Builds on PMS-472 - rebase / merge that branch first. #PMS-487