Add Dashboards UI: PromQL-backed bar/line/pie panels saved per profile (ticket 014)

Backend: replace Profile.dashboards' opaque JSON stub with typed
Dashboard/Panel structs, add ProfileStore CRUD (create/save/list/delete
dashboard) and matching /api/settings/profiles/:name/dashboards[/:id] routes,
with tests covering the HTTP round trip and persistence across a simulated
restart.

Frontend: add recharts (lightweight, React 19-compatible) and a Dashboards
component with a dashboard builder (create dashboards, add/remove/edit panels
with a PromQL query + chart type), live per-panel previews that respect the
active time range and show malformed-query errors inline instead of crashing,
and load/save wired to the new profile-backed persistence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XFUNZwCvz3kcod3352ZR2o
This commit is contained in:
Hugh Kaznowski
2026-09-05 13:29:45 +01:00
co-authored by Claude Sonnet 5
parent ae21a7a0ce
commit 41362aa3d8
9 changed files with 1445 additions and 15 deletions
+2 -2
View File
@@ -3,8 +3,8 @@ import { NavMenu } from './components/NavMenu'
import { FilterBar } from './components/FilterBar'
import { LogTimeline, type TimeRange } from './components/LogTimeline'
import { LogPreview } from './components/LogPreview'
import { ComingSoon } from './components/ComingSoon'
import { Metrics } from './components/Metrics'
import { Dashboards } from './components/Dashboards'
import { fetchLogs, fetchStats, fetchTimeline, type LogEntry, type Stats, type TimelineBucket } from './lib/api'
const POLL_MS = 2000
@@ -56,7 +56,7 @@ export default function App() {
<LogTimeline buckets={buckets} range={range} onSelectRange={setRange} />
<LogPreview logs={logs} />
<Metrics range={range} />
<ComingSoon title="Dashboards" />
<Dashboards range={range} />
</div>
</div>
)