Skip to content

Commit 90b2261

Browse files
committed
feat(eap-full): add submit for approval functionality for full eap
1 parent 530e3ce commit 90b2261

7 files changed

Lines changed: 189 additions & 66 deletions

File tree

app/src/views/EapFullForm/Overview/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ function Overview(props: Props) {
265265
error={error}
266266
disabled={disabled}
267267
readOnly={readOnly}
268-
withAsteriskOnTitle
268+
withRequiredNameAndEmail
269269
/>
270270
<InputSection
271271
title={strings.partnerNS}
@@ -309,7 +309,7 @@ function Overview(props: Props) {
309309
error={error}
310310
disabled={disabled}
311311
readOnly={readOnly}
312-
withAsteriskOnTitle
312+
withRequiredNameAndEmail
313313
/>
314314
<ContactInputsSection
315315
title={strings.delegation}
@@ -319,7 +319,7 @@ function Overview(props: Props) {
319319
error={error}
320320
disabled={disabled}
321321
readOnly={readOnly}
322-
withAsteriskOnTitle
322+
withRequiredNameAndEmail
323323
/>
324324
</>
325325
<>

app/src/views/EapFullForm/TriggerModel/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,6 @@ function TriggerModel(props: Props) {
424424
<InputSection
425425
title={strings.attachRelevantFilesTitle}
426426
description={strings.attachRelevantFilesDescription}
427-
withAsteriskOnTitle
428427
>
429428
<GoMultiFileInput
430429
name="trigger_model_relevant_files"

app/src/views/EapFullForm/i18n.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@
1919
"successMessage": "Successfully created a new Full EAP!",
2020
"updateFailure": "Sorry could not update Full EAP right now!",
2121
"updateSuccess": "Successfully updated a new Full EAP!",
22+
"submitApprovalSuccess": "Successfully submitted EAP for approval!",
23+
"submitFailedSuccess": "Failed to submit the EAP for approval!",
2224
"backToAccount": "Back",
23-
"readOnlyWarningMessage": "You’re viewing this form in read-only mode. Editing is currently disabled."
25+
"readOnlyWarningMessage": "You’re viewing this form in read-only mode. Editing is currently disabled.",
26+
"validationErrorAlertMessage": "Please fix all the errors before continuing!",
27+
"savingPendingMessage": "Saving data...",
28+
"submitFormErrorMessage": "Please make sure you've filled in all the required details before proceeding!",
29+
"submitButtonLabel": "Submit for approval",
30+
"submitConfirmButtonLabel": "Confirm",
31+
"submitConfirmHeading": "Submit EAP for approval",
32+
"submitConfirmMessage": "Are you sure you want to submit the EAP? Reviewers will be notified and you'll no longer be able to edit the form!"
2433
}
2534
}

app/src/views/EapFullForm/index.tsx

Lines changed: 139 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ import {
1111
useSearchParams,
1212
} from 'react-router-dom';
1313
import {
14+
Alert,
1415
Button,
16+
InlineLayout,
1517
ListView,
18+
Modal,
1619
Tab,
1720
TabList,
1821
TabPanel,
@@ -28,6 +31,7 @@ import {
2831
listToMap,
2932
} from '@togglecorp/fujs';
3033
import {
34+
analyzeErrors,
3135
createSubmitHandler,
3236
removeNull,
3337
useForm,
@@ -40,6 +44,7 @@ import useRouting from '#hooks/useRouting';
4044
import {
4145
EAP_STATUS_NS_ADDRESSING_COMMENTS,
4246
EAP_STATUS_UNDER_DEVELOPMENT,
47+
EAP_STATUS_UNDER_REVIEW,
4348
} from '#utils/constants';
4449
import {
4550
type GoApiBody,
@@ -76,6 +81,8 @@ import i18n from './i18n.json';
7681
type EapFullRequestBody = GoApiBody<'/api/v2/full-eap/', 'POST'>;
7782
type GetFullEapResponse = GoApiResponse<'/api/v2/full-eap/{id}/'>;
7883

84+
type EapStatusBody = GoApiBody<'/api/v2/eap-registration/{id}/status/', 'POST'>;
85+
7986
function getNextStep(current: TabKeys, direction: 1 | -1) {
8087
const tabKeyList: TabKeys[] = [
8188
'overview',
@@ -99,11 +106,16 @@ export function Component() {
99106
const [fileIdToUrlMap, setFileIdToUrlMap] = useState<Record<number, string>>(
100107
{},
101108
);
109+
const [shouldSubmit, setShouldSubmit] = useState(false);
110+
102111
const { eapId } = useParams<{ eapId: string }>();
103112
const [searchParams] = useSearchParams();
113+
104114
const version = searchParams.get('version') ?? undefined;
105-
const formContentRef = useRef<ElementRef<'div'>>(null);
115+
const tabListRef = useRef<ElementRef<'div'>>(null);
116+
106117
const strings = useTranslation(i18n);
118+
107119
const { navigate } = useRouting();
108120

109121
const alert = useAlert();
@@ -556,14 +568,13 @@ export function Component() {
556568
}
557569
}, [fullEapResponse, loadResponseToFormValue]);
558570

559-
const { pending: eapFullPending, trigger: createFullEap } = useLazyRequest({
571+
const { pending: createFullEapPending, trigger: triggerCreateFullEap } = useLazyRequest({
560572
method: 'POST',
561573
url: '/api/v2/full-eap/',
562574
body: (body: EapFullRequestBody) => body,
563575
onSuccess: () => {
564576
const message = strings.successMessage;
565577
alert.show(message, { variant: 'success' });
566-
navigate('accountMyFormsEap');
567578
},
568579
onFailure: (err) => {
569580
const {
@@ -579,18 +590,15 @@ export function Component() {
579590
},
580591
});
581592

582-
const { pending: updateFullFormPending, trigger: updateFullEap } = useLazyRequest({
593+
const { pending: updateFullFormPending, trigger: triggerUpdateFullEap } = useLazyRequest({
583594
url: '/api/v2/full-eap/{id}/',
584595
method: 'PATCH',
585596
pathVariables: {
586597
id: Number(latestFullEapId),
587598
},
588599
body: (formFields: EapFullRequestBody) => formFields,
589-
onSuccess: (response) => {
600+
onSuccess: () => {
590601
alert.show(strings.updateSuccess, { variant: 'success' });
591-
592-
// FIXME: only navigate to accounts page for the submit action
593-
navigate('accountMyFormsEap', { params: { eapId: response.id } });
594602
},
595603
onFailure: (err) => {
596604
const {
@@ -606,6 +614,35 @@ export function Component() {
606614
},
607615
});
608616

617+
const { trigger: triggerStatusUpdate } = useLazyRequest({
618+
method: 'POST',
619+
url: '/api/v2/eap-registration/{id}/status/',
620+
pathVariables: isTruthyString(eapId) ? {
621+
id: Number(eapId),
622+
} : undefined,
623+
body: () => ({
624+
status: EAP_STATUS_UNDER_REVIEW,
625+
// FIXME: fix typings in the server
626+
} as EapStatusBody),
627+
onSuccess: () => {
628+
alert.show(
629+
strings.submitApprovalSuccess,
630+
{ variant: 'success' },
631+
);
632+
633+
navigate('accountMyFormsEap');
634+
},
635+
onFailure: (error) => {
636+
alert.show(
637+
strings.submitFailedSuccess,
638+
{
639+
variant: 'danger',
640+
description: error.value.messageForNotification,
641+
},
642+
);
643+
},
644+
});
645+
609646
useEffect(() => {
610647
if (isNotDefined(eapDetailResponse)) {
611648
return;
@@ -660,36 +697,39 @@ export function Component() {
660697

661698
const readOnly = !isEditable;
662699

663-
const disabled = eapFullPending || updateFullFormPending || fetchingEap;
700+
const disabled = createFullEapPending || updateFullFormPending || fetchingEap;
664701

665702
const nextStep = getNextStep(activeTab, 1);
666703
const prevStep = getNextStep(activeTab, -1);
667704

668705
const handleValidationSuccess = useCallback(
669706
(validatedFormValue: PartialEapFullFormType) => {
670707
if (isNotDefined(latestFullEapId)) {
671-
createFullEap({
708+
triggerCreateFullEap({
672709
...(validatedFormValue as unknown as EapFullRequestBody),
673710
eap_registration: Number(eapId),
674711
});
675712
} else {
676-
updateFullEap({
713+
triggerUpdateFullEap({
677714
...validatedFormValue,
678715
id: latestFullEapId,
679716
} as unknown as EapFullRequestBody);
680717
}
681718
},
682-
[eapId, createFullEap, latestFullEapId, updateFullEap],
719+
[eapId, triggerCreateFullEap, latestFullEapId, triggerUpdateFullEap],
683720
);
684721

685722
const handleTabChange = useCallback((newTab: TabKeys) => {
686-
formContentRef.current?.scrollIntoView();
687723
setActiveTab(newTab);
724+
tabListRef.current?.scrollIntoView({ behavior: 'smooth' });
688725
}, []);
689726

690727
const handleFormError = useCallback(() => {
691-
setTimeout(() => formContentRef.current?.scrollIntoView(), 200);
692-
}, []);
728+
alert.show(
729+
strings.validationErrorAlertMessage,
730+
{ variant: 'warning' },
731+
);
732+
}, [alert, strings.validationErrorAlertMessage]);
693733

694734
const handleSave = useMemo(
695735
() => createSubmitHandler(
@@ -701,6 +741,25 @@ export function Component() {
701741
[handleFormError, handleValidationSuccess, validate, setError],
702742
);
703743

744+
const handleRequestForApprovalButtonClick = useCallback(() => {
745+
setShouldSubmit(true);
746+
handleSave();
747+
}, [handleSave]);
748+
749+
const handleRequestForApprovalCancel = useCallback(() => {
750+
setShouldSubmit(false);
751+
}, []);
752+
753+
const handleSubmitForApprovalConfirm = useCallback(() => {
754+
triggerStatusUpdate(null);
755+
setShouldSubmit(false);
756+
}, [triggerStatusUpdate]);
757+
758+
const hasFormErrors = useMemo(
759+
() => analyzeErrors(formError),
760+
[formError],
761+
);
762+
704763
return (
705764
<Tabs value={activeTab} onChange={setActiveTab} styleVariant="step">
706765
<Page
@@ -740,7 +799,7 @@ export function Component() {
740799
)
741800
}
742801
info={(
743-
<TabList>
802+
<TabList elementRef={tabListRef}>
744803
<Tab
745804
name="overview"
746805
step={1}
@@ -891,29 +950,78 @@ export function Component() {
891950
isRevision={isRevision}
892951
/>
893952
</TabPanel>
894-
<ListView withCenteredContents>
895-
<Button
896-
name={prevStep ?? activeTab}
897-
onClick={handleTabChange}
898-
disabled={isNotDefined(prevStep)}
899-
>
900-
{strings.backButton}
901-
</Button>
902-
{isDefined(nextStep) ? (
903-
<Button name={nextStep ?? activeTab} onClick={handleTabChange}>
904-
{strings.nextButton}
905-
</Button>
906-
) : (
953+
<InlineLayout
954+
after={(
907955
<Button
908956
name={undefined}
909957
onClick={handleSave}
910-
disabled={readOnly}
911958
>
912959
{strings.saveButton}
913960
</Button>
914961
)}
915-
</ListView>
962+
>
963+
<ListView withCenteredContents>
964+
<Button
965+
name={prevStep ?? activeTab}
966+
onClick={handleTabChange}
967+
disabled={isNotDefined(prevStep)}
968+
>
969+
{strings.backButton}
970+
</Button>
971+
{isDefined(nextStep) ? (
972+
<Button
973+
name={nextStep ?? activeTab}
974+
onClick={handleTabChange}
975+
>
976+
{strings.nextButton}
977+
</Button>
978+
) : (
979+
<Button
980+
name={undefined}
981+
onClick={handleRequestForApprovalButtonClick}
982+
disabled={readOnly}
983+
>
984+
{strings.submitButtonLabel}
985+
</Button>
986+
)}
987+
</ListView>
988+
</InlineLayout>
916989
</Page>
990+
{shouldSubmit && (
991+
<Modal
992+
heading={strings.submitConfirmHeading}
993+
onClose={handleRequestForApprovalCancel}
994+
pending={createFullEapPending || updateFullFormPending}
995+
pendingMessage={strings.savingPendingMessage}
996+
footerActions={(
997+
<Button
998+
name={undefined}
999+
disabled={hasFormErrors}
1000+
onClick={handleSubmitForApprovalConfirm}
1001+
>
1002+
{strings.submitConfirmButtonLabel}
1003+
</Button>
1004+
)}
1005+
>
1006+
<ListView
1007+
layout="block"
1008+
spacing="sm"
1009+
>
1010+
<div>
1011+
{strings.submitConfirmMessage}
1012+
</div>
1013+
{hasFormErrors && (
1014+
<Alert
1015+
name="form-error-warning"
1016+
title={strings.submitFormErrorMessage}
1017+
type="warning"
1018+
withLightBackground
1019+
withoutShadow
1020+
/>
1021+
)}
1022+
</ListView>
1023+
</Modal>
1024+
)}
9171025
</Tabs>
9181026
);
9191027
}

app/src/views/EapSimplifiedForm/Overview/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ function Overview(props: Props) {
198198
error={error}
199199
disabled={disabled}
200200
readOnly={readOnly}
201+
withRequiredNameAndEmail
201202
/>
202203
<InputSection
203204
title={strings.partnerNS}

app/src/views/EapSimplifiedForm/i18n.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"updateSuccessMessage": "Simplified EAP Form updated Successfully!",
2020
"backToAccountLinkLabel": "Back",
2121
"readOnlyWarningMessage": "You’re viewing this form in read-only mode. Editing is currently disabled.",
22+
"submitApprovalSuccess": "Successfully submitted EAP for approval!",
23+
"submitFailedSuccess": "Failed to submit the EAP for approval!",
2224
"validationErrorAlertMessage": "Please fix all the errors before continuing!",
2325
"savingPendingMessage": "Saving data...",
2426
"submitFormErrorMessage": "Please make sure you've filled in all the required details before proceeding!",

0 commit comments

Comments
 (0)