Browse Source

Gauge/BarGauge: Rewrite of how migrations are applied (#18375)

Torkel Ödegaard 6 years ago
parent
commit
541981c341

+ 3 - 3
devenv/dev-dashboards/panel-gauge/gauge_tests.json

@@ -44,7 +44,7 @@
       "nullPointMode": "null",
       "options-gauge": {
         "baseColor": "#299c46",
-        "decimals": "2",
+        "decimals": 2,
         "maxValue": 100,
         "minValue": 0,
         "options": {
@@ -111,7 +111,7 @@
       "nullPointMode": "null",
       "options-gauge": {
         "baseColor": "#299c46",
-        "decimals": "",
+        "decimals": null,
         "maxValue": 100,
         "minValue": 0,
         "options": {
@@ -178,7 +178,7 @@
       "nullPointMode": "null",
       "options-gauge": {
         "baseColor": "#299c46",
-        "decimals": "",
+        "decimals": null,
         "maxValue": 100,
         "minValue": 0,
         "options": {

+ 3 - 3
packages/grafana-data/src/utils/fieldReducer.ts

@@ -104,7 +104,7 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
     name: 'Last (not null)',
     description: 'Last non-null value',
     standard: true,
-    alias: 'current',
+    aliasIds: ['current'],
     reduce: calculateLastNotNull,
   },
   {
@@ -124,14 +124,14 @@ export const fieldReducers = new Registry<FieldReducerInfo>(() => [
   },
   { id: ReducerID.min, name: 'Min', description: 'Minimum Value', standard: true },
   { id: ReducerID.max, name: 'Max', description: 'Maximum Value', standard: true },
-  { id: ReducerID.mean, name: 'Mean', description: 'Average Value', standard: true, alias: 'avg' },
+  { id: ReducerID.mean, name: 'Mean', description: 'Average Value', standard: true, aliasIds: ['avg'] },
   {
     id: ReducerID.sum,
     name: 'Total',
     description: 'The sum of all values',
     emptyInputResult: 0,
     standard: true,
-    alias: 'total',
+    aliasIds: ['total'],
   },
   {
     id: ReducerID.count,

+ 39 - 0
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts

@@ -0,0 +1,39 @@
+import { sharedSingleStatMigrationCheck } from './SingleStatBaseOptions';
+
+describe('sharedSingleStatMigrationCheck', () => {
+  it('from old valueOptions model without pluginVersion', () => {
+    const panel = {
+      options: {
+        valueOptions: {
+          unit: 'watt',
+          stat: 'last',
+          decimals: 5,
+        },
+        minValue: 10,
+        maxValue: 100,
+        valueMappings: [{ type: 1, value: '1', text: 'OK' }],
+        thresholds: [
+          {
+            color: 'green',
+            index: 0,
+            value: null,
+          },
+          {
+            color: 'orange',
+            index: 1,
+            value: 40,
+          },
+          {
+            color: 'red',
+            index: 2,
+            value: 80,
+          },
+        ],
+      },
+      title: 'Usage',
+      type: 'bargauge',
+    };
+
+    expect(sharedSingleStatMigrationCheck(panel as any)).toMatchSnapshot();
+  });
+});

+ 72 - 40
packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts

@@ -3,7 +3,7 @@ import omit from 'lodash/omit';
 
 import { VizOrientation, PanelModel } from '../../types/panel';
 import { FieldDisplayOptions } from '../../utils/fieldDisplay';
-import { Field, fieldReducers, Threshold, sortThresholds } from '@grafana/data';
+import { fieldReducers, Threshold, sortThresholds } from '@grafana/data';
 
 export interface SingleStatBaseOptions {
   fieldOptions: FieldDisplayOptions;
@@ -25,54 +25,86 @@ export const sharedSingleStatOptionsCheck = (
   return options;
 };
 
-export const sharedSingleStatMigrationCheck = (panel: PanelModel<SingleStatBaseOptions>) => {
+export function sharedSingleStatMigrationCheck(panel: PanelModel<SingleStatBaseOptions>) {
   if (!panel.options) {
     // This happens on the first load or when migrating from angular
     return {};
   }
 
-  // This migration aims to keep the most recent changes up-to-date
-  // Plugins should explicitly migrate for known version changes and only use this
-  // as a backup
-  const old = panel.options as any;
-  if (old.valueOptions) {
-    const { valueOptions } = old;
-
-    const fieldOptions = (old.fieldOptions = {} as FieldDisplayOptions);
-
-    const field = (fieldOptions.defaults = {} as Field);
-    field.mappings = old.valueMappings;
-    field.thresholds = migrateOldThresholds(old.thresholds);
-    field.unit = valueOptions.unit;
-    field.decimals = valueOptions.decimals;
-
-    // Make sure the stats have a valid name
-    if (valueOptions.stat) {
-      const reducer = fieldReducers.get(valueOptions.stat);
-      if (reducer) {
-        fieldOptions.calcs = [reducer.id];
-      }
-    }
+  const previousVersion = parseFloat(panel.pluginVersion || '6.1');
+  let options = panel.options as any;
 
-    field.min = old.minValue;
-    field.max = old.maxValue;
-
-    // remove old props
-    return omit(old, 'valueMappings', 'thresholds', 'valueOptions', 'minValue', 'maxValue');
-  } else if (old.fieldOptions) {
-    // Move mappins & thresholds to field defautls (6.4+)
-    const { mappings, thresholds, ...fieldOptions } = old.fieldOptions;
-    fieldOptions.defaults = {
-      mappings,
-      thresholds: migrateOldThresholds(thresholds),
-      ...fieldOptions.defaults,
-    };
-    old.fieldOptions = fieldOptions;
+  if (previousVersion < 6.2) {
+    options = migrateFromValueOptions(options);
+  }
+
+  if (previousVersion < 6.3) {
+    options = moveThresholdsAndMappingsToField(options);
+  }
+
+  return options as SingleStatBaseOptions;
+}
+
+export function moveThresholdsAndMappingsToField(old: any) {
+  const { fieldOptions } = old;
+
+  if (!fieldOptions) {
     return old;
   }
 
-  return panel.options;
-};
+  const { mappings, thresholds, ...rest } = old.fieldOptions;
+
+  return {
+    ...old,
+    fieldOptions: {
+      ...rest,
+      defaults: {
+        ...fieldOptions.defaults,
+        mappings,
+        thresholds: migrateOldThresholds(thresholds),
+      },
+    },
+  };
+}
+
+/*
+ * Moves valueMappings and thresholds from root to new fieldOptions object
+ * Renames valueOptions to to defaults and moves it under fieldOptions
+ */
+export function migrateFromValueOptions(old: any) {
+  const { valueOptions } = old;
+  if (!valueOptions) {
+    return old;
+  }
+
+  const fieldOptions: any = {};
+  const fieldDefaults: any = {};
+
+  fieldOptions.mappings = old.valueMappings;
+  fieldOptions.thresholds = old.thresholds;
+  fieldOptions.defaults = fieldDefaults;
+
+  fieldDefaults.unit = valueOptions.unit;
+  fieldDefaults.decimals = valueOptions.decimals;
+
+  // Make sure the stats have a valid name
+  if (valueOptions.stat) {
+    const reducer = fieldReducers.get(valueOptions.stat);
+    if (reducer) {
+      fieldOptions.calcs = [reducer.id];
+    }
+  }
+
+  fieldDefaults.min = old.minValue;
+  fieldDefaults.max = old.maxValue;
+
+  const newOptions = {
+    ...old,
+    fieldOptions,
+  };
+
+  return omit(newOptions, 'valueMappings', 'thresholds', 'valueOptions', 'minValue', 'maxValue');
+}
 
 export function migrateOldThresholds(thresholds?: any[]): Threshold[] | undefined {
   if (!thresholds || !thresholds.length) {

+ 38 - 0
packages/grafana-ui/src/components/SingleStatShared/__snapshots__/SingleStatBaseOptions.test.ts.snap

@@ -0,0 +1,38 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`sharedSingleStatMigrationCheck from old valueOptions model without pluginVersion 1`] = `
+Object {
+  "fieldOptions": Object {
+    "calcs": Array [
+      "last",
+    ],
+    "defaults": Object {
+      "decimals": 5,
+      "mappings": Array [
+        Object {
+          "text": "OK",
+          "type": 1,
+          "value": "1",
+        },
+      ],
+      "max": 100,
+      "min": 10,
+      "thresholds": Array [
+        Object {
+          "color": "green",
+          "value": -Infinity,
+        },
+        Object {
+          "color": "orange",
+          "value": 40,
+        },
+        Object {
+          "color": "red",
+          "value": 80,
+        },
+      ],
+      "unit": "watt",
+    },
+  },
+}
+`;

+ 0 - 2
public/app/features/dashboard/dashgrid/PanelChrome.tsx

@@ -152,8 +152,6 @@ export class PanelChrome extends PureComponent<Props, State> {
   onRefresh = () => {
     const { panel, isInView, width } = this.props;
 
-    console.log('onRefresh', panel.id);
-
     if (!isInView) {
       console.log('Refresh when panel is visible', panel.id);
       this.setState({ refreshWhenInView: true });

+ 2 - 2
public/app/features/dashboard/state/PanelModel.ts

@@ -247,8 +247,6 @@ export class PanelModel {
   pluginLoaded(plugin: PanelPlugin) {
     this.plugin = plugin;
 
-    this.applyPluginOptionDefaults(plugin);
-
     if (plugin.panel && plugin.onPanelMigration) {
       const version = getPluginVersion(plugin);
       if (version !== this.pluginVersion) {
@@ -256,6 +254,8 @@ export class PanelModel {
         this.pluginVersion = version;
       }
     }
+
+    this.applyPluginOptionDefaults(plugin);
   }
 
   changePlugin(newPlugin: PanelPlugin) {

+ 1 - 12
public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts

@@ -40,18 +40,7 @@ describe('BarGauge Panel Migrations', () => {
         orientation: 'vertical',
       },
       pluginVersion: '6.2.0',
-      targets: [
-        {
-          refId: 'A',
-          scenarioId: 'random_walk',
-        },
-        {
-          refId: 'B',
-          scenarioId: 'random_walk',
-        },
-      ],
-      timeFrom: null,
-      timeShift: null,
+      targets: [],
       title: 'Usage',
       type: 'bargauge',
     } as PanelModel;

+ 1 - 30
public/app/plugins/panel/bargauge/BarGaugeMigrations.ts

@@ -1,36 +1,7 @@
 import { PanelModel } from '@grafana/ui';
-import {
-  sharedSingleStatMigrationCheck,
-  migrateOldThresholds,
-} from '@grafana/ui/src/components/SingleStatShared/SingleStatBaseOptions';
+import { sharedSingleStatMigrationCheck } from '@grafana/ui/src/components/SingleStatShared/SingleStatBaseOptions';
 import { BarGaugeOptions } from './types';
 
 export const barGaugePanelMigrationCheck = (panel: PanelModel<BarGaugeOptions>): Partial<BarGaugeOptions> => {
-  if (!panel.options) {
-    // This happens on the first load or when migrating from angular
-    return {};
-  }
-
-  // Move thresholds to field
-  const previousVersion = panel.pluginVersion || '';
-  if (previousVersion.startsWith('6.2') || previousVersion.startsWith('6.3')) {
-    console.log('TRANSFORM', panel.options);
-    const old = panel.options as any;
-    const { fieldOptions } = old;
-    if (fieldOptions) {
-      const { mappings, thresholds, ...rest } = fieldOptions;
-      rest.defaults = {
-        mappings,
-        thresholds: migrateOldThresholds(thresholds),
-        ...rest.defaults,
-      };
-      return {
-        ...old,
-        fieldOptions: rest,
-      };
-    }
-  }
-
-  // Default to the standard migration path
   return sharedSingleStatMigrationCheck(panel);
 };

+ 2 - 55
public/app/plugins/panel/gauge/GaugeMigrations.ts

@@ -1,60 +1,7 @@
-import { Field, fieldReducers } from '@grafana/data';
-import { PanelModel, FieldDisplayOptions } from '@grafana/ui';
+import { PanelModel } from '@grafana/ui';
 import { GaugeOptions } from './types';
-import {
-  sharedSingleStatMigrationCheck,
-  migrateOldThresholds,
-} from '@grafana/ui/src/components/SingleStatShared/SingleStatBaseOptions';
+import { sharedSingleStatMigrationCheck } from '@grafana/ui/src/components/SingleStatShared/SingleStatBaseOptions';
 
 export const gaugePanelMigrationCheck = (panel: PanelModel<GaugeOptions>): Partial<GaugeOptions> => {
-  if (!panel.options) {
-    // This happens on the first load or when migrating from angular
-    return {};
-  }
-
-  const previousVersion = panel.pluginVersion || '';
-  if (!previousVersion || previousVersion.startsWith('6.1')) {
-    const old = panel.options as any;
-    const { valueOptions } = old;
-
-    const options = {} as GaugeOptions;
-    options.showThresholdLabels = old.showThresholdLabels;
-    options.showThresholdMarkers = old.showThresholdMarkers;
-    options.orientation = old.orientation;
-
-    const fieldOptions = (options.fieldOptions = {} as FieldDisplayOptions);
-
-    const field = (fieldOptions.defaults = {} as Field);
-    field.mappings = old.valueMappings;
-    field.thresholds = migrateOldThresholds(old.thresholds);
-    field.unit = valueOptions.unit;
-    field.decimals = valueOptions.decimals;
-
-    // Make sure the stats have a valid name
-    if (valueOptions.stat) {
-      fieldOptions.calcs = [fieldReducers.get(valueOptions.stat).id];
-    }
-    field.min = old.minValue;
-    field.max = old.maxValue;
-
-    return options;
-  } else if (previousVersion.startsWith('6.2') || previousVersion.startsWith('6.3')) {
-    const old = panel.options as any;
-    const { fieldOptions } = old;
-    if (fieldOptions) {
-      const { mappings, thresholds, ...rest } = fieldOptions;
-      rest.default = {
-        mappings,
-        thresholds: migrateOldThresholds(thresholds),
-        ...rest.defaults,
-      };
-      return {
-        ...old.options,
-        fieldOptions: rest,
-      };
-    }
-  }
-
-  // Default to the standard migration path
   return sharedSingleStatMigrationCheck(panel);
 };