diff --git a/ui/src/dashboards/components/GaugeOptions.js b/ui/src/dashboards/components/GaugeOptions.js
index 2dc013f34..0142d128a 100644
--- a/ui/src/dashboards/components/GaugeOptions.js
+++ b/ui/src/dashboards/components/GaugeOptions.js
@@ -123,7 +123,7 @@ class GaugeOptions extends Component {
)
const isUnique = !colorsWithoutMinOrMax.some(
- color => color.value === targetValue
+ color => color.value === targetValue && color.id !== threshold.id
)
allowedToUpdate = greaterThanMin && lessThanMax && isUnique
@@ -146,11 +146,11 @@ class GaugeOptions extends Component {
handleUpdateAxes(newAxes)
}
- handleSortColors = () => {
- const {gaugeColors, handleUpdateGaugeColors} = this.props
- const sortedColors = _.sortBy(gaugeColors, color => color.value)
+ get sortedGaugeColors() {
+ const {gaugeColors} = this.props
+ const sortedColors = _.sortBy(gaugeColors, 'value')
- handleUpdateGaugeColors(sortedColors)
+ return sortedColors
}
render() {
@@ -174,12 +174,10 @@ class GaugeOptions extends Component {
>
Add Threshold
- {gaugeColors.map(color => (
+ {this.sortedGaugeColors.map((color, index) => (
))}
diff --git a/ui/src/dashboards/components/Threshold.js b/ui/src/dashboards/components/Threshold.js
deleted file mode 100644
index b4e1e237f..000000000
--- a/ui/src/dashboards/components/Threshold.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import React, {Component} from 'react'
-import PropTypes from 'prop-types'
-
-import ColorDropdown from 'shared/components/ColorDropdown'
-
-import {THRESHOLD_COLORS} from 'shared/constants/thresholds'
-
-class Threshold extends Component {
- constructor(props) {
- super(props)
-
- this.state = {
- workingValue: this.props.threshold.value,
- valid: true,
- }
- }
-
- handleChangeWorkingValue = e => {
- const {threshold, onValidateColorValue, onUpdateColorValue} = this.props
- const targetValue = Number(e.target.value)
-
- const valid = onValidateColorValue(threshold, targetValue)
-
- if (valid) {
- onUpdateColorValue(threshold, targetValue)
- }
-
- this.setState({valid, workingValue: targetValue})
- }
-
- handleBlur = () => {
- this.setState({workingValue: this.props.threshold.value, valid: true})
- this.props.onSortColors()
- }
-
- handleKeyUp = e => {
- if (e.key === 'Enter') {
- this.thresholdInputRef.blur()
- }
- }
-
- render() {
- const {
- visualizationType,
- threshold,
- threshold: {hex, name},
- disableMaxColor,
- onChooseColor,
- onDeleteThreshold,
- isMin,
- isMax,
- } = this.props
- const {workingValue, valid} = this.state
- const selectedColor = {hex, name}
-
- let label = 'Threshold'
- let labelClass = 'threshold-item--label__editable'
- let canBeDeleted = true
-
- if (visualizationType === 'gauge') {
- labelClass =
- isMin || isMax
- ? 'threshold-item--label'
- : 'threshold-item--label__editable'
- canBeDeleted = !(isMin || isMax)
- }
-
- if (isMin && visualizationType === 'gauge') {
- label = 'Minimum'
- }
- if (isMax && visualizationType === 'gauge') {
- label = 'Maximum'
- }
-
- const inputClass = valid
- ? 'form-control input-sm threshold-item--input'
- : 'form-control input-sm threshold-item--input form-volcano'
-
- return (
-
-
{label}
- {canBeDeleted ? (
-
- ) : null}
-
(this.thresholdInputRef = r)}
- />
-
-
- )
- }
-}
-
-const {bool, func, number, shape, string} = PropTypes
-
-Threshold.propTypes = {
- visualizationType: string.isRequired,
- threshold: shape({
- type: string.isRequired,
- hex: string.isRequired,
- id: string.isRequired,
- name: string.isRequired,
- value: number.isRequired,
- }).isRequired,
- disableMaxColor: bool,
- onChooseColor: func.isRequired,
- onValidateColorValue: func.isRequired,
- onUpdateColorValue: func.isRequired,
- onDeleteThreshold: func.isRequired,
- isMin: bool,
- isMax: bool,
- onSortColors: func.isRequired,
-}
-
-export default Threshold
diff --git a/ui/src/dashboards/components/Threshold.tsx b/ui/src/dashboards/components/Threshold.tsx
new file mode 100644
index 000000000..cad84c177
--- /dev/null
+++ b/ui/src/dashboards/components/Threshold.tsx
@@ -0,0 +1,173 @@
+import React, {PureComponent} from 'react'
+
+import ColorDropdown from 'src/shared/components/ColorDropdown'
+import {THRESHOLD_COLORS} from 'src/shared/constants/thresholds'
+
+interface SelectedColor {
+ hex: string
+ name: string
+}
+interface Threshold {
+ type: string
+ hex: string
+ id: string
+ name: string
+ value: number
+}
+
+interface Props {
+ visualizationType: string
+ threshold: Threshold
+ disableMaxColor: boolean
+ onChooseColor: (threshold: Threshold) => void
+ onValidateColorValue: (threshold: Threshold, targetValue: number) => boolean
+ onUpdateColorValue: (threshold: Threshold, targetValue: number) => void
+ onDeleteThreshold: (threshold: Threshold) => void
+ isMin: boolean
+ isMax: boolean
+}
+
+interface State {
+ workingValue: number
+ valid: boolean
+}
+
+class Threshold extends PureComponent {
+ private thresholdInputRef: HTMLInputElement
+
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ workingValue: this.props.threshold.value,
+ valid: true,
+ }
+ }
+
+ public render() {
+ const {threshold, disableMaxColor, onChooseColor, isMax} = this.props
+ const {workingValue} = this.state
+
+ return (
+
+
{this.label}
+ {this.canBeDeleted ? (
+
+ ) : null}
+
+
+
+ )
+ }
+
+ private get selectedColor(): SelectedColor {
+ const {threshold: {hex, name}} = this.props
+ return {hex, name}
+ }
+
+ private get inputClass(): string {
+ const {valid} = this.state
+
+ const inputClass = valid
+ ? 'form-control input-sm threshold-item--input'
+ : 'form-control input-sm threshold-item--input form-volcano'
+
+ return inputClass
+ }
+
+ private get canBeDeleted(): boolean {
+ const {visualizationType, isMax, isMin} = this.props
+
+ let canBeDeleted = true
+
+ if (visualizationType === 'gauge') {
+ canBeDeleted = !(isMin || isMax)
+ }
+
+ return canBeDeleted
+ }
+
+ private get labelClass(): string {
+ const {visualizationType, isMax, isMin} = this.props
+
+ let labelClass = 'threshold-item--label__editable'
+
+ if (visualizationType === 'gauge') {
+ labelClass =
+ isMin || isMax
+ ? 'threshold-item--label'
+ : 'threshold-item--label__editable'
+ }
+
+ return labelClass
+ }
+
+ private get label(): string {
+ let label = 'Threshold'
+ const {visualizationType, isMax, isMin} = this.props
+
+ if (isMin && visualizationType === 'gauge') {
+ label = 'Minimum'
+ }
+ if (isMax && visualizationType === 'gauge') {
+ label = 'Maximum'
+ }
+
+ return label
+ }
+
+ private handleChangeWorkingValue = e => {
+ const {threshold, onValidateColorValue} = this.props
+ const targetValue = Number(e.target.value)
+
+ const valid = onValidateColorValue(threshold, targetValue)
+
+ this.setState({valid, workingValue: targetValue})
+ }
+
+ private handleBlur = () => {
+ const {valid, workingValue} = this.state
+ const {threshold, onUpdateColorValue} = this.props
+
+ if (valid) {
+ onUpdateColorValue(threshold, workingValue)
+ } else {
+ this.setState({workingValue: threshold.value, valid: true})
+ }
+ }
+
+ private handleKeyUp = e => {
+ if (e.key === 'Enter') {
+ this.thresholdInputRef.blur()
+ }
+ }
+
+ private handleInputRef = (ref: HTMLInputElement) => {
+ this.thresholdInputRef = ref
+ }
+
+ private handleDelete = () => {
+ const {threshold, onDeleteThreshold} = this.props
+ onDeleteThreshold(threshold)
+ }
+}
+
+export default Threshold
diff --git a/ui/src/shared/components/ThresholdsList.js b/ui/src/shared/components/ThresholdsList.js
index 979fc3c80..75440d14d 100644
--- a/ui/src/shared/components/ThresholdsList.js
+++ b/ui/src/shared/components/ThresholdsList.js
@@ -113,11 +113,11 @@ class ThresholdsList extends Component {
return !sortedColors.some(color => color.value === targetValue)
}
- handleSortColors = () => {
- const {thresholdsListColors, handleUpdateThresholdsListColors} = this.props
- const sortedColors = _.sortBy(thresholdsListColors, color => color.value)
+ get sortedColors() {
+ const {thresholdsListColors} = this.props
+ const sortedColors = _.sortBy(thresholdsListColors, 'value')
- handleUpdateThresholdsListColors(sortedColors)
+ return sortedColors
}
render() {
@@ -138,7 +138,7 @@ class ThresholdsList extends Component {
>
Add Threshold
- {thresholdsListColors.map(
+ {this.sortedColors.map(
color =>
color.id === THRESHOLD_TYPE_BASE ? (
@@ -159,7 +159,6 @@ class ThresholdsList extends Component {
onValidateColorValue={this.handleValidateColorValue}
onUpdateColorValue={this.handleUpdateColorValue}
onDeleteThreshold={this.handleDeleteThreshold}
- onSortColors={this.handleSortColors}
/>
)
)}