Commit 12219a1d by Torkel Ödegaard Committed by GitHub

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

improve the new PreservePanelOptionsHandler
parents f059c25f 68f7e046
......@@ -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;
}
}
......
......@@ -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);
}
}
......
......@@ -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));
}
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -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;
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment