Skip to content

Commit 51a9510

Browse files
authored
Merge pull request #1942 from IFRCGo/project/dref-imminent-v2-final-report
DREF Imminent v2 Final Report
2 parents 3feed63 + 3ee9979 commit 51a9510

File tree

72 files changed

+10663
-740
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+10663
-740
lines changed

.changeset/sweet-gifts-cheer.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
"go-web-app": patch
3+
---
4+
5+
Updated Final Report form and export for DREF imminent type
6+
7+
- Added two versions for Final Report:
8+
- v1 for existing final report forms
9+
- v2 for newly created final report forms
10+
- Add new field and table in DREF Final Report for imminent type
11+
- Update `is_pga` option for DREF Final Report imminent type
12+

app/src/App/routes/index.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,37 @@ const drefFinalReportExport = customWrapRoute({
10181018
},
10191019
});
10201020

1021+
// TODO: Remove me after implementation of DrefFinalReport for imminent
1022+
const oldDrefFinalReportForm = customWrapRoute({
1023+
parent: rootLayout,
1024+
path: 'old-dref-final-reports/:finalReportId/edit',
1025+
component: {
1026+
render: () => import('#views/OldDrefFinalReportForm'),
1027+
props: {},
1028+
},
1029+
wrapperComponent: Auth,
1030+
context: {
1031+
title: 'Edit DREF Final Report Form',
1032+
visibility: 'is-authenticated',
1033+
permissions: ({ isGuestUser }) => !isGuestUser,
1034+
},
1035+
});
1036+
1037+
const oldDrefFinalReportExport = customWrapRoute({
1038+
path: 'old-dref-final-reports/:finalReportId/export',
1039+
component: {
1040+
render: () => import('#views/OldDrefFinalReportExport'),
1041+
props: {},
1042+
},
1043+
parent: rootLayout,
1044+
wrapperComponent: Auth,
1045+
context: {
1046+
title: 'DREF Final Report Export',
1047+
visibility: 'is-authenticated',
1048+
permissions: ({ isGuestUser }) => !isGuestUser,
1049+
},
1050+
});
1051+
10211052
const fieldReportFormNew = customWrapRoute({
10221053
parent: rootLayout,
10231054
path: 'field-reports/new',
@@ -1325,6 +1356,9 @@ const wrappedRoutes = {
13251356
...countryRoutes,
13261357
...surgeRoutes,
13271358

1359+
// TODO: Remove me after implementation of DrefFinalReport for imminent
1360+
oldDrefFinalReportForm,
1361+
oldDrefFinalReportExport,
13281362
// Redirects
13291363
preparednessOperationalLearning,
13301364
obsoleteFieldReportDetails,

app/src/components/domain/DrefExportModal/i18n.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55
"drefPreparingExport": "Preparing for export...",
66
"drefWaitingExport": "Waiting for the export to complete...",
77
"drefExportFailed": "Export failed",
8-
"drefExportSuccessfully": "Export completed successfully",
8+
"drefExportSuccessfully": "Export completed successfully!",
99
"drefClickDownloadLink": "Click on the download link below!",
1010
"drefDownloadPDF": "Download PDF",
11+
"includePgaLabel": "Include PGA",
12+
"startExportLabel": "Start Export",
13+
"configureExportLabel": "Configure export",
1114
"drefDownloadPDFWithPGA": "Download PDF with PGA",
1215
"drefDownloadPDFwithoutPGA": "Download PDF without PGA",
1316
"drefFailureToExportMessage":"Failed to export PDF."
1417
}
15-
}
18+
}

app/src/components/domain/DrefExportModal/index.tsx

