Skip to content

Commit 1b079a0

Browse files
author
Ruben van Leeuwen
committed
2076: Test and improve initialData function
1 parent b25ecf1 commit 1b079a0

File tree

4 files changed

+101
-79
lines changed

4 files changed

+101
-79
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
101101
// We are looking for a single value from a set list of options. With less than 4 options, use radio buttons.
102102
return (
103103
field.type === PydanticFormFieldType.STRING &&
104+
field.options &&
104105
field.options.length > 0 &&
105106
field.options.length <= 3
106107
);
@@ -116,6 +117,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
116117
// We are looking for a single value from a set list of options. With more than 3 options, use a dropdown.
117118
return (
118119
field.type === PydanticFormFieldType.STRING &&
120+
field.options &&
119121
field.options.length >= 4
120122
);
121123
},
@@ -139,6 +141,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
139141
matcher(field) {
140142
return (
141143
field.type === PydanticFormFieldType.ARRAY &&
144+
field.options &&
142145
field.options.length > 0 &&
143146
field.options.length <= 5
144147
);
@@ -153,6 +156,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [
153156
},
154157
matcher(field) {
155158
return (
159+
field.options &&
156160
field.options.length > 0 &&
157161
field.type === PydanticFormFieldType.ARRAY
158162
);

frontend/packages/pydantic-forms/src/core/PydanticFormContextProvider.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ function PydanticFormContextProvider({
158158
);
159159

160160
const initialData = getFormValuesFromFieldOrLabels(
161-
pydanticFormSchema,
161+
pydanticFormSchema?.properties,
162162
{
163163
...formLabels?.data,
164164
...customData,

frontend/packages/pydantic-forms/src/core/helper.spec.ts

Lines changed: 68 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import {
77
optionsToOption,
88
} from '@/core/helper';
99
import {
10+
Properties,
1011
PydanticFormApiResponse,
1112
PydanticFormField,
1213
PydanticFormFieldFormat,
1314
PydanticFormFieldType,
1415
PydanticFormPropertySchemaParsed,
15-
PydanticFormSchema,
1616
} from '@/types';
1717

1818
export const getMockPydanticFormField = (
@@ -40,18 +40,6 @@ export const getMockPydanticFormField = (
4040
};
4141
};
4242

43-
const getMockPydanticFormSchema = (
44-
overrides: Partial<PydanticFormSchema> = {},
45-
): PydanticFormSchema => {
46-
return {
47-
title: 'Mock Form Schema',
48-
type: PydanticFormFieldType.OBJECT,
49-
description: 'This is a mock schema description',
50-
properties: {},
51-
...overrides,
52-
};
53-
};
54-
5543
const getMockFormPropertySchemaParsed = (
5644
overrides: Partial<PydanticFormPropertySchemaParsed> = {},
5745
): PydanticFormPropertySchemaParsed => ({
@@ -598,50 +586,47 @@ describe('isNullable', () => {
598586
});
599587

600588
describe('getFormValuesFromFieldOrLabels', () => {
601-
it.only('returns an empty object if no schema is provided', () => {
589+
it('returns an empty object if no schema is provided', () => {
602590
const result = getFormValuesFromFieldOrLabels(undefined, {});
603591
expect(result).toEqual({});
604592
});
605593

606-
it.only('Returns empty object when schema has no properties', () => {
607-
const schema = getMockPydanticFormSchema();
608-
expect(getFormValuesFromFieldOrLabels(schema, {})).toEqual({});
594+
it('Returns empty object when schema has no properties', () => {
595+
const properties: Properties = {};
596+
expect(getFormValuesFromFieldOrLabels(properties, {})).toEqual({});
609597
});
610598

611-
it.only('Returns fieldNames with default values', () => {
612-
const schema = getMockPydanticFormSchema({
613-
properties: {
614-
test: getMockPydanticFormField({
615-
default: 'default value',
616-
id: 'test',
617-
}),
618-
test2: getMockPydanticFormField({
619-
default: 'default value 2',
620-
id: 'test2',
621-
}),
622-
},
623-
});
624-
expect(getFormValuesFromFieldOrLabels(schema, {})).toEqual({
599+
it('Returns fieldNames with default values', () => {
600+
const properties: Properties = {
601+
test: getMockPydanticFormField({
602+
default: 'default value',
603+
id: 'test',
604+
}),
605+
test2: getMockPydanticFormField({
606+
default: 'default value 2',
607+
id: 'test2',
608+
}),
609+
};
610+
expect(getFormValuesFromFieldOrLabels(properties, {})).toEqual({
625611
test: 'default value',
626612
test2: 'default value 2',
627613
});
628614
});
629615

630-
it.only('Returns label instead of default value if present', () => {
631-
const schema = getMockPydanticFormSchema({
632-
properties: {
633-
test: getMockPydanticFormField({
634-
default: 'default value',
635-
id: 'test',
636-
}),
637-
test2: getMockPydanticFormField({
638-
default: 'default value 2',
639-
id: 'test2',
640-
}),
641-
},
642-
});
616+
it('Returns label instead of default value if present', () => {
617+
const properties: Properties = {
618+
test: getMockPydanticFormField({
619+
default: 'default value',
620+
id: 'test',
621+
}),
622+
test2: getMockPydanticFormField({
623+
default: 'default value 2',
624+
id: 'test2',
625+
}),
626+
};
627+
643628
expect(
644-
getFormValuesFromFieldOrLabels(schema, {
629+
getFormValuesFromFieldOrLabels(properties, {
645630
test2: 'label for test2',
646631
}),
647632
).toEqual({
@@ -650,26 +635,24 @@ describe('getFormValuesFromFieldOrLabels', () => {
650635
});
651636
});
652637

653-
it.only('Returns nested default values in object fields', () => {
654-
const schema = getMockPydanticFormSchema({
655-
properties: {
656-
test: getMockPydanticFormField({
657-
default: 'default value',
658-
id: 'test',
659-
}),
660-
test2: getMockPydanticFormField({
661-
default: 'default value 2',
662-
id: 'test2',
663-
properties: {
664-
nestedField: getMockPydanticFormField({
665-
default: 'nested default value',
666-
id: 'nestedField',
667-
}),
668-
},
669-
}),
670-
},
671-
});
672-
expect(getFormValuesFromFieldOrLabels(schema)).toEqual({
638+
it('Returns nested default values in object fields', () => {
639+
const properties: Properties = {
640+
test: getMockPydanticFormField({
641+
default: 'default value',
642+
id: 'test',
643+
}),
644+
test2: getMockPydanticFormField({
645+
default: 'default value 2',
646+
id: 'test2',
647+
properties: {
648+
nestedField: getMockPydanticFormField({
649+
default: 'nested default value',
650+
id: 'nestedField',
651+
}),
652+
},
653+
}),
654+
};
655+
expect(getFormValuesFromFieldOrLabels(properties)).toEqual({
673656
test: 'default value',
674657
test2: {
675658
nestedField: 'nested default value',
@@ -678,10 +661,25 @@ describe('getFormValuesFromFieldOrLabels', () => {
678661
});
679662

680663
it('Returns nested default values in array fields', () => {
681-
expect(true).toEqual(false);
682-
});
683-
684-
it('Works with object field in array field in object field', () => {
685-
expect(true).toEqual(false);
664+
const properties: Properties = {
665+
test: getMockPydanticFormField({
666+
default: 'default value',
667+
type: PydanticFormFieldType.STRING,
668+
id: 'test',
669+
}),
670+
test2: getMockPydanticFormField({
671+
id: 'test2',
672+
type: PydanticFormFieldType.ARRAY,
673+
default: [1, 2, 3],
674+
arrayItem: getMockPydanticFormField({
675+
id: 'nestedField',
676+
type: PydanticFormFieldType.STRING,
677+
}),
678+
}),
679+
};
680+
expect(getFormValuesFromFieldOrLabels(properties)).toEqual({
681+
test: 'default value',
682+
test2: [1, 2, 3],
683+
});
686684
});
687685
});

frontend/packages/pydantic-forms/src/core/helper.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -289,36 +289,56 @@ export const isNullableField = (field: PydanticFormField) =>
289289
!!field.validations.isNullable;
290290

291291
/**
292-
* Will return a Record map of [fieldId]: "Fieldvalue"
292+
* Returns the initial values for the form field based on the
293+
* default values and const values found in the parsed PydanticFormSchema.
294+
* Iterates over the properties and arrayItems of the schema.
293295
*
294-
* Requires both fieldsDef (these can have default values)
295296
* And labelData (this holds the current values from API)
296297
*/
297298
export const getFormValuesFromFieldOrLabels = (
298-
pydanticFormSchema?: PydanticFormSchema,
299+
properties?: Properties,
299300
labelData?: Record<string, string>,
300301
componentMatcherExtender?: PydanticFormsContextConfig['componentMatcherExtender'],
301302
): FieldValues => {
302-
if (!pydanticFormSchema) {
303+
if (!properties) {
303304
return {};
304305
}
305306

307+
const propertyHasProperties = (
308+
pydanticFormField: PydanticFormField,
309+
): boolean => {
310+
return pydanticFormField.properties &&
311+
Object.keys(pydanticFormField.properties).length > 0
312+
? true
313+
: false;
314+
};
315+
306316
const fieldValues: FieldValues = {};
307317

308318
const includedFields: string[] = [];
309319

310320
const pydanticFormComponents = getPydanticFormComponents(
311-
pydanticFormSchema.properties,
321+
properties,
312322
componentMatcherExtender,
313323
);
314324

315325
pydanticFormComponents.forEach((component) => {
316326
const { Element, pydanticFormField } = component;
317327

318-
if (Element.isControlledElement) {
328+
if (
329+
Element.isControlledElement ||
330+
propertyHasProperties(pydanticFormField) ||
331+
pydanticFormField.arrayItem
332+
) {
319333
includedFields.push(pydanticFormField.id);
320-
321-
if (typeof pydanticFormField.default !== 'undefined') {
334+
if (propertyHasProperties(pydanticFormField)) {
335+
const nestedValues = getFormValuesFromFieldOrLabels(
336+
pydanticFormField.properties,
337+
labelData,
338+
componentMatcherExtender,
339+
);
340+
fieldValues[pydanticFormField.id] = nestedValues;
341+
} else if (typeof pydanticFormField.default !== 'undefined') {
322342
fieldValues[pydanticFormField.id] = pydanticFormField.default;
323343
}
324344
}

0 commit comments

Comments
 (0)