Skip to content

Commit

Permalink
FIX #96
Browse files Browse the repository at this point in the history
  • Loading branch information
quentinovega committed May 16, 2023
1 parent f5a6b17 commit 08a6033
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 20 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ export const Example = () => {
}
```
- **constraints**: a JSON array of constraints. see [constraints section](#constraints)
- **arrayConstraints**: a JSON array of constraints apply to the entire array (use constraints to apply constraints to inner fileds of array). see [constraints section](#constraints)
- **deps**: In case of the entry need some form values, thestepwill be re-render after all change. To avoid some perf issues, it would be nice to declare a deps array to listen. The array must contains the root path
```javascript
const schema = {
Expand Down
1 change: 0 additions & 1 deletion src/form/arrayStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ export const ArrayStep = ({ entry, step, component, disabled, addLabel }:
option(step.onChange)
.map(onChange => onChange({ rawValues: getValues(), value: getValues(entry), setValue }))
}} disabled={disabled}>{addLabel ? addLabel : 'Add'}</button>
{error && <div className="mrf-invalid-feedback">{error.message}</div>}
</div>
</>
)
Expand Down
1 change: 1 addition & 0 deletions src/form/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export interface SchemaEntry {
transformer?: ((v: any) => SelectOption) | { label: string, value: string };
conditionalSchema?: ConditionnalSchema;
constraints?: Array<Constraint | { type: TConstraintType, message?: string }>;
arrayConstraints?: Array<Constraint | { type: TConstraintType, message?: string }>;
flow?: Array<string | FlowObject>;
onAfterChange?: (obj: { entry: string, value: object, rawValues: object, previousValue?: object, getValue: (entry: string) => any, setValue: (entry: string, value: any) => void, onChange: (v: any) => void, reset: (v: any) => void, informations?: Informations }) => void;
visibleOnCollapse?: boolean;
Expand Down
41 changes: 22 additions & 19 deletions src/resolvers/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ObjectShape } from 'yup/lib/object';
const resolvers = {
[type.string]: (typeErrorMessage?: string) => yup.string().nullable().optional().typeError(typeErrorMessage || 'Value must be a string'),
[type.number]: (typeErrorMessage?: string) => yup.number().nullable().optional()
.transform(v => { return isNaN(v) ? null : v})
.transform(v => { return isNaN(v) ? null : v })
.typeError(typeErrorMessage || 'Value must be a number'),
[type.bool]: () => yup.bool().nullable().optional(),
[type.object]: () => yup.object().nullable().optional(),
Expand All @@ -17,28 +17,31 @@ const resolvers = {
[type.json]: () => yup.mixed()
}

export const buildSubResolver = (props: SchemaEntry, key: string, dependencies: Array<[string, string]>, rawValues: {[x: string]: any}): yup.AnySchema => {
export const buildSubResolver = (props: SchemaEntry, key: string, dependencies: Array<[string, string]>, rawValues: { [x: string]: any }): yup.AnySchema => {
const { constraints = [] } = props;
if (props.array || props.isMulti) {
let subResolver;
let arrayResolver = yup.array()

if (props.schema) {
const deps:Array<[string, string]> = [];
const deps: Array<[string, string]> = [];
subResolver = yup.object().shape(getShapeAndDependencies(props.flow || Object.keys(props.schema), props.schema, deps, rawValues).shape, deps);
arrayResolver = arrayResolver.of(yup.object().shape({ value: subResolver }))
} else if (props.constraints?.length) {
subResolver = props.constraints.reduce((resolver, constraint) => {
return jsonOrFunctionConstraint(constraint, resolver, key, dependencies)
}, resolvers[props.type]())

arrayResolver = arrayResolver.of(yup.object().shape({value: subResolver}))
}
// todo: https://github.com/MAIF/react-forms/issues/96
// if (props.item?.constraints) {
// subResolver = item?.constraints.reduce((resolver, constraint) => {
// return jsonOrFunctionConstraint(constraint, resolver, key, dependencies)
// }, resolvers[props.type]())

// arrayResolver = arrayResolver.of(subResolver)
// }
return constraints.reduce((resolver, constraint) => {
return jsonOrFunctionConstraint(constraint, resolver, key, dependencies)
}, arrayResolver)

if (props.arrayConstraints?.length) {
arrayResolver = props.arrayConstraints.reduce((resolver, constraint) => {
return jsonOrFunctionConstraint(constraint, resolver, key, dependencies)
}, arrayResolver)
}

return arrayResolver
} else if (props.type === type.object && props.schema) {
if (!Object.keys(props.schema).length) {
return yup.object()
Expand All @@ -62,10 +65,10 @@ export const buildSubResolver = (props: SchemaEntry, key: string, dependencies:

return option(filterSwitch)
.orElse(condiSchema.switch.find(s => s.default))
.getOrElse({schema: {}, flow: []})
.getOrElse({ schema: {}, flow: [] })

})
.getOrElse({schema: {}, flow: []})
.getOrElse({ schema: {}, flow: [] })

const realFlow = flow || Object.keys(schema)
const subResolver = getShapeAndDependencies(flow || Object.keys(schema), schema, dependencies, rawValues);
Expand All @@ -79,7 +82,7 @@ export const buildSubResolver = (props: SchemaEntry, key: string, dependencies:
}
}

const jsonOrFunctionConstraint = (constraint: Constraint | {type: TConstraintType}, resolver: yup.AnySchema, key: string, dependencies: Array<[string, string]>) => {
const jsonOrFunctionConstraint = (constraint: Constraint | { type: TConstraintType }, resolver: yup.AnySchema, key: string, dependencies: Array<[string, string]>) => {
if (typeof constraint === 'function') {
return constraint(resolver, key, dependencies)
} else {
Expand All @@ -88,7 +91,7 @@ const jsonOrFunctionConstraint = (constraint: Constraint | {type: TConstraintTyp
}
}

export const getShapeAndDependencies = (flow: Flow, schema: Schema, dependencies:Array<[string, string]> = [], rawData: object = {}): {shape: ObjectShape, dependencies: Array<[string, string]>} => {
export const getShapeAndDependencies = (flow: Flow, schema: Schema, dependencies: Array<[string, string]> = [], rawData: object = {}): { shape: ObjectShape, dependencies: Array<[string, string]> } => {
if (!Object.keys(schema).length) {
return { shape: {}, dependencies }
}
Expand Down

0 comments on commit 08a6033

Please sign in to comment.