diff --git a/__tests__/unit/backend/helpers/generate-form-data.ts b/__tests__/unit/backend/helpers/generate-form-data.ts index 2730e9b732..9dde071d77 100644 --- a/__tests__/unit/backend/helpers/generate-form-data.ts +++ b/__tests__/unit/backend/helpers/generate-form-data.ts @@ -279,12 +279,15 @@ export const generateNewSingleAnswerResponse = ( customParams?: Partial, ): ProcessedSingleAnswerResponse => { if ( - [BasicField.Attachment, BasicField.Table, BasicField.Checkbox].includes( - fieldType, - ) + [ + BasicField.Attachment, + BasicField.Table, + BasicField.Checkbox, + BasicField.Address, + ].includes(fieldType) ) { throw new Error( - 'Call the custom response generator functions for attachment, table and checkbox.', + 'Call the custom response generator functions for attachment, address, table and checkbox.', ) } return { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index b6f80c5567..6a90def9b8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -18,7 +18,7 @@ "@growthbook/growthbook-react": "^0.17.0", "@hello-pangea/dnd": "^16.6.0", "@loadable/component": "^5.16.4", - "@opengovsg/formsg-sdk": "^0.12.0-alpha.1", + "@opengovsg/formsg-sdk": "^0.13.0", "@stablelib/base64": "^1.0.1", "@stripe/react-stripe-js": "^1.15.0", "@stripe/stripe-js": "^1.44.1", @@ -3215,11 +3215,11 @@ "dev": true }, "node_modules/@opengovsg/formsg-sdk": { - "version": "0.12.0-alpha.1", - "resolved": "https://registry.npmjs.org/@opengovsg/formsg-sdk/-/formsg-sdk-0.12.0-alpha.1.tgz", - "integrity": "sha512-JmkPucmJM87+yALYTT+ZqblI3803ToWxgpeqCV92Tibeks6xqNf2WrBDbsr3WUFUnO27ohfg8XFfsio24kGDig==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@opengovsg/formsg-sdk/-/formsg-sdk-0.13.0.tgz", + "integrity": "sha512-rByyDeR98ubJbNSKk6zy98MmxFsiBqFTJqzLX3lWtQxDAJzcX17PCAdmi9U89riNff1H86yyCUvNtlUUJIVnDw==", "dependencies": { - "axios": "^1.6.2", + "axios": "^1.6.4", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1" } @@ -21362,11 +21362,11 @@ "dev": true }, "@opengovsg/formsg-sdk": { - "version": "0.12.0-alpha.1", - "resolved": "https://registry.npmjs.org/@opengovsg/formsg-sdk/-/formsg-sdk-0.12.0-alpha.1.tgz", - "integrity": "sha512-JmkPucmJM87+yALYTT+ZqblI3803ToWxgpeqCV92Tibeks6xqNf2WrBDbsr3WUFUnO27ohfg8XFfsio24kGDig==", + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/@opengovsg/formsg-sdk/-/formsg-sdk-0.13.0.tgz", + "integrity": "sha512-rByyDeR98ubJbNSKk6zy98MmxFsiBqFTJqzLX3lWtQxDAJzcX17PCAdmi9U89riNff1H86yyCUvNtlUUJIVnDw==", "requires": { - "axios": "^1.6.2", + "axios": "^1.6.4", "tweetnacl": "^1.0.3", "tweetnacl-util": "^0.15.1" } diff --git a/frontend/package.json b/frontend/package.json index 13c4803743..d384232cf8 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,7 +14,7 @@ "@growthbook/growthbook-react": "^0.17.0", "@hello-pangea/dnd": "^16.6.0", "@loadable/component": "^5.16.4", - "@opengovsg/formsg-sdk": "^0.12.0-alpha.1", + "@opengovsg/formsg-sdk": "^0.13.0", "@stablelib/base64": "^1.0.1", "@stripe/react-stripe-js": "^1.15.0", "@stripe/stripe-js": "^1.44.1", diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx index 55636375cc..67a1b7f96e 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignContent/FieldRow/FieldRowContainer.tsx @@ -23,6 +23,7 @@ import { useToast } from '~hooks/useToast' import IconButton from '~components/IconButton' import Tooltip from '~components/Tooltip' import { + AddressCompoundField, AttachmentField, CheckboxField, ChildrenCompoundField, @@ -512,5 +513,7 @@ const FieldRow = ({ field, ...rest }: FieldRowProps) => { return case BasicField.Children: return + case BasicField.Address: + return } } diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/EditFieldDrawer.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/EditFieldDrawer.tsx index aaddf23aac..169cb46daa 100644 --- a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/EditFieldDrawer.tsx +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/EditFieldDrawer.tsx @@ -26,6 +26,7 @@ import { EditMyInfoChildren, } from './edit-fieldtype/EditMyInfoChildren' import { + EditAddress, EditAttachment, EditCheckbox, EditCountryRegion, @@ -167,6 +168,8 @@ export const MemoFieldDrawerContent = memo( return case BasicField.Image: return + case BasicField.Address: + return default: return
TODO: Insert field options here
} diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.stories.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.stories.tsx new file mode 100644 index 0000000000..ee8815ec5a --- /dev/null +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.stories.tsx @@ -0,0 +1,57 @@ +import { Meta, StoryFn } from '@storybook/react' + +import { AddressCompoundFieldBase, BasicField } from '~shared/types' + +import { createFormBuilderMocks } from '~/mocks/msw/handlers/admin-form' + +import { EditFieldDrawerDecorator, StoryRouter } from '~utils/storybook' + +import { EditAddress, EditAddressProps } from './EditAddress' + +const DEFAULT_ADDRESS_FIELD: AddressCompoundFieldBase = { + title: 'Local address', + description: '', + required: true, + disabled: false, + fieldType: BasicField.Address, + globalId: 'unused', +} + +export default { + title: 'Features/AdminForm/EditFieldDrawer/EditAddress', + component: EditAddress, + decorators: [ + StoryRouter({ + initialEntries: ['/61540ece3d4a6e50ac0cc6ff'], + path: '/:formId', + }), + EditFieldDrawerDecorator, + ], + parameters: { + // Required so skeleton "animation" does not hide content. + chromatic: { pauseAnimationAtEnd: true }, + msw: createFormBuilderMocks({}, 0), + }, + args: { + field: DEFAULT_ADDRESS_FIELD, + }, +} as Meta + +interface StoryArgs { + field: AddressCompoundFieldBase +} + +const Template: StoryFn = ({ field }) => { + return +} + +export const Default = Template.bind({}) + +export const WithValues = Template.bind({}) +WithValues.args = { + field: { + ...DEFAULT_ADDRESS_FIELD, + title: 'Address Field Title', + description: 'Address Field Description', + }, +} diff --git a/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.tsx b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.tsx new file mode 100644 index 0000000000..69d1f2949e --- /dev/null +++ b/frontend/src/features/admin-form/create/builder-and-design/BuilderAndDesignDrawer/EditFieldDrawer/edit-fieldtype/EditAddress/EditAddress.tsx @@ -0,0 +1,77 @@ +import { useMemo } from 'react' +import { FormControl } from '@chakra-ui/react' +import { extend, pick } from 'lodash' + +import { AddressCompoundFieldBase } from '~shared/types/field' + +import { createBaseValidationRules } from '~utils/fieldValidation' +import FormErrorMessage from '~components/FormControl/FormErrorMessage' +import FormLabel from '~components/FormControl/FormLabel' +import Input from '~components/Input' +import Textarea from '~components/Textarea' +import Toggle from '~components/Toggle' + +import { CreatePageDrawerContentContainer } from '~features/admin-form/create/common' + +import { FormFieldDrawerActions } from '../common/FormFieldDrawerActions' +import { EditFieldProps } from '../common/types' +import { useEditFieldForm } from '../common/useEditFieldForm' + +export type EditAddressProps = EditFieldProps + +type EditAddressInputs = Pick< + AddressCompoundFieldBase, + 'title' | 'description' | 'required' +> + +export const EditAddress = ({ field }: EditAddressProps): JSX.Element => { + const { + register, + formState: { errors }, + getValues, + buttonText, + handleUpdateField, + watch, + control, + clearErrors, + isLoading, + handleCancel, + setValue, + } = useEditFieldForm({ + field, + transform: { + input: (inputField) => + pick(inputField, ['title', 'description', 'required']), + output: (formOutput, originalField) => + extend({}, originalField, formOutput), + }, + }) + + const requiredValidationRule = useMemo( + () => createBaseValidationRules({ required: true }), + [], + ) + return ( + + + Field Name + + {errors?.title?.message} + + + Description +