diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts index 4eda85f9a28..2da48b0fec6 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -1,3 +1,4 @@ +import { ComponentClass } from 'react'; import { TimeSeries, LoadingState, TableData } from './data'; import { TimeRange } from './time'; @@ -19,11 +20,29 @@ export interface PanelData { tableData?: TableData; } -export interface PanelOptionsProps { +export interface PanelEditorProps { options: T; onChange: (options: T) => void; } +export class ReactPanelPlugin { + panel: ComponentClass>; + editor?: ComponentClass>; + defaults?: TOptions; + + constructor(panel: ComponentClass>) { + this.panel = panel; + } + + setEditor(editor: ComponentClass>) { + this.editor = editor; + } + + setDefaults(defaults: TOptions) { + this.defaults = defaults; + } +} + export interface PanelSize { width: number; height: number; diff --git a/packages/grafana-ui/src/types/plugin.ts b/packages/grafana-ui/src/types/plugin.ts index c8f156c08dc..e2dda8ad407 100644 --- a/packages/grafana-ui/src/types/plugin.ts +++ b/packages/grafana-ui/src/types/plugin.ts @@ -1,5 +1,5 @@ import { ComponentClass } from 'react'; -import { PanelProps, PanelOptionsProps } from './panel'; +import { ReactPanelPlugin } from './panel'; import { DataQueryOptions, DataQuery, DataQueryResponse, QueryHint, QueryFixAction } from './datasource'; export interface DataSourceApi { @@ -81,9 +81,7 @@ export interface PluginExports { // Panel plugin PanelCtrl?: any; - Panel?: ComponentClass; - PanelOptions?: ComponentClass; - PanelDefaults?: any; + reactPanel: ReactPanelPlugin; } export interface PluginMeta { diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index b9c56e36382..8f52a9d18db 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -173,7 +173,7 @@ export class DashboardPanel extends PureComponent { onMouseLeave={this.onMouseLeave} style={styles} > - {plugin.exports.Panel && this.renderReactPanel()} + {plugin.exports.reactPanel && this.renderReactPanel()} {plugin.exports.PanelCtrl && this.renderAngularPanel()} )} diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 5a993293946..4f4e76b309d 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -139,7 +139,7 @@ export class PanelChrome extends PureComponent { renderPanelPlugin(loading: LoadingState, panelData: PanelData, width: number, height: number): JSX.Element { const { panel, plugin } = this.props; const { timeRange, renderCounter } = this.state; - const PanelComponent = plugin.exports.Panel; + const PanelComponent = plugin.exports.reactPanel.panel; // This is only done to increase a counter that is used by backend // image rendering (phantomjs/headless chrome) to know when to capture image @@ -153,7 +153,7 @@ export class PanelChrome extends PureComponent { loading={loading} panelData={panelData} timeRange={timeRange} - options={panel.getOptions(plugin.exports.PanelDefaults)} + options={panel.getOptions(plugin.exports.reactPanel.defaults)} width={width - 2 * variables.panelhorizontalpadding} height={height - PANEL_HEADER_HEIGHT - variables.panelverticalpadding} renderCounter={renderCounter} diff --git a/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx b/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx index 3f835bdbac2..4067f361f06 100644 --- a/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx +++ b/public/app/features/dashboard/dashgrid/PanelPluginNotFound.tsx @@ -3,7 +3,7 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; // Types -import { PanelProps } from '@grafana/ui'; +import { PanelProps, ReactPanelPlugin } from '@grafana/ui'; import { PanelPlugin } from 'app/types'; interface Props { @@ -63,7 +63,7 @@ export function getPanelPluginNotFound(id: string): PanelPlugin { }, exports: { - Panel: NotFound, + reactPanel: new ReactPanelPlugin(NotFound), }, }; } diff --git a/public/app/features/dashboard/panel_editor/VisualizationTab.tsx b/public/app/features/dashboard/panel_editor/VisualizationTab.tsx index f9d8b3df607..8a904961a4f 100644 --- a/public/app/features/dashboard/panel_editor/VisualizationTab.tsx +++ b/public/app/features/dashboard/panel_editor/VisualizationTab.tsx @@ -50,33 +50,27 @@ export class VisualizationTab extends PureComponent { }; } - getPanelDefaultOptions = () => { + getReactPanelOptions = () => { const { panel, plugin } = this.props; - - if (plugin.exports.PanelDefaults) { - return panel.getOptions(plugin.exports.PanelDefaults.options); - } - - return panel.getOptions(plugin.exports.PanelDefaults); + return panel.getOptions(plugin.exports.reactPanel.defaults); }; renderPanelOptions() { const { plugin, angularPanel } = this.props; - const { PanelOptions } = plugin.exports; if (angularPanel) { return
(this.element = element)} />; } - return ( - <> - {PanelOptions ? ( - - ) : ( -

Visualization has no options

- )} - - ); + if (plugin.exports.reactPanel) { + const PanelEditor = plugin.exports.reactPanel.editor; + + if (PanelEditor) { + return ; + } + } + + return

Visualization has no options

; } componentDidMount() { diff --git a/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx b/public/app/plugins/panel/gauge/GaugeOptionsBox.tsx similarity index 85% rename from public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx rename to public/app/plugins/panel/gauge/GaugeOptionsBox.tsx index 50e2a344a9b..b5d6acca806 100644 --- a/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx +++ b/public/app/plugins/panel/gauge/GaugeOptionsBox.tsx @@ -1,9 +1,14 @@ +// Libraries import React, { PureComponent } from 'react'; -import { FormField, PanelOptionsProps, PanelOptionsGroup, Switch } from '@grafana/ui'; +// Components +import { Switch, PanelOptionsGroup } from '@grafana/ui'; + +// Types +import { FormField, PanelEditorProps } from '@grafana/ui'; import { GaugeOptions } from './types'; -export default class GaugeOptionsEditor extends PureComponent> { +export class GaugeOptionsBox extends PureComponent> { onToggleThresholdLabels = () => this.props.onChange({ ...this.props.options, showThresholdLabels: !this.props.options.showThresholdLabels }); diff --git a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx b/public/app/plugins/panel/gauge/GaugePanelEditor.tsx similarity index 59% rename from public/app/plugins/panel/gauge/GaugePanelOptions.tsx rename to public/app/plugins/panel/gauge/GaugePanelEditor.tsx index 84726ac88bf..89b154e80f1 100644 --- a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugePanelEditor.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import { - PanelOptionsProps, + PanelEditorProps, ThresholdsEditor, Threshold, PanelOptionsGrid, @@ -8,29 +8,11 @@ import { ValueMapping, } from '@grafana/ui'; -import ValueOptions from 'app/plugins/panel/gauge/ValueOptions'; -import GaugeOptionsEditor from './GaugeOptionsEditor'; +import { ValueOptions } from 'app/plugins/panel/gauge/ValueOptions'; +import { GaugeOptionsBox } from './GaugeOptionsBox'; import { GaugeOptions } from './types'; -export const defaultProps = { - options: { - minValue: 0, - maxValue: 100, - prefix: '', - showThresholdMarkers: true, - showThresholdLabels: false, - suffix: '', - decimals: 0, - stat: 'avg', - unit: 'none', - valueMappings: [], - thresholds: [], - }, -}; - -export default class GaugePanelOptions extends PureComponent> { - static defaultProps = defaultProps; - +export class GaugePanelEditor extends PureComponent> { onThresholdsChanged = (thresholds: Threshold[]) => this.props.onChange({ ...this.props.options, @@ -50,7 +32,7 @@ export default class GaugePanelOptions extends PureComponent - + diff --git a/public/app/plugins/panel/gauge/ValueOptions.tsx b/public/app/plugins/panel/gauge/ValueOptions.tsx index 1fdccadddf2..23c97090bdc 100644 --- a/public/app/plugins/panel/gauge/ValueOptions.tsx +++ b/public/app/plugins/panel/gauge/ValueOptions.tsx @@ -1,7 +1,13 @@ +// Libraries import React, { PureComponent } from 'react'; -import { FormField, FormLabel, PanelOptionsProps, PanelOptionsGroup, Select } from '@grafana/ui'; + +// Components import UnitPicker from 'app/core/components/Select/UnitPicker'; +import { FormField, FormLabel, PanelOptionsGroup, Select } from '@grafana/ui'; + +// Types import { GaugeOptions } from './types'; +import { PanelEditorProps } from '@grafana/ui'; const statOptions = [ { value: 'min', label: 'Min' }, @@ -19,7 +25,7 @@ const statOptions = [ const labelWidth = 6; -export default class ValueOptions extends PureComponent> { +export class ValueOptions extends PureComponent> { onUnitChange = unit => this.props.onChange({ ...this.props.options, unit: unit.value }); onStatChange = stat => this.props.onChange({ ...this.props.options, stat: stat.value }); diff --git a/public/app/plugins/panel/gauge/module.tsx b/public/app/plugins/panel/gauge/module.tsx index 783e4825657..a32cb7cd538 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -1,4 +1,10 @@ -import GaugePanelOptions, { defaultProps } from './GaugePanelOptions'; -import { GaugePanel } from './GaugePanel'; +import { ReactPanelPlugin } from '@grafana/ui'; -export { GaugePanel as Panel, GaugePanelOptions as PanelOptions, defaultProps as PanelDefaults }; +import { GaugePanelEditor } from './GaugePanelEditor'; +import { GaugePanel } from './GaugePanel'; +import { GaugeOptions, defaults } from './types'; + +export const reactPanel = new ReactPanelPlugin(GaugePanel); + +reactPanel.setEditor(GaugePanelEditor); +reactPanel.setDefaults(defaults); diff --git a/public/app/plugins/panel/gauge/types.ts b/public/app/plugins/panel/gauge/types.ts index 42262178dc8..ff701eb8ed2 100644 --- a/public/app/plugins/panel/gauge/types.ts +++ b/public/app/plugins/panel/gauge/types.ts @@ -13,3 +13,17 @@ export interface GaugeOptions { thresholds: Threshold[]; unit: string; } + +export const defaults: GaugeOptions = { + minValue: 0, + maxValue: 100, + prefix: '', + showThresholdMarkers: true, + showThresholdLabels: false, + suffix: '', + decimals: 0, + stat: 'avg', + unit: 'none', + valueMappings: [], + thresholds: [], +}; diff --git a/public/app/plugins/panel/graph2/GraphPanelOptions.tsx b/public/app/plugins/panel/graph2/GraphPanelEditor.tsx similarity index 91% rename from public/app/plugins/panel/graph2/GraphPanelOptions.tsx rename to public/app/plugins/panel/graph2/GraphPanelEditor.tsx index a9c2d299589..80b17ccd5c4 100644 --- a/public/app/plugins/panel/graph2/GraphPanelOptions.tsx +++ b/public/app/plugins/panel/graph2/GraphPanelEditor.tsx @@ -3,10 +3,10 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; // Types -import { PanelOptionsProps, Switch } from '@grafana/ui'; +import { PanelEditorProps, Switch } from '@grafana/ui'; import { Options } from './types'; -export class GraphPanelOptions extends PureComponent> { +export class GraphPanelEditor extends PureComponent> { onToggleLines = () => { this.props.onChange({ ...this.props.options, showLines: !this.props.options.showLines }); }; diff --git a/public/app/plugins/panel/graph2/module.tsx b/public/app/plugins/panel/graph2/module.tsx index 762d5609541..a3a3fadf6bf 100644 --- a/public/app/plugins/panel/graph2/module.tsx +++ b/public/app/plugins/panel/graph2/module.tsx @@ -1,4 +1,4 @@ import { GraphPanel } from './GraphPanel'; -import { GraphPanelOptions } from './GraphPanelOptions'; +import { GraphPanelEditor } from './GraphPanelEditor'; -export { GraphPanel as Panel, GraphPanelOptions as PanelOptions }; +export { GraphPanel as Panel, GraphPanelEditor as PanelOptions }; diff --git a/public/app/plugins/panel/text2/module.tsx b/public/app/plugins/panel/text2/module.tsx index cc3ec016273..884a5927a19 100644 --- a/public/app/plugins/panel/text2/module.tsx +++ b/public/app/plugins/panel/text2/module.tsx @@ -1,5 +1,5 @@ import React, { PureComponent } from 'react'; -import { PanelProps } from '@grafana/ui'; +import { PanelProps, ReactPanelPlugin } from '@grafana/ui'; export class Text2 extends PureComponent { constructor(props: PanelProps) { @@ -11,4 +11,4 @@ export class Text2 extends PureComponent { } } -export { Text2 as Panel }; +export const reactPanel = new ReactPanelPlugin(Text2);