Skip to content

Commit

Permalink
sc-11501 Refactor the add new managed modal (#919)
Browse files Browse the repository at this point in the history
Co-authored-by: Cletus Razakou <[email protected]>
  • Loading branch information
elysee15 and masskoder authored Nov 29, 2022
1 parent e48cadb commit 69823bf
Show file tree
Hide file tree
Showing 5 changed files with 380 additions and 298 deletions.
97 changes: 97 additions & 0 deletions web/gds-user-ui/src/components/AddNewVaspForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { Stack, chakra, ModalFooter, Button, Text } from '@chakra-ui/react';
import { Trans } from '@lingui/macro';
import React from 'react';
import { SubmitHandler, useFormContext } from 'react-hook-form';
import CheckboxFormControl from './ui/CheckboxFormControl';
import InputFormControl from './ui/InputFormControl';

type AddNewVaspFormProps = {
onSubmit: SubmitHandler<any>;
isCreatingVasp: boolean;
closeModal: () => void;
};

function AddNewVaspForm({ onSubmit, isCreatingVasp, closeModal }: AddNewVaspFormProps) {
const {
handleSubmit,
register,
watch,
formState: { errors }
} = useFormContext();
const accept = watch('accept');

return (
<form onSubmit={handleSubmit(onSubmit)}>
<Text>
<Trans>
Please input the name of the new managed Virtual Asset Service Provider (VASP). When the
entity is created, you will have the ability to add collaborators, start and complete the
certificate registration process, and manage the VASP account. Please acknowledge below
and provide the name of the entity.
</Trans>
</Text>

<Stack pt={4}>
<InputFormControl
controlId="name"
isInvalid={!!errors.name}
data-testid="name"
formHelperText={errors.name?.message}
isDisabled={!accept || isCreatingVasp}
{...register('name')}
label={
<>
<chakra.span fontWeight={700}>
<Trans>VASP Name</Trans>
</chakra.span>{' '}
(<Trans>required</Trans>)
</>
}
/>
<InputFormControl
controlId="domain"
isInvalid={!!errors.domain}
data-testid="domain"
formHelperText={errors.domain?.message}
isDisabled={!accept || isCreatingVasp}
placeholder="https://"
{...register('domain')}
label={
<>
<chakra.span fontWeight={700}>
<Trans>VASP Domain</Trans>
</chakra.span>{' '}
(<Trans>required</Trans>)
</>
}
/>
</Stack>
<CheckboxFormControl
controlId="accept"
data-testid="accept"
{...register('accept', { required: true })}
colorScheme="gray">
<Trans>
TRISA is a network of trusted members. I acknowledge that the new VASP has a legitimate
business purpose to join TRISA.
</Trans>
</CheckboxFormControl>
<ModalFooter display="flex" flexDir="column" justifyContent="center" gap={2}>
<Button
isLoading={isCreatingVasp}
bg="orange"
_hover={{ bg: 'orange' }}
type="submit"
minW={150}
isDisabled={!accept || isCreatingVasp}>
<Trans id="Next">Create</Trans>
</Button>
<Button variant="ghost" onClick={closeModal} disabled={isCreatingVasp}>
<Trans id="Cancel">Cancel</Trans>
</Button>
</ModalFooter>
</form>
);
}

export default AddNewVaspForm;
49 changes: 49 additions & 0 deletions web/gds-user-ui/src/components/AddNewVaspModal.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Modal, ModalContent } from '@chakra-ui/react';
import userEvent from '@testing-library/user-event';
import { ReactNode } from 'react';
import { dynamicActivate } from 'utils/i18nLoaderHelper';
import { act, fireEvent, render, screen } from 'utils/test-utils';
import AddNewVaspForm from './AddNewVaspForm';

const ModalWrapper = ({ children }: { children: ReactNode }) => (
<Modal isOpen onClose={jest.fn()}>
<ModalContent>{children}</ModalContent>
</Modal>
);

describe('<AddNewVaspModal />', () => {
beforeEach(() => {
dynamicActivate('en');
});

it('should be disabled when checkbox is unchecked', () => {
render(
<ModalWrapper>
<AddNewVaspForm isCreatingVasp={false} onSubmit={jest.fn()} closeModal={jest.fn()} />
</ModalWrapper>
);

expect(screen.getByTestId('accept').querySelector('input[type="checkbox"]')).not.toBeChecked();

expect(screen.getByTestId('name')).toBeDisabled();
expect(screen.getByTestId('domain')).toBeDisabled();
expect(screen.getByRole('button', { name: /next/i })).toBeDisabled();
});

it('should be enabled when checkbox is checked', () => {
render(
<ModalWrapper>
<AddNewVaspForm isCreatingVasp={false} onSubmit={jest.fn()} closeModal={jest.fn()} />
</ModalWrapper>
);

const acceptElement = screen.getByTestId('accept').querySelector('input[type="checkbox"]');
userEvent.click(acceptElement!);

expect(screen.getByTestId('accept').querySelector('input[type="checkbox"]')).toBeChecked();

expect(screen.getByTestId('name')).toBeEnabled();
expect(screen.getByTestId('domain')).toBeEnabled();
expect(screen.getByRole('button', { name: /next/i })).toBeEnabled();
});
});
101 changes: 17 additions & 84 deletions web/gds-user-ui/src/components/AddNewVaspModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,19 @@ import {
Modal,
ModalBody,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
Stack,
Text,
useDisclosure,
chakra,
useToast
} from '@chakra-ui/react';
import { t, Trans } from '@lingui/macro';
import { usePostOrganizations } from 'modules/dashboard/organization/usePostOrganization';
import { FormProvider, useForm } from 'react-hook-form';
import CheckboxFormControl from './ui/CheckboxFormControl';
import InputFormControl from './ui/InputFormControl';
import * as Yup from 'yup';
import { yupResolver } from '@hookform/resolvers/yup';
import { queryClient } from 'utils/react-query';
import { FETCH_ORGANIZATION } from 'constants/query-keys';
import AddNewVaspForm from './AddNewVaspForm';

