diff --git a/src/Components/TriggerEditForm/TriggerEditForm.tsx b/src/Components/TriggerEditForm/TriggerEditForm.tsx index cab316603..a0dca3f35 100644 --- a/src/Components/TriggerEditForm/TriggerEditForm.tsx +++ b/src/Components/TriggerEditForm/TriggerEditForm.tsx @@ -12,7 +12,7 @@ import { import { defaultNumberEditFormat, defaultNumberViewFormat } from "../../helpers/Formats"; import FormattedNumberInput from "../FormattedNumberInput/FormattedNumberInput"; import ScheduleEdit from "../ScheduleEdit/ScheduleEdit"; -import TriggerModeEditor, { ValueType } from "../TriggerModeEditor/TriggerModeEditor"; +import { ValueType, TriggerModeEditor } from "../TriggerModeEditor/TriggerModeEditor"; import StatusSelect from "../StatusSelect/StatusSelect"; import TagDropdownSelect from "../TagDropdownSelect/TagDropdownSelect"; import { Status, StatusesList } from "../../Domain/Status"; diff --git a/src/Components/TriggerModeEditor/Components/TooltipExpressionHelp/TooltipExpressionHelp.tsx b/src/Components/TriggerModeEditor/Components/TooltipExpressionHelp/TooltipExpressionHelp.tsx new file mode 100644 index 000000000..9523ac049 --- /dev/null +++ b/src/Components/TriggerModeEditor/Components/TooltipExpressionHelp/TooltipExpressionHelp.tsx @@ -0,0 +1,36 @@ +import React from "react"; +import { Link } from "@skbkontur/react-ui/components/Link"; +import CodeRef from "../../../CodeRef/CodeRef"; +import classNames from "classnames/bind"; + +import styles from "../../TriggerModeEditor.less"; + +const cn = classNames.bind(styles); + +export const TooltipExpressionHelp = (): React.ReactNode => ( +
+
+ Expression uses{" "} + + govaluate + {" "} + with predefined constants: +
+
+ t1, t2, ... are values from your targets. +
+
+ OK, WARN, ERROR,{" "} + NODATA are states that must be the result of evaluation. +
+
+ PREV_STATE is equal to previously set state, and allows you to + prevent frequent state changes. +
+ +
+ NOTE: Only T1 target can resolve into multiple metrics in Advanced Mode. T2, T3, ... + must resolve to single metrics. +
+
+); diff --git a/src/Components/TriggerModeEditor/TriggerModeEditor.tsx b/src/Components/TriggerModeEditor/TriggerModeEditor.tsx index 0433ddc83..a9ea2e057 100644 --- a/src/Components/TriggerModeEditor/TriggerModeEditor.tsx +++ b/src/Components/TriggerModeEditor/TriggerModeEditor.tsx @@ -1,13 +1,12 @@ -import * as React from "react"; +import React, { FC, useState } from "react"; import { ValidationWrapperV1, tooltip, ValidationInfo } from "@skbkontur/react-ui-validations"; import { Tabs } from "@skbkontur/react-ui/components/Tabs"; import { Input } from "@skbkontur/react-ui/components/Input"; -import { Link } from "@skbkontur/react-ui/components/Link"; import { Trigger, TriggerType } from "../../Domain/Trigger"; import TriggerSimpleModeEditor from "../TriggerSimpleModeEditor/TriggerSimpleModeEditor"; import { RowStack, Fit, Fill } from "../ItemsStack/ItemsStack"; -import CodeRef from "../CodeRef/CodeRef"; import HelpTooltip from "../HelpTooltip/HelpTooltip"; +import { TooltipExpressionHelp } from "./Components/TooltipExpressionHelp/TooltipExpressionHelp"; import classNames from "classnames/bind"; import styles from "./TriggerModeEditor.less"; @@ -21,7 +20,7 @@ export type ValueType = { error_value: number | null; }; -type Props = { +type IProps = { disableSimpleMode?: boolean; triggerType: TriggerType; value: ValueType; @@ -30,146 +29,92 @@ type Props = { onChange: (update: Partial) => void; }; -type State = { - mode: string; - watchFor: WatchForType; - risingValues: ValueType; - fallingValues: ValueType; -}; - -export default class TriggerModeEditor extends React.Component { - static getDerivedStateFromProps(props: Props): State { - const modeType = TriggerModeEditor.getModeType(props.triggerType); - const watchForType = TriggerModeEditor.getWatchForType(props.triggerType); - - return { - mode: modeType, - watchFor: watchForType, - risingValues: - watchForType === "rising" ? props.value : { warn_value: null, error_value: null }, - fallingValues: - watchForType === "falling" ? props.value : { warn_value: null, error_value: null }, - }; - } - - static getWatchForType(type: string): WatchForType { +export const TriggerModeEditor: FC = ({ + disableSimpleMode, + triggerType, + value, + expression, + validateExpression, + onChange, +}) => { + const getWatchForType = (type: string): WatchForType => { return type === "falling" ? type : "rising"; - } + }; - static getModeType(type: string): string { + const getModeType = (type: string): string => { return type === "expression" ? "advanced" : "simple"; - } - - render(): React.ReactElement { - const { mode, watchFor, risingValues, fallingValues } = this.state; - const { expression, disableSimpleMode, validateExpression, onChange } = this.props; + }; - return ( - <> -
- - - Simple mode - - Advanced mode - -
- {mode === "simple" && ( - - )} - {mode === "advanced" && ( -
- - - - onChange({ expression: value })} - placeholder="t1 >= 10 ? ERROR : (t1 >= 1 ? WARN : OK)" - /> - - - -   - {this.tooltipExpressionHelp()} - - -
- )} - - ); - } + const [mode, setMode] = useState(getModeType(triggerType)); + const [watchForField, setWatchForField] = useState(getWatchForType(triggerType)); + const [values, setValues] = useState(value); - handleTabChange = (value: string): void => { - const { watchFor } = this.state; - const { disableSimpleMode, onChange } = this.props; + const handleTabChange = (value: string): void => { if (!disableSimpleMode) { - const triggerType = value === "advanced" ? "expression" : watchFor; + const triggerType = value === "advanced" ? "expression" : watchForField; onChange({ trigger_type: triggerType }); + setMode(value); } }; - handleRadioChange = (type: WatchForType): void => { - const { risingValues, fallingValues } = this.state; - const { onChange } = this.props; - const value = type === "falling" ? { ...fallingValues } : { ...risingValues }; - this.setState({ watchFor: type }); - onChange({ trigger_type: type, ...value }); + const handleRadioChange = (type: WatchForType): void => { + setWatchForField(type); + onChange({ trigger_type: type, ...values }); }; - handleInputChange = (value: number | null, valueType: string): void => { - const { watchFor, risingValues, fallingValues } = this.state; - const { onChange } = this.props; - if (watchFor === "rising") { - this.setState({ risingValues: { ...risingValues, [valueType]: value } }); - } - if (watchFor === "falling") { - this.setState({ fallingValues: { ...fallingValues, [valueType]: value } }); - } + const handleInputChange = (value: number | null, valueType: string): void => { + setValues((prev) => ({ ...prev, [valueType]: value })); onChange({ [valueType]: value }); }; - tooltipExpressionHelp = (): React.ReactNode => ( -
-
- Expression uses{" "} - - govaluate - {" "} - with predefined constants: -
-
- t1, t2, ... are values from your targets. -
-
- OK, WARN, ERROR,{" "} - NODATA are states that must be the result of evaluation. -
-
- PREV_STATE is equal to previously set state, and allows you to - prevent frequent state changes. -
- -
- NOTE: Only T1 target can resolve into multiple metrics in Advanced Mode. T2, T3, ... - must resolve to single metrics. + const configureValues = (watchForType: WatchForType) => + watchForField === `${watchForType}` ? values : { warn_value: null, error_value: null }; + + return ( + <> +
+ + + Simple mode + + Advanced mode +
-
+ {mode === "simple" && ( + + )} + {mode === "advanced" && ( +
+ + + + onChange({ expression: value })} + placeholder="t1 >= 10 ? ERROR : (t1 >= 1 ? WARN : OK)" + /> + + + +   + {TooltipExpressionHelp()} + + +
+ )} + ); -} +}; diff --git a/src/Stories/TriggerModeEditor.stories.tsx b/src/Stories/TriggerModeEditor.stories.tsx index e1f080208..274b455ae 100644 --- a/src/Stories/TriggerModeEditor.stories.tsx +++ b/src/Stories/TriggerModeEditor.stories.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { storiesOf } from "@storybook/react"; import { action } from "@storybook/addon-actions"; import { ValidationContainer } from "@skbkontur/react-ui-validations"; -import TriggerModeEditor from "../Components/TriggerModeEditor/TriggerModeEditor"; +import { TriggerModeEditor } from "../Components/TriggerModeEditor/TriggerModeEditor"; storiesOf("TriggerModeEditor", module) .addDecorator((story) => (