Skip to content

Commit a1e893c

Browse files
authored
Merge pull request #133 from workfloworchestrator/2040-fix-itemiziation
2040 Fixes navigation between steps and other stuff
2 parents a8d7057 + 6126b61 commit a1e893c

File tree

15 files changed

+1108
-242
lines changed

15 files changed

+1108
-242
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'pydantic-forms': minor
3+
---
4+
5+
Fixes history navigation. Fixes array item validations and rendering.

frontend/package-lock.json

Lines changed: 26 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/packages/pydantic-forms/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,9 @@
5555
"typescript": "^5.8.3"
5656
},
5757
"dependencies": {
58-
"@apidevtools/json-schema-ref-parser": "^11.7.3",
58+
"@apidevtools/json-schema-ref-parser": "^14.0.3",
5959
"@emotion/react": "^11.14.0",
60-
"@hookform/resolvers": "^3.9.1",
60+
"@hookform/resolvers": "^5.1.1",
6161
"dayjs": "^1.11.13",
6262
"i18next": "^24.1.2",
6363
"lodash": "^4.17.21",

frontend/packages/pydantic-forms/src/components/fields/ArrayField.tsx

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,41 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React from 'react';
22
import { useFieldArray } from 'react-hook-form';
33

44
import { usePydanticFormContext } from '@/core';
55
import { fieldToComponentMatcher } from '@/core/helper';
6-
import { PydanticFormElementProps } from '@/types';
6+
import {
7+
PydanticFormElementProps,
8+
PydanticFormField,
9+
PydanticFormFieldType,
10+
} from '@/types';
711
import { itemizeArrayItem } from '@/utils';
812

913
import { RenderFields } from '../render';
1014

1115
export const ArrayField = ({ pydanticFormField }: PydanticFormElementProps) => {
1216
const { rhf, config } = usePydanticFormContext();
13-
const [isInitialized, setInitialized] = useState(false);
17+
1418
const { control } = rhf;
1519
const { id: arrayName, arrayItem } = pydanticFormField;
16-
const { minItems, maxItems } = pydanticFormField.validations;
1720
const { fields, append, remove } = useFieldArray({
1821
control,
1922
name: arrayName,
2023
});
24+
const { minItems = 1, maxItems = undefined } =
25+
pydanticFormField?.validations;
2126

22-
useEffect(() => {
23-
if (!isInitialized) {
24-
const arrayValueObject = {
25-
[arrayName]: arrayItem?.default,
26-
};
27-
const minItemCount = minItems || 1;
28-
const initialArray = Array.from(
29-
{ length: minItemCount },
30-
() => arrayValueObject,
31-
);
32-
append(initialArray);
33-
setInitialized(true);
27+
const getInitialValue = (arrayItem?: PydanticFormField) => {
28+
switch (arrayItem?.type) {
29+
case PydanticFormFieldType.STRING:
30+
return '';
31+
case PydanticFormFieldType.INTEGER:
32+
return 0;
33+
case PydanticFormFieldType.BOOLEAN:
34+
return false;
35+
default:
36+
return undefined;
3437
}
35-
}, [
36-
append,
37-
arrayItem?.default,
38-
arrayName,
39-
fields.length,
40-
isInitialized,
41-
minItems,
42-
]);
38+
};
4339

4440
if (!arrayItem) return '';
4541

@@ -49,7 +45,7 @@ export const ArrayField = ({ pydanticFormField }: PydanticFormElementProps) => {
4945
);
5046

5147
const renderField = (field: Record<'id', string>, index: number) => {
52-
const arrayItemField = itemizeArrayItem(index, arrayItem);
48+
const arrayItemField = itemizeArrayItem(index, arrayItem, arrayName);
5349

5450
return (
5551
<div
@@ -95,12 +91,12 @@ export const ArrayField = ({ pydanticFormField }: PydanticFormElementProps) => {
9591
}}
9692
>
9793
{fields.map(renderField)}
98-
9994
{(!maxItems || (maxItems && fields.length < maxItems)) && (
10095
<div
10196
onClick={() => {
10297
append({
103-
[arrayName]: arrayItem.default ?? undefined,
98+
[arrayName]:
99+
arrayItem.default || getInitialValue(arrayItem),
104100
});
105101
}}
106102
style={{

frontend/packages/pydantic-forms/src/components/render/RenderFields.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,30 @@ export function RenderFields({
2020
}: RenderFieldsProps) {
2121
return pydanticFormComponents.map((component) => {
2222
const { Element, isControlledElement } = component.Element;
23-
const field: PydanticFormField = component.pydanticFormField;
23+
const pydanticFormField: PydanticFormField =
24+
component.pydanticFormField;
2425

2526
if (!Element) {
2627
return undefined;
2728
}
2829

2930
if (isControlledElement) {
3031
return (
31-
<div css={{ width: '100%' }} key={field.id}>
32+
<div css={{ width: '100%' }} key={pydanticFormField.id}>
3233
<WrapFieldElement
3334
PydanticFormControlledElement={Element}
34-
pydanticFormField={field}
35+
pydanticFormField={pydanticFormField}
3536
extraTriggerFields={extraTriggerFields}
3637
/>
3738
</div>
3839
);
3940
} else {
40-
return <Element pydanticFormField={field} key={field.id} />;
41+
return (
42+
<Element
43+
pydanticFormField={pydanticFormField}
44+
key={pydanticFormField.id}
45+
/>
46+
);
4147
}
4248
});
4349
}

frontend/packages/pydantic-forms/src/components/render/RenderForm.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@ const RenderForm = (contextProps: PydanticFormContextProps) => {
3131
const { formRenderer, footerRenderer, headerRenderer } = config || {};
3232

3333
useEffect(() => {
34-
rhf.trigger();
34+
if (rhf.getValues().length === 0) {
35+
// Only trigger validations if there are values
36+
rhf.trigger();
37+
}
3538
}, [rhf, pydanticFormSchema]);
3639

3740
const pydanticFormComponents: PydanticFormComponents =

frontend/packages/pydantic-forms/src/components/zodValidationsPresets.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* With these presets you can use this for both the textfield, as the list text field.
88
* Numbers might have a max&min num, etc.
99
*/
10-
import { z } from 'zod';
10+
import { z } from 'zod/v4';
1111

1212
import { PydanticFormZodValidationPresets } from '@/types';
1313

@@ -66,12 +66,7 @@ export const zodValidationPresets: PydanticFormZodValidationPresets = {
6666
multipleOf,
6767
} = field?.validations ?? {};
6868

69-
let validationRule = z
70-
.number({
71-
required_error: 'Dit veld is verplicht',
72-
invalid_type_error: 'Dit veld moet een integer zijn',
73-
})
74-
.int();
69+
let validationRule = z.number().int();
7570

7671
if (minimum) {
7772
validationRule = validationRule.gte(

0 commit comments

Comments
 (0)