diff --git a/public/app/core/components/Label/Label.tsx b/packages/grafana-ui/src/components/Label/Label.tsx similarity index 93% rename from public/app/core/components/Label/Label.tsx rename to packages/grafana-ui/src/components/Label/Label.tsx index 5d60efa056a..270b0161226 100644 --- a/public/app/core/components/Label/Label.tsx +++ b/packages/grafana-ui/src/components/Label/Label.tsx @@ -1,5 +1,5 @@ import React, { SFC, ReactNode } from 'react'; -import { Tooltip } from '@grafana/ui'; +import { Tooltip } from '../Tooltip/Tooltip'; interface Props { tooltip?: string; diff --git a/public/app/plugins/panel/gauge/MappingRow.tsx b/packages/grafana-ui/src/components/ValueMappingsEditor/MappingRow.tsx similarity index 75% rename from public/app/plugins/panel/gauge/MappingRow.tsx rename to packages/grafana-ui/src/components/ValueMappingsEditor/MappingRow.tsx index b975821f27a..9705304d354 100644 --- a/public/app/plugins/panel/gauge/MappingRow.tsx +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/MappingRow.tsx @@ -1,22 +1,23 @@ import React, { PureComponent } from 'react'; -import { MappingType, RangeMap, Select, ValueMap } from '@grafana/ui'; -import { Label } from 'app/core/components/Label/Label'; +import { MappingType, ValueMapping } from '../../types/panel'; +import { Label } from '../Label/Label'; +import { Select } from '../Select/Select'; -interface Props { - mapping: ValueMap | RangeMap; - updateMapping: (mapping) => void; - removeMapping: () => void; +export interface Props { + valueMapping: ValueMapping; + updateValueMapping: (valueMapping: ValueMapping) => void; + removeValueMapping: () => void; } interface State { - from: string; + from?: string; id: number; operator: string; text: string; - to: string; + to?: string; type: MappingType; - value: string; + value?: string; } const mappingOptions = [ @@ -25,36 +26,34 @@ const mappingOptions = [ ]; export default class MappingRow extends PureComponent { - constructor(props) { + constructor(props: Props) { super(props); - this.state = { - ...props.mapping, - }; + this.state = { ...props.valueMapping }; } - onMappingValueChange = event => { + onMappingValueChange = (event: React.ChangeEvent) => { this.setState({ value: event.target.value }); }; - onMappingFromChange = event => { + onMappingFromChange = (event: React.ChangeEvent) => { this.setState({ from: event.target.value }); }; - onMappingToChange = event => { + onMappingToChange = (event: React.ChangeEvent) => { this.setState({ to: event.target.value }); }; - onMappingTextChange = event => { + onMappingTextChange = (event: React.ChangeEvent) => { this.setState({ text: event.target.value }); }; - onMappingTypeChange = mappingType => { + onMappingTypeChange = (mappingType: MappingType) => { this.setState({ type: mappingType }); }; updateMapping = () => { - this.props.updateMapping({ ...this.state }); + this.props.updateValueMapping({ ...this.state } as ValueMapping); }; renderRow() { @@ -136,7 +135,7 @@ export default class MappingRow extends PureComponent { {this.renderRow()}
-
diff --git a/public/app/plugins/panel/gauge/ValueMappings.test.tsx b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.test.tsx similarity index 59% rename from public/app/plugins/panel/gauge/ValueMappings.test.tsx rename to packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.test.tsx index 07db4028c68..bbad3e5a7ca 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.test.tsx +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.test.tsx @@ -1,27 +1,23 @@ import React from 'react'; import { shallow } from 'enzyme'; -import { GaugeOptions, MappingType, PanelOptionsProps } from '@grafana/ui'; -import { defaultProps } from 'app/plugins/panel/gauge/GaugePanelOptions'; -import ValueMappings from './ValueMappings'; +import { ValueMappingsEditor, Props } from './ValueMappingsEditor'; +import { MappingType } from '../../types/panel'; const setup = (propOverrides?: object) => { - const props: PanelOptionsProps = { + const props: Props = { onChange: jest.fn(), - options: { - ...defaultProps.options, - mappings: [ - { id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' }, - { id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' }, - ], - }, + valueMappings: [ + { id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' }, + { id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' }, + ], }; Object.assign(props, propOverrides); - const wrapper = shallow(); + const wrapper = shallow(); - const instance = wrapper.instance() as ValueMappings; + const instance = wrapper.instance() as ValueMappingsEditor; return { instance, @@ -40,18 +36,20 @@ describe('Render', () => { describe('On remove mapping', () => { it('Should remove mapping with id 0', () => { const { instance } = setup(); + instance.onRemoveMapping(1); - expect(instance.state.mappings).toEqual([ + expect(instance.state.valueMappings).toEqual([ { id: 2, operator: '', type: MappingType.RangeToText, from: '21', to: '30', text: 'Meh' }, ]); }); it('should remove mapping with id 1', () => { const { instance } = setup(); + instance.onRemoveMapping(2); - expect(instance.state.mappings).toEqual([ + expect(instance.state.valueMappings).toEqual([ { id: 1, operator: '', type: MappingType.ValueToText, value: '20', text: 'Ok' }, ]); }); @@ -67,7 +65,7 @@ describe('Next id to add', () => { }); it('should default to 1', () => { - const { instance } = setup({ options: { ...defaultProps.options } }); + const { instance } = setup({ valueMappings: [] }); expect(instance.state.nextIdToAdd).toEqual(1); }); diff --git a/public/app/plugins/panel/gauge/ValueMappings.tsx b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx similarity index 50% rename from public/app/plugins/panel/gauge/ValueMappings.tsx rename to packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx index 9a3f87450f4..ca0a6e71f4a 100644 --- a/public/app/plugins/panel/gauge/ValueMappings.tsx +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/ValueMappingsEditor.tsx @@ -1,33 +1,39 @@ import React, { PureComponent } from 'react'; -import { GaugeOptions, PanelOptionsProps, MappingType, RangeMap, ValueMap, PanelOptionsGroup } from '@grafana/ui'; import MappingRow from './MappingRow'; +import { MappingType, ValueMapping } from '../../types/panel'; +import { PanelOptionsGroup } from '../PanelOptionsGroup/PanelOptionsGroup'; + +export interface Props { + valueMappings: ValueMapping[]; + onChange: (valueMappings: ValueMapping[]) => void; +} interface State { - mappings: Array; + valueMappings: ValueMapping[]; nextIdToAdd: number; } -export default class ValueMappings extends PureComponent, State> { - constructor(props) { +export class ValueMappingsEditor extends PureComponent { + constructor(props: Props) { super(props); - const mappings = props.options.mappings; + const mappings = props.valueMappings; this.state = { - mappings: mappings || [], - nextIdToAdd: mappings.length > 0 ? this.getMaxIdFromMappings(mappings) : 1, + valueMappings: mappings, + nextIdToAdd: mappings.length > 0 ? this.getMaxIdFromValueMappings(mappings) : 1, }; } - getMaxIdFromMappings(mappings) { + getMaxIdFromValueMappings(mappings: ValueMapping[]) { return Math.max.apply(null, mappings.map(mapping => mapping.id).map(m => m)) + 1; } addMapping = () => this.setState(prevState => ({ - mappings: [ - ...prevState.mappings, + valueMappings: [ + ...prevState.valueMappings, { id: prevState.nextIdToAdd, operator: '', @@ -41,23 +47,23 @@ export default class ValueMappings extends PureComponent { + onRemoveMapping = (id: number) => { this.setState( prevState => ({ - mappings: prevState.mappings.filter(m => { + valueMappings: prevState.valueMappings.filter(m => { return m.id !== id; }), }), () => { - this.props.onChange({ ...this.props.options, mappings: this.state.mappings }); + this.props.onChange(this.state.valueMappings); } ); }; - updateGauge = mapping => { + updateGauge = (mapping: ValueMapping) => { this.setState( prevState => ({ - mappings: prevState.mappings.map(m => { + valueMappings: prevState.valueMappings.map(m => { if (m.id === mapping.id) { return { ...mapping }; } @@ -66,24 +72,24 @@ export default class ValueMappings extends PureComponent { - this.props.onChange({ ...this.props.options, mappings: this.state.mappings }); + this.props.onChange(this.state.valueMappings); } ); }; render() { - const { mappings } = this.state; + const { valueMappings } = this.state; return (
- {mappings.length > 0 && - mappings.map((mapping, index) => ( + {valueMappings.length > 0 && + valueMappings.map((valueMapping, index) => ( this.onRemoveMapping(mapping.id)} + key={`${valueMapping.text}-${index}`} + valueMapping={valueMapping} + updateValueMapping={this.updateGauge} + removeValueMapping={() => this.onRemoveMapping(valueMapping.id)} /> ))}
diff --git a/public/sass/components/_value-mappings.scss b/packages/grafana-ui/src/components/ValueMappingsEditor/_ValueMappingsEditor.scss similarity index 100% rename from public/sass/components/_value-mappings.scss rename to packages/grafana-ui/src/components/ValueMappingsEditor/_ValueMappingsEditor.scss diff --git a/public/app/plugins/panel/gauge/__snapshots__/ValueMappings.test.tsx.snap b/packages/grafana-ui/src/components/ValueMappingsEditor/__snapshots__/ValueMappingsEditor.test.tsx.snap similarity index 81% rename from public/app/plugins/panel/gauge/__snapshots__/ValueMappings.test.tsx.snap rename to packages/grafana-ui/src/components/ValueMappingsEditor/__snapshots__/ValueMappingsEditor.test.tsx.snap index 592b3326421..8a465ff88df 100644 --- a/public/app/plugins/panel/gauge/__snapshots__/ValueMappings.test.tsx.snap +++ b/packages/grafana-ui/src/components/ValueMappingsEditor/__snapshots__/ValueMappingsEditor.test.tsx.snap @@ -7,7 +7,9 @@ exports[`Render should render component 1`] = `
; - maxValue: number; - minValue: number; - prefix: string; - showThresholdLabels: boolean; - showThresholdMarkers: boolean; - stat: string; - suffix: string; - thresholds: Threshold[]; - unit: string; -} diff --git a/packages/grafana-ui/src/types/index.ts b/packages/grafana-ui/src/types/index.ts index 814ab0478db..f618ce6db34 100644 --- a/packages/grafana-ui/src/types/index.ts +++ b/packages/grafana-ui/src/types/index.ts @@ -1,4 +1,3 @@ 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 17ef712b0dd..7e4012ad529 100644 --- a/packages/grafana-ui/src/types/panel.ts +++ b/packages/grafana-ui/src/types/panel.ts @@ -56,6 +56,8 @@ interface BaseMap { type: MappingType; } +export type ValueMapping = ValueMap | RangeMap; + export interface ValueMap extends BaseMap { value: string; } diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.tsx index b13393ab2e1..ed27de39cb8 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.tsx @@ -1,7 +1,6 @@ import React, { PureComponent } from 'react'; +import { Select, Label } from '@grafana/ui'; -import { Label } from 'app/core/components/Label/Label'; -import { Select } from '@grafana/ui'; import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv'; import { DashboardSearchHit } from 'app/types'; diff --git a/public/app/features/datasources/settings/BasicSettings.tsx b/public/app/features/datasources/settings/BasicSettings.tsx index 120e002ac68..2d36b79a44c 100644 --- a/public/app/features/datasources/settings/BasicSettings.tsx +++ b/public/app/features/datasources/settings/BasicSettings.tsx @@ -1,5 +1,6 @@ import React, { SFC } from 'react'; -import { Label } from 'app/core/components/Label/Label'; +import { Label } from '@grafana/ui'; + import { Switch } from '../../../core/components/Switch/Switch'; export interface Props { diff --git a/public/app/features/teams/TeamSettings.tsx b/public/app/features/teams/TeamSettings.tsx index 5e058289bf0..87c67b6e597 100644 --- a/public/app/features/teams/TeamSettings.tsx +++ b/public/app/features/teams/TeamSettings.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { connect } from 'react-redux'; +import { Label } from '@grafana/ui'; -import { Label } from 'app/core/components/Label/Label'; import { SharedPreferences } from 'app/core/components/SharedPreferences/SharedPreferences'; import { updateTeam } from './state/actions'; import { getRouteParamsId } from 'app/core/selectors/location'; diff --git a/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx b/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx index f1f78ab1172..93fd67d608c 100644 --- a/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx +++ b/public/app/plugins/panel/gauge/GaugeOptionsEditor.tsx @@ -1,8 +1,8 @@ import React, { PureComponent } from 'react'; -import { GaugeOptions, PanelOptionsProps, PanelOptionsGroup } from '@grafana/ui'; +import { PanelOptionsProps, PanelOptionsGroup, Label } from '@grafana/ui'; import { Switch } from 'app/core/components/Switch/Switch'; -import { Label } from '../../../core/components/Label/Label'; +import { GaugeOptions } from './types'; export default class GaugeOptionsEditor extends PureComponent> { onToggleThresholdLabels = () => diff --git a/public/app/plugins/panel/gauge/GaugePanel.tsx b/public/app/plugins/panel/gauge/GaugePanel.tsx index fd3d812f21e..cfce719b5a6 100644 --- a/public/app/plugins/panel/gauge/GaugePanel.tsx +++ b/public/app/plugins/panel/gauge/GaugePanel.tsx @@ -1,8 +1,9 @@ import React, { PureComponent } from 'react'; -import { GaugeOptions, PanelProps, NullValueMode } from '@grafana/ui'; +import { PanelProps, NullValueMode } from '@grafana/ui'; import { getTimeSeriesVMs } from 'app/viz/state/timeSeries'; import Gauge from 'app/viz/Gauge'; +import { GaugeOptions } from './types'; interface Props extends PanelProps {} diff --git a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx index a5334b0c6e1..9729416b7e6 100644 --- a/public/app/plugins/panel/gauge/GaugePanelOptions.tsx +++ b/public/app/plugins/panel/gauge/GaugePanelOptions.tsx @@ -1,16 +1,17 @@ import React, { PureComponent } from 'react'; import { BasicGaugeColor, - GaugeOptions, PanelOptionsProps, ThresholdsEditor, Threshold, PanelOptionsGrid, + ValueMappingsEditor, + ValueMapping, } from '@grafana/ui'; import ValueOptions from 'app/plugins/panel/gauge/ValueOptions'; -import ValueMappings from 'app/plugins/panel/gauge/ValueMappings'; import GaugeOptionsEditor from './GaugeOptionsEditor'; +import { GaugeOptions } from './types'; export const defaultProps = { options: { @@ -24,7 +25,7 @@ export const defaultProps = { decimals: 0, stat: 'avg', unit: 'none', - mappings: [], + valueMappings: [], thresholds: [], }, }; @@ -32,7 +33,17 @@ export const defaultProps = { export default class GaugePanelOptions extends PureComponent> { static defaultProps = defaultProps; - onThresholdsChanged = (thresholds: Threshold[]) => this.props.onChange({ ...this.props.options, thresholds }); + onThresholdsChanged = (thresholds: Threshold[]) => + this.props.onChange({ + ...this.props.options, + thresholds, + }); + + onValueMappingsChanged = (valueMappings: ValueMapping[]) => + this.props.onChange({ + ...this.props.options, + valueMappings, + }); render() { const { onChange, options } = this.props; @@ -44,7 +55,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 7cfbb382f7b..3bc529f0611 100644 --- a/public/app/plugins/panel/gauge/ValueOptions.tsx +++ b/public/app/plugins/panel/gauge/ValueOptions.tsx @@ -1,9 +1,8 @@ import React, { PureComponent } from 'react'; -import { GaugeOptions, PanelOptionsProps, PanelOptionsGroup } from '@grafana/ui'; +import { PanelOptionsProps, PanelOptionsGroup, Label, Select } 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 { GaugeOptions } from './types'; const statOptions = [ { value: 'min', label: 'Min' }, diff --git a/public/app/plugins/panel/gauge/types.ts b/public/app/plugins/panel/gauge/types.ts index 139597f9cb0..b698a3389c2 100644 --- a/public/app/plugins/panel/gauge/types.ts +++ b/public/app/plugins/panel/gauge/types.ts @@ -1,2 +1,16 @@ +import { Threshold, ValueMapping } from '@grafana/ui'; - +export interface GaugeOptions { + baseColor: string; + decimals: number; + valueMappings: ValueMapping[]; + maxValue: number; + minValue: number; + prefix: string; + showThresholdLabels: boolean; + showThresholdMarkers: boolean; + stat: string; + suffix: string; + thresholds: Threshold[]; + unit: string; +} diff --git a/public/app/viz/Gauge.test.tsx b/public/app/viz/Gauge.test.tsx index f0c4a874649..69c7733f44b 100644 --- a/public/app/viz/Gauge.test.tsx +++ b/public/app/viz/Gauge.test.tsx @@ -12,7 +12,7 @@ const setup = (propOverrides?: object) => { const props: Props = { baseColor: BasicGaugeColor.Green, maxValue: 100, - mappings: [], + valueMappings: [], minValue: 0, prefix: '', showThresholdMarkers: true, diff --git a/public/app/viz/Gauge.tsx b/public/app/viz/Gauge.tsx index d5e4eb94884..094e630a1c0 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 { BasicGaugeColor, Threshold, TimeSeriesVMs, RangeMap, ValueMap, MappingType } from '@grafana/ui'; +import { BasicGaugeColor, Threshold, TimeSeriesVMs, MappingType, ValueMapping } from '@grafana/ui'; import config from '../core/config'; import kbn from '../core/utils/kbn'; @@ -9,7 +9,7 @@ export interface Props { baseColor: string; decimals: number; height: number; - mappings: Array; + valueMappings: ValueMapping[]; maxValue: number; minValue: number; prefix: string; @@ -29,7 +29,7 @@ export class Gauge extends PureComponent { static defaultProps = { baseColor: BasicGaugeColor.Green, maxValue: 100, - mappings: [], + valueMappings: [], minValue: 0, prefix: '', showThresholdMarkers: true, @@ -64,20 +64,17 @@ export class Gauge extends PureComponent { } })[0]; - return { - rangeMap, - valueMap, - }; + return { rangeMap, valueMap }; } formatValue(value) { - const { decimals, mappings, prefix, suffix, unit } = this.props; + const { decimals, valueMappings, prefix, suffix, unit } = this.props; const formatFunc = kbn.valueFormats[unit]; const formattedValue = formatFunc(value, decimals); - if (mappings.length > 0) { - const { rangeMap, valueMap } = this.formatWithMappings(mappings, formattedValue); + if (valueMappings.length > 0) { + const { rangeMap, valueMap } = this.formatWithMappings(valueMappings, formattedValue); if (valueMap) { return `${prefix} ${valueMap} ${suffix}`; @@ -148,10 +145,7 @@ export class Gauge extends PureComponent { color: index === 0 ? threshold.color : thresholds[index].color, }; }), - { - value: maxValue, - color: thresholds.length > 0 ? BasicGaugeColor.Red : baseColor, - }, + { value: maxValue, color: thresholds.length > 0 ? BasicGaugeColor.Red : baseColor }, ]; const options = { @@ -184,19 +178,14 @@ export class Gauge extends PureComponent { formatter: () => { return this.formatValue(value); }, - font: { - size: fontSize, - family: '"Helvetica Neue", Helvetica, Arial, sans-serif', - }, + font: { size: fontSize, family: '"Helvetica Neue", Helvetica, Arial, sans-serif' }, }, show: true, }, }, }; - const plotSeries = { - data: [[0, value]], - }; + const plotSeries = { data: [[0, value]] }; try { $.plot(this.canvasElement, [plotSeries], options); diff --git a/public/sass/_grafana.scss b/public/sass/_grafana.scss index 93fd26b7ca8..e8859ff8255 100644 --- a/public/sass/_grafana.scss +++ b/public/sass/_grafana.scss @@ -1,4 +1,4 @@ - // DEPENDENCIES +// DEPENDENCIES @import '../../node_modules/react-table/react-table.css'; // VENDOR @@ -97,7 +97,6 @@ @import 'components/add_data_source.scss'; @import 'components/page_loader'; @import 'components/toggle_button_group'; -@import 'components/value-mappings'; @import 'components/popover-box'; // LOAD @grafana/ui components