diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts index 260ff78df76..da0d399fe65 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -26,9 +26,18 @@ export interface PanelEditorProps { onOptionsChange: (options: T) => void; } +/** + * Checks the existing model before the component is loaded + * This is useful for fixing options as configuration changes + * The object passed in is the panel model.... but not typed + * since that is not in grafana ui + */ +export type PanelOptionsValidator = (panelModel: any) => T; + export class ReactPanelPlugin { panel: ComponentClass>; editor?: ComponentClass>; + optionsValidator?: PanelOptionsValidator; defaults?: TOptions; constructor(panel: ComponentClass>) { @@ -39,6 +48,10 @@ export class ReactPanelPlugin { this.editor = editor; } + setOptionsValidator(validator: PanelOptionsValidator) { + this.optionsValidator = validator; + } + setDefaults(defaults: TOptions) { this.defaults = defaults; } diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index 9aeddd5a0d9..ef2edd0a13a 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -91,6 +91,14 @@ export class DashboardPanel extends PureComponent { this.setState({ plugin, angularPanel: null }); } + + // Clean the options when switching plugins + // ??? is there a better way that will make sure to call componentDidUpdate ??? + // The panel constructor may have already run + const { reactPanel } = plugin.exports; + if (reactPanel && reactPanel.optionsValidator) { + panel.options = reactPanel.optionsValidator(panel); + } } } @@ -98,8 +106,12 @@ export class DashboardPanel extends PureComponent { this.loadPlugin(this.props.panel.type); } - componentDidUpdate() { + componentDidUpdate(prevProps: Props, prevState: State) { if (!this.element || this.state.angularPanel) { + const { plugin } = this.state; + if (plugin && plugin !== prevState.plugin) { + console.log('PLUGIN Changed', plugin); + } return; } diff --git a/public/app/plugins/panel/text2/module.tsx b/public/app/plugins/panel/text2/module.tsx index bac292e8c29..ae94e16a766 100644 --- a/public/app/plugins/panel/text2/module.tsx +++ b/public/app/plugins/panel/text2/module.tsx @@ -3,8 +3,23 @@ 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'; export const reactPanel = new ReactPanelPlugin(TextPanel); +const validator = (model: PanelModel): TextOptions => { + const options = model.options as TextOptions; + if (!options) { + const old = get(model, 'cachedPluginOptions.text'); + if (old) { + return old; + } + } + return options; +}; + reactPanel.setEditor(TextPanelEditor); reactPanel.setDefaults(defaults); +reactPanel.setOptionsValidator(validator);