mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboards: It always detect changes when saving an existing dashboard (#76116)
Deep clone originalDashboard to avoid mutations by object reference
This commit is contained in:
parent
4d1f8f21bf
commit
1a96f3742f
@ -1,7 +1,7 @@
|
|||||||
import { keys as _keys } from 'lodash';
|
import { keys as _keys } from 'lodash';
|
||||||
|
|
||||||
import { dateTime, TimeRange, VariableHide } from '@grafana/data';
|
import { dateTime, TimeRange, VariableHide } from '@grafana/data';
|
||||||
import { defaultVariableModel } from '@grafana/schema';
|
import { Dashboard, defaultVariableModel } from '@grafana/schema';
|
||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
|
|
||||||
import { getDashboardModel } from '../../../../test/helpers/getDashboardModel';
|
import { getDashboardModel } from '../../../../test/helpers/getDashboardModel';
|
||||||
@ -52,6 +52,29 @@ describe('DashboardModel', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when storing original dashboard data', () => {
|
||||||
|
let originalDashboard: Dashboard = {
|
||||||
|
editable: true,
|
||||||
|
graphTooltip: 0,
|
||||||
|
schemaVersion: 1,
|
||||||
|
timezone: '',
|
||||||
|
title: 'original.title',
|
||||||
|
};
|
||||||
|
let model: DashboardModel;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
model = new DashboardModel(originalDashboard);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should be returned from getOriginalDashboard without modifications', () => {
|
||||||
|
expect(model.getOriginalDashboard()).toEqual(originalDashboard);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return a copy of the provided object', () => {
|
||||||
|
expect(model.getOriginalDashboard()).not.toBe(originalDashboard);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when getting next panel id', () => {
|
describe('when getting next panel id', () => {
|
||||||
let model: DashboardModel;
|
let model: DashboardModel;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import { GRID_CELL_HEIGHT, GRID_CELL_VMARGIN, GRID_COLUMN_COUNT, REPEAT_DIR_VERT
|
|||||||
import { contextSrv } from 'app/core/services/context_srv';
|
import { contextSrv } from 'app/core/services/context_srv';
|
||||||
import { sortedDeepCloneWithoutNulls } from 'app/core/utils/object';
|
import { sortedDeepCloneWithoutNulls } from 'app/core/utils/object';
|
||||||
import { isAngularDatasourcePlugin } from 'app/features/plugins/angularDeprecation/utils';
|
import { isAngularDatasourcePlugin } from 'app/features/plugins/angularDeprecation/utils';
|
||||||
|
import { deepFreeze } from 'app/features/plugins/extensions/utils';
|
||||||
import { variableAdapters } from 'app/features/variables/adapters';
|
import { variableAdapters } from 'app/features/variables/adapters';
|
||||||
import { onTimeRangeUpdated } from 'app/features/variables/state/actions';
|
import { onTimeRangeUpdated } from 'app/features/variables/state/actions';
|
||||||
import { GetVariables, getVariablesByKey } from 'app/features/variables/state/selectors';
|
import { GetVariables, getVariablesByKey } from 'app/features/variables/state/selectors';
|
||||||
@ -172,7 +173,8 @@ export class DashboardModel implements TimeModel {
|
|||||||
this.links = data.links ?? [];
|
this.links = data.links ?? [];
|
||||||
this.gnetId = data.gnetId || null;
|
this.gnetId = data.gnetId || null;
|
||||||
this.panels = map(data.panels ?? [], (panelData: any) => new PanelModel(panelData));
|
this.panels = map(data.panels ?? [], (panelData: any) => new PanelModel(panelData));
|
||||||
this.originalDashboard = data;
|
// Deep clone original dashboard to avoid mutations by object reference
|
||||||
|
this.originalDashboard = cloneDeep(data);
|
||||||
this.ensurePanelsHaveUniqueIds();
|
this.ensurePanelsHaveUniqueIds();
|
||||||
this.formatDate = this.formatDate.bind(this);
|
this.formatDate = this.formatDate.bind(this);
|
||||||
|
|
||||||
@ -1081,7 +1083,7 @@ export class DashboardModel implements TimeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resetOriginalTime() {
|
resetOriginalTime() {
|
||||||
this.originalTime = cloneDeep(this.time);
|
this.originalTime = deepFreeze(this.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasTimeChanged() {
|
hasTimeChanged() {
|
||||||
@ -1267,8 +1269,8 @@ export class DashboardModel implements TimeModel {
|
|||||||
return variables.map((variable) => ({
|
return variables.map((variable) => ({
|
||||||
name: variable.name,
|
name: variable.name,
|
||||||
type: variable.type,
|
type: variable.type,
|
||||||
current: cloneDeep(variable.current),
|
current: deepFreeze(variable.current),
|
||||||
filters: cloneDeep(variable.filters),
|
filters: deepFreeze(variable.filters),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user