diff --git a/packages/grafana-ui/src/components/Gauge/Gauge.tsx b/packages/grafana-ui/src/components/Gauge/Gauge.tsx index 8118fe82f19..f8aba6d210b 100644 --- a/packages/grafana-ui/src/components/Gauge/Gauge.tsx +++ b/packages/grafana-ui/src/components/Gauge/Gauge.tsx @@ -1,8 +1,6 @@ import React, { PureComponent } from 'react'; import $ from 'jquery'; - import { getColorFromHexRgbOrName } from '../../utils'; - import { DisplayValue, Threshold, GrafanaThemeType, Themeable } from '../../types'; export interface Props extends Themeable { diff --git a/packages/grafana-ui/src/utils/displayValue.ts b/packages/grafana-ui/src/utils/displayValue.ts index 012505be700..87fd101d3a7 100644 --- a/packages/grafana-ui/src/utils/displayValue.ts +++ b/packages/grafana-ui/src/utils/displayValue.ts @@ -100,6 +100,7 @@ export function getDisplayProcessor(options?: DisplayValueOptions): DisplayProce return { text, numeric, color }; }; } + return toStringProcessor; } diff --git a/public/app/features/dashboard/state/PanelModel.test.ts b/public/app/features/dashboard/state/PanelModel.test.ts index 1da0c786753..2a8fcbbfbaa 100644 --- a/public/app/features/dashboard/state/PanelModel.test.ts +++ b/public/app/features/dashboard/state/PanelModel.test.ts @@ -28,6 +28,7 @@ describe('PanelModel', () => { }, }; model = new PanelModel(modelJson); + model.pluginLoaded(getPanelPlugin({ id: 'table', exports: { PanelCtrl: {} as any } })); }); it('should apply defaults', () => { diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 7e67e280241..1d9343c1651 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -8,6 +8,7 @@ import { getNextRefIdChar } from 'app/core/utils/query'; // Types import { DataQuery, TimeSeries, Threshold, ScopedVars, TableData } from '@grafana/ui'; import { PanelPlugin } from 'app/types'; +import config from 'app/core/config'; export interface GridPos { 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) { this.plugin = plugin; const { reactPanel } = plugin.exports; + // Call PanelMigration Handler if the version has changed if (reactPanel && reactPanel.onPanelMigration) { - this.options = reactPanel.onPanelMigration(this); - this.pluginVersion = plugin.info ? plugin.info.version : '1.0.0'; + const version = this.getPluginVersion(plugin); + if (version !== this.pluginVersion) { + this.options = reactPanel.onPanelMigration(this); + this.pluginVersion = version; + } } } @@ -262,7 +271,7 @@ export class PanelModel { const reactPanel = newPlugin.exports.reactPanel; // for angular panels we must remove all events and let angular panels do some cleanup - if (!reactPanel) { + if (this.plugin.exports.PanelCtrl) { this.destroy(); } @@ -283,11 +292,15 @@ export class PanelModel { this.plugin = newPlugin; // Let panel plugins inspect options from previous panel and keep any that it can use - const onPanelTypeChanged = reactPanel ? reactPanel.onPanelTypeChanged : null; - if (onPanelTypeChanged) { - this.options = this.options || {}; - const old = oldOptions ? oldOptions.options : {}; - Object.assign(this.options, onPanelTypeChanged(this.options, oldPluginId, old)); + if (reactPanel) { + if (reactPanel.onPanelTypeChanged) { + this.options = this.options || {}; + const old = oldOptions && oldOptions.options ? oldOptions.options : {}; + Object.assign(this.options, reactPanel.onPanelTypeChanged(this.options, oldPluginId, old)); + } + if (reactPanel.onPanelMigration) { + this.pluginVersion = this.getPluginVersion(newPlugin); + } } } diff --git a/public/app/plugins/panel/singlestat2/ProcessedValuesRepeater.tsx b/public/app/plugins/panel/singlestat2/ProcessedValuesRepeater.tsx index b8abf3aabb0..2e5cd66c2ac 100644 --- a/public/app/plugins/panel/singlestat2/ProcessedValuesRepeater.tsx +++ b/public/app/plugins/panel/singlestat2/ProcessedValuesRepeater.tsx @@ -39,6 +39,7 @@ export class ProcessedValuesRepeater extends PureComponent, State render() { const { orientation, height, width, renderValue } = this.props; const { values } = this.state; + return ( {({ vizHeight, vizWidth, value }) => renderValue(value, vizWidth, vizHeight)} diff --git a/public/app/plugins/panel/singlestat2/module.tsx b/public/app/plugins/panel/singlestat2/module.tsx index d7e2667d605..b4892adef55 100644 --- a/public/app/plugins/panel/singlestat2/module.tsx +++ b/public/app/plugins/panel/singlestat2/module.tsx @@ -11,16 +11,22 @@ export const singleStatBaseOptionsCheck = ( prevPluginId: string, prevOptions: any ) => { - optionsToKeep.forEach(v => { - if (prevOptions.hasOwnProperty(v)) { - options[v] = cloneDeep(prevOptions.display); + for (const k of optionsToKeep) { + if (prevOptions.hasOwnProperty(k)) { + options[k] = cloneDeep(prevOptions[k]); } - }); + } return options; }; export const singleStatMigrationCheck = (panel: PanelModel) => { const options = panel.options; + + if (!options) { + // This happens on the first load or when migrating from angular + return {}; + } + if (options.valueOptions) { // 6.1 renamed some stats, This makes sure they are up to date // avg -> mean, current -> last, total -> sum diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index d812cf5d81e..86ad0799e11 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -6,7 +6,7 @@ export interface PanelPlugin { hideFromList?: boolean; module: string; baseUrl: string; - info: any; + info: PluginMetaInfo; sort: number; exports?: PluginExports; dataFormats: PanelDataFormat[];