feat(dashboards): MVP backend + grid frontend (PR 1 of 3)#217
Closed
BK1031 wants to merge 3 commits into
Closed
Conversation
PR #1 of the dashboards feature — gets the backend + grid layout in place so the rest of the work is purely widget-side. mapache-go: - New Dashboard + DashboardWidget models. Widget.Config is jsonb so each renderer carries its own type-specific shape without schema churn per widget type. X/Y/W/H are react-grid-layout cell coords. vehicle service: - CRUD endpoints under /dashboards and /dashboards/:id/widgets. - Widget update is granular (PUT per widget) because the grid's drag/resize fires UpdateWidget on every release; bundling the whole dashboard would make every move pay for the full widget payload. - AutoMigrate adds the two new tables. - go.mod gets a `replace` directive against the in-repo mapache-go so adding model types doesn't require a tag-and-release detour. Drop the replace + bump the version once mapache-go is released. kerbecs: - Two new routes: /api/dashboards (list) and /api/dashboards/* (rest). dashboard frontend: - DashboardsPage lists existing dashboards in a card grid with a create dialog. - DashboardDetailsPage embeds react-grid-layout with optimistic position/size persistence and an inline-renamed title. - DashboardWidgetCard is the widget shell — drag handle, title input, remove. The chart pane is a placeholder for PR #1; PR #2 plugs in actual SignalWidget rendering once it's refactored to accept seeded queries. - New sidebar entry "Dashboards" at /dashboards. Out of scope for PR #1 (parked for #2/#3): - Actual chart rendering inside the widget card. - Widget settings panel for editing queries (today's flow seeds them on create; PR #2 adds the editor). - Specialty widget types (gauge, big number, dedicated map). - Sharing / permissions / duplication.
Stacked onto PR #1's foundation: SignalWidget — opt-in embedded mode: - New seedQueries / onQueriesChange props prefill the chip rows from saved widget config and bubble subsequent edits back to the parent. - New seedChartType / onChartTypeChange follow the same contract for the chart-type select. - New refreshIntervalSec prop: when set, the widget re-runs its query every N seconds by folding a monotonic tick into the existing `fetchKey`. The chart's right edge keeps tracking `now` without holding a long-lived stream open. PR-N can drop this for a real SSE-driven aggregation hook against /live/sse for sub-second updates. DashboardWidgetCard: - Embeds the full SignalWidget when type=signal, wired with seed/change props so the widget's queries + chart type persist back through /dashboards/:id/widgets/:wid PUT. - The dashboard's shell (drag handle, title, remove) wraps the SignalWidget so the kebab's own delete/hide actions defer to the outer card. DashboardDetailsPage: - Page-level TimeframePicker (reused from the Signals page) drives every widget. `isRolling` is derived from the timeframe ("Past N" presets or any custom range ending within 5s of now) and flows into each widget; when true, refreshIntervalSec activates 5s polling. - Fetches signal names once per vehicle for the chip builder's autocomplete inside every embedded widget. - ECharts connect group shared across the dashboard so hover/tooltip/ dataZoom sync between panels. Out of scope (follow-ups): - True SSE-driven streaming + client-side incremental aggregation — needed for sub-second blends. The refresh-every-5s pattern here is the smallest end-to-end working version. - Specialty widget types (gauge, big-number, dedicated map) — the widget registry is type-keyed so these slot in cleanly later. - Per-widget timeframe override + per-widget settings dialog.
…ker drawer
Three coupled UX moves on top of the previous chart-rendering commit:
1) SSE-driven live blending
- New `useLiveTrigger` hook opens an EventSource against the live
service's /live/sse endpoint with the signal patterns pulled out of
each query's `where` clause. On each arrival it bumps a throttled
`tick` (default 500ms). The tick folds into SignalWidget's existing
fetchKey, so /query/run re-fires the moment a relevant sample
lands — the backend stays the source of truth for bucket math
(aggregator semantics differ enough across count/sum/avg/min/max/
last/p50/p95/p99/stddev that mirroring them client-side would have
been gnarly + bug-prone).
- Queries with no `where(name = "...")` filter don't subscribe; we'd
otherwise have to listen to every signal on the wire. Add a name
filter to opt into streaming.
- The 5s setInterval refresh stays as a heartbeat — guarantees the
chart still moves forward through signal lulls.
2) Chart-only widget + edit dialog
- New `chartOnly` prop on SignalWidget suppresses the chip-builder
header and chart-type picker, leaving just the canvas. The Card
wrapper drops its border/shadow so the widget reads as inline.
- DashboardWidgetCard renders the chart-only SignalWidget in the
grid cell and a Pencil button in the card header opens a Dialog
containing the full-fidelity SignalWidget (chip rows, chart type
toggle, all the knobs). Card and dialog never both mount at the
same time, so their internal query state can't drift apart; the
card's SignalWidget is keyed on the persisted config so the close-
after-edit path picks up the new seed.
3) Add-widget drawer
- New `Sheet` UI primitive (Radix Dialog with side-anchored
animation, right-edge variant). Reusable for any future right-
edge panel.
- `AddWidgetDrawer` lists every chart type from the existing
CHART_TYPES registry with a one-line description per entry; the
dashboard's "Add widget" button now opens the drawer instead of
dropping a default bar widget directly. PR-N will extend the list
with specialty widget types (gauge, big-number, dedicated map).
Contributor
Author
|
Faded for now — scope got too broad. Branch preserved (bk1031/dashboards-mvp) in case any of the pieces (SSE streaming, drawer, chart-only widget) are useful later. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR #1 of the dashboards feature. The remaining work splits into:
SignalWidgetto accept seeded queries, embed it inDashboardWidgetCard). Add a settings panel to edit queries inline.What landed
Backend (
mapache-go+vehicleservice):Kerbecs:
Dashboard frontend:
Deploy gotchas
Out of scope
Widget settings panel · chart rendering · gauges · big-number widgets · dedicated map widgets · sharing/permissions · dashboard cloning.