diff --git a/public/app/plugins/panel/gauge/Threshold.test.tsx b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx similarity index 72% rename from public/app/plugins/panel/gauge/Threshold.test.tsx rename to packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx index 852b9f4c104..14f84e00f80 100644 --- a/public/app/plugins/panel/gauge/Threshold.test.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.test.tsx @@ -1,23 +1,18 @@ import React from 'react'; import { shallow } from 'enzyme'; -import Thresholds from './Thresholds'; -import { defaultProps } from './GaugePanelOptions'; -import { BasicGaugeColor } from 'app/types'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; + +import { ThresholdsEditor, Props } from './ThresholdsEditor'; +import { BasicGaugeColor } from '../../types'; const setup = (propOverrides?: object) => { - const props: PanelOptionsProps = { + const props: Props = { onChange: jest.fn(), - options: { - ...defaultProps.options, - thresholds: [], - }, + thresholds: [], }; Object.assign(props, propOverrides); - return shallow().instance() as Thresholds; + return shallow().instance() as ThresholdsEditor; }; describe('Add threshold', () => { @@ -31,10 +26,7 @@ describe('Add threshold', () => { it('should add another threshold above a first', () => { const instance = setup({ - options: { - ...defaultProps.options, - thresholds: [{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }], - }, + thresholds: [{ index: 0, value: 50, color: 'rgb(127, 115, 64)' }], }); instance.onAddThreshold(1); diff --git a/public/app/plugins/panel/gauge/Thresholds.tsx b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx similarity index 68% rename from public/app/plugins/panel/gauge/Thresholds.tsx rename to packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx index 7699a499146..54165dfadb5 100644 --- a/public/app/plugins/panel/gauge/Thresholds.tsx +++ b/packages/grafana-ui/src/components/ThresholdsEditor/ThresholdsEditor.tsx @@ -1,32 +1,37 @@ import React, { PureComponent } from 'react'; -import tinycolor from 'tinycolor2'; -import { ColorPicker } from '@grafana/ui'; -import { BasicGaugeColor, Threshold } from 'app/types'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; +import tinycolor, { ColorInput } from 'tinycolor2'; + +import { Threshold, BasicGaugeColor } from '../../types'; +import { ColorPicker } from '../ColorPicker/ColorPicker'; + +export interface Props { + thresholds: Threshold[]; + onChange: (thresholds: Threshold[]) => void; +} interface State { thresholds: Threshold[]; baseColor: string; } -export default class Thresholds extends PureComponent, State> { - constructor(props) { +export class ThresholdsEditor extends PureComponent { + constructor(props: Props) { super(props); - this.state = { - thresholds: props.options.thresholds, - baseColor: props.options.baseColor, - }; + this.state = { thresholds: props.thresholds, baseColor: BasicGaugeColor.Green }; } - onAddThreshold = index => { - const { maxValue, minValue } = this.props.options; + onAddThreshold = (index: number) => { + const maxValue = 100; // hardcoded for now before we add the base threshold + const minValue = 0; // hardcoded for now before we add the base threshold const { thresholds } = this.state; const newThresholds = thresholds.map(threshold => { if (threshold.index >= index) { - threshold = { ...threshold, index: threshold.index + 1 }; + threshold = { + ...threshold, + index: threshold.index + 1, + }; } return threshold; @@ -48,27 +53,32 @@ export default class Thresholds extends PureComponent if (index === 0 && thresholds.length === 0) { color = tinycolor.mix(BasicGaugeColor.Green, BasicGaugeColor.Red, 50).toRgbString(); } else { - color = tinycolor.mix(thresholds[index - 1].color, BasicGaugeColor.Red, 50).toRgbString(); + color = tinycolor.mix(thresholds[index - 1].color as ColorInput, BasicGaugeColor.Red, 50).toRgbString(); } this.setState( { - thresholds: this.sortThresholds([...newThresholds, { index: index, value: value, color: color }]), + thresholds: this.sortThresholds([ + ...newThresholds, + { + index, + value: value as number, + color, + }, + ]), }, () => this.updateGauge() ); }; - onRemoveThreshold = threshold => { + onRemoveThreshold = (threshold: Threshold) => { this.setState( - prevState => ({ - thresholds: prevState.thresholds.filter(t => t !== threshold), - }), + prevState => ({ thresholds: prevState.thresholds.filter(t => t !== threshold) }), () => this.updateGauge() ); }; - onChangeThresholdValue = (event, threshold) => { + onChangeThresholdValue = (event: any, threshold: Threshold) => { const { thresholds } = this.state; const newThresholds = thresholds.map(t => { @@ -79,12 +89,10 @@ export default class Thresholds extends PureComponent return t; }); - this.setState({ - thresholds: newThresholds, - }); + this.setState({ thresholds: newThresholds }); }; - onChangeThresholdColor = (threshold, color) => { + onChangeThresholdColor = (threshold: Threshold, color: string) => { const { thresholds } = this.state; const newThresholds = thresholds.map(t => { @@ -103,20 +111,18 @@ export default class Thresholds extends PureComponent ); }; - onChangeBaseColor = color => this.props.onChange({ ...this.props.options, baseColor: color }); + onChangeBaseColor = (color: string) => this.props.onChange(this.state.thresholds); onBlur = () => { - this.setState(prevState => ({ - thresholds: this.sortThresholds(prevState.thresholds), - })); + this.setState(prevState => ({ thresholds: this.sortThresholds(prevState.thresholds) })); this.updateGauge(); }; updateGauge = () => { - this.props.onChange({ ...this.props.options, thresholds: this.state.thresholds }); + this.props.onChange(this.state.thresholds); }; - sortThresholds = thresholds => { + sortThresholds = (thresholds: Threshold[]) => { return thresholds.sort((t1, t2) => { return t2.value - t1.value; }); @@ -161,20 +167,8 @@ export default class Thresholds extends PureComponent return thresholds.map((t, i) => { return (
-
this.onAddThreshold(t.index + 1)} - style={{ - height: '50%', - backgroundColor: t.color, - }} - /> -
this.onAddThreshold(t.index)} - style={{ - height: '50%', - backgroundColor: t.color, - }} - /> +
this.onAddThreshold(t.index + 1)} style={{ height: '50%', backgroundColor: t.color }} /> +
this.onAddThreshold(t.index)} style={{ height: '50%', backgroundColor: t.color }} />
); }); @@ -185,14 +179,14 @@ export default class Thresholds extends PureComponent
this.onAddThreshold(0)} - style={{ height: '100%', backgroundColor: this.props.options.baseColor }} + style={{ height: '100%', backgroundColor: BasicGaugeColor.Green }} />
); } renderBase() { - const { baseColor } = this.props.options; + const baseColor = BasicGaugeColor.Green; return (
diff --git a/public/sass/components/_thresholds.scss b/packages/grafana-ui/src/components/ThresholdsEditor/_ThresholdsEditor.scss similarity index 100% rename from public/sass/components/_thresholds.scss rename to packages/grafana-ui/src/components/ThresholdsEditor/_ThresholdsEditor.scss diff --git a/packages/grafana-ui/src/components/index.scss b/packages/grafana-ui/src/components/index.scss index 77a2caa9c5c..c2fe032d24e 100644 --- a/packages/grafana-ui/src/components/index.scss +++ b/packages/grafana-ui/src/components/index.scss @@ -1,4 +1,5 @@ @import 'CustomScrollbar/CustomScrollbar'; @import 'DeleteButton/DeleteButton'; +@import 'ThresholdsEditor/ThresholdsEditor'; @import 'Tooltip/Tooltip'; @import 'Select/Select'; diff --git a/packages/grafana-ui/src/components/index.ts b/packages/grafana-ui/src/components/index.ts index a156143e3a5..936e1a1c759 100644 --- a/packages/grafana-ui/src/components/index.ts +++ b/packages/grafana-ui/src/components/index.ts @@ -13,3 +13,4 @@ export { LoadingPlaceholder } from './LoadingPlaceholder/LoadingPlaceholder'; export { ColorPicker } from './ColorPicker/ColorPicker'; export { SeriesColorPickerPopover } from './ColorPicker/SeriesColorPickerPopover'; export { SeriesColorPicker } from './ColorPicker/SeriesColorPicker'; +export { ThresholdsEditor } from './ThresholdsEditor/ThresholdsEditor'; diff --git a/public/app/plugins/panel/gauge/types.ts b/packages/grafana-ui/src/types/gauge.ts similarity index 76% rename from public/app/plugins/panel/gauge/types.ts rename to packages/grafana-ui/src/types/gauge.ts index 60c4fd1581d..e05849448f7 100644 --- a/public/app/plugins/panel/gauge/types.ts +++ b/packages/grafana-ui/src/types/gauge.ts @@ -1,6 +1,6 @@ -import { RangeMap, ValueMap, Threshold } from 'app/types'; +import { RangeMap, Threshold, ValueMap } from './panel'; -export interface Options { +export interface GaugeOptions { baseColor: string; decimals: number; mappings: Array; diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index f618ce6db34..814ab0478db 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -1,3 +1,4 @@ export * from './series'; export * from './time'; export * from './panel'; +export * from './gauge'; diff --git a/packages/grafana-ui/src/types/panel.ts b/packages/grafana-ui/src/types/panel.ts index 44336555a81..0b995f932f0 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -29,3 +29,35 @@ export interface PanelMenuItem { shortcut?: string; subMenu?: PanelMenuItem[]; } + +export interface Threshold { + index: number; + value: number; + color?: string; +} + +export enum BasicGaugeColor { + Green = '#299c46', + Red = '#d44a3a', +} + +export enum MappingType { + ValueToText = 1, + RangeToText = 2, +} + +interface BaseMap { + id: number; + operator: string; + text: string; + type: MappingType; +} + +export interface ValueMap extends BaseMap { + value: string; +} + +export interface RangeMap extends BaseMap { + from: string; + to: string; +} diff --git a/public/app/plugins/panel/gauge/GaugeOptions.tsx b/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx similarity index 91% rename from public/app/plugins/panel/gauge/GaugeOptions.tsx rename to public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx index 7607374b1b7..cb436180b49 100644 --- a/public/app/plugins/panel/gauge/GaugeOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx @@ -1,10 +1,10 @@ import React, { PureComponent } from 'react'; +import { GaugeOptions, PanelOptionsProps } from '@grafana/ui'; + import { Switch } from 'app/core/components/Switch/Switch'; import { Label } from '../../../core/components/Label/Label'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; -export default class GaugeOptions extends PureComponent> { +export default class GaugeOptionsEditor extends PureComponent> { onToggleThresholdLabels = () => this.props.onChange({ ...this.props.options, showThresholdLabels: !this.props.options.showThresholdLabels }); diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index 5f1a438863f..79220daf37a 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -1,10 +1,10 @@ import React, { PureComponent } from 'react'; -import { PanelProps, NullValueMode } from '@grafana/ui'; +import { GaugeOptions, PanelProps, NullValueMode } from '@grafana/ui'; + import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; import Gauge from 'app/viz/Gauge'; -import { Options } from './types'; -interface Props extends PanelProps {} +interface Props extends PanelProps {} export class GaugePanel extends PureComponent { render() { diff --git a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx index 2b16ef5a1fe..e43abad61a3 100644 --- a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx @@ -1,11 +1,9 @@ import React, { PureComponent } from 'react'; +import { BasicGaugeColor, GaugeOptions, PanelOptionsProps, ThresholdsEditor, Threshold } from '@grafana/ui'; + import ValueOptions from 'app/plugins/panel/gauge/ValueOptions'; -import Thresholds from 'app/plugins/panel/gauge/Thresholds'; -import { BasicGaugeColor } from 'app/types'; -import { PanelOptionsProps } from '@grafana/ui'; import ValueMappings from 'app/plugins/panel/gauge/ValueMappings'; -import { Options } from './types'; -import GaugeOptions from './GaugeOptions'; +import GaugeOptionsEditor from './GaugeOptionsEditor'; export const defaultProps = { options: { @@ -24,17 +22,19 @@ export const defaultProps = { }, }; -export default class GaugePanelOptions extends PureComponent> { +export default class GaugePanelOptions extends PureComponent> { static defaultProps = defaultProps; + onThresholdsChanged = (thresholds: Threshold[]) => this.props.onChange({ ...this.props.options, thresholds }); + render() { const { onChange, options } = this.props; return ( <>
- - + +
diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/public/app/plugins/panel/gauge/MappingRow.tsx index 277afb4fd5c..b975821f27a 100644 --- a/public/app/plugins/panel/gauge/MappingRow.tsx +++ b/public/app/plugins/panel/gauge/MappingRow.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; +import { MappingType, RangeMap, Select, ValueMap } from '@grafana/ui'; + import { Label } from 'app/core/components/Label/Label'; -import { Select } from '@grafana/ui'; -import { MappingType, RangeMap, ValueMap } from 'app/types'; interface Props { mapping: ValueMap | RangeMap; diff --git a/public/app/plugins/panel/gauge/ValueMappings.test.tsx b/public/app/plugins/panel/gauge/ValueMappings.test.tsx index 3e59cc76742..07db4028c68 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.test.tsx +++ b/public/app/plugins/panel/gauge/ValueMappings.test.tsx @@ -1,13 +1,12 @@ import React from 'react'; import { shallow } from 'enzyme'; -import ValueMappings from './ValueMappings'; -import { MappingType } from 'app/types'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; +import { GaugeOptions, MappingType, PanelOptionsProps } from '@grafana/ui'; import { defaultProps } from 'app/plugins/panel/gauge/GaugePanelOptions'; +import ValueMappings from './ValueMappings'; + const setup = (propOverrides?: object) => { - const props: PanelOptionsProps = { + const props: PanelOptionsProps = { onChange: jest.fn(), options: { ...defaultProps.options, diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/public/app/plugins/panel/gauge/ValueMappings.tsx index be800cf2412..4ce0d37b53c 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.tsx +++ b/public/app/plugins/panel/gauge/ValueMappings.tsx @@ -1,15 +1,14 @@ import React, { PureComponent } from 'react'; +import { GaugeOptions, PanelOptionsProps, MappingType, RangeMap, ValueMap } from '@grafana/ui'; + import MappingRow from './MappingRow'; -import { MappingType, RangeMap, ValueMap } from 'app/types'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; interface State { mappings: Array; nextIdToAdd: number; } -export default class ValueMappings extends PureComponent, State> { +export default class ValueMappings extends PureComponent, State> { constructor(props) { super(props); diff --git a/public/app/plugins/panel/gauge/ValueOptions.tsx b/public/app/plugins/panel/gauge/ValueOptions.tsx index e8af6bc2fe1..0b30da35d36 100644 --- a/public/app/plugins/panel/gauge/ValueOptions.tsx +++ b/public/app/plugins/panel/gauge/ValueOptions.tsx @@ -1,9 +1,9 @@ import React, { PureComponent } from 'react'; +import { GaugeOptions, PanelOptionsProps } from '@grafana/ui'; + import { Label } from 'app/core/components/Label/Label'; import { Select} from '@grafana/ui'; import UnitPicker from 'app/core/components/Select/UnitPicker'; -import { PanelOptionsProps } from '@grafana/ui'; -import { Options } from './types'; const statOptions = [ { value: 'min', label: 'Min' }, @@ -21,7 +21,7 @@ const statOptions = [ const labelWidth = 6; -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/types/index.ts b/public/app/types/index.ts index ab52b03ab17..72da1c76ea8 100644 --- a/public/app/types/index.ts +++ b/public/app/types/index.ts @@ -9,7 +9,6 @@ import { ApiKey, ApiKeysState, NewApiKey } from './apiKeys'; import { Invitee, OrgUser, User, UsersState, UserState } from './user'; import { DataSource, DataSourceSelectItem, DataSourcesState } from './datasources'; import { DataQuery, DataQueryResponse, DataQueryOptions } from './series'; -import { BasicGaugeColor, MappingType, RangeMap, Threshold, ValueMap } from './panel'; import { PluginDashboard, PluginMeta, Plugin, PanelPlugin, PluginsState } from './plugins'; import { Organization, OrganizationState } from './organization'; import { @@ -69,13 +68,8 @@ export { AppNotificationTimeout, DashboardSearchHit, UserState, - Threshold, ValidationEvents, ValidationRule, - ValueMap, - RangeMap, - MappingType, - BasicGaugeColor, }; export interface StoreState { diff --git a/public/app/types/panel.ts b/public/app/types/panel.ts deleted file mode 100644 index 31674d20304..00000000000 --- a/public/app/types/panel.ts +++ /dev/null @@ -1,31 +0,0 @@ -export interface Threshold { - index: number; - value: number; - color?: string; -} - -export enum MappingType { - ValueToText = 1, - RangeToText = 2, -} - -export enum BasicGaugeColor { - Green = '#299c46', - Red = '#d44a3a', -} - -interface BaseMap { - id: number; - operator: string; - text: string; - type: MappingType; -} - -export interface ValueMap extends BaseMap { - value: string; -} - -export interface RangeMap extends BaseMap { - from: string; - to: string; -} diff --git a/public/app/viz/Gauge.test.tsx b/public/app/viz/Gauge.test.tsx index 91107a563e5..f0c4a874649 100644 --- a/public/app/viz/Gauge.test.tsx +++ b/public/app/viz/Gauge.test.tsx @@ -1,8 +1,8 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { BasicGaugeColor, TimeSeriesVMs } from '@grafana/ui'; + import { Gauge, Props } from './Gauge'; -import { BasicGaugeColor } from '../types'; -import { TimeSeriesVMs } from '@grafana/ui'; jest.mock('jquery', () => ({ plot: jest.fn(), diff --git a/public/app/viz/Gauge.tsx b/public/app/viz/Gauge.tsx index defeaf8cc8f..5112ff9aa1b 100644 --- a/public/app/viz/Gauge.tsx +++ b/public/app/viz/Gauge.tsx @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react'; import $ from 'jquery'; -import { BasicGaugeColor, MappingType, RangeMap, Threshold, ValueMap } from 'app/types'; -import { TimeSeriesVMs } from '@grafana/ui'; +import { BasicGaugeColor, Threshold, TimeSeriesVMs, RangeMap, ValueMap, MappingType } from '@grafana/ui'; + import config from '../core/config'; import kbn from '../core/utils/kbn'; diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index c8ad1ce8edc..b8498f18b19 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -98,7 +98,6 @@ @import 'components/toolbar'; @import 'components/add_data_source.scss'; @import 'components/page_loader'; -@import 'components/thresholds'; @import 'components/toggle_button_group'; @import 'components/value-mappings'; @import 'components/popover-box';