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> { ...@@ -26,13 +26,21 @@ export interface PanelEditorProps<T = any> {
onOptionsChange: (options: T) => void; 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> { export class ReactPanelPlugin<TOptions = any> {
panel: ComponentClass<PanelProps<TOptions>>; panel: ComponentClass<PanelProps<TOptions>>;
editor?: ComponentClass<PanelEditorProps<TOptions>>; editor?: ComponentClass<PanelEditorProps<TOptions>>;
defaults?: TOptions; defaults?: TOptions;
preserveOptions?: PreservePanelOptionsHandler<TOptions>;
panelTypeChangedHook?: PanelTypeChangedHook<TOptions>;
constructor(panel: ComponentClass<PanelProps<TOptions>>) { constructor(panel: ComponentClass<PanelProps<TOptions>>) {
this.panel = panel; this.panel = panel;
...@@ -46,8 +54,12 @@ export class ReactPanelPlugin<TOptions = any> { ...@@ -46,8 +54,12 @@ export class ReactPanelPlugin<TOptions = any> {
this.defaults = defaults; 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'; ...@@ -14,6 +14,7 @@ import { PanelEditor } from '../panel_editor/PanelEditor';
import { PanelModel, DashboardModel } from '../state'; import { PanelModel, DashboardModel } from '../state';
import { PanelPlugin } from 'app/types'; import { PanelPlugin } from 'app/types';
import { PanelResizer } from './PanelResizer'; import { PanelResizer } from './PanelResizer';
import { PanelTypeChangedHook } from '@grafana/ui';
export interface Props { export interface Props {
panel: PanelModel; panel: PanelModel;
...@@ -91,7 +92,11 @@ export class DashboardPanel extends PureComponent<Props, State> { ...@@ -91,7 +92,11 @@ export class DashboardPanel extends PureComponent<Props, State> {
this.props.panel.changeType(pluginId); this.props.panel.changeType(pluginId);
} else { } 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'; ...@@ -3,7 +3,7 @@ import _ from 'lodash';
// Types // Types
import { Emitter } from 'app/core/utils/emitter'; 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'; import { TableData } from '@grafana/ui/src';
export interface GridPos { export interface GridPos {
...@@ -237,7 +237,7 @@ export class PanelModel { ...@@ -237,7 +237,7 @@ export class PanelModel {
}); });
} }
changeType(pluginId: string, preserveOptions?: any) { changeType(pluginId: string, hook?: PanelTypeChangedHook) {
const oldOptions: any = this.getOptionsToRemember(); const oldOptions: any = this.getOptionsToRemember();
const oldPluginId = this.type; const oldPluginId = this.type;
...@@ -255,9 +255,12 @@ export class PanelModel { ...@@ -255,9 +255,12 @@ export class PanelModel {
this.cachedPluginOptions[oldPluginId] = oldOptions; this.cachedPluginOptions[oldPluginId] = oldOptions;
this.restorePanelOptions(pluginId); this.restorePanelOptions(pluginId);
if (preserveOptions && oldOptions) { // Callback that can validate and migrate any existing settings
if (hook) {
this.options = this.options || {}; 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); ...@@ -8,10 +8,8 @@ export const reactPanel = new ReactPanelPlugin<BarGaugeOptions>(BarGaugePanel);
reactPanel.setEditor(BarGaugePanelEditor); reactPanel.setEditor(BarGaugePanelEditor);
reactPanel.setDefaults(defaults); reactPanel.setDefaults(defaults);
reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => { reactPanel.setPanelTypeChangedHook((options: BarGaugeOptions, prevPluginId?: string, prevOptions?: any) => {
const options: Partial<BarGaugeOptions> = {}; if (prevOptions && prevOptions.valueOptions) {
if (prevOptions.valueOptions) {
options.valueOptions = prevOptions.valueOptions; options.valueOptions = prevOptions.valueOptions;
options.thresholds = prevOptions.thresholds; options.thresholds = prevOptions.thresholds;
options.maxValue = prevOptions.maxValue; options.maxValue = prevOptions.maxValue;
......
...@@ -8,10 +8,8 @@ export const reactPanel = new ReactPanelPlugin<GaugeOptions>(GaugePanel); ...@@ -8,10 +8,8 @@ export const reactPanel = new ReactPanelPlugin<GaugeOptions>(GaugePanel);
reactPanel.setEditor(GaugePanelEditor); reactPanel.setEditor(GaugePanelEditor);
reactPanel.setDefaults(defaults); reactPanel.setDefaults(defaults);
reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => { reactPanel.setPanelTypeChangedHook((options: GaugeOptions, prevPluginId?: string, prevOptions?: any) => {
const options: Partial<GaugeOptions> = {}; if (prevOptions && prevOptions.valueOptions) {
if (prevOptions.valueOptions) {
options.valueOptions = prevOptions.valueOptions; options.valueOptions = prevOptions.valueOptions;
options.thresholds = prevOptions.thresholds; options.thresholds = prevOptions.thresholds;
options.maxValue = prevOptions.maxValue; options.maxValue = prevOptions.maxValue;
......
...@@ -8,3 +8,10 @@ export const reactPanel = new ReactPanelPlugin<TextOptions>(TextPanel); ...@@ -8,3 +8,10 @@ export const reactPanel = new ReactPanelPlugin<TextOptions>(TextPanel);
reactPanel.setEditor(TextPanelEditor); reactPanel.setEditor(TextPanelEditor);
reactPanel.setDefaults(defaults); 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