Skip to content

Commit

Permalink
fix: store selected relationship data for scalar fields
Browse files Browse the repository at this point in the history
  • Loading branch information
rtpascual committed Aug 16, 2023
1 parent a3ba324 commit c8b3c0c
Show file tree
Hide file tree
Showing 9 changed files with 1,812 additions and 201 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1184,6 +1184,30 @@ describe('amplify form renderer tests', () => {
expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});

it('should render an update form with child field', () => {
const { componentText, declaration } = generateWithAmplifyFormRenderer(
'models/custom-key-model/forms/ChildItemUpdateForm',
'models/custom-key-model/schema',
{ ...defaultCLIRenderConfig, ...rendererConfigWithGraphQL },
{ isNonModelSupported: true, isRelationshipSupported: true },
);

expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});

it('should render an update form with id field instead of belongsTo', () => {
const { componentText, declaration } = generateWithAmplifyFormRenderer(
'models/comment-with-postID/forms/PostUpdateForm',
'models/comment-with-postID/schema',
{ ...defaultCLIRenderConfig, ...rendererConfigWithGraphQL },
{ isNonModelSupported: true, isRelationshipSupported: true },
);

expect(componentText).toMatchSnapshot();
expect(declaration).toMatchSnapshot();
});
});

describe('NoApi form tests', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
isValidVariableName,
isNonModelDataType,
StudioForm,
StudioFormActionType,
} from '@aws-amplify/codegen-ui';
import {
factory,
Expand Down Expand Up @@ -49,7 +50,7 @@ import {
buildInitConstVariableExpression,
} from '../../helpers';
import { getElementAccessExpression } from './invalid-variable-helpers';
import { shouldWrapInArrayField } from './render-checkers';
import { isModelDataType, shouldWrapInArrayField } from './render-checkers';
import { DataApiKind } from '../../react-render-config';

// used just to sanitize nested array field names
Expand Down Expand Up @@ -237,10 +238,13 @@ export const getInitialValues = (
*/
export const getUseStateHooks = (
fieldConfigs: Record<string, FieldConfigMetadata>,
formActionType: StudioFormActionType,
dataApi?: DataApiKind,
hasAutoComplete?: boolean,
): Statement[] => {
const stateNames = new Set();
return Object.entries(fieldConfigs).reduce<Statement[]>((acc, [name, { sanitizedFieldName, relationship }]) => {
return Object.entries(fieldConfigs).reduce<Statement[]>((acc, fieldConfig) => {
const [name, { sanitizedFieldName, relationship }] = fieldConfig;
const fieldName = name.split('.')[0];
const renderedFieldName = sanitizedFieldName || fieldName;

Expand Down Expand Up @@ -268,6 +272,14 @@ export const getUseStateHooks = (
if (dataApi === 'GraphQL' && relationship) {
acc.push(buildUseStateExpression(`${renderedFieldName}Loading`, factory.createFalse()));
acc.push(buildUseStateExpression(`${renderedFieldName}Records`, factory.createArrayLiteralExpression([], false)));
if (hasAutoComplete && !isModelDataType(fieldConfig[1])) {
acc.push(
buildUseStateExpression(
`selected${capitalizeFirstLetter(renderedFieldName)}Records`,
factory.createArrayLiteralExpression([], false),
),
);
}
}
return acc;
}, []);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import { buildAccessChain, getRecordsName } from './form-state';
import { getElementAccessExpression, getValidProperty } from './invalid-variable-helpers';
import { isEnumDataType, isModelDataType } from './render-checkers';
import { DataApiKind } from '../../react-render-config';
import { capitalizeFirstLetter } from '../../helpers';

export const getDisplayValueObjectName = 'getDisplayValue';

Expand Down Expand Up @@ -74,7 +75,7 @@ const getDisplayValueCallChain = ({ fieldName, recordString }: { fieldName: stri
compositeDogRecords.find((r) => r.description === value)
)
*/
export function getDisplayValueScalar(fieldName: string, model: string, key: string) {
export function getDisplayValueScalar(fieldName: string, model: string, key: string, dataApi?: DataApiKind) {
const recordString = 'r';

return factory.createConditionalExpression(
Expand All @@ -87,39 +88,110 @@ export function getDisplayValueScalar(fieldName: string, model: string, key: str
),
undefined,
[
factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(getRecordsName(model)),
factory.createIdentifier('find'),
),
undefined,
[
factory.createArrowFunction(
undefined,
dataApi === 'GraphQL'
? factory.createBinaryExpression(
factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(`selected${capitalizeFirstLetter(fieldName)}Records`),
factory.createIdentifier('find'),
),
undefined,
[
factory.createArrowFunction(
undefined,
undefined,
[
factory.createParameterDeclaration(
undefined,
undefined,
undefined,
factory.createIdentifier(recordString),
undefined,
undefined,
undefined,
),
],
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBinaryExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(recordString),
factory.createIdentifier('id'),
),
factory.createToken(SyntaxKind.EqualsEqualsEqualsToken),
factory.createIdentifier('value'),
),
),
],
),
factory.createToken(SyntaxKind.QuestionQuestionToken),
factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(getRecordsName(model)),
factory.createIdentifier('find'),
),
undefined,
[
factory.createArrowFunction(
undefined,
undefined,
[
factory.createParameterDeclaration(
undefined,
undefined,
undefined,
factory.createIdentifier(recordString),
undefined,
undefined,
),
],
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBinaryExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(recordString),
factory.createIdentifier(key),
),
factory.createToken(SyntaxKind.EqualsEqualsEqualsToken),
factory.createIdentifier('value'),
),
),
],
),
)
: factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(getRecordsName(model)),
factory.createIdentifier('find'),
),
undefined,
[
factory.createParameterDeclaration(
factory.createArrowFunction(
undefined,
undefined,
[
factory.createParameterDeclaration(
undefined,
undefined,
undefined,
factory.createIdentifier(recordString),
undefined,
undefined,
),
],
undefined,
factory.createIdentifier(recordString),
undefined,
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBinaryExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(recordString),
factory.createIdentifier(key),
),
factory.createToken(SyntaxKind.EqualsEqualsEqualsToken),
factory.createIdentifier('value'),
),
),
],
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBinaryExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(recordString),
factory.createIdentifier(key),
),
factory.createToken(SyntaxKind.EqualsEqualsEqualsToken),
factory.createIdentifier('value'),
),
),
],
),
],
),
factory.createToken(SyntaxKind.ColonToken),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1371,9 +1371,11 @@ export const buildGetRelationshipModels = (
]),
),
factory.createExpressionStatement(
factory.createCallExpression(getSetNameIdentifier(`${fieldName}Records`), undefined, [
factory.createArrayLiteralExpression([factory.createIdentifier(`${relatedModelName}Record`)]),
]),
factory.createCallExpression(
getSetNameIdentifier(`selected${capitalizeFirstLetter(fieldName)}Records`),
undefined,
[factory.createArrayLiteralExpression([factory.createIdentifier(`${relatedModelName}Record`)])],
),
),
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@
limitations under the License.
*/
import { FieldConfigMetadata, LabelDecorator } from '@aws-amplify/codegen-ui';
import { Expression, factory, Identifier, JsxAttribute, JsxChild, NodeFlags, SyntaxKind } from 'typescript';
import { Expression, factory, Identifier, JsxAttribute, JsxChild, NodeFlags, Statement, SyntaxKind } from 'typescript';
import {
buildAccessChain,
getArrayChildRefName,
getCurrentDisplayValueName,
getCurrentValueIdentifier,
getCurrentValueName,
getDefaultValueExpression,
getRecordsName,
setFieldState,
} from './form-state';
import { buildOverrideOnChangeStatement } from './event-handler-props';
Expand Down Expand Up @@ -264,8 +265,8 @@ export const renderArrayFieldComponent = (
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
dataApi === 'GraphQL' && !isModelDataType(fieldConfig)
? getDisplayValueScalar(fieldName, fieldName, scalarKey)
: getDisplayValueScalar(fieldName, scalarModel, scalarKey),
? getDisplayValueScalar(fieldName, fieldName, scalarKey, dataApi)
: getDisplayValueScalar(fieldName, scalarModel, scalarKey, dataApi),
);
}

