From 2fab168fb1f26bf10c9a1791bac6a65c59e0bcf3 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Thu, 27 Jun 2024 12:08:46 +0300 Subject: [PATCH] history UI --- .../settings/VersionsEditView.tsx | 22 +++++----- .../version-history/HistorySrv.test.ts | 14 +++--- .../settings/version-history/HistorySrv.ts | 44 ++++++++++++------- .../version-history/VersionHistoryHeader.tsx | 4 +- .../version-history/VersionHistoryTable.tsx | 6 +-- .../DashboardSettings/VersionsSettings.tsx | 12 ++--- 6 files changed, 57 insertions(+), 45 deletions(-) diff --git a/public/app/features/dashboard-scene/settings/VersionsEditView.tsx b/public/app/features/dashboard-scene/settings/VersionsEditView.tsx index c2acbb9b7af..64dce2537b5 100644 --- a/public/app/features/dashboard-scene/settings/VersionsEditView.tsx +++ b/public/app/features/dashboard-scene/settings/VersionsEditView.tsx @@ -11,17 +11,17 @@ import { getDashboardSceneFor } from '../utils/utils'; import { DashboardEditView, DashboardEditViewState, useDashboardEditPageNav } from './utils'; import { - RevisionsModel, VersionHistoryComparison, VersionHistoryHeader, VersionHistoryTable, VersionsHistoryButtons, - historySrv, } from './version-history'; +import { VersionModel, getHistorySrv } from './version-history/HistorySrv'; export const VERSIONS_FETCH_LIMIT = 10; -export type DecoratedRevisionModel = RevisionsModel & { +export type DecoratedRevisionModel = VersionModel & { + checked: boolean; createdDateString: string; ageString: string; }; @@ -102,7 +102,7 @@ export class VersionsEditView extends SceneObjectBase imp this.setState({ isAppending: append }); - historySrv + getHistorySrv() .getHistoryList(uid, { limit: this._limit, start: this._start }) .then((result) => { this.setState({ @@ -128,8 +128,8 @@ export class VersionsEditView extends SceneObjectBase imp return; } - const lhs = await historySrv.getDashboardVersion(this._dashboard.state.uid, baseInfo.version); - const rhs = await historySrv.getDashboardVersion(this._dashboard.state.uid, newInfo.version); + const lhs = await getHistorySrv().getDashboardVersion(this._dashboard.state.uid, baseInfo.version); + const rhs = await getHistorySrv().getDashboardVersion(this._dashboard.state.uid, newInfo.version); this.setState({ baseInfo, @@ -138,8 +138,8 @@ export class VersionsEditView extends SceneObjectBase imp newInfo, viewMode: 'compare', diffData: { - lhs: lhs.data, - rhs: rhs.data, + lhs: JSON.stringify(lhs), + rhs: JSON.stringify(rhs), }, }); }; @@ -158,15 +158,15 @@ export class VersionsEditView extends SceneObjectBase imp }); }; - public onCheck = (ev: React.FormEvent, versionId: number) => { + public onCheck = (ev: React.FormEvent, versionId: number|string) => { this.setState({ versions: this.versions.map((version) => - version.id === versionId ? { ...version, checked: ev.currentTarget.checked } : version + version.version === versionId ? { ...version, checked: ev.currentTarget.checked } : version ), }); }; - private decorateVersions(versions: RevisionsModel[]): DecoratedRevisionModel[] { + private decorateVersions(versions: VersionModel[]): DecoratedRevisionModel[] { const timeZone = this.getTimeRange().getTimeZone(); return versions.map((version) => { diff --git a/public/app/features/dashboard-scene/settings/version-history/HistorySrv.test.ts b/public/app/features/dashboard-scene/settings/version-history/HistorySrv.test.ts index c2caee31a0e..e7bc09af7d9 100644 --- a/public/app/features/dashboard-scene/settings/version-history/HistorySrv.test.ts +++ b/public/app/features/dashboard-scene/settings/version-history/HistorySrv.test.ts @@ -1,6 +1,6 @@ import { createDashboardModelFixture } from 'app/features/dashboard/state/__fixtures__/dashboardFixtures'; -import { HistorySrv } from './HistorySrv'; +import { getHistorySrv } from './HistorySrv'; import { restore, versions } from './__mocks__/dashboardHistoryMocks'; const getMock = jest.fn().mockResolvedValue({}); @@ -27,7 +27,7 @@ describe('historySrv', () => { const versionsResponse = versions(); const restoreResponse = restore; - let historySrv = new HistorySrv(); + let historySrv = getHistorySrv(); const dash = createDashboardModelFixture({ uid: '_U4zObQMz' }); const emptyDash = createDashboardModelFixture(); @@ -40,7 +40,7 @@ describe('historySrv', () => { describe('getHistoryList', () => { it('should return a versions array for the given dashboard id', () => { getMock.mockImplementation(() => Promise.resolve(versionsResponse)); - historySrv = new HistorySrv(); + historySrv = getHistorySrv(); return historySrv.getHistoryList(dash.uid, historyListOpts).then((versions) => { expect(versions).toEqual(versionsResponse); @@ -63,7 +63,7 @@ describe('historySrv', () => { describe('getDashboardVersion', () => { it('should return a version object for the given dashboard id and version', () => { getMock.mockImplementation(() => Promise.resolve(versionsResponse[0])); - historySrv = new HistorySrv(); + historySrv = getHistorySrv(); return historySrv.getDashboardVersion(dash.uid, 4).then((version) => { expect(version).toEqual(versionsResponse[0]); @@ -71,7 +71,7 @@ describe('historySrv', () => { }); it('should return an empty object when not given an id', async () => { - historySrv = new HistorySrv(); + historySrv = getHistorySrv(); const rsp = await historySrv.getDashboardVersion(emptyDash.uid, 6); expect(rsp).toEqual({}); @@ -82,14 +82,14 @@ describe('historySrv', () => { it('should return a success response given valid parameters', () => { const version = 6; postMock.mockImplementation(() => Promise.resolve(restoreResponse(version))); - historySrv = new HistorySrv(); + historySrv = getHistorySrv(); return historySrv.restoreDashboard(dash.uid, version).then((response) => { expect(response).toEqual(restoreResponse(version)); }); }); it('should return an empty object when not given an id', async () => { - historySrv = new HistorySrv(); + historySrv = getHistorySrv(); const rsp = await historySrv.restoreDashboard(emptyDash.uid, 6); expect(rsp).toEqual({}); }); diff --git a/public/app/features/dashboard-scene/settings/version-history/HistorySrv.ts b/public/app/features/dashboard-scene/settings/version-history/HistorySrv.ts index 61312b8ad45..ece6206c22c 100644 --- a/public/app/features/dashboard-scene/settings/version-history/HistorySrv.ts +++ b/public/app/features/dashboard-scene/settings/version-history/HistorySrv.ts @@ -1,43 +1,48 @@ import { getBackendSrv } from '@grafana/runtime'; import { Dashboard } from '@grafana/schema'; +import { SaveDashboardResponseDTO } from 'app/types'; export interface HistoryListOpts { limit: number; start: number; } -export interface RevisionsModel { - id: number; - checked: boolean; +// The raw version from +export interface VersionModel { uid: string; - parentVersion: number; - version: number; - created: Date; + version: number | string; // resourceVersion in k8s + created: string; createdBy: string; message: string; - data: Dashboard; } -export class HistorySrv { +export interface HistorySrv { + getHistoryList(dashboardUID: string, options: HistoryListOpts): Promise; + getDashboardVersion(dashboardUID: string, version: number | string): Promise; // Just the spec (for now) + restoreDashboard(dashboardUID: string, version: number | string): Promise; +} + +class LegacyHistorySrv implements HistorySrv { getHistoryList(dashboardUID: string, options: HistoryListOpts) { if (typeof dashboardUID !== 'string') { return Promise.resolve([]); } - return getBackendSrv().get(`api/dashboards/uid/${dashboardUID}/versions`, options); + return getBackendSrv().get(`api/dashboards/uid/${dashboardUID}/versions`, options); } - getDashboardVersion(dashboardUID: string, version: number) { + async getDashboardVersion(dashboardUID: string, version: number): Promise { if (typeof dashboardUID !== 'string') { - return Promise.resolve({}); + return Promise.reject('invalid uid') } - return getBackendSrv().get(`api/dashboards/uid/${dashboardUID}/versions/${version}`); + const info = await getBackendSrv().get(`api/dashboards/uid/${dashboardUID}/versions/${version}`); + return info.data; // the dashboard body } - restoreDashboard(dashboardUID: string, version: number) { + restoreDashboard(dashboardUID: string, version: number): Promise { if (typeof dashboardUID !== 'string') { - return Promise.resolve({}); + return Promise.reject('invalid uid') } const url = `api/dashboards/uid/${dashboardUID}/restore`; @@ -46,5 +51,12 @@ export class HistorySrv { } } -const historySrv = new HistorySrv(); -export { historySrv }; + +let historySrv: HistorySrv|undefined = undefined; + +export function getHistorySrv(): HistorySrv { + if (!historySrv) { + historySrv = new LegacyHistorySrv() + } + return historySrv +} diff --git a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.tsx b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.tsx index 05987ee2838..73a7e1f6af6 100644 --- a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.tsx +++ b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryHeader.tsx @@ -6,8 +6,8 @@ import { Icon, IconButton, useStyles2 } from '@grafana/ui'; type VersionHistoryHeaderProps = { onClick?: () => void; - baseVersion?: number; - newVersion?: number; + baseVersion?: number | string; + newVersion?: number | string; isNewLatest?: boolean; }; diff --git a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx index 5ae97bc63e7..b5aa53a230b 100644 --- a/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx +++ b/public/app/features/dashboard-scene/settings/version-history/VersionHistoryTable.tsx @@ -11,7 +11,7 @@ import { RevertDashboardModal } from './RevertDashboardModal'; type VersionsTableProps = { versions: DecoratedRevisionModel[]; canCompare: boolean; - onCheck: (ev: React.FormEvent, versionId: number) => void; + onCheck: (ev: React.FormEvent, versionId: number | string) => void; onRestore: (version: DecoratedRevisionModel) => Promise; }; @@ -33,7 +33,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore } {versions.map((version, idx) => ( - + onCheck(ev, version.id)} + onChange={(ev) => onCheck(ev, version.version)} disabled={!version.checked && canCompare} /> diff --git a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx index c22f31c9437..30bd8138bd8 100644 --- a/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx +++ b/public/app/features/dashboard/components/DashboardSettings/VersionsSettings.tsx @@ -4,11 +4,11 @@ import * as React from 'react'; import { Spinner, HorizontalGroup } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { - historySrv, RevisionsModel, VersionHistoryHeader, VersionsHistoryButtons, } from 'app/features/dashboard-scene/settings/version-history'; +import { getHistorySrv } from 'app/features/dashboard-scene/settings/version-history/HistorySrv'; import { VersionHistoryComparison } from '../VersionHistory/VersionHistoryComparison'; import { VersionHistoryTable } from '../VersionHistory/VersionHistoryTable'; @@ -62,7 +62,7 @@ export class VersionsSettings extends PureComponent { getVersions = (append = false) => { this.setState({ isAppending: append }); - historySrv + getHistorySrv() .getHistoryList(this.props.dashboard.uid, { limit: this.limit, start: this.start }) .then((res) => { this.setState({ @@ -84,8 +84,8 @@ export class VersionsSettings extends PureComponent { isLoading: true, }); - const lhs = await historySrv.getDashboardVersion(this.props.dashboard.uid, baseInfo.version); - const rhs = await historySrv.getDashboardVersion(this.props.dashboard.uid, newInfo.version); + const lhs = await getHistorySrv().getDashboardVersion(this.props.dashboard.uid, baseInfo.version); + const rhs = await getHistorySrv().getDashboardVersion(this.props.dashboard.uid, newInfo.version); this.setState({ baseInfo, @@ -94,8 +94,8 @@ export class VersionsSettings extends PureComponent { newInfo, viewMode: 'compare', diffData: { - lhs: lhs.data, - rhs: rhs.data, + lhs: JSON.stringify(lhs), + rhs: JSON.stringify(rhs), }, }); };