Skip to content

Commit

Permalink
Form Submission - UseMutation Refactor - 2 retries; style: secondary …
Browse files Browse the repository at this point in the history
…button - pipe - changed to the proper color (#746)

closes #507 
closes #463 
closes #763 

## Changes
- enhancement: Adds a `react-query` useMutation wrapper around many of
the form submissions that adds a retry to combat the 503/504 issues on
deployment
- style: secondary button - right icon vertical bar - changed to the
proper color

## Screenshot - secondary button - right icon vertical bar
|Before|After|
|--|--|
|<img width="1038" alt="Screenshot 2024-06-24 at 4 49 58 PM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/2ac98413-99c2-4dac-8843-a3c7d058218c">|<img
width="378" alt="Screenshot 2024-06-24 at 4 48 59 PM"
src="https://github.com/cfpb/sbl-frontend/assets/13324863/eff5dbe3-5ff6-4146-b30b-c6d7cced29a5">|
  • Loading branch information
shindigira authored Jun 25, 2024
1 parent 14f446b commit e8dc535
Show file tree
Hide file tree
Showing 18 changed files with 360 additions and 157 deletions.
190 changes: 95 additions & 95 deletions .pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
5 changes: 1 addition & 4 deletions src/api/requests/createFiling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ export const createFiling = async (
lei: string,
filingPeriod: FilingPeriodType,
): Promise<FilingType> => {
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
return request<FilingType>({
return request<undefined, FilingType>({
axiosInstance: filingApiClient,
url: `/v1/filing/institutions/${lei}/filings/${filingPeriod}`,
method: 'post',
headers: { Authorization: `Bearer ${auth.user?.access_token}` },
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
body: 'no-body',
});
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { filingApiClient, request } from 'api/axiosService';
import type { SblAuthProperties } from 'api/useSblAuth';
import type { SubmissionResponse } from 'types/filingTypes';
import type { FilingPeriodType } from 'types/filingTypes';

interface Parameters {
lei: string;
filingPeriod: string;
submissionId: number;
filingPeriod: FilingPeriodType;
submissionId: number | undefined;
}

const submitWarningsAccept = async (
Expand All @@ -15,7 +15,7 @@ const submitWarningsAccept = async (
if (![lei, filingPeriod, submissionId].every(Boolean))
throw new Error('submitWarningsAccept: Missing required parameter');

return request<Partial<SubmissionResponse>, null>({
return request<undefined, null>({
axiosInstance: filingApiClient,
url: `/v1/filing/institutions/${lei}/filings/${filingPeriod}/submissions/${submissionId}/accept`,
method: 'put',
Expand Down
17 changes: 17 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,21 @@ https://v1.tailwindcss.com/docs/adding-base-styles#using-css */
@apply border-pacific;
}

.a-btn.a-btn__secondary .a-btn_icon__on-right{
@apply border-pacific;
}

.a-btn.a-btn__secondary:hover {
@apply border-pacificDark bg-white text-pacificDark;
}

.a-btn.a-btn__secondary:hover .a-btn_icon__on-left {
@apply border-pacificDark;
}

.a-btn.a-btn__secondary:hover .a-btn_icon__on-right {
@apply border-pacificDark;
}

.a-btn.a-btn__secondary:focus {
@apply border-pacificDark bg-white text-pacificDark outline-pacificDark;
Expand All @@ -44,6 +52,10 @@ https://v1.tailwindcss.com/docs/adding-base-styles#using-css */
.a-btn.a-btn__secondary:focus .a-btn_icon__on-left {
@apply border-pacificDark;
}

.a-btn.a-btn__secondary:focus .a-btn_icon__on-right {
@apply border-pacificDark;
}

.a-btn.a-btn__secondary:active {
@apply border-navy bg-white text-navy;
Expand All @@ -52,6 +64,11 @@ https://v1.tailwindcss.com/docs/adding-base-styles#using-css */
.a-btn.a-btn__secondary:active .a-btn_icon__on-left {
@apply border-navy;
}

.a-btn.a-btn__secondary:active .a-btn_icon__on-right {
@apply border-navy;
}

}

select.error {
Expand Down
33 changes: 17 additions & 16 deletions src/pages/Filing/FilingApp/FilingWarnings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { useQueryClient } from '@tanstack/react-query';
import submitWarningsAccept from 'api/requests/submitWarningsVerified';
import useSblAuth from 'api/useSblAuth';
import FormButtonGroup from 'components/FormButtonGroup';
import FormHeaderWrapper from 'components/FormHeaderWrapper';
import FormWrapper from 'components/FormWrapper';
Expand All @@ -22,6 +20,7 @@ import { FileSubmissionState } from 'types/filingTypes';
import { sblHelpMail } from 'utils/common';
import useGetSubmissionLatest from 'utils/useGetSubmissionLatest';
import useInstitutionDetails from 'utils/useInstitutionDetails';
import useSubmitWarningsAccept from 'utils/useSubmitWarningsAccept';
import FieldSummary from '../FieldSummary';
import { getErrorsWarningsSummary } from '../FilingErrors/FilingErrors.helpers';
import FilingFieldLinks from '../FilingFieldLinks';
Expand All @@ -38,11 +37,9 @@ const isSubmissionAccepted = (submission?: SubmissionResponse): boolean => {

function FilingWarnings(): JSX.Element {
const navigate = useNavigate();
const auth = useSblAuth();
const queryClient = useQueryClient();
const { lei, year } = useParams();
const [boxChecked, setBoxChecked] = useState(false);
const [formSubmitLoading, setFormSubmitLoading] = useState(false);
const [formSubmitError, setFormSubmitError] = useState(false);
const [hasVerifyError, setHasVerifyError] = useState(false);

Expand Down Expand Up @@ -90,6 +87,16 @@ function FilingWarnings(): JSX.Element {
setBoxChecked(!boxChecked);
};

const {
mutateAsync: mutateSubmitWarningsAccept,
isLoading: isLoadingSubmitWarningsAccept,
} = useSubmitWarningsAccept({
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
lei,
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
filingPeriod: year,
});

const onFormSubmit = async (): Promise<void> => {
const nextPage = `/filing/${year}/${lei}/contact`;

Expand All @@ -108,15 +115,7 @@ function FilingWarnings(): JSX.Element {
return;
}

setFormSubmitLoading(true); // Show loading indicator

// TODO: Refactor to use useMutation
const response = await submitWarningsAccept(auth, {
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
lei,
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
filingPeriod: year,
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
const response = await mutateSubmitWarningsAccept({
submissionId: submission?.id,
});

Expand All @@ -127,7 +126,6 @@ function FilingWarnings(): JSX.Element {
});
navigate(nextPage);
} else {
setFormSubmitLoading(false); // Clear loading indicator
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
setFormSubmitError(response); // Display error alert
}
Expand Down Expand Up @@ -234,7 +232,10 @@ function FilingWarnings(): JSX.Element {
label='I verify the accuracy of register values flagged by warning validations and no corrections are required.'
onChange={onClickCheckbox}
checked={isVerified}
disabled={formSubmitLoading || isSubmissionAccepted(submission)}
disabled={
isLoadingSubmitWarningsAccept ||
isSubmissionAccepted(submission)
}
status={hasVerifyError ? 'error' : undefined}
/>
{hasVerifyError ? (
Expand Down Expand Up @@ -273,7 +274,7 @@ function FilingWarnings(): JSX.Element {
onPreviousClick={onPreviousClick}
onNextClick={onFormSubmit}
appearanceNext={canContinue ? 'primary' : 'secondary'}
isLoading={formSubmitLoading}
isLoading={isLoadingSubmitWarningsAccept}
/>
</FormButtonGroup>
</FormWrapper>
Expand Down
23 changes: 12 additions & 11 deletions src/pages/Filing/UpdateFinancialProfile/UfpForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { zodResolver } from '@hookform/resolvers/zod';
import submitUpdateFinancialProfile, {
collectChangedData,
} from 'api/requests/submitUpdateFinancialProfile';
import useSblAuth from 'api/useSblAuth';
import { collectChangedData } from 'api/requests/submitUpdateFinancialProfile';
import Button from 'components/Button';
import CrumbTrail from 'components/CrumbTrail';
import FormButtonGroup from 'components/FormButtonGroup';
Expand All @@ -18,13 +15,14 @@ import type { UpdateInstitutionType } from 'pages/Filing/UpdateFinancialProfile/
import { UpdateInstitutionSchema } from 'pages/Filing/UpdateFinancialProfile/types';
import { scrollToElement } from 'pages/ProfileForm/ProfileFormUtils';
import { scenarios } from 'pages/Summary/Summary.data';
import { useMemo, useState } from 'react';
import { useMemo } from 'react';
import { useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import type { InstitutionDetailsApiType } from 'types/formTypes';
import { Five } from 'utils/constants';
import { updateFinancialProfileKeyLogic } from 'utils/getFormErrorKeyLogic';
import getIsRoutingEnabled from 'utils/getIsRoutingEnabled';
import useSubmitUpdateFinancialProfile from 'utils/useSubmitUpdateFinancialProfile';
import FinancialInstitutionDetailsForm from './FinancialInstitutionDetailsForm';
import UpdateAffiliateInformation from './UpdateAffiliateInformation';
import UpdateIdentifyingInformation from './UpdateIdentifyingInformation';
Expand All @@ -37,10 +35,8 @@ export default function UFPForm({
data: InstitutionDetailsApiType;
}): JSXElement {
const { lei } = useParams();
const auth = useSblAuth();
const isRoutingEnabled = getIsRoutingEnabled();
const navigate = useNavigate();
const [loading, setLoading] = useState(false);

const defaultValues = useMemo(() => buildProfileFormDefaults(data), [data]);

Expand All @@ -61,6 +57,11 @@ export default function UFPForm({
// Used for error scrolling
const formErrorHeaderId = 'UFPFormErrorHeader';

const {
mutateAsync: mutateSubmitUpdateFinancialProfile,
isLoading: isLoadingSubmitUpdateFinancialProfile,
} = useSubmitUpdateFinancialProfile();

// NOTE: This function is used for submitting the multipart/formData
const onSubmitButtonAction = async (): Promise<void> => {
const passesValidation = await trigger();
Expand All @@ -74,9 +75,9 @@ export default function UFPForm({
);
}
try {
setLoading(true);
await submitUpdateFinancialProfile(auth, changedData);
setLoading(false);
await mutateSubmitUpdateFinancialProfile({
financialProfileObject: changedData,
});
if (isRoutingEnabled)
navigate('/summary', {
state: { scenario: scenarios.SuccessInstitutionProfileUpdate },
Expand Down Expand Up @@ -161,7 +162,7 @@ export default function UFPForm({
appearance='primary'
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onClick={onSubmitButtonAction}
iconRight={loading ? 'updating' : ''}
iconRight={isLoadingSubmitUpdateFinancialProfile ? 'updating' : ''}
disabled={!changedData}
type='submit'
/>
Expand Down
19 changes: 9 additions & 10 deletions src/pages/PointOfContact/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import { normalKeyLogic } from 'utils/getFormErrorKeyLogic';

import { zodResolver } from '@hookform/resolvers/zod';
import { useQueryClient } from '@tanstack/react-query';
import submitPointOfContact from 'api/requests/submitPointOfContact';
import useSblAuth from 'api/useSblAuth';
import FormErrorHeader from 'components/FormErrorHeader';
import type { PocFormHeaderErrorsType } from 'components/FormErrorHeader.data';
import { PocFormHeaderErrors } from 'components/FormErrorHeader.data';
Expand Down Expand Up @@ -45,6 +43,7 @@ import { ContactInfoMap, pointOfContactSchema } from 'types/formTypes';
import useAddressStates from 'utils/useAddressStates';
import useFilingStatus from 'utils/useFilingStatus';
import useInstitutionDetails from 'utils/useInstitutionDetails';
import useSubmitPointOfContact from 'utils/useSubmitPointOfContact';

const defaultValuesPOC = {
firstName: '',
Expand All @@ -63,7 +62,6 @@ const defaultValuesPOC = {
function PointOfContact(): JSX.Element {
const [previousContactInfoValid, setPreviousContactInfoValid] =
useState<boolean>(false);
const auth = useSblAuth();
const queryClient = useQueryClient();
const navigate = useNavigate();
const { lei, year } = useParams();
Expand Down Expand Up @@ -155,6 +153,13 @@ function PointOfContact(): JSX.Element {
const navigateSignSubmit = (): void =>
navigate(`/filing/${year}/${lei}/submit`);

const { mutateAsync: mutateSubmitPointOfContact } = useSubmitPointOfContact({
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
lei,
// @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
filingPeriod: year,
});

// NOTE: This function is used for submitting the multipart/formData
const onSubmitButtonAction = async (
event: React.FormEvent,
Expand All @@ -175,13 +180,7 @@ function PointOfContact(): JSX.Element {
const formattedUserProfileObject =
formatPointOfContactObject(preFormattedData);

await submitPointOfContact(auth, {
data: formattedUserProfileObject,
// @ts-expect-error @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
lei,
// @ts-expect-error @ts-expect-error Part of code cleanup for post-mvp see: https://github.com/cfpb/sbl-frontend/issues/717
filingPeriod: year,
});
await mutateSubmitPointOfContact({ data: formattedUserProfileObject });

await queryClient.invalidateQueries({
queryKey: [`fetch-filing-submission`, lei, year],
Expand Down
14 changes: 10 additions & 4 deletions src/pages/ProfileForm/CreateProfileForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { validationSchemaCPF } from 'types/formTypes';
import Step1FormInfoFieldGroup from '../Step1Form/Step1FormInfoFieldGroup';
import AddFinancialInstitution from './AddFinancialInstitution';

import { submitUserProfile, submitUserProfileFi } from 'api/requests';
import { scenarios } from 'pages/Summary/Summary.data';

import { useNavigate } from 'react-router-dom';
Expand All @@ -39,10 +38,12 @@ import { sblHelpMail } from 'utils/common';
import { One } from 'utils/constants';
import { normalKeyLogic } from 'utils/getFormErrorKeyLogic';

import useSubmitUserProfile from 'utils/useSubmitUserProfile';
import useSubmitUserProfileFi from 'utils/useSubmitUserProfileFi';

function CreateProfileForm(): JSX.Element {
const navigate = useNavigate();
const { emailAddress } = useSblAuth();
const auth = useSblAuth();
const formErrorHeaderId = 'CreateProfileFormErrors';
const defaultValues: ValidationSchemaCPF = {
firstName: '',
Expand Down Expand Up @@ -73,6 +74,9 @@ function CreateProfileForm(): JSX.Element {
const onAppendFinancialInstitutions = (): void =>
append(emptyAddFinancialInstitution);

const { mutateAsync: mutateSubmitUserProfile } = useSubmitUserProfile();
const { mutateAsync: mutateSubmitUserProfileFi } = useSubmitUserProfileFi();

const onSubmitButtonAction = async (): Promise<void> => {
const passesValidation = await trigger();
if (passesValidation) {
Expand All @@ -86,9 +90,11 @@ function CreateProfileForm(): JSX.Element {
},
false,
);
await submitUserProfile(auth, formattedUserProfileObject);
await mutateSubmitUserProfile({
userProfileObject: formattedUserProfileObject,
});
// 2.) Sending the financial institutions list to the mail api
await submitUserProfileFi(auth, preFormattedData);
await mutateSubmitUserProfileFi({ formFieldsObject: preFormattedData });
navigate('/summary', { state: { scenario: scenarios.Warning4 } });
} catch (error) {
// eslint-disable-next-line no-console
Expand Down
15 changes: 6 additions & 9 deletions src/pages/ProfileForm/Step1Form/Step1Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { useQuery, useQueryClient } from '@tanstack/react-query';
import type { CupFormHeaderErrorsType } from 'components/FormErrorHeader.data';
import { CupFormHeaderErrors } from 'components/FormErrorHeader.data';

import { fetchInstitutions, submitUserProfile } from 'api/requests';
import { fetchInstitutions } from 'api/requests';
import FormMain from 'components/FormMain';
import FormWrapper from 'components/FormWrapper';
import {
Expand All @@ -45,6 +45,7 @@ import Step1FormInfoHeader from './Step1FormInfoHeader';
import CrumbTrail from 'components/CrumbTrail';
import { Link } from 'components/Link';
import { useNavigate } from 'react-router-dom';
import useSubmitUserProfile from 'utils/useSubmitUserProfile';

function Step1Form(): JSX.Element {
const queryClient = useQueryClient();
Expand Down Expand Up @@ -155,6 +156,8 @@ function Step1Form(): JSX.Element {
// Used for error scrolling
const formErrorHeaderId = 'step1FormErrorHeader';

const { mutateAsync: mutateSubmitUserProfile } = useSubmitUserProfile();

// Post Submission
const onSubmitButtonAction = async (): Promise<void> => {
// TODO: Handle error UX on submission failure or timeout
Expand All @@ -165,14 +168,8 @@ function Step1Form(): JSX.Element {
userProfileObject,
true,
);
await submitUserProfile(auth, formattedUserProfileObject);
await auth.signinSilent();
// cache busting
await queryClient.invalidateQueries({
queryKey: ['fetch-associated-institutions', email],
});
await queryClient.invalidateQueries({
queryKey: ['fetch-user-profile', email],
await mutateSubmitUserProfile({
userProfileObject: formattedUserProfileObject,
});
navigate('/landing');
} else {
Expand Down
Loading

0 comments on commit e8dc535

Please sign in to comment.