history UI
This commit is contained in:
@@ -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<VersionsEditViewState> 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<VersionsEditViewState> 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<VersionsEditViewState> 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<VersionsEditViewState> imp
|
||||
});
|
||||
};
|
||||
|
||||
public onCheck = (ev: React.FormEvent<HTMLInputElement>, versionId: number) => {
|
||||
public onCheck = (ev: React.FormEvent<HTMLInputElement>, 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) => {
|
||||
|
||||
@@ -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({});
|
||||
});
|
||||
|
||||
@@ -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<VersionModel[]>;
|
||||
getDashboardVersion(dashboardUID: string, version: number | string): Promise<Dashboard>; // Just the spec (for now)
|
||||
restoreDashboard(dashboardUID: string, version: number | string): Promise<SaveDashboardResponseDTO>;
|
||||
}
|
||||
|
||||
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<VersionModel[]>(`api/dashboards/uid/${dashboardUID}/versions`, options);
|
||||
}
|
||||
|
||||
getDashboardVersion(dashboardUID: string, version: number) {
|
||||
async getDashboardVersion(dashboardUID: string, version: number): Promise<Dashboard> {
|
||||
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<SaveDashboardResponseDTO> {
|
||||
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
|
||||
}
|
||||
|
||||
+2
-2
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -11,7 +11,7 @@ import { RevertDashboardModal } from './RevertDashboardModal';
|
||||
type VersionsTableProps = {
|
||||
versions: DecoratedRevisionModel[];
|
||||
canCompare: boolean;
|
||||
onCheck: (ev: React.FormEvent<HTMLInputElement>, versionId: number) => void;
|
||||
onCheck: (ev: React.FormEvent<HTMLInputElement>, versionId: number | string) => void;
|
||||
onRestore: (version: DecoratedRevisionModel) => Promise<boolean>;
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore }
|
||||
</thead>
|
||||
<tbody>
|
||||
{versions.map((version, idx) => (
|
||||
<tr key={version.id}>
|
||||
<tr key={version.version}>
|
||||
<td>
|
||||
<Checkbox
|
||||
aria-label={`Toggle selection of version ${version.version}`}
|
||||
@@ -41,7 +41,7 @@ export const VersionHistoryTable = ({ versions, canCompare, onCheck, onRestore }
|
||||
display: 'inline',
|
||||
})}
|
||||
checked={version.checked}
|
||||
onChange={(ev) => onCheck(ev, version.id)}
|
||||
onChange={(ev) => onCheck(ev, version.version)}
|
||||
disabled={!version.checked && canCompare}
|
||||
/>
|
||||
</td>
|
||||
|
||||
@@ -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<Props, State> {
|
||||
|
||||
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<Props, State> {
|
||||
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<Props, State> {
|
||||
newInfo,
|
||||
viewMode: 'compare',
|
||||
diffData: {
|
||||
lhs: lhs.data,
|
||||
rhs: rhs.data,
|
||||
lhs: JSON.stringify(lhs),
|
||||
rhs: JSON.stringify(rhs),
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user