Skip to content

Commit 47a4c73

Browse files
authored
fix: prevent decimal places customization from crashing the visualization (#5992)
1 parent 6d8400a commit 47a4c73

File tree

9 files changed

+242
-316
lines changed

9 files changed

+242
-316
lines changed
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Libraries
2+
import React, {FC, useState} from 'react'
3+
4+
// Components
5+
import {
6+
AutoInput,
7+
AutoInputMode,
8+
Form,
9+
Input,
10+
InputType,
11+
} from '@influxdata/clockface'
12+
13+
// Utils
14+
import {convertUserInputToNumOrNaN} from 'src/shared/utils/convertUserInput'
15+
16+
// Constants
17+
import {
18+
MIN_DECIMAL_PLACES,
19+
MAX_DECIMAL_PLACES,
20+
} from 'src/visualization/constants'
21+
22+
interface DecimalPlacesProps {
23+
isEnforced: boolean
24+
digits: number
25+
update: (obj: any) => void
26+
}
27+
28+
export const DecimalPlaces: FC<DecimalPlacesProps> = (
29+
props: DecimalPlacesProps
30+
) => {
31+
const {isEnforced, digits, update} = props
32+
const [decimalPlaces, setDecimalPlaces] = useState<number | null>(digits)
33+
34+
const setDigits = (updatedDigits: number | null) => {
35+
setDecimalPlaces(updatedDigits)
36+
if (!Number.isNaN(updatedDigits)) {
37+
update({
38+
decimalPlaces: {
39+
isEnforced,
40+
digits: updatedDigits,
41+
},
42+
})
43+
}
44+
}
45+
46+
const handleChangeMode = (mode: AutoInputMode): void => {
47+
if (mode === AutoInputMode.Auto) {
48+
setDigits(null)
49+
} else {
50+
setDigits(2)
51+
}
52+
}
53+
54+
return (
55+
<Form.Element label="Decimal Places">
56+
<AutoInput
57+
mode={
58+
typeof decimalPlaces === 'number'
59+
? AutoInputMode.Custom
60+
: AutoInputMode.Auto
61+
}
62+
onChangeMode={handleChangeMode}
63+
inputComponent={
64+
<Input
65+
name="decimal-places"
66+
placeholder="Enter a number"
67+
onChange={event => {
68+
setDigits(convertUserInputToNumOrNaN(event))
69+
}}
70+
value={decimalPlaces}
71+
min={MIN_DECIMAL_PLACES}
72+
max={MAX_DECIMAL_PLACES}
73+
type={InputType.Number}
74+
/>
75+
}
76+
/>
77+
</Form.Element>
78+
)
79+
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import icon from './icon'
22
import properties from './properties'
3-
import options from './options'
3+
import {GaugeOptions} from './options'
44
import view from './view'
55

66
export default register => {
@@ -10,6 +10,6 @@ export default register => {
1010
graphic: icon,
1111
initial: properties,
1212
component: view,
13-
options,
13+
options: GaugeOptions,
1414
})
1515
}
Lines changed: 85 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,141 +1,98 @@
1+
// Libraries
12
import React, {FC} from 'react'
3+
import {Columns, Form, Grid, Input} from '@influxdata/clockface'
24

3-
import {
4-
Grid,
5-
Columns,
6-
Form,
7-
AutoInput,
8-
AutoInputMode,
9-
Input,
10-
InputType,
11-
} from '@influxdata/clockface'
12-
5+
// Components
136
import ThresholdsSettings from 'src/visualization/components/internal/ThresholdsSettings'
14-
import {
15-
MIN_DECIMAL_PLACES,
16-
MAX_DECIMAL_PLACES,
17-
} from 'src/visualization/constants'
18-
import {convertUserInputToNumOrNaN} from 'src/shared/utils/convertUserInput'
7+
import {DecimalPlaces} from 'src/visualization/components/internal/DecimalPlaces'
198

9+
// Types
2010
import {GaugeViewProperties} from 'src/types'
2111
import {VisualizationOptionProps} from 'src/visualization'
2212

2313
interface Props extends VisualizationOptionProps {
2414
properties: GaugeViewProperties
2515
}
2616

27-
const GaugeOptions: FC<Props> = ({properties, update}) => {
28-
const setDigits = (digits: number | null) => {
29-
update({
30-
decimalPlaces: {
31-
...properties.decimalPlaces,
32-
digits,
33-
},
34-
})
35-
}
36-
const handleChangeMode = (mode: AutoInputMode): void => {
37-
if (mode === AutoInputMode.Auto) {
38-
setDigits(null)
39-
} else {
40-
setDigits(2)
41-
}
42-
}
43-
44-
return (
45-
<Grid>
46-
<Grid.Row>
47-
<Grid.Column>
48-
<Grid.Row>
49-
<Grid.Column widthXS={Columns.Six}>
50-
<Form.Element label="Value Prefix">
51-
<Input
52-
testID="prefix-input"
53-
value={properties.prefix}
54-
onChange={evt => {
55-
update({prefix: evt.target.value})
56-
}}
57-
placeholder="%, MPH, etc."
58-
/>
59-
</Form.Element>
60-
</Grid.Column>
61-
<Grid.Column widthXS={Columns.Six}>
62-
<Form.Element label="Value Suffix">
63-
<Input
64-
testID="suffix-input"
65-
value={properties.suffix}
66-
onChange={evt => {
67-
update({suffix: evt.target.value})
68-
}}
69-
placeholder="%, MPH, etc."
70-
/>
71-
</Form.Element>
72-
</Grid.Column>
73-
</Grid.Row>
74-
<Grid.Row>
75-
<Grid.Column widthXS={Columns.Six}>
76-
<Form.Element label="Axis Prefix">
77-
<Input
78-
testID="tick-prefix-input"
79-
value={properties.tickPrefix}
80-
onChange={evt => {
81-
update({tickPrefix: evt.target.value})
82-
}}
83-
placeholder="%, MPH, etc."
84-
/>
85-
</Form.Element>
86-
</Grid.Column>
87-
<Grid.Column widthXS={Columns.Six}>
88-
<Form.Element label="Axis Suffix">
89-
<Input
90-
testID="tick-suffix-input"
91-
value={properties.tickSuffix}
92-
onChange={evt => {
93-
update({tickSuffix: evt.target.value})
94-
}}
95-
placeholder="%, MPH, etc."
96-
/>
97-
</Form.Element>
98-
</Grid.Column>
99-
</Grid.Row>
100-
{properties.decimalPlaces && (
101-
<Form.Element label="Decimal Places">
102-
<AutoInput
103-
mode={
104-
properties.decimalPlaces.digits
105-
? AutoInputMode.Custom
106-
: AutoInputMode.Auto
107-
}
108-
onChangeMode={handleChangeMode}
109-
inputComponent={
110-
<Input
111-
name="decimal-places"
112-
placeholder="Enter a number"
113-
onChange={evt => {
114-
setDigits(convertUserInputToNumOrNaN(evt))
115-
}}
116-
value={properties.decimalPlaces.digits}
117-
min={MIN_DECIMAL_PLACES}
118-
max={MAX_DECIMAL_PLACES}
119-
type={InputType.Number}
120-
/>
121-
}
17+
export const GaugeOptions: FC<Props> = ({properties, update}) => (
18+
<Grid>
19+
<Grid.Row>
20+
<Grid.Column>
21+
<Grid.Row>
22+
<Grid.Column widthXS={Columns.Six}>
23+
<Form.Element label="Value Prefix">
24+
<Input
25+
testID="prefix-input"
26+
value={properties.prefix}
27+
onChange={evt => {
28+
update({prefix: evt.target.value})
29+
}}
30+
placeholder="%, MPH, etc."
12231
/>
12332
</Form.Element>
124-
)}
125-
</Grid.Column>
126-
<Grid.Column widthXS={Columns.Twelve} widthMD={Columns.Six}>
127-
<Form.Element label="Colorized Thresholds">
128-
<ThresholdsSettings
129-
thresholds={properties.colors}
130-
onSetThresholds={colors => {
131-
update({colors})
132-
}}
133-
/>
134-
</Form.Element>
135-
</Grid.Column>
136-
</Grid.Row>
137-
</Grid>
138-
)
139-
}
140-
141-
export default GaugeOptions
33+
</Grid.Column>
34+
<Grid.Column widthXS={Columns.Six}>
35+
<Form.Element label="Value Suffix">
36+
<Input
37+
testID="suffix-input"
38+
value={properties.suffix}
39+
onChange={evt => {
40+
update({suffix: evt.target.value})
41+
}}
42+
placeholder="%, MPH, etc."
43+
/>
44+
</Form.Element>
45+
</Grid.Column>
46+
</Grid.Row>
47+
<Grid.Row>
48+
<Grid.Column widthXS={Columns.Six}>
49+
<Form.Element label="Axis Prefix">
50+
<Input
51+
testID="tick-prefix-input"
52+
value={properties.tickPrefix}
53+
onChange={evt => {
54+
update({tickPrefix: evt.target.value})
55+
}}
56+
placeholder="%, MPH, etc."
57+
/>
58+
</Form.Element>
59+
</Grid.Column>
60+
<Grid.Column widthXS={Columns.Six}>
61+
<Form.Element label="Axis Suffix">
62+
<Input
63+
testID="tick-suffix-input"
64+
value={properties.tickSuffix}
65+
onChange={evt => {
66+
update({tickSuffix: evt.target.value})
67+
}}
68+
placeholder="%, MPH, etc."
69+
/>
70+
</Form.Element>
71+
</Grid.Column>
72+
</Grid.Row>
73+
{properties.decimalPlaces && (
74+
<DecimalPlaces
75+
isEnforced={properties?.decimalPlaces?.isEnforced === true}
76+
digits={
77+
typeof properties?.decimalPlaces?.digits === 'number' ||
78+
properties?.decimalPlaces?.digits === null
79+
? properties.decimalPlaces.digits
80+
: NaN
81+
}
82+
update={update}
83+
/>
84+
)}
85+
</Grid.Column>
86+
<Grid.Column widthXS={Columns.Twelve} widthMD={Columns.Six}>
87+
<Form.Element label="Colorized Thresholds">
88+
<ThresholdsSettings
89+
thresholds={properties.colors}
90+
onSetThresholds={colors => {
91+
update({colors})
92+
}}
93+
/>
94+
</Form.Element>
95+
</Grid.Column>
96+
</Grid.Row>
97+
</Grid>
98+
)
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import icon from './icon'
22
import properties from './properties'
3-
import options from './options'
3+
import {SingleStatOptions} from './options'
44
import view from './view'
55

66
export default register => {
@@ -10,6 +10,6 @@ export default register => {
1010
graphic: icon,
1111
component: view,
1212
initial: properties,
13-
options,
13+
options: SingleStatOptions,
1414
})
1515
}

0 commit comments

Comments
 (0)