浏览代码

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
Ryan McKinley 6 年之前
父节点
当前提交
e5c8375ec2

+ 0 - 2
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 {

+ 1 - 0
packages/grafana-ui/src/utils/displayValue.ts

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

+ 1 - 0
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', () => {

+ 21 - 8
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);
+      }
     }
   }
 

+ 1 - 0
public/app/plugins/panel/singlestat2/ProcessedValuesRepeater.tsx

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

+ 10 - 4
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<SingleStatOptions>) => {
   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

+ 1 - 1
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[];