From 91fe184a13cd07c032f1a95e66ee95eec24af357 Mon Sep 17 00:00:00 2001 From: NasgulNexus Date: Thu, 11 May 2023 12:13:51 +0200 Subject: [PATCH 1/2] fix: initial value --- src/lib/core/components/Form/Controller.tsx | 7 ++--- src/lib/core/components/Form/DynamicField.tsx | 2 +- .../core/components/Form/hooks/useField.tsx | 17 +++++++----- .../core/components/Form/hooks/useStore.tsx | 26 +++++++++++++------ src/lib/core/components/Form/types/context.ts | 5 ++-- .../components/Inputs/ArrayBase/ArrayBase.tsx | 2 +- .../components/Inputs/CardOneOf/CardOneOf.tsx | 2 +- .../Inputs/ObjectBase/ObjectBase.tsx | 2 +- .../ObjectValueInput/ObjectValueInput.tsx | 2 +- src/lib/kit/components/Inputs/OneOf/OneOf.tsx | 2 +- .../components/Inputs/OneOfCard/OneOfCard.tsx | 2 +- .../kit/components/Inputs/Secret/Secret.tsx | 2 +- .../TableArrayInput/TableArrayInput.tsx | 4 +-- .../components/Inputs/TextLink/TextLink.tsx | 2 +- .../components/InputPreview/SpecSelector.tsx | 2 +- 15 files changed, 46 insertions(+), 33 deletions(-) diff --git a/src/lib/core/components/Form/Controller.tsx b/src/lib/core/components/Form/Controller.tsx index eb42bd45..c59eae74 100644 --- a/src/lib/core/components/Form/Controller.tsx +++ b/src/lib/core/components/Form/Controller.tsx @@ -17,7 +17,7 @@ import {ControllerMirror, FieldValue, ValidateError} from './types'; export interface ControllerProps { spec: SpecType; name: string; - initialValue: Value; + value: Value; parentOnChange: | (( childName: string, @@ -31,7 +31,7 @@ export interface ControllerProps({ spec, name, - initialValue, + value, parentOnChange, parentOnUnmount, }: ControllerProps) => { @@ -41,7 +41,8 @@ export const Controller = ({ const validate = useValidate(spec); const renderProps = useField({ name, - initialValue, + initialValue: _.get(tools.initialValue, name), + value, spec, validate, tools, diff --git a/src/lib/core/components/Form/DynamicField.tsx b/src/lib/core/components/Form/DynamicField.tsx index 8ae75ce1..0445cf60 100644 --- a/src/lib/core/components/Form/DynamicField.tsx +++ b/src/lib/core/components/Form/DynamicField.tsx @@ -85,7 +85,7 @@ export const DynamicField: React.FC = ({ name={name} parentOnChange={null} parentOnUnmount={null} - initialValue={_.get(tools.initialValue, name)} + value={_.get(tools.values, name)} /> {watcher} diff --git a/src/lib/core/components/Form/hooks/useField.tsx b/src/lib/core/components/Form/hooks/useField.tsx index 4aae6d16..d5ba3d08 100644 --- a/src/lib/core/components/Form/hooks/useField.tsx +++ b/src/lib/core/components/Form/hooks/useField.tsx @@ -18,6 +18,7 @@ export interface UseFieldProps name: string; spec: SpecType; initialValue: Value; + value: Value; validate?: (value?: Value) => ValidateError; tools: DynamicFormsContext['tools']; parentOnChange: @@ -34,6 +35,7 @@ export const useField = ({ name, spec, initialValue, + value: externalValue, validate: propsValidate, tools, parentOnChange, @@ -53,7 +55,7 @@ export const useField = ({ ); const [state, setState] = React.useState(() => { - let value = _.cloneDeep(initialValue); + let value = _.cloneDeep(externalValue); if (_.isNil(value)) { if (spec.defaultValue) { @@ -71,18 +73,19 @@ export const useField = ({ } const error = validate?.(value); + const isDiffentValues = !_.isEqual(value, initialValue); return { active: false, - dirty: false, + dirty: isDiffentValues, error, invalid: Boolean(error), - modified: false, - pristine: false, - touched: false, + modified: isDiffentValues, + pristine: isDiffentValues, + touched: isDiffentValues, valid: !error, value, - visited: false, + visited: isDiffentValues, childErrors: {}, }; }); @@ -239,7 +242,7 @@ export const useField = ({ ]); React.useEffect(() => { - if (!firstRenderRef.current || !_.isEqual(initialValue, state.value) || state.error) { + if (!firstRenderRef.current || !_.isEqual(externalValue, state.value) || state.error) { (parentOnChange ? parentOnChange : tools.onChange)(name, state.value, { ...state.childErrors, [name]: state.error, diff --git a/src/lib/core/components/Form/hooks/useStore.tsx b/src/lib/core/components/Form/hooks/useStore.tsx index 9c3782f4..336535e7 100644 --- a/src/lib/core/components/Form/hooks/useStore.tsx +++ b/src/lib/core/components/Form/hooks/useStore.tsx @@ -11,14 +11,18 @@ export const useStore = (name: string) => { const form = useForm(); const firstRenderRef = React.useRef(true); const [store, setStore] = React.useState(() => { - const initialValue: FieldObjectValue = transformArrIn({ + const values: FieldObjectValue = transformArrIn({ [name]: _.get(form.getState().values, name), }); + const initialValue = transformArrIn({ + [name]: _.get(form.getState().initialValues, name), + }); + return { name, - initialValue, - values: _.cloneDeep(initialValue), + initialValue: _.cloneDeep(initialValue), + values: _.cloneDeep(values), errors: {}, }; }); @@ -28,13 +32,14 @@ export const useStore = (name: string) => { const tools = React.useMemo( () => ({ initialValue: store.initialValue, + values: store.values, onChange: (name: string, value: FieldValue, errors?: Record) => setStore((store) => ({ ...store, values: _.set({...store.values}, name, _.clone(value)), errors: errors || {}, })), - onUnmount: (name: string) => + onUnmount: (name: string) => { setStore((store) => ({ ...store, values: _.omit(store.values, name), @@ -42,7 +47,8 @@ export const useStore = (name: string) => { store.errors, Object.keys(store.errors).filter((key) => key.startsWith(name)), ), - })), + })); + }, submitFailed, }), [store.initialValue, setStore, submitFailed], @@ -50,14 +56,18 @@ export const useStore = (name: string) => { React.useEffect(() => { if (!firstRenderRef.current) { - const initialValue: FieldObjectValue = transformArrIn({ + const values: FieldObjectValue = transformArrIn({ [name]: _.get(form.getState().values, name), }); + const initialValue = transformArrIn({ + [name]: _.get(form.getState().initialValues, name), + }); + setStore({ name: name, - initialValue, - values: _.cloneDeep(initialValue), + initialValue: _.cloneDeep(initialValue), + values: _.cloneDeep(values), errors: {}, }); } diff --git a/src/lib/core/components/Form/types/context.ts b/src/lib/core/components/Form/types/context.ts index 6f729173..bd180c9e 100644 --- a/src/lib/core/components/Form/types/context.ts +++ b/src/lib/core/components/Form/types/context.ts @@ -2,13 +2,14 @@ import React from 'react'; import type {MonacoEditorProps} from 'react-monaco-editor/lib/types'; -import {DynamicFormConfig, FieldObjectValue, FieldValue, ValidateError, WonderMirror} from './'; +import {DynamicFormConfig, FieldValue, ValidateError, WonderMirror} from './'; export interface DynamicFormsContext { config: DynamicFormConfig; Monaco?: React.ComponentType; tools: { - initialValue: FieldObjectValue; + initialValue: FieldValue; + values: FieldValue; onChange: (name: string, value: FieldValue, errors?: Record) => void; onUnmount: (name: string) => void; submitFailed: boolean; diff --git a/src/lib/kit/components/Inputs/ArrayBase/ArrayBase.tsx b/src/lib/kit/components/Inputs/ArrayBase/ArrayBase.tsx index 111e0c44..de05d669 100644 --- a/src/lib/kit/components/Inputs/ArrayBase/ArrayBase.tsx +++ b/src/lib/kit/components/Inputs/ArrayBase/ArrayBase.tsx @@ -102,7 +102,7 @@ export const ArrayBase: ArrayInput = ({spec, name, arrayInput, input}) => { return ( `]} + value={input.value?.[`<${key}>`]} parentOnChange={parentOnChange} parentOnUnmount={parentOnUnmount} spec={itemSpec} diff --git a/src/lib/kit/components/Inputs/CardOneOf/CardOneOf.tsx b/src/lib/kit/components/Inputs/CardOneOf/CardOneOf.tsx index 99dc66bd..79ce75b8 100644 --- a/src/lib/kit/components/Inputs/CardOneOf/CardOneOf.tsx +++ b/src/lib/kit/components/Inputs/CardOneOf/CardOneOf.tsx @@ -76,7 +76,7 @@ export const CardOneOf: ObjectIndependentInput = (props) => { > {specProperties[oneOfValue] ? ( specProperties[property] ? ( { const content = ( { {specProperties[oneOfValue] ? ( { > {specProperties[oneOfValue] ? ( { const content = ( key={`${name}.<${key}>.${property}`} > `] as FieldObjectValue)?.[property] - } + value={(input.value?.[`<${key}>`] as FieldObjectValue)?.[property]} spec={preparedEntitySpec} name={`${name}.<${key}>.${property}`} parentOnChange={parentOnChange} diff --git a/src/lib/kit/components/Inputs/TextLink/TextLink.tsx b/src/lib/kit/components/Inputs/TextLink/TextLink.tsx index 89e235c0..ef9019ef 100644 --- a/src/lib/kit/components/Inputs/TextLink/TextLink.tsx +++ b/src/lib/kit/components/Inputs/TextLink/TextLink.tsx @@ -51,7 +51,7 @@ export const TextLink: ObjectIndependentInput = (props) => { const content = ( {