diff --git a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react-forms.test.ts.snap b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react-forms.test.ts.snap index ab25a6830..b0c48ff98 100644 --- a/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react-forms.test.ts.snap +++ b/packages/codegen-ui-react/lib/__tests__/__snapshots__/studio-ui-codegen-react-forms.test.ts.snap @@ -4881,6 +4881,7 @@ import { RadioGroupField, ScrollView, Text, + TextAreaField, TextField, ToggleButton, useTheme, @@ -5036,6 +5037,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide: false, maybeCheck: false, arrayTypeField: [], + jsonArray: [], + jsonField: undefined, timestamp: undefined, ippy: undefined, timeisnow: undefined, @@ -5048,6 +5051,12 @@ export default function InputGalleryCreateForm(props) { const [arrayTypeField, setArrayTypeField] = React.useState( initialValues.arrayTypeField ); + const [jsonArray, setJsonArray] = React.useState(initialValues.jsonArray); + const [jsonField, setJsonField] = React.useState( + initialValues.jsonField + ? JSON.stringify(initialValues.jsonField) + : undefined + ); const [timestamp, setTimestamp] = React.useState(initialValues.timestamp); const [ippy, setIppy] = React.useState(initialValues.ippy); const [timeisnow, setTimeisnow] = React.useState(initialValues.timeisnow); @@ -5060,6 +5069,9 @@ export default function InputGalleryCreateForm(props) { setMaybeCheck(initialValues.maybeCheck); setArrayTypeField(initialValues.arrayTypeField); setCurrentArrayTypeFieldValue(undefined); + setJsonArray(initialValues.jsonArray); + setCurrentJsonArrayValue(undefined); + setJsonField(initialValues.jsonField); setTimestamp(initialValues.timestamp); setIppy(initialValues.ippy); setTimeisnow(initialValues.timeisnow); @@ -5068,6 +5080,9 @@ export default function InputGalleryCreateForm(props) { const [currentArrayTypeFieldValue, setCurrentArrayTypeFieldValue] = React.useState(undefined); const arrayTypeFieldRef = React.createRef(); + const [currentJsonArrayValue, setCurrentJsonArrayValue] = + React.useState(undefined); + const jsonArrayRef = React.createRef(); const validations = { num: [], rootbeer: [], @@ -5075,6 +5090,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide: [], maybeCheck: [], arrayTypeField: [], + jsonArray: [{ type: \\"JSON\\" }], + jsonField: [{ type: \\"JSON\\" }], timestamp: [], ippy: [{ type: \\"IpAddress\\" }], timeisnow: [], @@ -5103,6 +5120,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5169,6 +5188,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5209,6 +5230,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5241,6 +5264,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5284,6 +5309,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide: value, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5317,6 +5344,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck: value, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5345,6 +5374,8 @@ export default function InputGalleryCreateForm(props) { maybeSlide, maybeCheck, arrayTypeField: values, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5384,6 +5415,89 @@ export default function InputGalleryCreateForm(props) { {...getOverrideProps(overrides, \\"arrayTypeField\\")} > + { + let values = items; + if (onChange) { + const modelFields = { + num, + rootbeer, + attend, + maybeSlide, + maybeCheck, + arrayTypeField, + jsonArray: values, + jsonField, + timestamp, + ippy, + timeisnow, + }; + const result = onChange(modelFields); + values = result?.jsonArray ?? values; + } + setJsonArray(values); + setCurrentJsonArrayValue(undefined); + }} + currentFieldValue={currentJsonArrayValue} + label={\\"Json array\\"} + items={jsonArray} + hasError={errors.jsonArray?.hasError} + setFieldValue={setCurrentJsonArrayValue} + inputFieldRef={jsonArrayRef} + defaultFieldValue={undefined} + > + { + let { value } = e.target; + if (errors.jsonArray?.hasError) { + runValidationTasks(\\"jsonArray\\", value); + } + setCurrentJsonArrayValue(value); + }} + onBlur={() => runValidationTasks(\\"jsonArray\\", currentJsonArrayValue)} + errorMessage={errors.jsonArray?.errorMessage} + hasError={errors.jsonArray?.hasError} + ref={jsonArrayRef} + {...getOverrideProps(overrides, \\"jsonArray\\")} + > + + { + let { value } = e.target; + if (onChange) { + const modelFields = { + num, + rootbeer, + attend, + maybeSlide, + maybeCheck, + arrayTypeField, + jsonArray, + jsonField: value, + timestamp, + ippy, + timeisnow, + }; + const result = onChange(modelFields); + value = result?.jsonField ?? value; + } + if (errors.jsonField?.hasError) { + runValidationTasks(\\"jsonField\\", value); + } + setJsonField(value); + }} + onBlur={() => runValidationTasks(\\"jsonField\\", jsonField)} + errorMessage={errors.jsonField?.errorMessage} + hasError={errors.jsonField?.hasError} + {...getOverrideProps(overrides, \\"jsonField\\")} + > ; maybeCheck?: ValidationFunction; arrayTypeField?: ValidationFunction; + jsonArray?: ValidationFunction; + jsonField?: ValidationFunction; timestamp?: ValidationFunction; ippy?: ValidationFunction; timeisnow?: ValidationFunction; @@ -5561,6 +5685,8 @@ export declare type InputGalleryCreateFormOverridesProps = { maybeSlide?: FormProps; maybeCheck?: FormProps; arrayTypeField?: FormProps; + jsonArray?: FormProps; + jsonField?: FormProps; timestamp?: FormProps; ippy?: FormProps; timeisnow?: FormProps; @@ -5598,6 +5724,7 @@ import { RadioGroupField, ScrollView, Text, + TextAreaField, TextField, ToggleButton, useTheme, @@ -5754,6 +5881,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide: false, maybeCheck: false, arrayTypeField: [], + jsonArray: [], + jsonField: undefined, timestamp: undefined, ippy: undefined, timeisnow: undefined, @@ -5766,6 +5895,12 @@ export default function InputGalleryUpdateForm(props) { const [arrayTypeField, setArrayTypeField] = React.useState( initialValues.arrayTypeField ); + const [jsonArray, setJsonArray] = React.useState(initialValues.jsonArray); + const [jsonField, setJsonField] = React.useState( + initialValues.jsonField + ? JSON.stringify(initialValues.jsonField) + : undefined + ); const [timestamp, setTimestamp] = React.useState(initialValues.timestamp); const [ippy, setIppy] = React.useState(initialValues.ippy); const [timeisnow, setTimeisnow] = React.useState(initialValues.timeisnow); @@ -5779,6 +5914,9 @@ export default function InputGalleryUpdateForm(props) { setMaybeCheck(cleanValues.maybeCheck); setArrayTypeField(cleanValues.arrayTypeField ?? []); setCurrentArrayTypeFieldValue(undefined); + setJsonArray(cleanValues.jsonArray ?? []); + setCurrentJsonArrayValue(undefined); + setJsonField(cleanValues.jsonField); setTimestamp(cleanValues.timestamp); setIppy(cleanValues.ippy); setTimeisnow(cleanValues.timeisnow); @@ -5799,6 +5937,9 @@ export default function InputGalleryUpdateForm(props) { const [currentArrayTypeFieldValue, setCurrentArrayTypeFieldValue] = React.useState(undefined); const arrayTypeFieldRef = React.createRef(); + const [currentJsonArrayValue, setCurrentJsonArrayValue] = + React.useState(undefined); + const jsonArrayRef = React.createRef(); const validations = { num: [], rootbeer: [], @@ -5806,6 +5947,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide: [], maybeCheck: [], arrayTypeField: [], + jsonArray: [{ type: \\"JSON\\" }], + jsonField: [{ type: \\"JSON\\" }], timestamp: [], ippy: [{ type: \\"IpAddress\\" }], timeisnow: [], @@ -5857,6 +6000,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5926,6 +6071,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -5967,6 +6114,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -6000,6 +6149,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -6043,6 +6194,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide: value, maybeCheck, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -6077,6 +6230,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck: value, arrayTypeField, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -6105,6 +6260,8 @@ export default function InputGalleryUpdateForm(props) { maybeSlide, maybeCheck, arrayTypeField: values, + jsonArray, + jsonField, timestamp, ippy, timeisnow, @@ -6144,6 +6301,90 @@ export default function InputGalleryUpdateForm(props) { {...getOverrideProps(overrides, \\"arrayTypeField\\")} > + { + let values = items; + if (onChange) { + const modelFields = { + num, + rootbeer, + attend, + maybeSlide, + maybeCheck, + arrayTypeField, + jsonArray: values, + jsonField, + timestamp, + ippy, + timeisnow, + }; + const result = onChange(modelFields); + values = result?.jsonArray ?? values; + } + setJsonArray(values); + setCurrentJsonArrayValue(undefined); + }} + currentFieldValue={currentJsonArrayValue} + label={\\"Json array\\"} + items={jsonArray} + hasError={errors.jsonArray?.hasError} + setFieldValue={setCurrentJsonArrayValue} + inputFieldRef={jsonArrayRef} + defaultFieldValue={undefined} + > + { + let { value } = e.target; + if (errors.jsonArray?.hasError) { + runValidationTasks(\\"jsonArray\\", value); + } + setCurrentJsonArrayValue(value); + }} + onBlur={() => runValidationTasks(\\"jsonArray\\", currentJsonArrayValue)} + errorMessage={errors.jsonArray?.errorMessage} + hasError={errors.jsonArray?.hasError} + ref={jsonArrayRef} + {...getOverrideProps(overrides, \\"jsonArray\\")} + > + + { + let { value } = e.target; + if (onChange) { + const modelFields = { + num, + rootbeer, + attend, + maybeSlide, + maybeCheck, + arrayTypeField, + jsonArray, + jsonField: value, + timestamp, + ippy, + timeisnow, + }; + const result = onChange(modelFields); + value = result?.jsonField ?? value; + } + if (errors.jsonField?.hasError) { + runValidationTasks(\\"jsonField\\", value); + } + setJsonField(value); + }} + onBlur={() => runValidationTasks(\\"jsonField\\", jsonField)} + errorMessage={errors.jsonField?.errorMessage} + hasError={errors.jsonField?.hasError} + {...getOverrideProps(overrides, \\"jsonField\\")} + > ; maybeCheck?: ValidationFunction; arrayTypeField?: ValidationFunction; + jsonArray?: ValidationFunction; + jsonField?: ValidationFunction; timestamp?: ValidationFunction; ippy?: ValidationFunction; timeisnow?: ValidationFunction; @@ -6327,6 +6578,8 @@ export declare type InputGalleryUpdateFormOverridesProps = { maybeSlide?: FormProps; maybeCheck?: FormProps; arrayTypeField?: FormProps; + jsonArray?: FormProps; + jsonField?: FormProps; timestamp?: FormProps; ippy?: FormProps; timeisnow?: FormProps; diff --git a/packages/codegen-ui-react/lib/forms/form-state.ts b/packages/codegen-ui-react/lib/forms/form-state.ts index e6f4e8a8e..c26dd56a7 100644 --- a/packages/codegen-ui-react/lib/forms/form-state.ts +++ b/packages/codegen-ui-react/lib/forms/form-state.ts @@ -194,7 +194,7 @@ export const getInitialValues = (fieldConfigs: Record): Statement[] => { const stateNames = new Set(); - return Object.entries(fieldConfigs).reduce((acc, [name, { sanitizedFieldName, dataType }]) => { + return Object.entries(fieldConfigs).reduce((acc, [name, { sanitizedFieldName, dataType, isArray }]) => { const fieldName = name.split('.')[0]; const renderedFieldName = sanitizedFieldName || fieldName; @@ -211,7 +211,7 @@ export const getUseStateHooks = (fieldConfigs: Record