diff --git a/frontend/.changeset/big-dingos-follow.md b/frontend/.changeset/big-dingos-follow.md new file mode 100644 index 0000000..f98629a --- /dev/null +++ b/frontend/.changeset/big-dingos-follow.md @@ -0,0 +1,5 @@ +--- +'pydantic-forms': patch +--- + +Fixes resetting formdata with forms that have no properties diff --git a/frontend/packages/pydantic-forms/src/components/defaultComponentMatchers.ts b/frontend/packages/pydantic-forms/src/components/defaultComponentMatchers.ts index 31ea907..6750c3b 100644 --- a/frontend/packages/pydantic-forms/src/components/defaultComponentMatchers.ts +++ b/frontend/packages/pydantic-forms/src/components/defaultComponentMatchers.ts @@ -3,6 +3,8 @@ * * We will search for the first field that returns a positive match */ +import _ from 'lodash'; + import { ArrayField, CheckboxField, @@ -101,6 +103,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [ // We are looking for a single value from a set list of options. With less than 4 options, use radio buttons. return ( field.type === PydanticFormFieldType.STRING && + _.isArray(field.options) && field.options?.length > 0 && field.options?.length <= 3 ); @@ -116,6 +119,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [ // We are looking for a single value from a set list of options. With more than 3 options, use a dropdown. return ( field.type === PydanticFormFieldType.STRING && + _.isArray(field.options) && field.options?.length >= 4 ); }, @@ -139,6 +143,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [ matcher(field) { return ( field.type === PydanticFormFieldType.ARRAY && + _.isArray(field.options) && field.options?.length > 0 && field.options?.length <= 5 ); @@ -153,6 +158,7 @@ const defaultComponentMatchers: PydanticComponentMatcher[] = [ }, matcher(field) { return ( + _.isArray(field.options) && field.options?.length > 0 && field.type === PydanticFormFieldType.ARRAY ); diff --git a/frontend/packages/pydantic-forms/src/components/fields/IntegerField.tsx b/frontend/packages/pydantic-forms/src/components/fields/IntegerField.tsx index 23b4e26..c198e0f 100644 --- a/frontend/packages/pydantic-forms/src/components/fields/IntegerField.tsx +++ b/frontend/packages/pydantic-forms/src/components/fields/IntegerField.tsx @@ -1,6 +1,9 @@ import React from 'react'; +import _ from 'lodash'; + import type { PydanticFormControlledElementProps } from '@/types'; +import { getFormFieldIdWithPath } from '@/utils'; export const IntegerField = ({ value, @@ -9,6 +12,14 @@ export const IntegerField = ({ disabled, pydanticFormField, }: PydanticFormControlledElementProps) => { + // If the field is part of an array the value is passed in as an object with the field name as key + // this is imposed by react-hook-form. We try to detect this and extract the actual value + const fieldName = getFormFieldIdWithPath(pydanticFormField.id); + const fieldValue = + _.isObject(value) && _.has(value, fieldName) + ? _.get(value, fieldName) + : value; + return ( - {options.map((option: PydanticFormFieldOption) => { + {options?.map((option: PydanticFormFieldOption) => { // Extract the unique ID for this option const optionId = `${id}-${option.value}`; diff --git a/frontend/packages/pydantic-forms/src/components/fields/MultiSelectField.tsx b/frontend/packages/pydantic-forms/src/components/fields/MultiSelectField.tsx index 9f49ac6..f03452b 100644 --- a/frontend/packages/pydantic-forms/src/components/fields/MultiSelectField.tsx +++ b/frontend/packages/pydantic-forms/src/components/fields/MultiSelectField.tsx @@ -38,7 +38,7 @@ export const MultiSelectField = ({ }} multiple > - {pydanticFormField.options.map( + {pydanticFormField.options?.map( (option: PydanticFormFieldOption) => (