mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge pull request #15957 from ryantxu/panel-options-init
improve the new PreservePanelOptionsHandler
This commit is contained in:
@@ -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;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user