Commit 75022ebd by ryan

single hook

parent b933c57c
......@@ -27,26 +27,20 @@ export interface PanelEditorProps<T = any> {
}
/**
* This function is called with the full panelModel before
* the pluginPanel is constructed. This gives you an opportunity
* to validate the panel settings before the panel loads.
*
* @param panelModel the whole panel object. including the configuration
* saved for other panels
*
* @returns the validated panel options that will be passed into the
* panel constructor
* Called before a panel is initalized
*/
export type PanelOptionsValidator<T = any> = (panelModel: any) => T;
export type PreservePanelOptionsHandler<TOptions = any> = (pluginId: string, prevOptions: any) => Partial<TOptions>;
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>>;
optionsValidator?: PanelOptionsValidator<TOptions>;
defaults?: TOptions;
preserveOptions?: PreservePanelOptionsHandler<TOptions>;
panelTypeChangedHook?: PanelTypeChangedHook<TOptions>;
constructor(panel: ComponentClass<PanelProps<TOptions>>) {
this.panel = panel;
......@@ -56,16 +50,16 @@ export class ReactPanelPlugin<TOptions = any> {
this.editor = editor;
}
setOptionsValidator(validator: PanelOptionsValidator<TOptions>) {
this.optionsValidator = validator;
}
setDefaults(defaults: TOptions) {
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;
}
}
......
......@@ -92,10 +92,7 @@ export class DashboardPanel extends PureComponent<Props, State> {
this.props.panel.changeType(pluginId);
} else {
const { reactPanel } = plugin.exports;
panel.changeType(pluginId, reactPanel.preserveOptions);
if (reactPanel && reactPanel.optionsValidator) {
panel.options = reactPanel.optionsValidator(panel);
}
panel.changeType(pluginId, reactPanel.panelTypeChangedHook);
}
}
......
......@@ -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,9 @@ export class PanelModel {
this.cachedPluginOptions[oldPluginId] = oldOptions;
this.restorePanelOptions(pluginId);
if (preserveOptions && oldOptions) {
this.options = this.options || {};
Object.assign(this.options, preserveOptions(oldPluginId, oldOptions.options));
// Callback that can validate and migrate any existing settings
if (hook) {
Object.assign(this.options, hook(this.options || {}, oldPluginId, oldOptions.options));
}
}
......
......@@ -8,9 +8,7 @@ export const reactPanel = new ReactPanelPlugin<BarGaugeOptions>(BarGaugePanel);
reactPanel.setEditor(BarGaugePanelEditor);
reactPanel.setDefaults(defaults);
reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => {
const options: Partial<BarGaugeOptions> = {};
reactPanel.setPanelTypeChangedHook((options: BarGaugeOptions, prevPluginId: string, prevOptions: any) => {
if (prevOptions.valueOptions) {
options.valueOptions = prevOptions.valueOptions;
options.thresholds = prevOptions.thresholds;
......
......@@ -8,9 +8,7 @@ export const reactPanel = new ReactPanelPlugin<GaugeOptions>(GaugePanel);
reactPanel.setEditor(GaugePanelEditor);
reactPanel.setDefaults(defaults);
reactPanel.setPreserveOptionsHandler((pluginId: string, prevOptions: any) => {
const options: Partial<GaugeOptions> = {};
reactPanel.setPanelTypeChangedHook((options: GaugeOptions, prevPluginId: string, prevOptions: any) => {
if (prevOptions.valueOptions) {
options.valueOptions = prevOptions.valueOptions;
options.thresholds = prevOptions.thresholds;
......
......@@ -3,22 +3,15 @@ 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';
import cloneDeep from 'lodash/cloneDeep';
export const reactPanel = new ReactPanelPlugin<TextOptions>(TextPanel);
const validator = (model: PanelModel): TextOptions => {
const options = model.options as TextOptions;
if (!options) {
// Use the same settings from an existing 'text' panel
return cloneDeep(get(model, 'cachedPluginOptions.text'));
}
return options;
};
reactPanel.setEditor(TextPanelEditor);
reactPanel.setDefaults(defaults);
reactPanel.setOptionsValidator(validator);
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