diff --git a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx index c8c3809fcc4..d312ee1982c 100644 --- a/public/app/features/dashboard/dashgrid/DashboardPanel.tsx +++ b/public/app/features/dashboard/dashgrid/DashboardPanel.tsx @@ -136,7 +136,7 @@ export class DashboardPanel extends PureComponent { return (
- +
{panel.isEditing && ( diff --git a/public/app/features/dashboard/dashgrid/PanelChrome.tsx b/public/app/features/dashboard/dashgrid/PanelChrome.tsx index 8f4fc7b4150..fe1d1ebf145 100644 --- a/public/app/features/dashboard/dashgrid/PanelChrome.tsx +++ b/public/app/features/dashboard/dashgrid/PanelChrome.tsx @@ -1,5 +1,5 @@ // Libraries -import React, { ComponentClass, PureComponent } from 'react'; +import React, { PureComponent } from 'react'; import { AutoSizer } from 'react-virtualized'; // Services @@ -16,12 +16,12 @@ import { PANEL_HEADER_HEIGHT } from 'app/core/constants'; // Types import { PanelModel } from '../panel_model'; import { DashboardModel } from '../dashboard_model'; -import { TimeRange, PanelProps } from 'app/types'; +import { PanelPlugin, TimeRange } from 'app/types'; export interface Props { panel: PanelModel; dashboard: DashboardModel; - component: ComponentClass; + plugin: PanelPlugin; } export interface State { @@ -80,11 +80,11 @@ export class PanelChrome extends PureComponent { } render() { - const { panel, dashboard } = this.props; + const { panel, dashboard, plugin } = this.props; const { refreshCounter, timeRange, timeInfo, renderCounter } = this.state; const { datasource, targets } = panel; - const PanelComponent = this.props.component; + const PanelComponent = plugin.exports.Panel; return ( @@ -111,7 +111,7 @@ export class PanelChrome extends PureComponent { loading={loading} timeSeries={timeSeries} timeRange={timeRange} - options={panel.getOptions()} + options={panel.getOptions(plugin.exports.PanelDefaults)} width={width} height={height - PANEL_HEADER_HEIGHT} renderCounter={renderCounter} diff --git a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx index 8702fab3ae4..1a956b69a33 100644 --- a/public/app/features/dashboard/dashgrid/VisualizationTab.tsx +++ b/public/app/features/dashboard/dashgrid/VisualizationTab.tsx @@ -24,7 +24,9 @@ export class VisualizationTab extends PureComponent { const { PanelOptions } = plugin.exports; if (PanelOptions) { - return ; + return ( + + ); } else { return

Visualization has no options

; } diff --git a/public/app/features/dashboard/panel_model.ts b/public/app/features/dashboard/panel_model.ts index 20388a0450c..e3d8abf8d6e 100644 --- a/public/app/features/dashboard/panel_model.ts +++ b/public/app/features/dashboard/panel_model.ts @@ -70,8 +70,8 @@ export class PanelModel { _.defaultsDeep(this, _.cloneDeep(defaults)); } - getOptions() { - return this[this.getOptionsKey()] || {}; + getOptions(panelDefaults) { + return _.defaultsDeep(this[this.getOptionsKey()] || {}, panelDefaults); } updateOptions(options: object) { diff --git a/public/app/plugins/panel/gauge/GaugeOptions.tsx b/public/app/plugins/panel/gauge/GaugeOptions.tsx index 55bdde406bd..2f0a1b598fb 100644 --- a/public/app/plugins/panel/gauge/GaugeOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugeOptions.tsx @@ -1,13 +1,9 @@ import React, { PureComponent } from 'react'; -import { OptionsProps } from './Options'; import { Switch } from 'app/core/components/Switch/Switch'; +import { PanelOptionsProps } from 'app/types'; +import { OptionsProps } from './module'; -interface Props { - onChange: (item: any) => any; - options: OptionsProps; -} - -export default class GaugeOptions extends PureComponent { +export default class GaugeOptions extends PureComponent> { toggleThresholdLabels = () => this.props.onChange({ ...this.props.options, showThresholdLabels: !this.props.options.showThresholdLabels }); diff --git a/public/app/plugins/panel/gauge/Options.tsx b/public/app/plugins/panel/gauge/Options.tsx deleted file mode 100644 index 99463e062b5..00000000000 --- a/public/app/plugins/panel/gauge/Options.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { PureComponent } from 'react'; -import ValueOptions from './ValueOptions'; -import { PanelOptionsProps } from 'app/types'; -import GaugeOptions from './GaugeOptions'; - -export interface OptionsProps { - decimals: number; - prefix: string; - showThresholdLabels: boolean; - showThresholdMarkers: boolean; - stat: string; - suffix: string; - unit: string; - thresholds: number[]; - minValue: number; - maxValue: number; -} - -export default class Options extends PureComponent> { - render() { - return ( -
- - -
- ); - } -} diff --git a/public/app/plugins/panel/gauge/Thresholds.tsx b/public/app/plugins/panel/gauge/Thresholds.tsx new file mode 100644 index 00000000000..80e664f3b3f --- /dev/null +++ b/public/app/plugins/panel/gauge/Thresholds.tsx @@ -0,0 +1,56 @@ +import React, { PureComponent } from 'react'; +import { PanelOptionsProps, Threshold } from 'app/types'; +import { OptionsProps } from './module'; +import { Label } from '../../../core/components/Label/Label'; + +interface State { + thresholds: Threshold[]; +} + +export default class Thresholds extends PureComponent, State> { + state = { + thresholds: [{ label: 'Min', value: 0 }, { label: 'Max', value: 100 }], + }; + + onAddThreshold = () => { + this.setState(prevState => ({ + thresholds: [prevState.thresholds[0], { label: '', value: 0 }, { label: 'Max', value: 100 }], + })); + }; + + render() { + const { thresholds } = this.state; + + return ( +
+
Thresholds
+
+
+
+ {thresholds.map((threshold, index) => { + return ( +
+ + +
+ ); + })} +
+ + + + + +
+
+
+
+ ); + } +} diff --git a/public/app/plugins/panel/gauge/ValueOptions.tsx b/public/app/plugins/panel/gauge/ValueOptions.tsx index fec93947e01..afd0731652b 100644 --- a/public/app/plugins/panel/gauge/ValueOptions.tsx +++ b/public/app/plugins/panel/gauge/ValueOptions.tsx @@ -2,7 +2,8 @@ import React, { PureComponent } from 'react'; import { Label } from 'app/core/components/Label/Label'; import SimplePicker from 'app/core/components/Picker/SimplePicker'; import UnitPicker from 'app/core/components/Picker/Unit/UnitPicker'; -import { OptionsProps } from './Options'; +import { PanelOptionsProps } from 'app/types'; +import { OptionsProps } from './module'; const statOptions = [ { value: 'min', text: 'Min' }, @@ -20,12 +21,7 @@ const statOptions = [ const labelWidth = 6; -interface Props { - onChange: (arg: any) => void; - options: OptionsProps; -} - -export default class ValueOptions extends PureComponent { +export default 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 17a601076ae..b61e188489a 100644 --- a/public/app/plugins/panel/gauge/module.tsx +++ b/public/app/plugins/panel/gauge/module.tsx @@ -1,8 +1,34 @@ import React, { PureComponent } from 'react'; import Gauge from 'app/viz/Gauge'; -import Options, { OptionsProps } from './Options'; -import { NullValueMode, PanelProps } from 'app/types'; +import { NullValueMode, PanelOptionsProps, PanelProps, Threshold } from 'app/types'; import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; +import ValueOptions from './ValueOptions'; +import GaugeOptions from './GaugeOptions'; +import Thresholds from './Thresholds'; + +export interface OptionsProps { + decimals: number; + prefix: string; + showThresholdLabels: boolean; + showThresholdMarkers: boolean; + stat: string; + suffix: string; + unit: string; + thresholds: Threshold[]; + minValue: number; + maxValue: number; +} + +export const defaultProps = { + options: { + minValue: 0, + maxValue: 100, + prefix: '', + showThresholdMarkers: true, + showThresholdLabels: false, + suffix: '', + }, +}; interface Props extends PanelProps {} @@ -19,4 +45,18 @@ class GaugePanel extends PureComponent { } } -export { GaugePanel as Panel, Options as PanelOptions }; +class Options extends PureComponent> { + static defaultProps = defaultProps; + + render() { + return ( +
+ + + +
+ ); + } +} + +export { GaugePanel as Panel, Options as PanelOptions, defaultProps as PanelDefaults }; diff --git a/public/app/types/index.ts b/public/app/types/index.ts index bf19e52468b..d546fe69c24 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -20,7 +20,7 @@ import { DataQueryResponse, DataQueryOptions, } from './series'; -import { PanelProps, PanelOptionsProps } from './panel'; +import { PanelProps, PanelOptionsProps, Threshold } from './panel'; import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; import { Organization, OrganizationState } from './organization'; import { @@ -89,6 +89,7 @@ export { AppNotificationTimeout, DashboardSearchHit, UserState, + Threshold, }; export interface StoreState { diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts index 88540c16f04..59ba8aa2b45 100644 --- a/public/app/types/panel.ts +++ b/public/app/types/panel.ts @@ -28,3 +28,9 @@ export interface PanelMenuItem { shortcut?: string; subMenu?: PanelMenuItem[]; } + +export interface Threshold { + label: string; + value: number; + color?: string; +} diff --git a/public/app/types/plugins.ts b/public/app/types/plugins.ts index 4e598382a9a..13bbbd1ca72 100644 --- a/public/app/types/plugins.ts +++ b/public/app/types/plugins.ts @@ -13,6 +13,7 @@ export interface PluginExports { PanelCtrl?; Panel?: ComponentClass; PanelOptions?: ComponentClass; + PanelDefaults?: any; } export interface PanelPlugin { diff --git a/public/app/viz/Gauge.tsx b/public/app/viz/Gauge.tsx index 5633fe04edc..9c879175970 100644 --- a/public/app/viz/Gauge.tsx +++ b/public/app/viz/Gauge.tsx @@ -1,6 +1,6 @@ import React, { PureComponent } from 'react'; import $ from 'jquery'; -import { TimeSeriesVMs } from 'app/types'; +import { Threshold, TimeSeriesVMs } from 'app/types'; import config from '../core/config'; import kbn from '../core/utils/kbn'; @@ -10,7 +10,7 @@ interface Props { minValue: number; maxValue: number; showThresholdMarkers: boolean; - thresholds: number[]; + thresholds: Threshold[]; showThresholdLabels: boolean; unit: string; width: number; @@ -32,7 +32,7 @@ export class Gauge extends PureComponent { showThresholdMarkers: true, showThresholdLabels: false, suffix: '', - thresholds: [0, 100], + thresholds: [{ label: 'Min', value: 0 }, { label: 'Max', value: 100 }], }; componentDidMount() { @@ -75,7 +75,7 @@ export class Gauge extends PureComponent { const formattedThresholds = thresholds.map((threshold, index) => { return { - value: threshold, + value: threshold.value, color: colors[index], }; });