const validationSchema = Yup.object().shape({
name: Yup.string().required(t`The VASP Name is required.`),
Expand All @@ -30,7 +25,7 @@ const validationSchema = Yup.object().shape({
});

function AddNewVaspModal() {
const { isOpen, onOpen, onClose } = useDisclosure();
const { isOpen, onOpen, onClose: closeModal } = useDisclosure();
const methods = useForm({
defaultValues: {
name: '',
Expand All @@ -41,26 +36,22 @@ function AddNewVaspModal() {
resolver: yupResolver(validationSchema)
});
const {
register,
watch,
handleSubmit,
reset,
formState: { errors, isSubmitting }
formState: { isSubmitting }
} = methods;
const { mutate, isLoading } = usePostOrganizations();
const toast = useToast();
const isCreatingVasp = isSubmitting || isLoading;

const accept = watch('accept');
const onSubmit = (values: any) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { accept: _accept, ...payload } = values;
const { accept, ...payload } = values;

mutate(payload, {
onSuccess() {
queryClient.invalidateQueries([FETCH_ORGANIZATION]);
reset();
onClose();
closeModal();
},
onError: (error) => {
console.log('[mutate] error', error.response?.data.error);
Expand All @@ -75,82 +66,24 @@ function AddNewVaspModal() {

return (
<>
<Button onClick={onOpen}>+ Add New VASP</Button>
<Button onClick={onOpen}>
+ <Trans>Add New VASP</Trans>
</Button>

<Modal blockScrollOnMount isOpen={isOpen} onClose={onClose}>
<Modal blockScrollOnMount isOpen={isOpen} onClose={closeModal}>
<ModalOverlay />
<ModalContent>
<ModalHeader textAlign="center">Modal Title</ModalHeader>
<ModalHeader textAlign="center" textTransform="capitalize">
<Trans>Add new managed VASP</Trans>
</ModalHeader>

<ModalBody>
<FormProvider {...methods}>
<form onSubmit={handleSubmit(onSubmit)}>
<Text>
<Trans>
Please input the name of the new managed Virtual Asset Service Provider (VASP).
When the entity is created, you will have the ability to add collaborators,
start and complete the certificate registration process, and manage the VASP
account. Please acknowledge below and provide the name of the entity.
</Trans>
</Text>
<CheckboxFormControl
controlId="accept"
{...register('accept', { required: true })}
colorScheme="gray">
<Trans>
TRISA is a network of trusted members. I acknowledge that the new VASP has a
legitimate business purpose to join TRISA.
</Trans>
</CheckboxFormControl>
<Stack py={5}>
<InputFormControl
controlId="name"
isInvalid={!!errors.name}
data-testid="name"
formHelperText={errors.name?.message}
isDisabled={!accept}
{...register('name')}
label={
<>
<chakra.span fontWeight={700}>
<Trans>VASP Name</Trans>
</chakra.span>{' '}
(<Trans>required</Trans>)
</>
}
/>
<InputFormControl
controlId="domain"
isInvalid={!!errors.domain}
data-testid="domain"
formHelperText={errors.domain?.message}
isDisabled={!accept}
placeholder="https://"
{...register('domain')}
label={
<>
<chakra.span fontWeight={700}>
<Trans>VASP Domain</Trans>
</chakra.span>{' '}
(<Trans>required</Trans>)
</>
}
/>
</Stack>
<ModalFooter display="flex" flexDir="column" justifyContent="center" gap={2}>
<Button
bg="orange"
_hover={{ bg: 'orange' }}
type="submit"
minW={150}
isDisabled={!accept || isCreatingVasp}>
<Trans id="Next">Create</Trans>
</Button>
<Button variant="ghost" onClick={onClose} disabled={isCreatingVasp}>
<Trans id="Cancel">Cancel</Trans>
</Button>
</ModalFooter>
</form>
<AddNewVaspForm
onSubmit={onSubmit}
isCreatingVasp={isCreatingVasp}
closeModal={closeModal}
/>
</FormProvider>
</ModalBody>
</ModalContent>
Expand Down
Loading

0 comments on commit 69823bf

Please sign in to comment.