From 75022ebd6317b1cd9fd05a642468c17065179a92 Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 13 Mar 2019 12:46:04 -0700 Subject: [PATCH] single hook --- packages/grafana-ui/src/types/panel.ts | 34 ++++++++----------- .../dashboard/dashgrid/DashboardPanel.tsx | 5 +-- .../features/dashboard/state/PanelModel.ts | 10 +++--- public/app/plugins/panel/bargauge/module.tsx | 4 +-- public/app/plugins/panel/gauge/module.tsx | 4 +-- public/app/plugins/panel/text2/module.tsx | 21 ++++-------- 6 files changed, 29 insertions(+), 49 deletions(-) diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts index 0b9e5ab4b90..2ac38b6253a 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -27,26 +27,20 @@ export interface PanelEditorProps { } /** - * This function is called with the full panelModel before - * the pluginPanel is constructed. This gives you an opportunity - * to validate the panel settings before the panel loads. - * - * @param panelModel the whole panel object. including the configuration - * saved for other panels - * - * @returns the validated panel options that will be passed into the - * panel constructor + * Called before a panel is initalized */ -export type PanelOptionsValidator = (panelModel: any) => T; - -export type PreservePanelOptionsHandler = (pluginId: string, prevOptions: any) => Partial; +export type PanelTypeChangedHook = ( + options: TOptions, + prevPluginId?: string, + prevOptions?: any +) => TOptions; export class ReactPanelPlugin { panel: ComponentClass>; editor?: ComponentClass>; - optionsValidator?: PanelOptionsValidator; defaults?: TOptions; - preserveOptions?: PreservePanelOptionsHandler; + + panelTypeChangedHook?: PanelTypeChangedHook; constructor(panel: ComponentClass>) { this.panel = panel; @@ -56,16 +50,16 @@ export class ReactPanelPlugin { this.editor = editor; } - setOptionsValidator(validator: PanelOptionsValidator) { - this.optionsValidator = validator; - } - setDefaults(defaults: TOptions) { this.defaults = defaults; } - setPreserveOptionsHandler(handler: PreservePanelOptionsHandler) { - this.preserveOptions = handler; + /** + * Called when the visualization changes. + * Lets you keep whatever settings made sense in the previous panel + */ + setPanelTypeChangedHook(v: PanelTypeChangedHook) { + this.panelTypeChangedHook = v; } } diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index c111349c6fa..d5dba7cfe06 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -92,10 +92,7 @@ export class DashboardPanel extends PureComponent { this.props.panel.changeType(pluginId); } else { const { reactPanel } = plugin.exports; - panel.changeType(pluginId, reactPanel.preserveOptions); - if (reactPanel && reactPanel.optionsValidator) { - panel.options = reactPanel.optionsValidator(panel); - } + panel.changeType(pluginId, reactPanel.panelTypeChangedHook); } } diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 88065fdf208..ddbd2f79440 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -3,7 +3,7 @@ import _ from 'lodash'; // Types import { Emitter } from 'app/core/utils/emitter'; -import { DataQuery, TimeSeries, Threshold, ScopedVars } from '@grafana/ui'; +import { DataQuery, TimeSeries, Threshold, ScopedVars, PanelTypeChangedHook } from '@grafana/ui'; import { TableData } from '@grafana/ui/src'; export interface GridPos { @@ -237,7 +237,7 @@ export class PanelModel { }); } - changeType(pluginId: string, preserveOptions?: any) { + changeType(pluginId: string, hook?: PanelTypeChangedHook) { const oldOptions: any = this.getOptionsToRemember(); const oldPluginId = this.type; @@ -255,9 +255,9 @@ export class PanelModel { this.cachedPluginOptions[oldPluginId] = oldOptions; this.restorePanelOptions(pluginId); - if (preserveOptions && oldOptions) { - this.options = this.options || {}; - Object.assign(this.options, preserveOptions(oldPluginId, oldOptions.options)); + // Callback that can validate and migrate any existing settings + if (hook) { + Object.assign(this.options, hook(this.options || {}, oldPluginId, oldOptions.options)); } } diff --git a/public/app/plugins/panel/bargauge/module.tsx b/public/app/plugins/panel/bargauge/module.tsx index d5dcbabc34f..14fc7696d25 100644 --- a/public/app/plugins/panel/bargauge/module.tsx +++ b/public/app/plugins/panel/bargauge/module.tsx @@ -8,9 +8,7 @@ export const reactPanel = new ReactPanelPlugin(BarGaugePanel); reactPanel.setEditor(BarGaugePanelEditor); reactPanel.setDefaults(defaults); -reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => { - const options: Partial = {}; - +reactPanel.setPanelTypeChangedHook((options: BarGaugeOptions, prevPluginId: string, prevOptions: any) => { if (prevOptions.valueOptions) { options.valueOptions = prevOptions.valueOptions; options.thresholds = prevOptions.thresholds; diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 95a6e29ae4d..8d179f7b403 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -8,9 +8,7 @@ export const reactPanel = new ReactPanelPlugin(GaugePanel); reactPanel.setEditor(GaugePanelEditor); reactPanel.setDefaults(defaults); -reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => { - const options: Partial = {}; - +reactPanel.setPanelTypeChangedHook((options: GaugeOptions, prevPluginId: string, prevOptions: any) => { if (prevOptions.valueOptions) { options.valueOptions = prevOptions.valueOptions; options.thresholds = prevOptions.thresholds; diff --git a/public/app/plugins/panel/text2/module.tsx b/public/app/plugins/panel/text2/module.tsx index f2cf52fbd75..b2e3057de34 100644 --- a/public/app/plugins/panel/text2/module.tsx +++ b/public/app/plugins/panel/text2/module.tsx @@ -3,22 +3,15 @@ import { ReactPanelPlugin } from '@grafana/ui'; import { TextPanelEditor } from './TextPanelEditor'; import { TextPanel } from './TextPanel'; import { TextOptions, defaults } from './types'; -import { PanelModel } from 'app/features/dashboard/state'; - -import get from 'lodash/get'; -import cloneDeep from 'lodash/cloneDeep'; export const reactPanel = new ReactPanelPlugin(TextPanel); -const validator = (model: PanelModel): TextOptions => { - const options = model.options as TextOptions; - if (!options) { - // Use the same settings from an existing 'text' panel - return cloneDeep(get(model, 'cachedPluginOptions.text')); - } - return options; -}; - reactPanel.setEditor(TextPanelEditor); reactPanel.setDefaults(defaults); -reactPanel.setOptionsValidator(validator); +reactPanel.setPanelTypeChangedHook((options: TextOptions, prevPluginId: string, prevOptions: any) => { + if (prevPluginId === 'text') { + return prevOptions as TextOptions; + } + + return options; +});