diff --git a/devenv/dev-dashboards/panel-gauge/gauge_tests.json b/devenv/dev-dashboards/panel-gauge/gauge_tests.json index abcde39bd63..a26f3d299f3 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge_tests.json +++ b/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": { diff --git a/packages/grafana-data/src/utils/fieldReducer.ts b/packages/grafana-data/src/utils/fieldReducer.ts index d3cb1f787cb..9951f4abfa9 100644 --- a/packages/grafana-data/src/utils/fieldReducer.ts +++ b/packages/grafana-data/src/utils/fieldReducer.ts @@ -104,7 +104,7 @@ export const fieldReducers = new Registry(() => [ 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(() => [ }, { 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, diff --git a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.test.ts new file mode 100644 index 00000000000..209953fc5fa --- /dev/null +++ b/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(); + }); +}); diff --git a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts b/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts index 48730894017..3215d0c72b2 100644 --- a/packages/grafana-ui/src/components/SingleStatShared/SingleStatBaseOptions.ts +++ b/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) => { +export function sharedSingleStatMigrationCheck(panel: PanelModel) { 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) { diff --git a/packages/grafana-ui/src/components/SingleStatShared/__snapshots__/SingleStatBaseOptions.test.ts.snap b/packages/grafana-ui/src/components/SingleStatShared/__snapshots__/SingleStatBaseOptions.test.ts.snap new file mode 100644 index 00000000000..422d49bccdb --- /dev/null +++ b/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", + }, + }, +} +`; diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 1778ac0cb5c..e4a13b0e1ce 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -152,8 +152,6 @@ export class PanelChrome extends PureComponent { 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 }); diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 78018d3f64c..9869c830c41 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/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) { diff --git a/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts b/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts index 5d354f13706..540dd8ddc19 100644 --- a/public/app/plugins/panel/bargauge/BarGaugeMigrations.test.ts +++ b/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; diff --git a/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts b/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts index d85796ee85e..c6f8c029ffc 100644 --- a/public/app/plugins/panel/bargauge/BarGaugeMigrations.ts +++ b/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): Partial => { - 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); }; diff --git a/public/app/plugins/panel/gauge/GaugeMigrations.ts b/public/app/plugins/panel/gauge/GaugeMigrations.ts index d31cddeeb06..d3227eaf8cb 100644 --- a/public/app/plugins/panel/gauge/GaugeMigrations.ts +++ b/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): Partial => { - 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); };