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 e864f47bd..a93dea864 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
@@ -3977,6 +3977,7 @@ export default function MyPostForm(props) {
children=\\"Reset\\"
type=\\"reset\\"
onClick={resetStateValues}
+ isDisabled={!(id || post)}
{...getOverrideProps(overrides, \\"ResetButton\\")}
>
e?.hasError)}
+ isDisabled={
+ !(id || post) || Object.values(errors).some((e) => e?.hasError)
+ }
{...getOverrideProps(overrides, \\"SubmitButton\\")}
>
@@ -4182,6 +4185,7 @@ export default function MyPostForm(props) {
children=\\"Reset\\"
type=\\"reset\\"
onClick={resetStateValues}
+ isDisabled={!(id || post)}
{...getOverrideProps(overrides, \\"ResetButton\\")}
>
e?.hasError)}
+ isDisabled={
+ !(id || post) || Object.values(errors).some((e) => e?.hasError)
+ }
{...getOverrideProps(overrides, \\"SubmitButton\\")}
>
@@ -4413,10 +4419,9 @@ function ArrayField({
);
}
-export default function MyFlexUpdateForm(props) {
+export default function MyFlexCreateForm(props) {
const {
- id,
- flex,
+ clearOnSuccess = true,
onSuccess,
onError,
onSubmit,
@@ -4442,25 +4447,15 @@ export default function MyFlexUpdateForm(props) {
);
const [errors, setErrors] = React.useState({});
const resetStateValues = () => {
- const cleanValues = { ...initialValues, ...flexRecord };
- setUsername(cleanValues.username);
- setCaption(cleanValues.caption);
- setCustomtags(cleanValues.Customtags ?? []);
+ setUsername(initialValues.username);
+ setCaption(initialValues.caption);
+ setCustomtags(initialValues.Customtags);
setCurrentCustomtagsValue(undefined);
- setTags(cleanValues.tags ?? []);
+ setTags(initialValues.tags);
setCurrentTagsValue(undefined);
- setProfile_url(cleanValues.profile_url);
+ setProfile_url(initialValues.profile_url);
setErrors({});
};
- const [flexRecord, setFlexRecord] = React.useState(flex);
- React.useEffect(() => {
- const queryData = async () => {
- const record = id ? await DataStore.query(Flex0, id) : flex0;
- setFlexRecord(record);
- };
- queryData();
- }, [id, flex]);
- React.useEffect(resetStateValues, [flexRecord]);
const [currentCustomtagsValue, setCurrentCustomtagsValue] =
React.useState(undefined);
const CustomtagsRef = React.createRef();
@@ -4526,21 +4521,20 @@ export default function MyFlexUpdateForm(props) {
modelFields = onSubmit(modelFields);
}
try {
- await DataStore.save(
- Flex0.copyOf(flexRecord, (updated) => {
- Object.assign(updated, modelFields);
- })
- );
+ await DataStore.save(new Flex0(modelFields));
if (onSuccess) {
onSuccess(modelFields);
}
+ if (clearOnSuccess) {
+ resetStateValues();
+ }
} catch (err) {
if (onError) {
onError(modelFields, err.message);
}
}
}}
- {...getOverrideProps(overrides, \\"MyFlexUpdateForm\\")}
+ {...getOverrideProps(overrides, \\"MyFlexCreateForm\\")}
{...rest}
>
{
let { value } = e.target;
if (onChange) {
@@ -4614,7 +4607,6 @@ export default function MyFlexUpdateForm(props) {
isRequired={false}
isReadOnly={false}
placeholder=\\"i love code\\"
- defaultValue={caption}
onChange={(e) => {
let { value } = e.target;
if (onChange) {
@@ -4732,7 +4724,6 @@ export default function MyFlexUpdateForm(props) {
label=\\"Profile url\\"
isRequired={false}
isReadOnly={false}
- defaultValue={profile_url}
onChange={(e) => {
let { value } = e.target;
if (onChange) {
@@ -4764,7 +4755,6 @@ export default function MyFlexUpdateForm(props) {
exports[`amplify form renderer tests datastore form tests should render a create form with colliding model name 2`] = `
"import * as React from \\"react\\";
-import { Flex as Flex0 } from \\"../models\\";
import { EscapeHatchProps } from \\"@aws-amplify/ui-react/internal\\";
import { GridProps, TextFieldProps } from \\"@aws-amplify/ui-react\\";
export declare type ValidationResponse = {
@@ -4772,14 +4762,14 @@ export declare type ValidationResponse = {
errorMessage?: string;
};
export declare type ValidationFunction = (value: T, validationResponse: ValidationResponse) => ValidationResponse | Promise;
-export declare type MyFlexUpdateFormInputValues = {
+export declare type MyFlexCreateFormInputValues = {
username?: string;
caption?: string;
Customtags?: string[];
tags?: string[];
profile_url?: string;
};
-export declare type MyFlexUpdateFormValidationValues = {
+export declare type MyFlexCreateFormValidationValues = {
username?: ValidationFunction;
caption?: ValidationFunction;
Customtags?: ValidationFunction;
@@ -4787,8 +4777,8 @@ export declare type MyFlexUpdateFormValidationValues = {
profile_url?: ValidationFunction;
};
export declare type FormProps = Partial & React.DOMAttributes;
-export declare type MyFlexUpdateFormOverridesProps = {
- MyFlexUpdateFormGrid?: FormProps;
+export declare type MyFlexCreateFormOverridesProps = {
+ MyFlexCreateFormGrid?: FormProps;
RowGrid0?: FormProps;
username?: FormProps;
caption?: FormProps;
@@ -4796,19 +4786,18 @@ export declare type MyFlexUpdateFormOverridesProps = {
tags?: FormProps;
profile_url?: FormProps;
} & EscapeHatchProps;
-export declare type MyFlexUpdateFormProps = React.PropsWithChildren<{
- overrides?: MyFlexUpdateFormOverridesProps | undefined | null;
+export declare type MyFlexCreateFormProps = React.PropsWithChildren<{
+ overrides?: MyFlexCreateFormOverridesProps | undefined | null;
} & {
- id?: string;
- flex?: Flex0;
- onSubmit?: (fields: MyFlexUpdateFormInputValues) => MyFlexUpdateFormInputValues;
- onSuccess?: (fields: MyFlexUpdateFormInputValues) => void;
- onError?: (fields: MyFlexUpdateFormInputValues, errorMessage: string) => void;
+ clearOnSuccess?: boolean;
+ onSubmit?: (fields: MyFlexCreateFormInputValues) => MyFlexCreateFormInputValues;
+ onSuccess?: (fields: MyFlexCreateFormInputValues) => void;
+ onError?: (fields: MyFlexCreateFormInputValues, errorMessage: string) => void;
onCancel?: () => void;
- onChange?: (fields: MyFlexUpdateFormInputValues) => MyFlexUpdateFormInputValues;
- onValidate?: MyFlexUpdateFormValidationValues;
+ onChange?: (fields: MyFlexCreateFormInputValues) => MyFlexCreateFormInputValues;
+ onValidate?: MyFlexCreateFormValidationValues;
} & React.CSSProperties>;
-export default function MyFlexUpdateForm(props: MyFlexUpdateFormProps): React.ReactElement;
+export default function MyFlexCreateForm(props: MyFlexCreateFormProps): React.ReactElement;
"
`;
@@ -6993,6 +6982,7 @@ export default function InputGalleryUpdateForm(props) {
children=\\"Reset\\"
type=\\"reset\\"
onClick={resetStateValues}
+ isDisabled={!(id || inputGallery)}
{...getOverrideProps(overrides, \\"ResetButton\\")}
>
e?.hasError)}
+ isDisabled={
+ !(id || inputGallery) ||
+ Object.values(errors).some((e) => e?.hasError)
+ }
{...getOverrideProps(overrides, \\"SubmitButton\\")}
>
diff --git a/packages/codegen-ui-react/lib/forms/form-renderer-helper.ts b/packages/codegen-ui-react/lib/forms/form-renderer-helper.ts
index 7ae321582..ee31beb52 100644
--- a/packages/codegen-ui-react/lib/forms/form-renderer-helper.ts
+++ b/packages/codegen-ui-react/lib/forms/form-renderer-helper.ts
@@ -143,6 +143,9 @@ export const createValidationExpression = (validationRules: FieldValidationConfi
export const addFormAttributes = (component: StudioComponent | StudioComponentChild, formMetadata: FormMetadata) => {
const { name: componentName, componentType } = component;
+ const {
+ dataType: { dataTypeName },
+ } = formMetadata;
const attributes: JsxAttribute[] = [];
/*
boolean => RadioGroupField
@@ -242,54 +245,136 @@ export const addFormAttributes = (component: StudioComponent | StudioComponentCh
factory.createJsxExpression(undefined, resetValuesName),
),
);
+ if (formMetadata.formActionType === 'update' && formMetadata.dataType.dataSourceType === 'DataStore') {
+ attributes.push(
+ factory.createJsxAttribute(
+ factory.createIdentifier('isDisabled'),
+ factory.createJsxExpression(
+ undefined,
+ factory.createPrefixUnaryExpression(
+ SyntaxKind.ExclamationToken,
+ factory.createParenthesizedExpression(
+ factory.createBinaryExpression(
+ factory.createIdentifier('id'),
+ factory.createToken(SyntaxKind.BarBarToken),
+ factory.createIdentifier(lowerCaseFirst(dataTypeName)),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
}
if (componentName === 'SubmitButton') {
- attributes.push(
- factory.createJsxAttribute(
- factory.createIdentifier('isDisabled'),
- factory.createJsxExpression(
- undefined,
- factory.createCallExpression(
- factory.createPropertyAccessExpression(
+ if (formMetadata.formActionType === 'update' && formMetadata.dataType.dataSourceType === 'DataStore') {
+ attributes.push(
+ factory.createJsxAttribute(
+ factory.createIdentifier('isDisabled'),
+ factory.createJsxExpression(
+ undefined,
+ factory.createBinaryExpression(
+ factory.createPrefixUnaryExpression(
+ SyntaxKind.ExclamationToken,
+ factory.createParenthesizedExpression(
+ factory.createBinaryExpression(
+ factory.createIdentifier('id'),
+ factory.createToken(SyntaxKind.BarBarToken),
+ factory.createIdentifier(lowerCaseFirst(dataTypeName)),
+ ),
+ ),
+ ),
+ SyntaxKind.BarBarToken,
factory.createCallExpression(
factory.createPropertyAccessExpression(
- factory.createIdentifier('Object'),
- factory.createIdentifier('values'),
+ factory.createCallExpression(
+ factory.createPropertyAccessExpression(
+ factory.createIdentifier('Object'),
+ factory.createIdentifier('values'),
+ ),
+ undefined,
+ [factory.createIdentifier('errors')],
+ ),
+ factory.createIdentifier('some'),
),
undefined,
- [factory.createIdentifier('errors')],
- ),
- factory.createIdentifier('some'),
- ),
- undefined,
- [
- factory.createArrowFunction(
- undefined,
- undefined,
[
- factory.createParameterDeclaration(
- undefined,
- undefined,
- undefined,
- factory.createIdentifier('e'),
+ factory.createArrowFunction(
undefined,
undefined,
+ [
+ factory.createParameterDeclaration(
+ undefined,
+ undefined,
+ undefined,
+ factory.createIdentifier('e'),
+ undefined,
+ undefined,
+ undefined,
+ ),
+ ],
undefined,
+ factory.createToken(SyntaxKind.EqualsGreaterThanToken),
+ factory.createPropertyAccessChain(
+ factory.createIdentifier('e'),
+ factory.createToken(SyntaxKind.QuestionDotToken),
+ factory.createIdentifier('hasError'),
+ ),
),
],
- undefined,
- factory.createToken(SyntaxKind.EqualsGreaterThanToken),
- factory.createPropertyAccessChain(
- factory.createIdentifier('e'),
- factory.createToken(SyntaxKind.QuestionDotToken),
- factory.createIdentifier('hasError'),
+ ),
+ ),
+ ),
+ ),
+ );
+ } else {
+ attributes.push(
+ factory.createJsxAttribute(
+ factory.createIdentifier('isDisabled'),
+ factory.createJsxExpression(
+ undefined,
+ factory.createCallExpression(
+ factory.createPropertyAccessExpression(
+ factory.createCallExpression(
+ factory.createPropertyAccessExpression(
+ factory.createIdentifier('Object'),
+ factory.createIdentifier('values'),
+ ),
+ undefined,
+ [factory.createIdentifier('errors')],
),
+ factory.createIdentifier('some'),
),
- ],
+ undefined,
+ [
+ factory.createArrowFunction(
+ undefined,
+ undefined,
+ [
+ factory.createParameterDeclaration(
+ undefined,
+ undefined,
+ undefined,
+ factory.createIdentifier('e'),
+ undefined,
+ undefined,
+ undefined,
+ ),
+ ],
+ undefined,
+ factory.createToken(SyntaxKind.EqualsGreaterThanToken),
+ factory.createPropertyAccessChain(
+ factory.createIdentifier('e'),
+ factory.createToken(SyntaxKind.QuestionDotToken),
+ factory.createIdentifier('hasError'),
+ ),
+ ),
+ ],
+ ),
),
),
- ),
- );
+ );
+ }
}
if (componentName === 'CancelButton') {
attributes.push(
diff --git a/packages/codegen-ui/example-schemas/forms/flex-datastore-create.json b/packages/codegen-ui/example-schemas/forms/flex-datastore-create.json
index b08063adf..f34857b48 100644
--- a/packages/codegen-ui/example-schemas/forms/flex-datastore-create.json
+++ b/packages/codegen-ui/example-schemas/forms/flex-datastore-create.json
@@ -1,6 +1,6 @@
{
- "name": "MyFlexUpdateForm",
- "formActionType": "update",
+ "name": "MyFlexCreateForm",
+ "formActionType": "create",
"dataType": {
"dataSourceType": "DataStore",
"dataTypeName": "Flex"
diff --git a/packages/codegen-ui/lib/types/form/form-metadata.ts b/packages/codegen-ui/lib/types/form/form-metadata.ts
index 21768b201..42a5b92ae 100644
--- a/packages/codegen-ui/lib/types/form/form-metadata.ts
+++ b/packages/codegen-ui/lib/types/form/form-metadata.ts
@@ -22,6 +22,17 @@ import { FormStyleConfig, StudioFormStyle } from './style';
*/
export type StudioFormActionType = 'create' | 'update';
+export type StudioDataSourceType = 'DataStore' | 'Custom';
+
+/**
+ * Data type definition for StudioForm
+ */
+export type StudioFormDataType = {
+ dataSourceType: StudioDataSourceType;
+
+ dataTypeName: string;
+};
+
export type FieldConfigMetadata = {
// ex. name field has a string validation type where the rule is char length > 5
validationRules: FieldValidationConfiguration[];
@@ -37,6 +48,7 @@ export type FieldConfigMetadata = {
export type FormMetadata = {
id?: string;
formActionType: StudioFormActionType;
+ dataType: StudioFormDataType;
name: string;
fieldConfigs: Record;
layoutConfigs: Record;
diff --git a/packages/codegen-ui/lib/types/form/index.ts b/packages/codegen-ui/lib/types/form/index.ts
index 542aee7fe..1ad3edb5a 100644
--- a/packages/codegen-ui/lib/types/form/index.ts
+++ b/packages/codegen-ui/lib/types/form/index.ts
@@ -21,18 +21,13 @@ import { FormDefinition, ModelFieldsConfigs, FieldTypeMapKeys, ButtonConfig } fr
import { StudioFieldInputConfig, StudioFormValueMappings } from './input-config';
import { StudioFieldPosition } from './position';
import { StudioFormCTA } from './form-cta';
-import { FormMetadata, FieldConfigMetadata, StudioFormActionType } from './form-metadata';
-
-export type StudioDataSourceType = 'DataStore' | 'Custom';
-
-/**
- * Data type definition for StudioForm
- */
-export type StudioFormDataType = {
- dataSourceType: StudioDataSourceType;
-
- dataTypeName: string;
-};
+import {
+ FormMetadata,
+ FieldConfigMetadata,
+ StudioFormActionType,
+ StudioFormDataType,
+ StudioDataSourceType,
+} from './form-metadata';
/**
* This is the base type for all StudioForms
@@ -86,6 +81,7 @@ export type {
SectionalElement,
StudioFormFieldConfig,
StudioFormActionType,
+ StudioDataSourceType,
FormDefinition,
FormMetadata,
FieldConfigMetadata,
diff --git a/packages/codegen-ui/lib/utils/form-component-metadata.ts b/packages/codegen-ui/lib/utils/form-component-metadata.ts
index 58405238a..bdbedda49 100644
--- a/packages/codegen-ui/lib/utils/form-component-metadata.ts
+++ b/packages/codegen-ui/lib/utils/form-component-metadata.ts
@@ -66,6 +66,7 @@ export const mapFormMetadata = (form: StudioForm, formDefinition: FormDefinition
id: form.id,
name: form.name,
formActionType: form.formActionType,
+ dataType: form.dataType,
layoutConfigs: formDefinition.form.layoutStyle,
fieldConfigs: inputElementEntries.reduce>((configs, [name, config]) => {
const updatedConfigs = configs;