feat(dashboards): Add UI to view dashboard revisions#113441
feat(dashboards): Add UI to view dashboard revisions#113441
Conversation
Adds a clock icon button to the dashboard controls toolbar (gated behind the dashboards-revisions feature flag) that opens a modal listing all revisions for the current dashboard. Each row shows the revision title, who created it, and a relative timestamp via TimeSince. The revisions endpoint is only called when the modal is opened, not on page load. Refs DAIN-1545 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Covers: feature flag gate, prebuilt/default-overview exclusions, lazy API fetching (endpoint not called until modal opens), revision list rendering, createdBy fallbacks, and the empty state. Also moves the feature flag check inside the component for testability, removing the Feature wrapper from controls.tsx. Refs DAIN-1545 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ce551f2. Configure here.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Show an error state (Alert danger) when the revisions API request fails instead of silently falling through to the empty state - Move typography (font-weight, font-size, color) out of the Th styled component into Text primitives, keeping styled components layout-only - Remove unused orgSlug prop from DashboardRevisionsModal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a muted grey tag to revisions created as a pre-restore snapshot. The source type is narrowed to 'edit' | 'pre-restore' to match the updated backend value. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| { | ||
| staleTime: 30_000, | ||
| enabled, | ||
| } |
There was a problem hiding this comment.
When we actually restore the revision, or create a new one, it would be a good idea to invalidate the cache for the next request to this endpoint.
There was a problem hiding this comment.
Okay, added invalidation on edits to the dashboard, which would make a new revision. I'll do the same when we allow restore.
| export function makeDashboardRevisionsQueryKey(orgSlug: string, dashboardId: string) { | ||
| return [ | ||
| getApiUrl('/organizations/$organizationIdOrSlug/dashboards/$dashboardId/revisions/', { | ||
| path: {organizationIdOrSlug: orgSlug, dashboardId}, | ||
| }), | ||
| ] as const; | ||
| } | ||
|
|
There was a problem hiding this comment.
I would move this into the file with the hook as it's directly related to that and only used there
| enabled = true, | ||
| }: UseDashboardRevisionsOptions) { | ||
| const organization = useOrganization(); | ||
| return useApiQuery<DashboardRevision[]>( |
There was a problem hiding this comment.
I think thew new pattern is to use useQuery + apiOptions and not useApiQuery
| ); | ||
| } | ||
|
|
||
| function RevisionList({revisions}: {revisions: DashboardRevision[]}) { |
There was a problem hiding this comment.
instead of using the <Table> component here we have a <SimpleTable> core component that i think would be better to use. Not sure if the table is going to stick around or continue to be formatted like this but I still think it's good practice to use the design system!
There was a problem hiding this comment.
Thank you - it looks much nicer with that change!
- Switch useDashboardRevisions to useQuery + apiOptions (new preferred pattern) - Move DashboardRevision type and query options factory to the hook file since they are only used there; export for future cache invalidation - Replace custom styled table with SimpleTable core component Co-Authored-By: Claude Sonnet 4 <noreply@example.com>
Remove the exported makeDashboardRevisionsQueryOptions helper since nothing uses it yet — knip flagged it as an unused export. The query options can be exported when a restore action needs to invalidate the cache. Co-Authored-By: Claude Sonnet 4 <noreply@example.com>
After any successful updateDashboard call, invalidate the revisions query so the next modal open reflects the newly created revision immediately rather than serving stale cached data. Co-Authored-By: Claude Sonnet 4 <noreply@example.com>

Adds a clock icon button to the dashboard controls toolbar that opens a modal listing the revision history for the current dashboard. Each row shows the revision title, who created it, and a relative timestamp.
The button is gated behind the
dashboards-revisionsfeature flag and hidden for prebuilt and default-overview dashboards (which have no stored revisions). The revisions endpoint is not called until the modal is opened — no eager fetch on page load.Refs DAIN-1545