From e6c26cb304f35c57018a6e40b78b13e7f5604341 Mon Sep 17 00:00:00 2001 From: Chika Date: Mon, 28 Sep 2020 13:37:23 +0300 Subject: [PATCH] refactor validation: inject validation status --- src/client/Elements/InputNumber.jsx | 11 ++++++-- src/client/Elements/Radio.jsx | 4 ++- src/client/Elements/Select.jsx | 12 +++++++-- src/client/Elements/Switch.jsx | 11 ++++++-- src/client/hocs/withStore.js | 5 +--- src/client/hooks/useValidation.ts | 39 +++++++++++++++++++++-------- src/core/constants/errorMessages.js | 1 + src/core/types/stores.ts | 5 +++- 8 files changed, 65 insertions(+), 23 deletions(-) create mode 100644 src/core/constants/errorMessages.js diff --git a/src/client/Elements/InputNumber.jsx b/src/client/Elements/InputNumber.jsx index 447fa10..bf3a13a 100644 --- a/src/client/Elements/InputNumber.jsx +++ b/src/client/Elements/InputNumber.jsx @@ -2,9 +2,16 @@ import { Form, InputNumber as AntInputNumber } from 'antd'; import { Status } from 'core/types/statuses'; import React from 'react'; -const InputNumber = ({ value, setCurrentValue, status, ...props }) => { +const InputNumber = ({ + value, + setCurrentValue, + status, + validateStatus, + message, + ...props +}) => { return ( - + { return ( - + { +const Select = ({ + value, + setCurrentValue, + status, + validateStatus, + message, + options, + ...props +}) => { return ( - + { +const Switch = ({ + value, + setCurrentValue, + status, + validateStatus, + message, + ...props +}) => { return ( - + ({ const { isValid, validateStatus, message } = useValidation({ elementName: name, value: debouncedValue, - validation: validation || { - errorMessage: '', - validator: () => {}, - }, + validation, }); const { options } = useOptions(name); diff --git a/src/client/hooks/useValidation.ts b/src/client/hooks/useValidation.ts index 906d634..86351fa 100644 --- a/src/client/hooks/useValidation.ts +++ b/src/client/hooks/useValidation.ts @@ -1,4 +1,5 @@ import { ValidateStatus } from 'antd/lib/form/FormItem'; +import { INVALID_INPUT as INVALID_INPUT_MESSAGE } from 'core/constants/errorMessages'; import { ElementsNames } from 'core/types/elements'; import { useEffect, useState } from 'react'; import { useStores } from './useStores'; @@ -12,30 +13,46 @@ interface IUseValidationArgs { export const useValidation = ({ elementName, value, - validation: { validator, errorMessage }, + validation, }: IUseValidationArgs) => { - const [isValid, setIsValid] = useState(false); + const { validator, errorMessage } = validation || { + validator: undefined, + errorMessage: undefined, + }; + const [isValid, setValidation] = useState(undefined); const { calculationStore } = useStores(); + // inject value from store + const validationStatus = calculationStore.validations[elementName]; useEffect(() => { - const validationResult = validator(value); - setIsValid(validationResult); - calculationStore.setValidation(elementName, validationResult); - }, [value, validator, calculationStore, elementName]); + setValidation(validationStatus); + }, [validationStatus]); + + // inner validation && set validation status to store + useEffect(() => { + if (!validator) { + return; + } + if (!value) { + setValidation(undefined); + calculationStore.setValidation(elementName, undefined); + } else { + const validationResult = validator(value); + setValidation(validationResult); + calculationStore.setValidation(elementName, validationResult); + } + }, [value, validator, elementName]); const getValidateStatus = (): ValidateStatus | undefined => { - if (!value) { + if (isValid === undefined) { return undefined; } return isValid === false ? 'error' : 'success'; }; const getMessage = (): string | undefined => { - if (!value) { - return undefined; - } if (isValid === false) { - return errorMessage; + return errorMessage || INVALID_INPUT_MESSAGE; } }; diff --git a/src/core/constants/errorMessages.js b/src/core/constants/errorMessages.js new file mode 100644 index 0000000..baf7be5 --- /dev/null +++ b/src/core/constants/errorMessages.js @@ -0,0 +1 @@ +export const INVALID_INPUT = 'Некорректные данные'; diff --git a/src/core/types/stores.ts b/src/core/types/stores.ts index 63abd59..362df16 100644 --- a/src/core/types/stores.ts +++ b/src/core/types/stores.ts @@ -34,7 +34,10 @@ export interface ICalculationStore { validations: TElements; getValidation: (elementName: ElementsNames) => boolean; - setValidation: (elementName: ElementsNames, validation: boolean) => void; + setValidation: ( + elementName: ElementsNames, + validation: boolean | undefined, + ) => void; tables: IStoreTable; setTableRow: (