Skip to content

Commit 7b157b3

Browse files
authored
Merge pull request #1641 from IFRCGo/project/dref-imminent-returns
project: Dref Imminent Returns
2 parents 3bb6074 + 4032688 commit 7b157b3

File tree

36 files changed

+2743
-618
lines changed

36 files changed

+2743
-618
lines changed

.changeset/lovely-bears-type.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"go-web-app": minor
3+
---
4+
5+
Update Imminent DREF Application in [#1455](https://github.com/IFRCGo/go-web-app/issues/1455)
6+
7+
- Hide sections/fields
8+
- Rename sections/fields
9+
- Remove sections/fields
10+
- Reflect changes in the PDF export

.changeset/tall-bees-flow.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ifrc-go/ui": minor
3+
---
4+
5+
Add printable Signature component

app/src/components/SelectOutput/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TextOutput } from '@ifrc-go/ui';
33
import { isDefined } from '@togglecorp/fujs';
44

55
interface Props<VALUE, OPTION> {
6+
className: string;
67
value: VALUE | undefined;
78
options: OPTION[] | undefined;
89
keySelector: (datum: OPTION) => VALUE;
@@ -12,6 +13,7 @@ interface Props<VALUE, OPTION> {
1213

1314
function SelectOutput<VALUE, OPTION>(props: Props<VALUE, OPTION>) {
1415
const {
16+
className,
1517
value,
1618
options,
1719
keySelector,
@@ -31,6 +33,7 @@ function SelectOutput<VALUE, OPTION>(props: Props<VALUE, OPTION>) {
3133

3234
return (
3335
<TextOutput
36+
className={className}
3437
label={label}
3538
value={valueLabel}
3639
strongLabel

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
"drefExportFailed": "Export failed",
88
"drefExportSuccessfully": "Export completed successfully",
99
"drefClickDownloadLink": "Click on the download link below!",
10-
"drefDownloadPDF": "Download PDF"
10+
"drefDownloadPDF": "Download PDF",
11+
"drefDownloadPDFWithPGA": "Download PDF with PGA",
12+
"drefDownloadPDFwithoutPGA": "Download PDF without PGA",
13+
"drefFailureToExportMessage":"Failed to export PDF."
1114
}
1215
}

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

Lines changed: 135 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import {
2+
useCallback,
23
useMemo,
34
useState,
45
} from 'react';
56
import {
7+
Button,
8+
Checkbox,
69
Message,
710
Modal,
811
} from '@ifrc-go/ui';
@@ -14,7 +17,15 @@ import {
1417

1518
import Link from '#components/Link';
1619
import { type components } from '#generated/types';
17-
import { useRequest } from '#utils/restRequest';
20+
import useAlert from '#hooks/useAlert';
21+
import {
22+
DREF_TYPE_IMMINENT,
23+
type TypeOfDrefEnum,
24+
} from '#utils/constants';
25+
import {
26+
useLazyRequest,
27+
useRequest,
28+
} from '#utils/restRequest';
1829

1930
import i18n from './i18n.json';
2031

@@ -29,18 +40,48 @@ interface Props {
2940
id: number;
3041
onCancel: () => void;
3142
applicationType: 'DREF' | 'OPS_UPDATE' | 'FINAL_REPORT';
43+
drefType?: TypeOfDrefEnum | null;
3244
}
3345

3446
function DrefExportModal(props: Props) {
3547
const {
3648
id,
3749
onCancel,
3850
applicationType,
51+
drefType,
3952
} = props;
4053

4154
const strings = useTranslation(i18n);
55+
const alert = useAlert();
4256

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

4586
const exportTriggerBody = useMemo(
4687
() => {
@@ -60,14 +101,39 @@ function DrefExportModal(props: Props) {
60101
per_country: undefined, // FIXME: typing is altered by the useRequest function
61102
};
62103
},
63-
[id, applicationType],
104+
[
105+
id,
106+
applicationType,
107+
],
64108
);
65109

110+
const {
111+
pending: pendingDrefImminentExportTrigger,
112+
error: drefImminentExportError,
113+
trigger: drefImminentExportTrigger,
114+
} = useLazyRequest({
115+
method: 'POST',
116+
useCurrentLanguageForMutation: true,
117+
url: '/api/v2/pdf-export/',
118+
body: drefExportTriggerBody,
119+
onSuccess: (response) => {
120+
if (isDefined(response.id)) {
121+
setExportId(response.id);
122+
}
123+
},
124+
onFailure: () => {
125+
alert.show(
126+
strings.drefFailureToExportMessage,
127+
{ variant: 'danger' },
128+
);
129+
},
130+
});
131+
66132
const {
67133
pending: pendingExportTrigger,
68134
error: exportTriggerError,
69135
} = useRequest({
70-
skip: isDefined(exportId) || isNotDefined(id),
136+
skip: isDefined(exportId) || isNotDefined(id) || drefType === DREF_TYPE_IMMINENT,
71137
method: 'POST',
72138
useCurrentLanguageForMutation: true,
73139
url: '/api/v2/pdf-export/',
@@ -77,6 +143,12 @@ function DrefExportModal(props: Props) {
77143
setExportId(response.id);
78144
}
79145
},
146+
onFailure: () => {
147+
alert.show(
148+
strings.drefFailureToExportMessage,
149+
{ variant: 'danger' },
150+
);
151+
},
80152
});
81153

82154
const {
@@ -97,18 +169,40 @@ function DrefExportModal(props: Props) {
97169
},
98170
});
99171

172+
const handleDrefImminent = useCallback(() => {
173+
setIsPgaCheckboxVisible(false);
174+
drefImminentExportTrigger(drefExportTriggerBody);
175+
}, [
176+
drefExportTriggerBody,
177+
drefImminentExportTrigger,
178+
]);
179+
100180
return (
101181
<Modal
102182
heading={strings.drefExportTitle}
103183
onClose={onCancel}
104184
>
105-
{pendingExportTrigger && (
185+
{drefType === DREF_TYPE_IMMINENT
186+
&& isPgaCheckboxVisible
187+
&& !(pendingExportTrigger
188+
|| pendingExportStatus
189+
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
190+
&& (
191+
<Checkbox
192+
name={undefined}
193+
value={isPga}
194+
onChange={setIsPga}
195+
label={strings.drefDownloadPDFWithPGA}
196+
/>
197+
)}
198+
{pendingExportTrigger && pendingDrefImminentExportTrigger && (
106199
<Message
107200
pending
108201
title={strings.drefPreparingExport}
109202
/>
110203
)}
111-
{(pendingExportStatus || exportStatusResponse?.status === EXPORT_STATUS_PENDING) && (
204+
{(pendingExportStatus
205+
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING) && (
112206
<Message
113207
pending
114208
title={strings.drefWaitingExport}
@@ -117,16 +211,50 @@ function DrefExportModal(props: Props) {
117211
{(exportStatusResponse?.status === EXPORT_STATUS_ERRORED
118212
|| isDefined(exportTriggerError)
119213
|| isDefined(exportStatusError)
214+
|| isDefined(drefImminentExportError)
120215
) && (
121216
<Message
122217
title={strings.drefExportFailed}
123218
description={exportTriggerError?.value.messageForNotification
124-
?? exportStatusError?.value.messageForNotification}
219+
?? exportStatusError?.value.messageForNotification
220+
?? drefImminentExportError?.value.messageForNotification}
125221
/>
126222
)}
223+
{!(pendingExportTrigger
224+
|| pendingExportStatus
225+
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
226+
&& drefType === DREF_TYPE_IMMINENT
227+
&& !drefImminentExportError && (
228+
exportStatusResponse?.pdf_file ? (
229+
<Message
230+
title={strings.drefExportSuccessfully}
231+
description={strings.drefClickDownloadLink}
232+
actions={(
233+
<Link
234+
variant="secondary"
235+
href={exportStatusResponse?.pdf_file}
236+
external
237+
>
238+
{strings.drefDownloadPDF}
239+
</Link>
240+
)}
241+
/>
242+
) : (!exportStatusResponse && (
243+
<Button
244+
variant="secondary"
245+
name={undefined}
246+
onClick={handleDrefImminent}
247+
>
248+
{isPga
249+
? strings.drefDownloadPDFWithPGA
250+
: strings.drefDownloadPDFwithoutPGA}
251+
</Button>
252+
))
253+
)}
127254
{isDefined(exportStatusResponse)
128255
&& exportStatusResponse.status === EXPORT_STATUS_COMPLETED
129-
&& isDefined(exportStatusResponse.pdf_file) && (
256+
&& isDefined(exportStatusResponse.pdf_file)
257+
&& drefType !== DREF_TYPE_IMMINENT && (
130258
<Message
131259
title={strings.drefExportSuccessfully}
132260
description={strings.drefClickDownloadLink}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"riskCategoryVeryHigh": "Very High",
1818
"riskSeasonalMapHeading": "Risk Map",
1919
"riskSeasonalCountriesByRiskHeading": "Countries by Risk",
20-
"riskPopupLabel": "Risk"
20+
"riskPopupLabel": "Risk",
21+
"riskDataNotAvailable": "Data not available for selected filters"
2122
}
2223
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -980,8 +980,7 @@ function RiskSeasonalMap(props: Props) {
980980
{dataPending && <BlockLoading />}
981981
{!dataPending && (isNotDefined(filteredData) || filteredData?.length === 0) && (
982982
<Message
983-
// FIXME: add translations
984-
title="Data not available for selected filters"
983+
title={strings.riskDataNotAvailable}
985984
/>
986985
)}
987986
{/* FIXME: use List */}

app/src/views/AccountMyFormsDref/ActiveDrefTable/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ function ActiveDrefTable(props: Props) {
259259
canCreateFinalReport,
260260
hasPermissionToApprove: isRegionCoordinator || userMe?.is_superuser,
261261
onPublishSuccess: refetchActiveDref,
262+
drefType: item.type_of_dref,
262263
};
263264
},
264265
{ columnClassName: styles.actions },

app/src/views/AccountMyFormsDref/DrefTableActions/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import {
3131
DREF_TYPE_IMMINENT,
3232
DREF_TYPE_LOAN,
3333
type DrefStatus,
34+
type TypeOfDrefEnum,
3435
} from '#utils/constants';
3536
import {
3637
type GoApiBody,
@@ -53,6 +54,7 @@ export interface Props {
5354
hasPermissionToApprove?: boolean;
5455

5556
onPublishSuccess?: () => void;
57+
drefType: TypeOfDrefEnum | null | undefined;
5658
}
5759

5860
function DrefTableActions(props: Props) {
@@ -65,6 +67,7 @@ function DrefTableActions(props: Props) {
6567
canCreateFinalReport,
6668
hasPermissionToApprove,
6769
onPublishSuccess,
70+
drefType,
6871
} = props;
6972

7073
const { navigate } = useRouting();
@@ -497,6 +500,7 @@ function DrefTableActions(props: Props) {
497500
onCancel={setShowExportModalFalse}
498501
id={id}
499502
applicationType={applicationType}
503+
drefType={drefType}
500504
/>
501505
)}
502506
{showShareModal && (
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"namespace": "drefApplicationExport",
3+
"strings": {
4+
"imminentDREFRequestHeading": "Imminent DREF Request and Obligations",
5+
"requestHeading": "Request:",
6+
"requestDescription": "The National Society hereby requests an Imminent DREF funding of CHF 75,000 to implement anticipatory actions to mitigate the risk of the foreseen disaster and possibly a few immediate response activities should the disaster materialize.",
7+
"nationalSocietyHeading": "National Society Obligations:",
8+
"nationalSocietyDescriptionOne": "The National Society commits to use the Imminent DREF funding solely for the proposed activities as per the budget indicated on page 1 and in accordance with the DREF Guidelines.",
9+
"nationalSocietyDescriptionTwo": "The maximum timeframe for implementing the proposed activities shall be 45 days after the date of approval of the Imminent DREF request, with no possibility of extension.",
10+
"nationalSocietyDescriptionThree": "In the event the foreseen disaster materializes, and the National Society requires additional funding from the DREF,",
11+
"nationalSocietyDescriptionFour": "The National Society shall promptly but no later than 14 days from the date of the disaster occurrence, submit a DREF application for the next operation (using the Operations Update form via GO). Upon approval of the response DREF application, the National Society shall promptly but no later than 15 days from receiving the Project Funding Agreement from the IFRC, sign such Project Funding Agreement.",
12+
"nationalSocietyDescriptionFive": "The Project Funding Agreement shall indicate the amount already paid out as Imminent DREF funding which shall be included in the total DREF cap allocation.",
13+
"nationalSocietyDescriptionSix": "The DREF application budget shall reflect the full funding needed for the operation, including the activities carried out using the Imminent DREF funding.",
14+
"nationalSocietyDescriptionSeven": "The National Society shall provide the following reports:",
15+
"nationalSocietyDescriptionEight": "two narrative reports:",
16+
"nationalSocietyDescriptionNine": "Operations Update to scale up through response DREF request and update on Imminent DREF implemented activities",
17+
"nationalSocietyDescriptionTen": "Imminent DREF and response DREF report in one common final report",
18+
"nationalSocietyDescriptionEleven": "One financial report of the final Imminent DREF and the response DREF operations.",
19+
"nationalSocietyDescriptionTwelve": "In the event the disaster materializes, however the National Society does not wish to request international support, the National Society shall:",
20+
"nationalSocietyDescriptionThirteen": "Provide a final financial and narrative report on the use of the Imminent DREF request within 30 days after the 45 days implementation period set out in paragraph 4 above,",
21+
"nationalSocietyDescriptionFourteen": "In the event the disaster does not materialize, the National Society shall:",
22+
"nationalSocietyDescriptionFifteen": "Refund the amount dedicated to immediate response activities of the Imminent DREF request within 30 days after the implementation period set out in paragraph 4 above.",
23+
"nationalSocietyDescriptionSixteen": "By signing this Imminent DREF request, the National Society commits to zero tolerance for, and shall take appropriate measures against, fraud, corruption, and any form of abuse against any person, in particular children, including without limitation sexual exploitation, abuse and harassment. The IFRC reserves the right to perform audits, financial reviews, checks and verifications and/or investigations to ensure the proper use of the Imminent DREF and compliance with the above-mentioned obligations. In order to facilitate such audits, financial reviews, checks and verifications and/or investigations, the National Society shall grant the IFRC access to its documents, records, and premises as well as its staff, agents, volunteers, beneficiaries, sub-grantees and contractors. Any breach of the above obligations shall entitle the IFRC to request a full refund of this Imminent DREF request.",
24+
"nationalSocietyBankDetails": "Bank details of the National Society",
25+
"nationalSocietyBankDescription": "to which the IFRC shall transfer the funds will be transferred.",
26+
"nationalSocietyBankName": "Bank Name and Address",
27+
"nationalSocietyBankAccountNumber": "Bank Account Number and Currency",
28+
"nationalSocietySwiftCode": "IBAN / SWIFT Code",
29+
"nationalSocietyAmount": "Amount(CHF)",
30+
"nationalSocietyAmountCHF": "CHF 75,000/CHF 90800",
31+
"nationalSocietyAdvancePayment": "For the Purpose of Advance Payment",
32+
"nationalSocietyBankFooter": "Please find attached letter from the Bank confirming banking relationship details.",
33+
"imminentDrefRequest": "This Imminent DREF request is signed on behalf of:",
34+
"imminentDrefSigned": "SIGNED by the authorised representative of the National Society",
35+
"imminentIFRCSigned": "SIGNED by the authorised representative of the IFRC",
36+
"imminentSignature": "Signature",
37+
"imminentPrintedSignatory": "Printed Signatory's Name",
38+
"imminentTitle": "Title",
39+
"imminentDate": "Date"
40+
}
41+
}

0 commit comments

Comments
 (0)