Make dashboard prompt ignoreChanges schema version independent

This commit is contained in:
Dominik Prokop 2024-12-18 16:33:41 +01:00
parent 30321a59a9
commit 65466c2ef1
9 changed files with 54 additions and 20 deletions

View File

@ -24,7 +24,7 @@ describe('DashboardPrompt', () => {
describe('when called without original dashboard', () => {
it('then it should return true', () => {
const scene = buildTestScene();
scene.setInitialSaveModel(undefined);
scene.setInitialSaveModel(undefined, undefined);
expect(ignoreChanges(scene)).toBe(true);
});
});
@ -59,7 +59,7 @@ describe('DashboardPrompt', () => {
},
});
const initialSaveModel = transformSceneToSaveModel(scene);
scene.setInitialSaveModel(initialSaveModel);
scene.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
contextSrv.isEditor = false;
@ -76,7 +76,7 @@ describe('DashboardPrompt', () => {
},
});
const initialSaveModel = transformSceneToSaveModel(scene);
scene.setInitialSaveModel(initialSaveModel);
scene.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
contextSrv.isSignedIn = false;
expect(ignoreChanges(scene)).toBe(true);
@ -92,7 +92,7 @@ describe('DashboardPrompt', () => {
},
});
const initialSaveModel = transformSceneToSaveModel(scene);
scene.setInitialSaveModel(initialSaveModel);
scene.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
expect(ignoreChanges(scene)).toBe(true);
});
@ -108,7 +108,7 @@ describe('DashboardPrompt', () => {
},
});
const initialSaveModel = transformSceneToSaveModel(scene);
scene.setInitialSaveModel(initialSaveModel);
scene.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
expect(ignoreChanges(scene)).toBe(true);
});
@ -124,7 +124,7 @@ describe('DashboardPrompt', () => {
},
});
const initialSaveModel = transformSceneToSaveModel(scene);
scene.setInitialSaveModel(initialSaveModel);
scene.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
expect(ignoreChanges(scene)).toBe(undefined);
});

View File

