only call onPanelMigration when the version actually changes (#16186)

* set the plugin version if there is a migration handler
* only call panel migration if the version changes
* set the version after change also
* avoid NPE... check that we have options
* destroy is based on the previous panel type, not the next one
* Panels: Minor refactoring on panel plugin version code, #16186
This commit is contained in:
Ryan McKinley 2019-03-25 06:10:23 -07:00 committed by Torkel Ödegaard
parent a8c50ed6ba
commit e5c8375ec2
7 changed files with 35 additions and 15 deletions

View File

@ -1,8 +1,6 @@
import React, { PureComponent } from 'react'; import React, { PureComponent } from 'react';
import $ from 'jquery'; import $ from 'jquery';
import { getColorFromHexRgbOrName } from '../../utils'; import { getColorFromHexRgbOrName } from '../../utils';
import { DisplayValue, Threshold, GrafanaThemeType, Themeable } from '../../types'; import { DisplayValue, Threshold, GrafanaThemeType, Themeable } from '../../types';
export interface Props extends Themeable { export interface Props extends Themeable {

View File

@ -100,6 +100,7 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce
return { text, numeric, color }; return { text, numeric, color };
}; };
} }
return toStringProcessor; return toStringProcessor;
} }

View File

@ -28,6 +28,7 @@ describe('PanelModel', () => {
}, },
}; };
model = new PanelModel(modelJson); model = new PanelModel(modelJson);
model.pluginLoaded(getPanelPlugin({ id: 'table', exports: { PanelCtrl: {} as any } }));
}); });
it('should apply defaults', () => { it('should apply defaults', () => {

View File

@ -8,6 +8,7 @@ import { getNextRefIdChar } from 'app/core/utils/query';
// Types // Types
import { DataQuery, TimeSeries, Threshold, ScopedVars, TableData } from '@grafana/ui'; import { DataQuery, TimeSeries, Threshold, ScopedVars, TableData } from '@grafana/ui';
import { PanelPlugin } from 'app/types'; import { PanelPlugin } from 'app/types';
import config from 'app/core/config';
export interface GridPos { export interface GridPos {
x: number; x: number;
@ -244,14 +245,22 @@ export class PanelModel {
}); });
} }
private getPluginVersion(plugin: PanelPlugin): string {
return this.plugin && this.plugin.info.version ? this.plugin.info.version : config.buildInfo.version;
}
pluginLoaded(plugin: PanelPlugin) { pluginLoaded(plugin: PanelPlugin) {
this.plugin = plugin; this.plugin = plugin;
const { reactPanel } = plugin.exports; const { reactPanel } = plugin.exports;
// Call PanelMigration Handler if the version has changed
if (reactPanel && reactPanel.onPanelMigration) { if (reactPanel && reactPanel.onPanelMigration) {
this.options = reactPanel.onPanelMigration(this); const version = this.getPluginVersion(plugin);
this.pluginVersion = plugin.info ? plugin.info.version : '1.0.0'; if (version !== this.pluginVersion) {
this.options = reactPanel.onPanelMigration(this);
this.pluginVersion = version;
}
} }
} }
@ -262,7 +271,7 @@ export class PanelModel {
const reactPanel = newPlugin.exports.reactPanel; const reactPanel = newPlugin.exports.reactPanel;
// for angular panels we must remove all events and let angular panels do some cleanup // for angular panels we must remove all events and let angular panels do some cleanup
if (!reactPanel) { if (this.plugin.exports.PanelCtrl) {
this.destroy(); this.destroy();
} }
@ -283,11 +292,15 @@ export class PanelModel {
this.plugin = newPlugin; this.plugin = newPlugin;
// Let panel plugins inspect options from previous panel and keep any that it can use // Let panel plugins inspect options from previous panel and keep any that it can use
const onPanelTypeChanged = reactPanel ? reactPanel.onPanelTypeChanged : null; if (reactPanel) {
if (onPanelTypeChanged) { if (reactPanel.onPanelTypeChanged) {
this.options = this.options || {}; this.options = this.options || {};
const old = oldOptions ? oldOptions.options : {}; const old = oldOptions && oldOptions.options ? oldOptions.options : {};
Object.assign(this.options, onPanelTypeChanged(this.options, oldPluginId, old)); Object.assign(this.options, reactPanel.onPanelTypeChanged(this.options, oldPluginId, old));
}
if (reactPanel.onPanelMigration) {
this.pluginVersion = this.getPluginVersion(newPlugin);
}
} }
} }

View File

@ -39,6 +39,7 @@ export class ProcessedValuesRepeater<T> extends PureComponent<Props<T>, State<T>
render() { render() {
const { orientation, height, width, renderValue } = this.props; const { orientation, height, width, renderValue } = this.props;
const { values } = this.state; const { values } = this.state;
return ( return (
<VizRepeater height={height} width={width} values={values} orientation={orientation}> <VizRepeater height={height} width={width} values={values} orientation={orientation}>
{({ vizHeight, vizWidth, value }) => renderValue(value, vizWidth, vizHeight)} {({ vizHeight, vizWidth, value }) => renderValue(value, vizWidth, vizHeight)}

View File

@ -11,16 +11,22 @@ export const singleStatBaseOptionsCheck = (
prevPluginId: string, prevPluginId: string,
prevOptions: any prevOptions: any
) => { ) => {
optionsToKeep.forEach(v => { for (const k of optionsToKeep) {
if (prevOptions.hasOwnProperty(v)) { if (prevOptions.hasOwnProperty(k)) {
options[v] = cloneDeep(prevOptions.display); options[k] = cloneDeep(prevOptions[k]);
} }
}); }
return options; return options;
}; };
export const singleStatMigrationCheck = (panel: PanelModel<SingleStatOptions>) => { export const singleStatMigrationCheck = (panel: PanelModel<SingleStatOptions>) => {
const options = panel.options; const options = panel.options;
if (!options) {
// This happens on the first load or when migrating from angular
return {};
}
if (options.valueOptions) { if (options.valueOptions) {
// 6.1 renamed some stats, This makes sure they are up to date // 6.1 renamed some stats, This makes sure they are up to date
// avg -> mean, current -> last, total -> sum // avg -> mean, current -> last, total -> sum

View File

@ -6,7 +6,7 @@ export interface PanelPlugin {
hideFromList?: boolean; hideFromList?: boolean;
module: string; module: string;
baseUrl: string; baseUrl: string;
info: any; info: PluginMetaInfo;
sort: number; sort: number;
exports?: PluginExports; exports?: PluginExports;
dataFormats: PanelDataFormat[]; dataFormats: PanelDataFormat[];