Lines changed: 82 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import {
2-
useCallback,
2+
useEffect,
33
useMemo,
44
useState,
55
} from 'react';
6+
import { DownloadLineIcon } from '@ifrc-go/icons';
67
import {
78
Button,
89
Checkbox,
@@ -56,33 +57,7 @@ function DrefExportModal(props: Props) {
5657
const alert = useAlert();
5758

5859
const [exportId, setExportId] = useState<number | undefined>();
59-
const [isPga, setIsPga] = useState<boolean>(false);
60-
const [isPgaCheckboxVisible, setIsPgaCheckboxVisible] = useState(true);
61-
62-
const drefExportTriggerBody = useMemo(
63-
() => {
64-
let type: ExportTypeEnum;
65-
if (applicationType === 'OPS_UPDATE') {
66-
type = 'dref-operational-updates';
67-
} else if (applicationType === 'FINAL_REPORT') {
68-
type = 'dref-final-reports';
69-
} else {
70-
type = 'dref-applications';
71-
}
72-
return {
73-
export_id: id,
74-
export_type: type,
75-
is_pga: isPga,
76-
selector: '#pdf-preview-ready',
77-
per_country: undefined,
78-
};
79-
},
80-
[
81-
id,
82-
isPga,
83-
applicationType,
84-
],
85-
);
60+
const [includePga, setIncludePga] = useState<boolean>(false);
8661

8762
const exportTriggerBody = useMemo(
8863
() => {
@@ -98,45 +73,23 @@ function DrefExportModal(props: Props) {
9873
return {
9974
export_id: id,
10075
export_type: type,
101-
is_pga: isPga,
76+
is_pga: includePga,
10277
selector: '#pdf-preview-ready',
10378
per_country: undefined,
10479
};
10580
},
10681
[
10782
id,
108-
isPga,
83+
includePga,
10984
applicationType,
11085
],
11186
);
11287

11388
const {
114-
pending: pendingDrefImminentExportTrigger,
115-
error: drefImminentExportError,
116-
trigger: drefImminentExportTrigger,
89+
pending: exportPending,
90+
error: exportError,
91+
trigger: triggerExport,
11792
} = useLazyRequest({
118-
method: 'POST',
119-
useCurrentLanguageForMutation: true,
120-
url: '/api/v2/pdf-export/',
121-
body: drefExportTriggerBody,
122-
onSuccess: (response) => {
123-
if (isDefined(response.id)) {
124-
setExportId(response.id);
125-
}
126-
},
127-
onFailure: () => {
128-
alert.show(
129-
strings.drefFailureToExportMessage,
130-
{ variant: 'danger' },
131-
);
132-
},
133-
});
134-
135-
const {
136-
pending: pendingExportTrigger,
137-
error: exportTriggerError,
138-
} = useRequest({
139-
skip: isDefined(exportId) || isNotDefined(id) || drefType === DREF_TYPE_IMMINENT,
14093
method: 'POST',
14194
useCurrentLanguageForMutation: true,
14295
url: '/api/v2/pdf-export/',
@@ -154,8 +107,22 @@ function DrefExportModal(props: Props) {
154107
},
155108
});
156109

110+
useEffect(() => {
111+
if (isDefined(exportId) || isNotDefined(id)) {
112+
return;
113+
}
114+
115+
// Don't automatically trigger the export for imminent DREF Applications
116+
// We need to allow users to configure PGA before the export
117+
if (drefType === DREF_TYPE_IMMINENT && applicationType === 'DREF') {
118+
return;
119+
}
120+
121+
triggerExport(null);
122+
}, [exportId, id, drefType, applicationType, triggerExport]);
123+
157124
const {
158-
pending: pendingExportStatus,
125+
pending: exportStatusPending,
159126
response: exportStatusResponse,
160127
error: exportStatusError,
161128
} = useRequest({
@@ -172,108 +139,101 @@ function DrefExportModal(props: Props) {
172139
},
173140
});
174141

175-
const handleDrefImminent = useCallback(() => {
176-
setIsPgaCheckboxVisible(false);
177-
drefImminentExportTrigger(drefExportTriggerBody);
142+
const exportStatus = useMemo(() => {
143+
if (exportPending) {
144+
return 'PREPARE';
145+
}
146+
147+
if (exportStatusPending || exportStatusResponse?.status === EXPORT_STATUS_PENDING) {
148+
return 'WAITING';
149+
}
150+
151+
if (isDefined(exportStatusError)
152+
|| isDefined(exportError)
153+
|| (isDefined(exportStatusResponse)
154+
&& exportStatusResponse.status === EXPORT_STATUS_ERRORED)
155+
) {
156+
return 'FAILED';
157+
}
158+
159+
if (isDefined(exportStatusResponse)
160+
&& isDefined(exportStatusResponse.status === EXPORT_STATUS_COMPLETED)
161+
&& isDefined(exportStatusResponse.pdf_file)
162+
) {
163+
return 'SUCCESS';
164+
}
165+
166+
return 'NOT_STARTED';
178167
}, [
179-
drefExportTriggerBody,
180-
drefImminentExportTrigger,
168+
exportPending,
169+
exportStatusError,
170+
exportError,
171+
exportStatusPending,
172+
exportStatusResponse,
181173
]);
182174

183175
return (
184176
<Modal
185177
heading={strings.drefExportTitle}
186178
onClose={onCancel}
179+
className={styles.drefExportModal}
187180
>
188-
{drefType === DREF_TYPE_IMMINENT
189-
&& isPgaCheckboxVisible
190-
&& !(pendingExportTrigger
191-
|| pendingExportStatus
192-
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
193-
&& (
194-
<Checkbox
195-
name={undefined}
196-
value={isPga}
197-
onChange={setIsPga}
198-
label={strings.drefDownloadPDFWithPGA}
199-
/>
200-
)}
201-
{pendingExportTrigger && pendingDrefImminentExportTrigger && (
181+
{exportStatus === 'PREPARE' && (
202182
<Message
203183
pending
204184
title={strings.drefPreparingExport}
205185
/>
206186
)}
207-
{(pendingExportStatus
208-
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING) && (
187+
{exportStatus === 'WAITING' && (
209188
<Message
210189
pending
211190
title={strings.drefWaitingExport}
212191
/>
213192
)}
214-
{(exportStatusResponse?.status === EXPORT_STATUS_ERRORED
215-
|| isDefined(exportTriggerError)
216-
|| isDefined(exportStatusError)
217-
|| isDefined(drefImminentExportError)
218-
) && (
193+
{exportStatus === 'FAILED' && (
219194
<Message
220195
title={strings.drefExportFailed}
221-
description={exportTriggerError?.value.messageForNotification
222-
?? exportStatusError?.value.messageForNotification
223-
?? drefImminentExportError?.value.messageForNotification}
196+
description={exportError?.value.messageForNotification
197+
?? exportStatusError?.value.messageForNotification}
224198
/>
225199
)}
226-
{!(pendingExportTrigger
227-
|| pendingExportStatus
228-
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
229-
&& drefType === DREF_TYPE_IMMINENT
230-
&& !drefImminentExportError && (
231-
exportStatusResponse?.pdf_file ? (
232-
<Message
233-
title={strings.drefExportSuccessfully}
234-
description={strings.drefClickDownloadLink}
235-
actions={(
236-
<Link
237-
variant="secondary"
238-
href={exportStatusResponse?.pdf_file}
239-
external
240-
>
241-
{strings.drefDownloadPDF}
242-
</Link>
243-
)}
244-
/>
245-
) : (!exportStatusResponse && (
246-
<div className={styles.downloadButton}>
247-
<Button
248-
variant="secondary"
249-
name={undefined}
250-
onClick={handleDrefImminent}
251-
>
252-
{isPga
253-
? strings.drefDownloadPDFWithPGA
254-
: strings.drefDownloadPDFwithoutPGA}
255-
</Button>
256-
</div>
257-
))
258-
)}
259-
{isDefined(exportStatusResponse)
260-
&& exportStatusResponse.status === EXPORT_STATUS_COMPLETED
261-
&& isDefined(exportStatusResponse.pdf_file)
262-
&& drefType !== DREF_TYPE_IMMINENT && (
200+
{exportStatus === 'SUCCESS' && (
263201
<Message
264202
title={strings.drefExportSuccessfully}
265203
description={strings.drefClickDownloadLink}
266204
actions={(
267205
<Link
268206
variant="secondary"
269207
href={exportStatusResponse?.pdf_file}
208+
icons={<DownloadLineIcon className={styles.icon} />}
270209
external
271210
>
272211
{strings.drefDownloadPDF}
273212
</Link>
274213
)}
275214
/>
276215
)}
216+
{exportStatus === 'NOT_STARTED' && (
217+
<Message
218+
title={strings.configureExportLabel}
219+
description={drefType === DREF_TYPE_IMMINENT && applicationType !== 'FINAL_REPORT' && (
220+
<Checkbox
221+
name={undefined}
222+
value={includePga}
223+
onChange={setIncludePga}
224+
label={strings.includePgaLabel}
225+
/>
226+
)}
227+
actions={(
228+
<Button
229+
name={null}
230+
onClick={triggerExport}
231+
>
232+
{strings.startExportLabel}
233+
</Button>
234+
)}
235+
/>
236+
)}
277237
</Modal>
278238
);
279239
}
Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
.download-button {
2-
display: flex;
3-
align-items: center;
4-
flex-direction: column;
5-
padding: var(--go-ui-spacing-md);
6-
}
1+
.dref-export-modal {
2+
.icon {
3+
font-size: var(--go-ui-height-icon-multiplier);
4+
}
5+
}

0 commit comments

Comments
 (0)