From 46c74c4b88c06d80597ee2534a2ea72f94cf7230 Mon Sep 17 00:00:00 2001 From: Christopher Woolum Date: Tue, 13 Dec 2022 23:40:49 +0000 Subject: [PATCH] fix: handle customized fields getting renamed --- .../generate-form-definition.test.ts | 53 +++++++++++++++++++ .../helpers/form-field.test.ts | 25 ++++++--- .../helpers/form-field.ts | 7 ++- .../codegen-ui/lib/types/form/input-config.ts | 2 +- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/packages/codegen-ui/lib/__tests__/generate-form-definition/generate-form-definition.test.ts b/packages/codegen-ui/lib/__tests__/generate-form-definition/generate-form-definition.test.ts index a262bcf83..bb15080f6 100644 --- a/packages/codegen-ui/lib/__tests__/generate-form-definition/generate-form-definition.test.ts +++ b/packages/codegen-ui/lib/__tests__/generate-form-definition/generate-form-definition.test.ts @@ -291,6 +291,59 @@ describe('generateFormDefinition', () => { expect(formDefinition.elementMatrix).toStrictEqual([['Heading123']]); }); + it('should gracefully handle a customized field being renamed', () => { + const formDefinition = generateFormDefinition({ + form: { + cta: { + cancel: {}, + clear: {}, + position: 'bottom', + submit: {}, + }, + dataType: { + dataSourceType: 'DataStore', + dataTypeName: 'Event', + }, + fields: { + startDate: { + position: { + fixed: 'first', + }, + }, + sourceAccountId: { + position: { + below: 'startDate', + }, + }, + endTime: { + position: { + below: 'sourceAccountId', + }, + }, + }, + formActionType: 'create', + name: 'EventFormTest', + sectionalElements: {}, + style: {}, + }, + dataSchema: { + dataSourceType: 'DataStore', + enums: {}, + nonModels: {}, + models: { + Event: { + fields: { + sourceAccountId: { dataType: 'String', readOnly: false, required: true, isArray: false }, + endTime: { dataType: 'Float', readOnly: false, required: true, isArray: false }, + }, + }, + }, + }, + }); + + expect(formDefinition.elementMatrix).toStrictEqual([['startDate'], ['sourceAccountId'], ['endTime']]); + }); + it('should correctly map positions', () => { const formDefinition = generateFormDefinition({ form: { diff --git a/packages/codegen-ui/lib/__tests__/generate-form-definition/helpers/form-field.test.ts b/packages/codegen-ui/lib/__tests__/generate-form-definition/helpers/form-field.test.ts index 18f902bf4..6e9416fb6 100644 --- a/packages/codegen-ui/lib/__tests__/generate-form-definition/helpers/form-field.test.ts +++ b/packages/codegen-ui/lib/__tests__/generate-form-definition/helpers/form-field.test.ts @@ -119,6 +119,25 @@ describe('getFormDefinitionInputElement', () => { }); }); + it(`should gracefully fall back to TextField if the field type isn't available`, () => { + const config = { + label: 'MyLabel', + inputType: { + isReadOnly: false, + placeholder: 'MyPlaceholder', + }, + }; + + expect(getFormDefinitionInputElement(config)).toStrictEqual({ + componentType: 'TextField', + props: { + label: 'MyLabel', + placeholder: 'MyPlaceholder', + }, + studioFormComponentType: 'TextField', + }); + }); + it('should get NumberField', () => { const config = { inputType: { @@ -551,12 +570,6 @@ describe('getFormDefinitionInputElement', () => { expect(() => getFormDefinitionInputElement(config)).toThrow(); }); - - it('should throw if the inputType is missing type', () => { - const config = { label: 'MyLabel' }; - - expect(() => getFormDefinitionInputElement(config)).toThrow(); - }); }); describe('mergeValueMappings', () => { diff --git a/packages/codegen-ui/lib/generate-form-definition/helpers/form-field.ts b/packages/codegen-ui/lib/generate-form-definition/helpers/form-field.ts index 662cc654b..6904a998a 100644 --- a/packages/codegen-ui/lib/generate-form-definition/helpers/form-field.ts +++ b/packages/codegen-ui/lib/generate-form-definition/helpers/form-field.ts @@ -147,14 +147,17 @@ export function getFormDefinitionInputElement( config: StudioGenericFieldConfig, baseConfig?: StudioGenericFieldConfig, ): FormDefinitionInputElement { - const componentType = config.inputType?.type || baseConfig?.inputType?.type; + let componentType = config.inputType?.type || baseConfig?.inputType?.type; if (!componentType) { - throw new InvalidInputError('Field config is missing input type'); + // Gracefully fall back to a TextField if the inputType is no longer available due to a field rename + componentType = 'TextField'; } + const defaultStringValue = getFirstString([config.inputType?.defaultValue, baseConfig?.inputType?.defaultValue]); const isRequiredValue = getFirstDefinedValue([config.inputType?.required, baseConfig?.inputType?.required]); let formDefinitionElement: FormDefinitionInputElement; + switch (componentType) { case 'TextField': case 'NumberField': diff --git a/packages/codegen-ui/lib/types/form/input-config.ts b/packages/codegen-ui/lib/types/form/input-config.ts index 9569d9cc2..7f8cb85cc 100644 --- a/packages/codegen-ui/lib/types/form/input-config.ts +++ b/packages/codegen-ui/lib/types/form/input-config.ts @@ -36,7 +36,7 @@ export type StudioFormValueMappings = { // represents API shape after type casting export type StudioFieldInputConfig = { - type: string; + type?: string; required?: boolean;