Expand Down Expand Up @@ -348,7 +349,61 @@ export const renderArrayFieldComponent = (
),
);
} else if (scalarModel && scalarKey) {
const setStateStatements: Statement[] = [];
const valueArgument = 'value';

setStateStatements.push(
factory.createExpressionStatement(
factory.createCallExpression(setStateName, undefined, [factory.createIdentifier(valueArgument)]),
),
);

if (dataApi === 'GraphQL') {
setStateStatements.push(
factory.createExpressionStatement(
factory.createCallExpression(
getSetNameIdentifier(`selected${capitalizeFirstLetter(fieldName)}Records`),
undefined,
[
factory.createCallExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier(getRecordsName(fieldName)),
factory.createIdentifier('find'),
),
undefined,
[
factory.createArrowFunction(
undefined,
undefined,
[
factory.createParameterDeclaration(
undefined,
undefined,
undefined,
factory.createIdentifier('r'),
undefined,
undefined,
),
],
undefined,
factory.createToken(SyntaxKind.EqualsGreaterThanToken),
factory.createBinaryExpression(
factory.createPropertyAccessExpression(
factory.createIdentifier('r'),
factory.createIdentifier(scalarKey),
),
factory.createToken(SyntaxKind.EqualsEqualsEqualsToken),
factory.createIdentifier('value'),
),
),
],
),
],
),
),
);
}

