feat(dashboards): visual previews + tech marks on template cards#160
Conversation
Template cards were text-only (name, description, badges), so telling
templates apart meant reading every card. Each card now renders a
miniature wireframe of the actual dashboard it creates — widget rects at
their real grid positions with per-type glyphs (smoothed sparkline/area,
bars, stat block, table rows) — plus a technology mark (Postgres, Redis,
Kafka, K8s, Node.js, OpenJDK, …) and a widget-composition line
("4 stats · 3 charts").
The preview geometry is data-derived, not hand-drawn: template metadata
now carries a `preview` field (DashboardTemplatePreviewWidget[]) computed
once per template from its build({}) output, so previews can never drift
from what instantiation produces. Glyph series are seeded from the
template id (deterministic, SSR-stable). The blank template renders a
dashed empty-grid placeholder.
Also fixes the parameter dialog composition: form fields were placed
directly in DialogContent, skipping DialogPanel (the padded body slot),
leaving the fields flush against the popup edge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Your LLM provider API key was rejected. Rotate the key in your provider dashboard, then update the matching GitHub Actions secret. Update repo secret → · Model settings → · Setup docs → · Ask in Discord →
|
| "description_changed", | ||
| "tags_changed", | ||
| "time_range_changed", | ||
| "variables_changed", |
There was a problem hiding this comment.
🟡 Dashboard variable changes are silently ignored in version history, showing "No changes"
The new "variables_changed" change kind is declared (packages/domain/src/http/dashboards.ts:351) and variables is added to the document schema (packages/domain/src/http/dashboards.ts:295), but the change-detection function that produces version history entries never compares the variables field, so a variables-only edit is recorded as "No changes."
Impact: Users editing dashboard variables see a misleading "No changes" label in the version history timeline.
Change-detection function never inspects the new variables field
The summarizeDashboardChange function in apps/api/src/services/dashboard-changes.ts:26-119 checks name, description, tags, timeRange, and widgets for differences between the previous and next dashboard documents. It does not compare the new variables field added to DashboardDocument at packages/domain/src/http/dashboards.ts:305.
When only variables change, no kind is added to the kinds set, so the function falls through to the kinds.size === 0 branch at apps/api/src/services/dashboard-changes.ts:110-111 and returns { kind: "multiple", summary: "No changes" }. The version record is still persisted with the correct snapshot, so there is no data loss, but the change kind and summary shown in the UI are wrong.
A block like the following is needed between the timeRange and widget checks:
if (!sameJson(prev.variables ?? [], next.variables ?? [])) {
kinds.add("variables_changed")
detail = detail ?? "Variables updated"
}Prompt for agents
The PR adds a 'variables' optional field to DashboardDocument and PortableDashboardDocument (packages/domain/src/http/dashboards.ts lines 295 and 305), and adds 'variables_changed' as a new DashboardVersionChangeKind literal (line 351). However, the change-detection function summarizeDashboardChange in apps/api/src/services/dashboard-changes.ts does not compare the variables field between the previous and next dashboard documents. When only variables change, the function returns kind 'multiple' with summary 'No changes', producing a misleading version history entry. To fix this, add a variables comparison block (similar to the existing tags or timeRange checks) in summarizeDashboardChange, between the timeRange check and the widget diffing, using sameJson(prev.variables ?? [], next.variables ?? []) and adding 'variables_changed' to the kinds set when they differ.
Was this helpful? React with 👍 or 👎 to provide feedback.

What
The dashboard template picker (
/dashboards/templates) rendered every template as a text-only card. Each card now shows:4 stats · 3 charts) in mono for quick scanning.How
The preview geometry is derived from the template definitions, not hand-drawn:
DashboardTemplateMetadatagains apreview: DashboardTemplatePreviewWidget[]field (x/y/w/h + kind + title), computed once per template from itsbuild({})output inlistTemplateMetadata(). Chart kind comes fromdisplay.chartId(-area/-bar/default line); unknown visualizations fall back to the table glyph. Previews therefore can't drift from what instantiating the template actually creates.Client-side,
TemplatePreviewrenders a small SVG: series points come from a seeded random walk (FNV-1a + mulberry32 over template id), normalized to the glyph height and drawn as midpoint-smoothed quadratic curves — deterministic, SSR-stable, no data fetching, no charting library. Widget titles are exposed as native<title>tooltips and the SVG carriesrole="img"+aria-label.Also fixes the template parameter dialog composition: the form fields were placed directly inside
DialogContent, skippingDialogPanel(the design system's padded body slot), which left labels/inputs flush against the popup edge. Now composedDialogHeader → DialogPanel → DialogFooterlike the other dialogs, with Enter-to-submit.Notes for review
apps/api/src/dashboard-templates/index.test.ts) asserts every template's preview matches its built widget list, kinds stay within the literal set, and blank stays empty.previewmetadata field is additive; the MCPcreate-dashboardtool readsDASHBOARD_TEMPLATESdirectly and is unaffected.🤖 Generated with Claude Code