@ -8,7 +8,7 @@ import { Prompt } from 'app/core/components/FormPrompt/Prompt';
import { contextSrv } from 'app/core/services/context_srv';
import { SaveLibraryVizPanelModal } from '../panel-edit/SaveLibraryVizPanelModal';
import { DashboardScene, isV2Dashboard } from '../scene/DashboardScene';
import { DashboardScene } from '../scene/DashboardScene';
import { getLibraryPanelBehavior, isLibraryPanel } from '../utils/utils';
interface DashboardPromptProps {
@ -154,17 +154,14 @@ const getStyles = () => ({
*/
export function ignoreChanges(scene: DashboardScene | null) {
const original = scene?.getInitialSaveModel();
if (original && isV2Dashboard(original)) {
throw new Error('isV2Dashboard is not implemented');
}
const originalVersion = scene?.getInitialVersion();
if (!original) {
return true;
}
// Ignore changes if original is unsaved
if (original.version === 0) {
if (originalVersion === 0) {
return true;
}

View File

@ -215,7 +215,7 @@ function setup() {
dashboard.setState({ $data: undefined });
const initialSaveModel = transformSceneToSaveModel(dashboard);
dashboard.setInitialSaveModel(initialSaveModel);
dashboard.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
cleanUp();
cleanUp = dashboard.activate();

View File

@ -173,7 +173,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
private _prevScrollPos?: number;
// TODO: use feature toggle to allow v2 serializer
private _serializer: DashboardSceneSerializerLike<Dashboard | DashboardV2Spec> = getDashboardSceneSerializer(true);
private _serializer: DashboardSceneSerializerLike<Dashboard | DashboardV2Spec> = getDashboardSceneSerializer();
public constructor(state: Partial<DashboardSceneState>) {
super({
@ -642,9 +642,14 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
return this._serializer.initialSaveModel;
}
public getInitialVersion = () => {
return this._serializer.getInitialVersion();
};
/** Hacky temp function until we refactor transformSaveModelToScene a bit */
public setInitialSaveModel(saveModel?: Dashboard | DashboardV2Spec) {
public setInitialSaveModel(version: number | undefined, saveModel?: Dashboard | DashboardV2Spec) {
this._serializer.initialSaveModel = saveModel;
this._serializer.initialVersion = version;
}
public getTrackingInformation() {

View File

@ -17,6 +17,21 @@ import { findVizPanelByKey } from '../utils/utils';
import { V1DashboardSerializer, V2DashboardSerializer } from './DashboardSceneSerializer';
describe('DashboardSceneSerializer', () => {
it('should allow retrieving initial dashboard version', () => {
const dashboard = transformSaveModelToScene({
dashboard: {
title: 'hello',
uid: 'my-uid',
schemaVersion: 30,
version: 10,
},
meta: {},
});
const initialSaveModel = transformSceneToSaveModel(dashboard);
dashboard.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
expect(dashboard.getInitialVersion()).toBe(10);
});
describe('v1 schema', () => {
it('Can detect no changes', () => {
const dashboard = setup();
@ -160,7 +175,7 @@ describe('DashboardSceneSerializer', () => {
meta: {},
});
const initialSaveModel = transformSceneToSaveModel(dashboard);
dashboard.setInitialSaveModel(initialSaveModel);
dashboard.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
const variable = sceneGraph.lookupVariable('GroupBy', dashboard) as GroupByVariable;
variable.setState({ defaultOptions: [{ text: 'Host', value: 'host' }] });
@ -217,7 +232,7 @@ describe('DashboardSceneSerializer', () => {
});
const initialSaveModel = transformSceneToSaveModel(dashboard);
dashboard.setInitialSaveModel(initialSaveModel);
dashboard.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
const variable = sceneGraph.lookupVariable('adhoc', dashboard) as AdHocFiltersVariable;
variable.setState({ defaultKeys: [{ text: 'Host', value: 'host' }] });
@ -378,7 +393,7 @@ function setup(options: ScenarioOptions = {}) {
});
const initialSaveModel = transformSceneToSaveModel(dashboard);
dashboard.setInitialSaveModel(initialSaveModel);
dashboard.setInitialSaveModel(initialSaveModel.version, initialSaveModel);
return dashboard;
}

View File

@ -17,6 +17,7 @@ export interface DashboardSceneSerializerLike<T> {
* The save model which the dashboard scene was originally created from
*/
initialSaveModel?: T;
initialVersion?: number;
getSaveModel: (s: DashboardScene) => T;
getSaveAsModel: (s: DashboardScene, options: SaveDashboardAsOptions) => T;
getDashboardChangesFromScene: (
@ -29,6 +30,7 @@ export interface DashboardSceneSerializerLike<T> {
) => DashboardChangeInfo;
onSaveComplete(saveModel: T, result: SaveDashboardResponseDTO): void;
getTrackingInformation: () => DashboardTrackingInfo | undefined;
getInitialVersion: () => number | undefined;
}
interface DashboardTrackingInfo {
@ -43,6 +45,7 @@ interface DashboardTrackingInfo {
export class V1DashboardSerializer implements DashboardSceneSerializerLike<Dashboard> {
initialSaveModel?: Dashboard;
initialVersion?: number | undefined;
getSaveModel(s: DashboardScene) {
return transformSceneToSaveModel(s);
@ -111,10 +114,15 @@ export class V1DashboardSerializer implements DashboardSceneSerializerLike<Dashb
}
return undefined;
}
getInitialVersion() {
return this.initialVersion;
}
}
export class V2DashboardSerializer implements DashboardSceneSerializerLike<DashboardV2Spec> {
initialSaveModel?: DashboardV2Spec;
initialVersion?: number | undefined;
getSaveModel(s: DashboardScene) {
return transformSceneToSaveModelSchemaV2(s);
@ -140,6 +148,10 @@ export class V2DashboardSerializer implements DashboardSceneSerializerLike<Dashb
throw new Error('v2 schema: Method not implemented.');
return undefined;
}
getInitialVersion() {
return this.initialVersion;
}
}
export function getDashboardSceneSerializer(

View File

@ -176,6 +176,11 @@ export function transformSaveModelSchemaV2ToScene(dto: DashboardWithAccessInfo<D
}),
});
dashboardScene.setInitialSaveModel(
dto.metadata.resourceVersion ? parseInt(dto.metadata.resourceVersion, 10) : undefined,
dto.spec
);
return dashboardScene;
}

View File

@ -71,7 +71,7 @@ export function transformSaveModelToScene(rsp: DashboardDTO): DashboardScene {
const scene = createDashboardSceneFromDashboardModel(oldModel, rsp.dashboard);
// TODO: refactor createDashboardSceneFromDashboardModel to work on Dashboard schema model
scene.setInitialSaveModel(rsp.dashboard);
scene.setInitialSaveModel(rsp.dashboard.version, rsp.dashboard);
return scene;
}

View File

@ -73,7 +73,7 @@ export class JsonModelEditView extends SceneObjectBase<JsonModelEditViewState> i
const newState = sceneUtils.cloneSceneObjectState(newDashboardScene.state);
dashboard.pauseTrackingChanges();
dashboard.setInitialSaveModel(rsp.dashboard);
dashboard.setInitialSaveModel(rsp.dashboard.version, rsp.dashboard);
dashboard.setState(newState);
this.setState({ jsonText: this.getJsonText() });