From 2a1ea755e074e1a364f9424653d57f33c0723855 Mon Sep 17 00:00:00 2001 From: Hein Jeong Date: Wed, 5 Apr 2023 23:42:20 +0000 Subject: [PATCH] fix: change handlers and props for StorageField --- ...studio-ui-codegen-react-forms.test.ts.snap | 125 ++++++++++------ .../event-handler-props.ts | 136 +++++++++++++++++- .../lib/react-required-dependency-provider.ts | 2 +- .../utils/forms/storage-field-component.ts | 39 ++--- 4 files changed, 241 insertions(+), 61 deletions(-) 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 9d6e002a..17e9c485 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 @@ -24936,20 +24936,33 @@ export default function CreateProductForm(props) { isReadOnly={false} > { - let value = files.map(({ key }) => key); - if (onChange) { - const modelFields = { - name, - imgKeys: value, - }; - const result = onChange(modelFields); - value = result?.imgKeys ?? value; - } - if (errors.imgKeys?.hasError) { - runValidationTasks(\\"imgKeys\\", value); - } - setImgKeys(value); + onUploadSuccess={({ key }) => { + setImgKeys((prev) => { + let value = [...prev, key]; + if (onChange) { + const modelFields = { + name, + imgKeys: value, + }; + const result = onChange(modelFields); + value = result?.imgKeys ?? value; + } + return value; + }); + }} + onFileRemove={({ key }) => { + setImgKeys((prev) => { + let value = prev.filter((f) => f !== key); + if (onChange) { + const modelFields = { + name, + imgKeys: value, + }; + const result = onChange(modelFields); + value = result?.imgKeys ?? value; + } + return value; + }); }} accessLevel={\\"protected\\"} acceptedFileTypes={[\\".txt\\", \\".pdf\\"]} @@ -25150,20 +25163,33 @@ export default function UpdateProductForm(props) { > ({ key }))} - onUploadSuccess={(files) => { - let value = files.map(({ key }) => key); - if (onChange) { - const modelFields = { - name, - imgKeys: value, - }; - const result = onChange(modelFields); - value = result?.imgKeys ?? value; - } - if (errors.imgKeys?.hasError) { - runValidationTasks(\\"imgKeys\\", value); - } - setImgKeys(value); + onUploadSuccess={({ key }) => { + setImgKeys((prev) => { + let value = [...prev, key]; + if (onChange) { + const modelFields = { + name, + imgKeys: value, + }; + const result = onChange(modelFields); + value = result?.imgKeys ?? value; + } + return value; + }); + }} + onFileRemove={({ key }) => { + setImgKeys((prev) => { + let value = prev.filter((f) => f !== key); + if (onChange) { + const modelFields = { + name, + imgKeys: value, + }; + const result = onChange(modelFields); + value = result?.imgKeys ?? value; + } + return value; + }); }} accessLevel={\\"private\\"} acceptedFileTypes={[\\".doc\\", \\".pdf\\"]} @@ -25367,21 +25393,34 @@ export default function UpdateProductForm(props) { isReadOnly={false} > { - let value = files?.[0]?.key; - if (onChange) { - const modelFields = { - name, - singleImgKey: value, - }; - const result = onChange(modelFields); - value = result?.singleImgKey ?? value; - } - if (errors.singleImgKey?.hasError) { - runValidationTasks(\\"singleImgKey\\", value); - } - setSingleImgKey(value); + defaultFiles={singleImgKey ? [{ key: singleImgKey }] : undefined} + onUploadSuccess={({ key }) => { + setSingleImgKey((prev) => { + let value = key; + if (onChange) { + const modelFields = { + name, + singleImgKey: value, + }; + const result = onChange(modelFields); + value = result?.singleImgKey ?? value; + } + return value; + }); + }} + onFileRemove={({ key }) => { + setSingleImgKey((prev) => { + let value = initialValues?.singleImgKey; + if (onChange) { + const modelFields = { + name, + singleImgKey: value, + }; + const result = onChange(modelFields); + value = result?.singleImgKey ?? value; + } + return value; + }); }} accessLevel={\\"protected\\"} acceptedFileTypes={[\\".txt\\", \\".pdf\\"]} diff --git a/packages/codegen-ui-react/lib/forms/form-renderer-helper/event-handler-props.ts b/packages/codegen-ui-react/lib/forms/form-renderer-helper/event-handler-props.ts index 117705a4..e54cd2ba 100644 --- a/packages/codegen-ui-react/lib/forms/form-renderer-helper/event-handler-props.ts +++ b/packages/codegen-ui-react/lib/forms/form-renderer-helper/event-handler-props.ts @@ -54,7 +54,7 @@ import { getOnChangeValidationBlock } from './validation'; import { buildModelFieldObject } from './model-fields'; import { isModelDataType, shouldWrapInArrayField } from './render-checkers'; import { extractModelAndKeys, getMatchEveryModelFieldCallExpression } from './model-values'; -import { COMPOSITE_PRIMARY_KEY_PROP_NAME } from '../../utils/constants'; +import { COMPOSITE_PRIMARY_KEY_PROP_NAME, STORAGE_FILE_KEY } from '../../utils/constants'; export const buildMutationBindings = (form: StudioForm, primaryKeys: string[] = []) => { const { @@ -447,3 +447,137 @@ export function buildOnSelect({ ), ); } + +const storageManagerOnChangeHandlerMap = { + onUploadSuccess: { + value: { + scalar: () => factory.createIdentifier('key'), + array: () => + factory.createArrayLiteralExpression( + [factory.createSpreadElement(factory.createIdentifier('prev')), factory.createIdentifier(STORAGE_FILE_KEY)], + false, + ), + }, + }, + onFileRemove: { + value: { + scalar: (fieldName?: string) => + fieldName ? buildAccessChain(['initialValues', fieldName]) : factory.createIdentifier('undefined'), + array: () => + factory.createCallExpression( + factory.createPropertyAccessExpression(factory.createIdentifier('prev'), factory.createIdentifier('filter')), + undefined, + [ + factory.createArrowFunction( + undefined, + undefined, + [ + factory.createParameterDeclaration( + undefined, + undefined, + undefined, + factory.createIdentifier('f'), + undefined, + undefined, + undefined, + ), + ], + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createBinaryExpression( + factory.createIdentifier('f'), + factory.createToken(SyntaxKind.ExclamationEqualsEqualsToken), + factory.createIdentifier(STORAGE_FILE_KEY), + ), + ), + ], + ), + }, + }, +}; + +export const buildStorageManagerOnChangeStatement = ( + component: StudioComponent | StudioComponentChild, + fieldConfigs: Record, + handlerName: 'onUploadSuccess' | 'onFileRemove', +) => { + const { name: fieldName } = component; + const fieldConfig = fieldConfigs[fieldName]; + const { sanitizedFieldName, isArray } = fieldConfig; + const renderedFieldName = sanitizedFieldName || fieldName; + + return factory.createJsxAttribute( + factory.createIdentifier(handlerName), + factory.createJsxExpression( + undefined, + factory.createArrowFunction( + undefined, + undefined, + [ + factory.createParameterDeclaration( + undefined, + undefined, + undefined, + factory.createObjectBindingPattern([ + factory.createBindingElement(undefined, undefined, factory.createIdentifier(STORAGE_FILE_KEY), undefined), + ]), + undefined, + undefined, + undefined, + ), + ], + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createBlock( + [ + factory.createExpressionStatement( + factory.createCallExpression(getSetNameIdentifier(renderedFieldName), undefined, [ + factory.createArrowFunction( + undefined, + undefined, + [ + factory.createParameterDeclaration( + undefined, + undefined, + undefined, + factory.createIdentifier('prev'), + undefined, + undefined, + undefined, + ), + ], + undefined, + factory.createToken(SyntaxKind.EqualsGreaterThanToken), + factory.createBlock( + [ + factory.createVariableStatement( + undefined, + factory.createVariableDeclarationList( + [ + factory.createVariableDeclaration( + factory.createIdentifier('value'), + undefined, + undefined, + storageManagerOnChangeHandlerMap[handlerName].value[isArray ? 'array' : 'scalar']( + renderedFieldName, + ), + ), + ], + NodeFlags.Let, + ), + ), + buildOverrideOnChangeStatement(fieldName, fieldConfigs), + factory.createReturnStatement(factory.createIdentifier('value')), + ], + true, + ), + ), + ]), + ), + ], + true, + ), + ), + ), + ); +}; diff --git a/packages/codegen-ui-react/lib/react-required-dependency-provider.ts b/packages/codegen-ui-react/lib/react-required-dependency-provider.ts index 69446bf9..6459875c 100644 --- a/packages/codegen-ui-react/lib/react-required-dependency-provider.ts +++ b/packages/codegen-ui-react/lib/react-required-dependency-provider.ts @@ -34,7 +34,7 @@ export class ReactRequiredDependencyProvider extends RequiredDependencyProvider< }, { dependencyName: '@aws-amplify/ui-react-storage', - supportedSemVerPattern: '^1.0.2', + supportedSemVerPattern: '^1.0.1', reason: 'Required to leverage StorageManager.', }, ]; diff --git a/packages/codegen-ui-react/lib/utils/forms/storage-field-component.ts b/packages/codegen-ui-react/lib/utils/forms/storage-field-component.ts index fbddcbfe..57c3fc55 100644 --- a/packages/codegen-ui-react/lib/utils/forms/storage-field-component.ts +++ b/packages/codegen-ui-react/lib/utils/forms/storage-field-component.ts @@ -24,7 +24,7 @@ import { } from '@aws-amplify/codegen-ui'; import { factory, JsxAttribute, JsxAttributeLike, JsxElement, JsxExpression, SyntaxKind } from 'typescript'; import { getDecoratedLabel } from '../../forms/form-renderer-helper'; -import { buildOnChangeStatement } from '../../forms/form-renderer-helper/event-handler-props'; +import { buildStorageManagerOnChangeStatement } from '../../forms/form-renderer-helper/event-handler-props'; import { propertyToExpression } from '../../react-component-render-helper'; import { STORAGE_FILE_KEY } from '../constants'; @@ -78,7 +78,7 @@ export const renderStorageFieldComponent = ( undefined, factory.createCallExpression( factory.createPropertyAccessExpression( - factory.createIdentifier('imgKeys'), + factory.createIdentifier(componentName), factory.createIdentifier('map'), ), undefined, @@ -118,19 +118,25 @@ export const renderStorageFieldComponent = ( ) : factory.createJsxExpression( undefined, - factory.createArrayLiteralExpression( - [ - factory.createObjectLiteralExpression( - [ - factory.createPropertyAssignment( - factory.createIdentifier(STORAGE_FILE_KEY), - factory.createIdentifier('singleImgKey'), - ), - ], - false, - ), - ], - false, + factory.createConditionalExpression( + factory.createIdentifier(componentName), + factory.createToken(SyntaxKind.QuestionToken), + factory.createArrayLiteralExpression( + [ + factory.createObjectLiteralExpression( + [ + factory.createPropertyAssignment( + factory.createIdentifier('key'), + factory.createIdentifier(componentName), + ), + ], + false, + ), + ], + false, + ), + factory.createToken(SyntaxKind.ColonToken), + factory.createIdentifier('undefined'), ), ); @@ -139,7 +145,8 @@ export const renderStorageFieldComponent = ( ); } - storageManagerAttributes.push(buildOnChangeStatement(component, fieldConfigs)); + storageManagerAttributes.push(buildStorageManagerOnChangeStatement(component, fieldConfigs, 'onUploadSuccess')); + storageManagerAttributes.push(buildStorageManagerOnChangeStatement(component, fieldConfigs, 'onFileRemove')); fieldAttributes.push( factory.createJsxAttribute( factory.createIdentifier('errorMessage'),