props.push(
factory.createJsxAttribute(
factory.createIdentifier('setFieldValue'),
Expand All @@ -375,13 +430,11 @@ export const renderArrayFieldComponent = (
factory.createExpressionStatement(
factory.createCallExpression(setFieldValueIdentifier, undefined, [
dataApi === 'GraphQL'
? getDisplayValueScalar(fieldName, fieldName, scalarKey)
: getDisplayValueScalar(fieldName, scalarModel, scalarKey),
? getDisplayValueScalar(fieldName, fieldName, scalarKey, dataApi)
: getDisplayValueScalar(fieldName, scalarModel, scalarKey, dataApi),
]),
),
factory.createExpressionStatement(
factory.createCallExpression(setStateName, undefined, [factory.createIdentifier(valueArgument)]),
),
...setStateStatements,
],
true,
),
Expand Down
2 changes: 1 addition & 1 deletion packages/codegen-ui-react/lib/forms/react-form-renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ export abstract class ReactFormTemplateRenderer extends StudioTemplateRenderer<

statements.push(getInitialValues(formMetadata.fieldConfigs, this.component));

statements.push(...getUseStateHooks(formMetadata.fieldConfigs, dataApi));
statements.push(...getUseStateHooks(formMetadata.fieldConfigs, formActionType, dataApi, hasAutoComplete));

statements.push(...getAutocompleteOptions(formMetadata.fieldConfigs, hasAutoComplete, dataApi));

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "PostUpdateForm",
"dataType": {
"dataSourceType": "DataStore",
"dataTypeName": "Post"
},
"formActionType": "update",
"fields": {},
"sectionalElements": {},
"style": {},
"cta": {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "ChildItemUpdateForm",
"dataType": {
"dataSourceType": "DataStore",
"dataTypeName": "ChildItem"
},
"formActionType": "update",
"fields": {},
"sectionalElements": {},
"style": {},
"cta": {}
}

0 comments on commit c8b3c0c

Please sign in to comment.