Browse Source

API to fix/update properties before load

ryan 6 years ago
parent
commit
7311b14da1

+ 13 - 0
packages/grafana-ui/src/types/panel.ts

@@ -26,9 +26,18 @@ export interface PanelEditorProps<T = any> {
   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<T = any> = (panelModel: any) => T;
+
 export class ReactPanelPlugin<TOptions = any> {
   panel: ComponentClass<PanelProps<TOptions>>;
   editor?: ComponentClass<PanelEditorProps<TOptions>>;
+  optionsValidator?: PanelOptionsValidator<TOptions>;
   defaults?: TOptions;
 
   constructor(panel: ComponentClass<PanelProps<TOptions>>) {
@@ -39,6 +48,10 @@ export class ReactPanelPlugin<TOptions = any> {
     this.editor = editor;
   }
 
+  setOptionsValidator(validator: PanelOptionsValidator<TOptions>) {
+    this.optionsValidator = validator;
+  }
+
   setDefaults(defaults: TOptions) {
     this.defaults = defaults;
   }

+ 13 - 1
public/app/features/dashboard/dashgrid/DashboardPanel.tsx

@@ -91,6 +91,14 @@ export class DashboardPanel extends PureComponent<Props, State> {
 
         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<Props, State> {
     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;
     }
 

+ 15 - 0
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<TextOptions>(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);