Skip to content

Commit

Permalink
fix: fix mutators logic (#157)
Browse files Browse the repository at this point in the history
  • Loading branch information
bocembocem authored Jan 17, 2024
1 parent 908b168 commit 701d18f
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 69 deletions.
8 changes: 4 additions & 4 deletions src/lib/core/components/Form/Controller/Controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ export const Controller = <
parentOnChange,
parentOnUnmount,
}: ControllerProps<DirtyValue, SpecType>) => {
const {config, tools, mutators, __mirror} = useDynamicFormsCtx();
const {config, tools, mutatorsStore, __mirror} = useDynamicFormsCtx();

const firstRenderRef = React.useRef(true);
const [store, setStore] = React.useState<ControllerStore<DirtyValue, Value, SpecType>>(
initializeStore({
name,
spec: _spec,
mutators,
mutatorsStore,
config,
valueFromParent,
tools,
Expand Down Expand Up @@ -148,7 +148,7 @@ export const Controller = <
name,
parentOnChange,
parentOnUnmount,
mutators,
mutatorsStore,
config,
tools,
methodOnChange: fieldMethods.onChange,
Expand All @@ -160,7 +160,7 @@ export const Controller = <
name,
parentOnChange,
parentOnUnmount,
mutators,
mutatorsStore,
config,
tools.onChange,
tools.onUnmount,
Expand Down
12 changes: 6 additions & 6 deletions src/lib/core/components/Form/Controller/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {FormValue, Spec} from '../../../types';
import {
DynamicFormConfig,
DynamicFormMutators,
DynamicFormMutatorsStore,
DynamicFormsContext,
FieldRenderProps,
FieldValue,
Expand All @@ -14,7 +14,7 @@ import {
export interface GetSpecParams<SpecType extends Spec> {
name: string;
spec: SpecType;
mutators: DynamicFormMutators;
mutatorsStore: DynamicFormMutatorsStore;
}

export interface GetComponentsParams<SpecType extends Spec> {
Expand Down Expand Up @@ -49,7 +49,7 @@ export interface GetFieldInitialsParams<
valueFromParent: DirtyValue;
initialValue: DirtyValue;
validate: (value?: Value) => ValidateError;
mutators: DynamicFormMutators;
mutatorsStore: DynamicFormMutatorsStore;
}

export type FieldMethod<
Expand Down Expand Up @@ -88,7 +88,7 @@ export interface GetFieldMethodsReturn<
export interface InitializeStoreParams<DirtyValue extends FieldValue, SpecType extends Spec> {
name: string;
spec: SpecType;
mutators: DynamicFormMutators;
mutatorsStore: DynamicFormMutatorsStore;
config: DynamicFormConfig;
valueFromParent: DirtyValue;
tools: DynamicFormsContext['tools'];
Expand All @@ -112,7 +112,7 @@ export interface ControllerStore<
initialSpec: SpecType;
config: DynamicFormConfig;
tools: DynamicFormsContext['tools'];
mutators: DynamicFormMutators;
mutatorsStore: DynamicFormMutatorsStore;
render: (props: FieldRenderProps<DirtyValue>) => JSX.Element | null;
validate: (value?: Value) => ValidateError;
parentOnChange:
Expand Down Expand Up @@ -157,7 +157,7 @@ export interface UpdateStoreParams<
) => void)
| null;
parentOnUnmount: ((childName: string) => void) | null;
mutators: DynamicFormMutators;
mutatorsStore: DynamicFormMutatorsStore;
valueFromParent: DirtyValue;
config: DynamicFormConfig;
tools: DynamicFormsContext['tools'];
Expand Down
102 changes: 62 additions & 40 deletions src/lib/core/components/Form/Controller/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {isArraySpec, isCorrectSpec, isNumberSpec, isObjectSpec} from '../../../h
import {FormValue, Spec} from '../../../types';
import {EMPTY_MUTATOR, OBJECT_ARRAY_CNT, OBJECT_ARRAY_FLAG} from '../constants';
import {
BaseValidateError,
FieldArrayValue,
FieldObjectValue,
FieldRenderProps,
Expand All @@ -30,13 +31,20 @@ import {
UpdateStoreParams,
} from './types';

const isErrorMutatorCorrect = (errorMutator: ValidateError) =>
errorMutator !== EMPTY_MUTATOR && (_.isString(errorMutator) || _.isBoolean(errorMutator));
const isErrorMutatorCorrect = (errorMutator: {value: ValidateError} | typeof EMPTY_MUTATOR) =>
errorMutator !== EMPTY_MUTATOR &&
(_.isString(errorMutator.value) ||
_.isBoolean(errorMutator.value) ||
_.isUndefined(errorMutator.value));

const isValueMutatorCorrect = (valueMutator: FormValue, spec: Spec) =>
const isValueMutatorCorrect = (
valueMutator: {value: FormValue} | typeof EMPTY_MUTATOR,
spec: Spec,
) =>
valueMutator !== EMPTY_MUTATOR &&
(typeof valueMutator === spec.type ||
(_.isArray(valueMutator) && spec.type === SpecTypes.Array));
(typeof valueMutator.value === spec.type ||
(_.isArray(valueMutator.value) && spec.type === SpecTypes.Array) ||
valueMutator.value === undefined);

export const updateParentStore = <
DirtyValue extends FieldValue,
Expand Down Expand Up @@ -68,12 +76,12 @@ export const callUnmout = <
export const getSpec = <SpecType extends Spec>({
name,
spec,
mutators,
mutatorsStore,
}: GetSpecParams<SpecType>): SpecType => {
const mutator = _.get(mutators.spec, name, EMPTY_MUTATOR);
const mutator = _.get(mutatorsStore.spec, name, EMPTY_MUTATOR);

if (mutator !== EMPTY_MUTATOR) {
const mutatedSpec = _.merge(_.cloneDeep(spec), mutator);
const mutatedSpec = _.merge(_.cloneDeep(spec), mutator.value);

if (isCorrectSpec(mutatedSpec)) {
return mutatedSpec;
Expand Down Expand Up @@ -196,15 +204,15 @@ export const getFieldInitials = <
valueFromParent,
initialValue,
validate,
mutators,
mutatorsStore,
}: GetFieldInitialsParams<DirtyValue, Value, SpecType>) => {
const valueMutator = transformArrIn(_.get(mutators.values, name, EMPTY_MUTATOR)) as
| DirtyValue
const valueMutator = transformArrIn(_.get(mutatorsStore.values, name, EMPTY_MUTATOR)) as
| {value: DirtyValue}
| typeof EMPTY_MUTATOR;
let value = _.cloneDeep(valueFromParent);

if (isValueMutatorCorrect(valueMutator, spec)) {
value = valueMutator as DirtyValue;
value = (valueMutator as {value: DirtyValue}).value;
}

if (_.isNil(value)) {
Expand All @@ -222,13 +230,18 @@ export const getFieldInitials = <
}
}

let errorMutator: ValidateError = _.get(mutators.errors, name, EMPTY_MUTATOR);
let errorMutator: {value: BaseValidateError} | typeof EMPTY_MUTATOR = _.get(
mutatorsStore.errors,
name,
EMPTY_MUTATOR,
);

if (!isErrorMutatorCorrect(errorMutator)) {
errorMutator = undefined;
errorMutator = {value: undefined};
}

const error = validate?.(transformArrOut(value)) || errorMutator;
const error =
validate?.(transformArrOut(value)) || (errorMutator as {value: BaseValidateError})?.value;
const dirty = !_.isEqual(value, initialValue);

return {
Expand Down Expand Up @@ -425,14 +438,14 @@ export const initializeStore = <
>({
name,
spec: _spec,
mutators,
mutatorsStore,
config,
valueFromParent,
tools,
parentOnChange,
parentOnUnmount,
}: InitializeStoreParams<DirtyValue, SpecType>): ControllerStore<DirtyValue, Value, SpecType> => {
const spec = getSpec({name, spec: _spec, mutators});
const spec = getSpec({name, spec: _spec, mutatorsStore});
const components = getComponents<DirtyValue, Value, SpecType>({spec, config});
const render = getRender({name, spec, ...components});
const validate = getValidate({spec, config});
Expand All @@ -441,7 +454,7 @@ export const initializeStore = <
spec,
valueFromParent,
validate,
mutators,
mutatorsStore,
initialValue: _.get(tools.initialValue, name),
});

Expand All @@ -451,7 +464,7 @@ export const initializeStore = <
initialSpec: _spec,
config,
tools,
mutators,
mutatorsStore,
render,
validate,
parentOnChange,
Expand All @@ -477,26 +490,26 @@ export const updateStore = <
name,
parentOnChange,
parentOnUnmount,
mutators,
mutatorsStore,
valueFromParent,
config,
tools,
methodOnChange,
}: UpdateStoreParams<DirtyValue, Value, SpecType>) => {
const storeSpecMutator = _.get(store.mutators.spec, store.name, EMPTY_MUTATOR);
const storeValueMutator = _.get(store.mutators.values, store.name, EMPTY_MUTATOR) as
| DirtyValue
const storeSpecMutator = _.get(store.mutatorsStore.spec, store.name, EMPTY_MUTATOR);
const storeValueMutator = _.get(store.mutatorsStore.values, store.name, EMPTY_MUTATOR) as
| {value: DirtyValue}
| typeof EMPTY_MUTATOR;
const storeErrorMutator = _.get(store.mutators.errors, store.name, EMPTY_MUTATOR);
const storeErrorMutator = _.get(store.mutatorsStore.errors, store.name, EMPTY_MUTATOR);

const specMutator = _.get(mutators.spec, name, EMPTY_MUTATOR);
const valueMutator = _.get(mutators.values, name, EMPTY_MUTATOR) as
| DirtyValue
const specMutator = _.get(mutatorsStore.spec, name, EMPTY_MUTATOR);
const valueMutator = _.get(mutatorsStore.values, name, EMPTY_MUTATOR) as
| {value: DirtyValue}
| typeof EMPTY_MUTATOR;
const errorMutator = _.get(mutators.errors, name, EMPTY_MUTATOR);
const errorMutator = _.get(mutatorsStore.errors, name, EMPTY_MUTATOR);

const valueMutatorUpdated =
isValueMutatorCorrect(valueMutator, getSpec({name, spec: _spec, mutators})) &&
isValueMutatorCorrect(valueMutator, getSpec({name, spec: _spec, mutatorsStore})) &&
valueMutator !== storeValueMutator;
const errorMutatorUpdated =
isErrorMutatorCorrect(errorMutator) && errorMutator !== storeErrorMutator;
Expand All @@ -519,7 +532,7 @@ export const updateStore = <
initializeStore({
name,
spec: _spec,
mutators,
mutatorsStore,
config,
valueFromParent,
tools,
Expand All @@ -532,7 +545,7 @@ export const updateStore = <
...initializeStore({
name,
spec: _spec,
mutators,
mutatorsStore,
config,
valueFromParent,
tools,
Expand All @@ -545,8 +558,10 @@ export const updateStore = <
if (updateState) {
nextStore = methodOnChange(nextStore, {
valOrSetter: (value) =>
valueMutatorUpdated ? (valueMutator as DirtyValue) : value,
...(errorMutatorUpdated ? {errorMutator} : {}),
valueMutatorUpdated ? (valueMutator as {value: DirtyValue}).value : value,
...(errorMutatorUpdated
? {errorMutator: (errorMutator as {value: BaseValidateError}).value}
: {}),
});
}

Expand All @@ -562,19 +577,26 @@ export const updateStore = <
if (updateState) {
nextStore = methodOnChange(nextStore, {
valOrSetter: (value) =>
valueMutatorUpdated ? (valueMutator as DirtyValue) : value,
...(errorMutatorUpdated ? {errorMutator} : {}),
valueMutatorUpdated ? (valueMutator as {value: DirtyValue}).value : value,
...(errorMutatorUpdated
? {errorMutator: (errorMutator as {value: BaseValidateError}).value}
: {}),
});
}

setStore(nextStore);
} else if (updateState) {
setStore(
methodOnChange(store, {
valOrSetter: (value) =>
valueMutatorUpdated ? (valueMutator as DirtyValue) : value,
...(errorMutatorUpdated ? {errorMutator} : {}),
}),
methodOnChange(
{...store, mutatorsStore},
{
valOrSetter: (value) =>
valueMutatorUpdated ? (valueMutator as {value: DirtyValue}).value : value,
...(errorMutatorUpdated
? {errorMutator: (errorMutator as {value: BaseValidateError}).value}
: {}),
},
),
);
}
};
6 changes: 3 additions & 3 deletions src/lib/core/components/Form/DynamicField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const DynamicField: React.FC<DynamicFieldProps> = ({
const SearchContext = useCreateSearchContext();
const {tools, store} = useStore(name);
const watcher = useIntegrationFF(store, withoutInsertFFDebounce);
const {mutators, mutateDFState} = useMutators(externalMutators);
const {mutatorsStore, mutateDFState} = useMutators(externalMutators);
const {store: searchStore, setField, removeField, isHiddenField} = useSearchStore();

const context = React.useMemo(
Expand All @@ -57,10 +57,10 @@ export const DynamicField: React.FC<DynamicFieldProps> = ({
generateRandomValue,
tools: {...tools, mutateDFState},
store,
mutators,
mutatorsStore,
__mirror,
}),
[tools, config, Monaco, __mirror, generateRandomValue, mutators, mutateDFState, store],
[tools, config, Monaco, __mirror, generateRandomValue, mutatorsStore, mutateDFState, store],
);

const searchContext = React.useMemo(
Expand Down
Loading

0 comments on commit 701d18f

Please sign in to comment.