mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
DashboardSceneSerializerLike: Update interface to support initial version and snapshot url (#98206)
* Make dashboard prompt ignoreChanges schema version independent * Serializer: add interface for snapshot url retrieval * Revert "Make dashboard prompt ignoreChanges schema version independent" This reverts commit65466c2ef1
. * Add dashbaord version to scene metadata * Add tracking info * Revert "Add tracking info" This reverts commit4c58c6687b
. --------- Co-authored-by: Ivan Ortega <ivanortegaalba@gmail.com>
This commit is contained in:
parent
a37b6f455e
commit
746bde0fac
@ -8,7 +8,7 @@ import { Prompt } from 'app/core/components/FormPrompt/Prompt';
|
|||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
import { SaveLibraryVizPanelModal } from '../panel-edit/SaveLibraryVizPanelModal';
|
import { SaveLibraryVizPanelModal } from '../panel-edit/SaveLibraryVizPanelModal';
|
||||||
import { DashboardScene, isV2Dashboard } from '../scene/DashboardScene';
|
import { DashboardScene } from '../scene/DashboardScene';
|
||||||
import { getLibraryPanelBehavior, isLibraryPanel } from '../utils/utils';
|
import { getLibraryPanelBehavior, isLibraryPanel } from '../utils/utils';
|
||||||
|
|
||||||
interface DashboardPromptProps {
|
interface DashboardPromptProps {
|
||||||
@ -155,16 +155,12 @@ const getStyles = () => ({
|
|||||||
export function ignoreChanges(scene: DashboardScene | null) {
|
export function ignoreChanges(scene: DashboardScene | null) {
|
||||||
const original = scene?.getInitialSaveModel();
|
const original = scene?.getInitialSaveModel();
|
||||||
|
|
||||||
if (original && isV2Dashboard(original)) {
|
|
||||||
throw new Error('isV2Dashboard is not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!original) {
|
if (!original) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore changes if original is unsaved
|
// Ignore changes if original is unsaved
|
||||||
if (original.version === 0) {
|
if (scene?.state.meta.version === 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,6 +168,7 @@ describe('DashboardScene', () => {
|
|||||||
expect(scene.state.isDirty).toBe(false);
|
expect(scene.state.isDirty).toBe(false);
|
||||||
scene.exitEditMode({ skipConfirm: true });
|
scene.exitEditMode({ skipConfirm: true });
|
||||||
expect(scene.state.title).toEqual('Updated title');
|
expect(scene.state.title).toEqual('Updated title');
|
||||||
|
expect(scene.state.meta.version).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should start the detect changes worker', () => {
|
it('Should start the detect changes worker', () => {
|
||||||
|
@ -281,6 +281,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
|||||||
slug: result.slug,
|
slug: result.slug,
|
||||||
folderUid: folderUid,
|
folderUid: folderUid,
|
||||||
isNew: false,
|
isNew: false,
|
||||||
|
version: result.version,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -642,6 +643,10 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
|||||||
return this._serializer.initialSaveModel;
|
return this._serializer.initialSaveModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSnapshotUrl = () => {
|
||||||
|
return this._serializer.getSnapshotUrl();
|
||||||
|
};
|
||||||
|
|
||||||
/** Hacky temp function until we refactor transformSaveModelToScene a bit */
|
/** Hacky temp function until we refactor transformSaveModelToScene a bit */
|
||||||
public setInitialSaveModel(saveModel?: Dashboard | DashboardV2Spec) {
|
public setInitialSaveModel(saveModel?: Dashboard | DashboardV2Spec) {
|
||||||
this._serializer.initialSaveModel = saveModel;
|
this._serializer.initialSaveModel = saveModel;
|
||||||
|
@ -34,7 +34,7 @@ import { DashboardInteractions } from '../utils/interactions';
|
|||||||
import { DynamicDashNavButtonModel, dynamicDashNavActions } from '../utils/registerDynamicDashNavAction';
|
import { DynamicDashNavButtonModel, dynamicDashNavActions } from '../utils/registerDynamicDashNavAction';
|
||||||
import { isLibraryPanel } from '../utils/utils';
|
import { isLibraryPanel } from '../utils/utils';
|
||||||
|
|
||||||
import { DashboardScene, isV2Dashboard } from './DashboardScene';
|
import { DashboardScene } from './DashboardScene';
|
||||||
import { GoToSnapshotOriginButton } from './GoToSnapshotOriginButton';
|
import { GoToSnapshotOriginButton } from './GoToSnapshotOriginButton';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -140,17 +140,9 @@ export function ToolbarActions({ dashboard }: Props) {
|
|||||||
toolbarActions.push({
|
toolbarActions.push({
|
||||||
group: 'icon-actions',
|
group: 'icon-actions',
|
||||||
condition: meta.isSnapshot && !meta.dashboardNotFound && !isEditing,
|
condition: meta.isSnapshot && !meta.dashboardNotFound && !isEditing,
|
||||||
render: () => {
|
render: () => (
|
||||||
const saveModel = dashboard.getInitialSaveModel();
|
<GoToSnapshotOriginButton key="go-to-snapshot-origin" originalURL={dashboard.getSnapshotUrl() ?? ''} />
|
||||||
|
),
|
||||||
if (saveModel && isV2Dashboard(saveModel)) {
|
|
||||||
throw new Error('v2 schema not implemented');
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<GoToSnapshotOriginButton key="go-to-snapshot-origin" originalURL={saveModel?.snapshot?.originalUrl ?? ''} />
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isEditingPanel && !isEditing) {
|
if (!isEditingPanel && !isEditing) {
|
||||||
|
@ -326,6 +326,33 @@ describe('DashboardSceneSerializer', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should allow retrieving snapshot url', () => {
|
||||||
|
const initialSaveModel: Dashboard = {
|
||||||
|
snapshot: {
|
||||||
|
originalUrl: 'originalUrl/snapshot',
|
||||||
|
created: '2023-01-01T00:00:00Z',
|
||||||
|
expires: '2023-12-31T23:59:59Z',
|
||||||
|
external: false,
|
||||||
|
externalUrl: '',
|
||||||
|
id: 1,
|
||||||
|
key: 'snapshot-key',
|
||||||
|
name: 'snapshot-name',
|
||||||
|
orgId: 1,
|
||||||
|
updated: '2023-01-01T00:00:00Z',
|
||||||
|
userId: 1,
|
||||||
|
},
|
||||||
|
title: 'hello',
|
||||||
|
uid: 'my-uid',
|
||||||
|
schemaVersion: 30,
|
||||||
|
version: 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
const serializer = new V1DashboardSerializer();
|
||||||
|
serializer.initialSaveModel = initialSaveModel;
|
||||||
|
|
||||||
|
expect(serializer.getSnapshotUrl()).toBe('originalUrl/snapshot');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('v2 schema', () => {
|
describe('v2 schema', () => {
|
||||||
@ -563,6 +590,11 @@ describe('DashboardSceneSerializer', () => {
|
|||||||
})
|
})
|
||||||
).toThrow('Method not implemented.');
|
).toThrow('Method not implemented.');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw on getSnapshotUrl', () => {
|
||||||
|
const serializer = new V2DashboardSerializer();
|
||||||
|
expect(() => serializer.getSnapshotUrl()).toThrow('Method not implemented.');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ export interface DashboardSceneSerializerLike<T> {
|
|||||||
) => DashboardChangeInfo;
|
) => DashboardChangeInfo;
|
||||||
onSaveComplete(saveModel: T, result: SaveDashboardResponseDTO): void;
|
onSaveComplete(saveModel: T, result: SaveDashboardResponseDTO): void;
|
||||||
getTrackingInformation: () => DashboardTrackingInfo | undefined;
|
getTrackingInformation: () => DashboardTrackingInfo | undefined;
|
||||||
|
getSnapshotUrl: () => string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DashboardTrackingInfo {
|
interface DashboardTrackingInfo {
|
||||||
@ -111,6 +112,10 @@ export class V1DashboardSerializer implements DashboardSceneSerializerLike<Dashb
|
|||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSnapshotUrl() {
|
||||||
|
return this.initialSaveModel?.snapshot?.originalUrl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class V2DashboardSerializer implements DashboardSceneSerializerLike<DashboardV2Spec> {
|
export class V2DashboardSerializer implements DashboardSceneSerializerLike<DashboardV2Spec> {
|
||||||
@ -158,6 +163,11 @@ export class V2DashboardSerializer implements DashboardSceneSerializerLike<Dashb
|
|||||||
throw new Error('v2 schema: Method not implemented.');
|
throw new Error('v2 schema: Method not implemented.');
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSnapshotUrl() {
|
||||||
|
throw new Error('v2 schema: Method not implemented.');
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getDashboardSceneSerializer(): DashboardSceneSerializerLike<Dashboard | DashboardV2Spec> {
|
export function getDashboardSceneSerializer(): DashboardSceneSerializerLike<Dashboard | DashboardV2Spec> {
|
||||||
|
@ -120,7 +120,9 @@ export function transformSaveModelSchemaV2ToScene(dto: DashboardWithAccessInfo<D
|
|||||||
isDirty: false,
|
isDirty: false,
|
||||||
links: dashboard.links,
|
links: dashboard.links,
|
||||||
// TODO: Combine access and metadata to compose the V1 meta object
|
// TODO: Combine access and metadata to compose the V1 meta object
|
||||||
meta: {},
|
meta: {
|
||||||
|
version: parseInt(metadata.resourceVersion, 10),
|
||||||
|
},
|
||||||
tags: dashboard.tags,
|
tags: dashboard.tags,
|
||||||
title: dashboard.title,
|
title: dashboard.title,
|
||||||
uid: metadata.name,
|
uid: metadata.name,
|
||||||
|
@ -118,6 +118,7 @@ export function ensureV1Response(
|
|||||||
isFolder: false,
|
isFolder: false,
|
||||||
uid: dashboard.metadata.name,
|
uid: dashboard.metadata.name,
|
||||||
k8s: dashboard.metadata,
|
k8s: dashboard.metadata,
|
||||||
|
version: parseInt(dashboard.metadata.resourceVersion, 10),
|
||||||
},
|
},
|
||||||
dashboard: spec,
|
dashboard: spec,
|
||||||
};
|
};
|
||||||
|
@ -88,6 +88,7 @@ export class K8sDashboardAPI implements DashboardAPI<DashboardDTO> {
|
|||||||
isFolder: false,
|
isFolder: false,
|
||||||
uid: dash.metadata.name,
|
uid: dash.metadata.name,
|
||||||
k8s: dash.metadata,
|
k8s: dash.metadata,
|
||||||
|
version: parseInt(dash.metadata.resourceVersion, 10),
|
||||||
},
|
},
|
||||||
dashboard: dash.spec,
|
dashboard: dash.spec,
|
||||||
};
|
};
|
||||||
|
@ -69,6 +69,7 @@ export interface DashboardMeta {
|
|||||||
dashboardNotFound?: boolean;
|
dashboardNotFound?: boolean;
|
||||||
isEmbedded?: boolean;
|
isEmbedded?: boolean;
|
||||||
isNew?: boolean;
|
isNew?: boolean;
|
||||||
|
version?: number;
|
||||||
|
|
||||||
// When loaded from kubernetes, we stick the raw metadata here
|
// When loaded from kubernetes, we stick the raw metadata here
|
||||||
// yes weird, but this means all the editor structures can exist unchanged
|
// yes weird, but this means all the editor structures can exist unchanged
|
||||||
|
Loading…
Reference in New Issue
Block a user