mirror of
https://github.com/grafana/grafana.git
synced 2025-01-24 07:17:08 -06:00
Dashboard: Don't show unsaved changes modal for automatic schema changes (#50822)
* Dashboard: Don't show unsaved changes modal for automatic schema changes * More refinements * Fix logic in updateGridPos
This commit is contained in:
parent
eb25d8df89
commit
7e22b8e6fb
@ -1,3 +1,5 @@
|
||||
import { getPanelPlugin } from 'app/features/plugins/__mocks__/pluginMocks';
|
||||
|
||||
import { setContextSrv } from '../../../../core/services/context_srv';
|
||||
import { DashboardModel } from '../../state/DashboardModel';
|
||||
import { PanelModel } from '../../state/PanelModel';
|
||||
@ -138,6 +140,17 @@ describe('DashboardPrompt', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('Should ignore panel schema migrations', () => {
|
||||
const { original, dash } = getTestContext();
|
||||
const plugin = getPanelPlugin({}).setMigrationHandler((panel) => {
|
||||
delete (panel as any).legend;
|
||||
return { option1: 'Aasd' };
|
||||
});
|
||||
|
||||
dash.panels[0].pluginLoaded(plugin);
|
||||
expect(hasChanges(dash, original)).toBe(false);
|
||||
});
|
||||
|
||||
describe('when called with fromFile', () => {
|
||||
it('then it should return true', () => {
|
||||
const { original, dash } = getTestContext();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as H from 'history';
|
||||
import { each, filter, find } from 'lodash';
|
||||
import { each, find } from 'lodash';
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Prompt } from 'react-router-dom';
|
||||
@ -184,22 +184,7 @@ function cleanDashboardFromIgnoredChanges(dashData: any) {
|
||||
// ignore iteration property
|
||||
delete dash.iteration;
|
||||
|
||||
dash.panels = filter(dash.panels, (panel) => {
|
||||
if (panel.repeatPanelId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// remove scopedVars
|
||||
panel.scopedVars = undefined;
|
||||
|
||||
// ignore panel legend sort
|
||||
if (panel.legend) {
|
||||
delete panel.legend.sort;
|
||||
delete panel.legend.sortDesc;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
dash.panels = [];
|
||||
|
||||
// ignore template variable values
|
||||
each(dash.getVariables(), (variable: any) => {
|
||||
@ -212,6 +197,10 @@ function cleanDashboardFromIgnoredChanges(dashData: any) {
|
||||
}
|
||||
|
||||
export function hasChanges(current: DashboardModel, original: any) {
|
||||
if (current.hasUnsavedChanges()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const currentClean = cleanDashboardFromIgnoredChanges(current.getSaveModelClone());
|
||||
const originalClean = cleanDashboardFromIgnoredChanges(original);
|
||||
|
||||
|
@ -50,8 +50,8 @@ export class DashboardRow extends React.Component<DashboardRowProps, any> {
|
||||
};
|
||||
|
||||
onUpdate = (title: string, repeat?: string | null) => {
|
||||
this.props.panel['title'] = title;
|
||||
this.props.panel['repeat'] = repeat ?? undefined;
|
||||
this.props.panel.setProperty('title', title);
|
||||
this.props.panel.setProperty('repeat', repeat ?? undefined);
|
||||
this.props.panel.render();
|
||||
this.props.dashboard.processRepeats();
|
||||
this.forceUpdate();
|
||||
|
@ -122,7 +122,6 @@ export class DashboardGridUnconnected extends PureComponent<Props, State> {
|
||||
onResize: ItemCallback = (layout, oldItem, newItem) => {
|
||||
const panel = this.panelMap[newItem.i!];
|
||||
panel.updateGridPos(newItem);
|
||||
panel.configRev++; // trigger change handler
|
||||
};
|
||||
|
||||
onResizeStop: ItemCallback = (layout, oldItem, newItem) => {
|
||||
|
@ -367,6 +367,15 @@ describe('DashboardModel', () => {
|
||||
dashboard.toggleRow(dashboard.panels[1]);
|
||||
});
|
||||
|
||||
it('should not impact hasUnsavedChanges', () => {
|
||||
expect(dashboard.hasUnsavedChanges()).toBe(false);
|
||||
});
|
||||
|
||||
it('should impact hasUnsavedChanges if panels have changes when row is collapsed', () => {
|
||||
dashboard.panels[0].setProperty('title', 'new title');
|
||||
expect(dashboard.hasUnsavedChanges()).toBe(true);
|
||||
});
|
||||
|
||||
it('should remove panels and put them inside collapsed row', () => {
|
||||
expect(dashboard.panels.length).toBe(3);
|
||||
expect(dashboard.panels[1].panels?.length).toBe(2);
|
||||
|
@ -499,10 +499,6 @@ export class DashboardModel implements TimeModel {
|
||||
|
||||
hasUnsavedChanges() {
|
||||
const changedPanel = this.panels.find((p) => p.hasChanged);
|
||||
if (changedPanel) {
|
||||
console.log('Panel has changed', changedPanel);
|
||||
}
|
||||
|
||||
return Boolean(changedPanel);
|
||||
}
|
||||
|
||||
@ -875,6 +871,10 @@ export class DashboardModel implements TimeModel {
|
||||
row.panels = rowPanels.map((panel: PanelModel) => panel.getSaveModel());
|
||||
row.collapsed = true;
|
||||
|
||||
if (rowPanels.some((panel) => panel.hasChanged)) {
|
||||
row.configRev++;
|
||||
}
|
||||
|
||||
// emit change event
|
||||
this.events.publish(new DashboardPanelsChangedEvent());
|
||||
return;
|
||||
|
@ -435,6 +435,20 @@ describe('PanelModel', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateGridPos', () => {
|
||||
it('Should not cause configRev if no change', () => {
|
||||
model.gridPos = { w: 1, h: 1, x: 1, y: 2 };
|
||||
model.updateGridPos({ w: 1, h: 1, x: 1, y: 2 });
|
||||
expect(model.hasChanged).toBe(false);
|
||||
});
|
||||
|
||||
it('Should not cause configRev if gridPos is different', () => {
|
||||
model.gridPos = { w: 1, h: 1, x: 1, y: 2 };
|
||||
model.updateGridPos({ w: 10, h: 1, x: 1, y: 2 });
|
||||
expect(model.hasChanged).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('destroy', () => {
|
||||
it('Should still preserve last query result', () => {
|
||||
model.getQueryRunner().useLastResultFrom({
|
||||
|
@ -298,10 +298,20 @@ export class PanelModel implements DataConfigSource, IPanelModel {
|
||||
}
|
||||
|
||||
updateGridPos(newPos: GridPos) {
|
||||
if (
|
||||
newPos.x === this.gridPos.x &&
|
||||
newPos.y === this.gridPos.y &&
|
||||
newPos.h === this.gridPos.h &&
|
||||
newPos.w === this.gridPos.w
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.gridPos.x = newPos.x;
|
||||
this.gridPos.y = newPos.y;
|
||||
this.gridPos.w = newPos.w;
|
||||
this.gridPos.h = newPos.h;
|
||||
this.configRev++;
|
||||
}
|
||||
|
||||
runAllPanelQueries(
|
||||
|
Loading…
Reference in New Issue
Block a user