Merge pull request #14303 from grafana/develop-keep-panel-settings

Develop keep panel settings when switching visualizations
This commit is contained in:
Torkel Ödegaard
2018-12-05 09:06:55 +01:00
committed by GitHub
2 changed files with 90 additions and 6 deletions

View File

@@ -15,6 +15,7 @@ const notPersistedProperties: { [str: string]: boolean } = {
fullscreen: true,
isEditing: true,
hasRefreshed: true,
cachedPluginOptions: true,
};
// For angular panels we need to clean up properties when changing type
@@ -51,12 +52,14 @@ const mustKeepProps: { [str: string]: boolean } = {
events: true,
cacheTimeout: true,
nullPointMode: true,
cachedPluginOptions: true,
};
const defaults: any = {
gridPos: { x: 0, y: 0, h: 3, w: 6 },
datasource: null,
targets: [{}],
cachedPluginOptions: {},
};
export class PanelModel {
@@ -96,6 +99,9 @@ export class PanelModel {
events: Emitter;
cacheTimeout?: any;
// cache props between plugins
cachedPluginOptions?: any;
constructor(model) {
this.events = new Emitter();
@@ -120,7 +126,7 @@ export class PanelModel {
}
private getOptionsKey() {
return 'options-' + this.type;
return PANEL_OPTIONS_KEY_PREFIX + this.type;
}
getSaveModel() {
@@ -184,24 +190,48 @@ export class PanelModel {
this.events.emit('panel-initialized');
}
changeType(pluginId: string, fromAngularPanel: boolean) {
this.type = pluginId;
private getOptionsToRemember() {
return Object.keys(this).reduce((acc, property) => {
if (notPersistedProperties[property] || mustKeepProps[property]) {
return acc;
}
return {
...acc,
[property]: this[property],
};
}, {});
}
// for now we need to remove alert rules when changing type
delete this.alert;
private saveCurrentPanelOptions() {
this.cachedPluginOptions[this.type] = this.getOptionsToRemember();
}
private restorePanelOptions(pluginId: string) {
const prevOptions = this.cachedPluginOptions[pluginId] || {};
Object.keys(prevOptions).map(property => {
this[property] = prevOptions[property];
});
}
changeType(pluginId: string, fromAngularPanel: boolean) {
this.saveCurrentPanelOptions();
this.type = pluginId;
// for angular panels only we need to remove all events and let angular panels do some cleanup
if (fromAngularPanel) {
this.destroy();
for (const key of _.keys(this)) {
if (mustKeepProps[key] || key.indexOf(PANEL_OPTIONS_KEY_PREFIX) === 0) {
if (mustKeepProps[key]) {
continue;
}
delete this[key];
}
}
this.restorePanelOptions(pluginId);
}
destroy() {

View File

@@ -0,0 +1,54 @@
import _ from 'lodash';
import { PanelModel } from '../panel_model';
describe('PanelModel', () => {
describe('when creating new panel model', () => {
let model;
beforeEach(() => {
model = new PanelModel({
type: 'table',
showColumns: true,
});
});
it('should apply defaults', () => {
expect(model.gridPos.h).toBe(3);
});
it('should set model props on instance', () => {
expect(model.showColumns).toBe(true);
});
it('getSaveModel should remove defaults', () => {
const saveModel = model.getSaveModel();
expect(saveModel.gridPos).toBe(undefined);
});
it('getSaveModel should remove nonPersistedProperties', () => {
const saveModel = model.getSaveModel();
expect(saveModel.events).toBe(undefined);
});
describe('when changing panel type', () => {
beforeEach(() => {
model.changeType('graph', true);
model.alert = { id: 2 };
});
it('should remove table properties but keep core props', () => {
expect(model.showColumns).toBe(undefined);
});
it('should restore table properties when changing back', () => {
model.changeType('table', true);
expect(model.showColumns).toBe(true);
});
it('should remove alert rule when changing type that does not support it', () => {
model.changeType('table', true);
expect(model.alert).toBe(undefined);
});
});
});
});