Просмотр исходного кода

Merge pull request #15957 from ryantxu/panel-options-init

improve the new PreservePanelOptionsHandler
Torkel Ödegaard 6 лет назад
Родитель
Сommit
12219a1d7e

+ 16 - 4
packages/grafana-ui/src/types/panel.ts

@@ -26,13 +26,21 @@ export interface PanelEditorProps<T = any> {
   onOptionsChange: (options: T) => void;
 }
 
-export type PreservePanelOptionsHandler<TOptions = any> = (pluginId: string, prevOptions: any) => Partial<TOptions>;
+/**
+ * Called before a panel is initalized
+ */
+export type PanelTypeChangedHook<TOptions = any> = (
+  options: TOptions,
+  prevPluginId?: string,
+  prevOptions?: any
+) => TOptions;
 
 export class ReactPanelPlugin<TOptions = any> {
   panel: ComponentClass<PanelProps<TOptions>>;
   editor?: ComponentClass<PanelEditorProps<TOptions>>;
   defaults?: TOptions;
-  preserveOptions?: PreservePanelOptionsHandler<TOptions>;
+
+  panelTypeChangedHook?: PanelTypeChangedHook<TOptions>;
 
   constructor(panel: ComponentClass<PanelProps<TOptions>>) {
     this.panel = panel;
@@ -46,8 +54,12 @@ export class ReactPanelPlugin<TOptions = any> {
     this.defaults = defaults;
   }
 
-  setPreserveOptionsHandler(handler: PreservePanelOptionsHandler<TOptions>) {
-    this.preserveOptions = handler;
+  /**
+   * Called when the visualization changes.
+   * Lets you keep whatever settings made sense in the previous panel
+   */
+  setPanelTypeChangedHook(v: PanelTypeChangedHook<TOptions>) {
+    this.panelTypeChangedHook = v;
   }
 }
 

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

@@ -14,6 +14,7 @@ import { PanelEditor } from '../panel_editor/PanelEditor';
 import { PanelModel, DashboardModel } from '../state';
 import { PanelPlugin } from 'app/types';
 import { PanelResizer } from './PanelResizer';
+import { PanelTypeChangedHook } from '@grafana/ui';
 
 export interface Props {
   panel: PanelModel;
@@ -91,7 +92,11 @@ export class DashboardPanel extends PureComponent<Props, State> {
 
           this.props.panel.changeType(pluginId);
         } else {
-          panel.changeType(pluginId, plugin.exports.reactPanel.preserveOptions);
+          let hook: PanelTypeChangedHook | null = null;
+          if (plugin.exports.reactPanel) {
+            hook = plugin.exports.reactPanel.panelTypeChangedHook;
+          }
+          panel.changeType(pluginId, hook);
         }
       }
 

+ 7 - 4
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,12 @@ export class PanelModel {
     this.cachedPluginOptions[oldPluginId] = oldOptions;
     this.restorePanelOptions(pluginId);
 
-    if (preserveOptions && oldOptions) {
+    // Callback that can validate and migrate any existing settings
+    if (hook) {
       this.options = this.options || {};
-      Object.assign(this.options, preserveOptions(oldPluginId, oldOptions.options));
+      const old = oldOptions ? oldOptions.options : null;
+
+      Object.assign(this.options, hook(this.options, oldPluginId, old));
     }
   }
 

+ 2 - 4
public/app/plugins/panel/bargauge/module.tsx

@@ -8,10 +8,8 @@ export const reactPanel = new ReactPanelPlugin<BarGaugeOptions>(BarGaugePanel);
 
 reactPanel.setEditor(BarGaugePanelEditor);
 reactPanel.setDefaults(defaults);
-reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => {
-  const options: Partial<BarGaugeOptions> = {};
-
-  if (prevOptions.valueOptions) {
+reactPanel.setPanelTypeChangedHook((options: BarGaugeOptions, prevPluginId?: string, prevOptions?: any) => {
+  if (prevOptions && prevOptions.valueOptions) {
     options.valueOptions = prevOptions.valueOptions;
     options.thresholds = prevOptions.thresholds;
     options.maxValue = prevOptions.maxValue;

+ 2 - 4
public/app/plugins/panel/gauge/module.tsx

@@ -8,10 +8,8 @@ export const reactPanel = new ReactPanelPlugin<GaugeOptions>(GaugePanel);
 
 reactPanel.setEditor(GaugePanelEditor);
 reactPanel.setDefaults(defaults);
-reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => {
-  const options: Partial<GaugeOptions> = {};
-
-  if (prevOptions.valueOptions) {
+reactPanel.setPanelTypeChangedHook((options: GaugeOptions, prevPluginId?: string, prevOptions?: any) => {
+  if (prevOptions && prevOptions.valueOptions) {
     options.valueOptions = prevOptions.valueOptions;
     options.thresholds = prevOptions.thresholds;
     options.maxValue = prevOptions.maxValue;

+ 7 - 0
public/app/plugins/panel/text2/module.tsx

@@ -8,3 +8,10 @@ export const reactPanel = new ReactPanelPlugin<TextOptions>(TextPanel);
 
 reactPanel.setEditor(TextPanelEditor);
 reactPanel.setDefaults(defaults);
+reactPanel.setPanelTypeChangedHook((options: TextOptions, prevPluginId: string, prevOptions: any) => {
+  if (prevPluginId === 'text') {
+    return prevOptions as TextOptions;
+  }
+
+  return options;
+});