Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

project: DREF Imminent Changes #1674

Draft
wants to merge 1 commit into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion app/src/components/domain/DrefExportModal/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
"drefExportFailed": "Export failed",
"drefExportSuccessfully": "Export completed successfully",
"drefClickDownloadLink": "Click on the download link below!",
"drefDownloadPDF": "Download PDF"
"drefDownloadPDF": "Download PDF",
"drefDownloadPDFWithPGA": "Download PDF with PGA",
"drefDownloadPDFwithoutPGA": "Download PDF without PGA",
"drefFailureToExportMessage":"Failed to export PDF."
}
}
145 changes: 138 additions & 7 deletions app/src/components/domain/DrefExportModal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import {
useCallback,
useMemo,
useState,
} from 'react';
import {
Button,
Checkbox,
Message,
Modal,
} from '@ifrc-go/ui';
Expand All @@ -14,9 +17,18 @@ import {

import Link from '#components/Link';
import { type components } from '#generated/types';
import { useRequest } from '#utils/restRequest';
import useAlert from '#hooks/useAlert';
import {
DREF_TYPE_IMMINENT,
type TypeOfDrefEnum,
} from '#utils/constants';
import {
useLazyRequest,
useRequest,
} from '#utils/restRequest';

import i18n from './i18n.json';
import styles from './styles.module.css';

type ExportTypeEnum = components<'read'>['schemas']['ExportTypeEnum'];
type ExportStatusEnum = components<'read'>['schemas']['ExportStatusEnum'];
Expand All @@ -29,18 +41,48 @@ interface Props {
id: number;
onCancel: () => void;
applicationType: 'DREF' | 'OPS_UPDATE' | 'FINAL_REPORT';
drefType?: TypeOfDrefEnum | null;
}

function DrefExportModal(props: Props) {
const {
id,
onCancel,
applicationType,
drefType,
} = props;

const strings = useTranslation(i18n);
const alert = useAlert();

const [exportId, setExportId] = useState<number | undefined>();
const [isPga, setIsPga] = useState<boolean>(false);
const [isPgaCheckboxVisible, setIsPgaCheckboxVisible] = useState(true);

const drefExportTriggerBody = useMemo(
() => {
let type: ExportTypeEnum;
if (applicationType === 'OPS_UPDATE') {
type = 'dref-operational-updates';
} else if (applicationType === 'FINAL_REPORT') {
type = 'dref-final-reports';
} else {
type = 'dref-applications';
}
return {
export_id: id,
export_type: type,
is_pga: isPga,
selector: '#pdf-preview-ready',
per_country: undefined,
};
},
[
id,
isPga,
applicationType,
],
);

const exportTriggerBody = useMemo(
() => {
Expand All @@ -60,14 +102,39 @@ function DrefExportModal(props: Props) {
per_country: undefined, // FIXME: typing is altered by the useRequest function
};
},
[id, applicationType],
[
id,
applicationType,
],
);

const {
pending: pendingDrefImminentExportTrigger,
error: drefImminentExportError,
trigger: drefImminentExportTrigger,
} = useLazyRequest({
method: 'POST',
useCurrentLanguageForMutation: true,
url: '/api/v2/pdf-export/',
body: drefExportTriggerBody,
onSuccess: (response) => {
if (isDefined(response.id)) {
setExportId(response.id);
}
},
onFailure: () => {
alert.show(
strings.drefFailureToExportMessage,
{ variant: 'danger' },
);
},
});

const {
pending: pendingExportTrigger,
error: exportTriggerError,
} = useRequest({
skip: isDefined(exportId) || isNotDefined(id),
skip: isDefined(exportId) || isNotDefined(id) || drefType === DREF_TYPE_IMMINENT,
method: 'POST',
useCurrentLanguageForMutation: true,
url: '/api/v2/pdf-export/',
Expand All @@ -77,6 +144,12 @@ function DrefExportModal(props: Props) {
setExportId(response.id);
}
},
onFailure: () => {
alert.show(
strings.drefFailureToExportMessage,
{ variant: 'danger' },
);
},
});

const {
Expand All @@ -97,18 +170,40 @@ function DrefExportModal(props: Props) {
},
});

const handleDrefImminent = useCallback(() => {
setIsPgaCheckboxVisible(false);
drefImminentExportTrigger(drefExportTriggerBody);
}, [
drefExportTriggerBody,
drefImminentExportTrigger,
]);

return (
<Modal
heading={strings.drefExportTitle}
onClose={onCancel}
>
{pendingExportTrigger && (
{drefType === DREF_TYPE_IMMINENT
&& isPgaCheckboxVisible
&& !(pendingExportTrigger
|| pendingExportStatus
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
&& (
<Checkbox
name={undefined}
value={isPga}
onChange={setIsPga}
label={strings.drefDownloadPDFWithPGA}
/>
)}
{pendingExportTrigger && pendingDrefImminentExportTrigger && (
<Message
pending
title={strings.drefPreparingExport}
/>
)}
{(pendingExportStatus || exportStatusResponse?.status === EXPORT_STATUS_PENDING) && (
{(pendingExportStatus
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING) && (
<Message
pending
title={strings.drefWaitingExport}
Expand All @@ -117,16 +212,52 @@ function DrefExportModal(props: Props) {
{(exportStatusResponse?.status === EXPORT_STATUS_ERRORED
|| isDefined(exportTriggerError)
|| isDefined(exportStatusError)
|| isDefined(drefImminentExportError)
) && (
<Message
title={strings.drefExportFailed}
description={exportTriggerError?.value.messageForNotification
?? exportStatusError?.value.messageForNotification}
?? exportStatusError?.value.messageForNotification
?? drefImminentExportError?.value.messageForNotification}
/>
)}
{!(pendingExportTrigger
|| pendingExportStatus
|| exportStatusResponse?.status === EXPORT_STATUS_PENDING)
&& drefType === DREF_TYPE_IMMINENT
&& !drefImminentExportError && (
exportStatusResponse?.pdf_file ? (
<Message
title={strings.drefExportSuccessfully}
description={strings.drefClickDownloadLink}
actions={(
<Link
variant="secondary"
href={exportStatusResponse?.pdf_file}
external
>
{strings.drefDownloadPDF}
</Link>
)}
/>
) : (!exportStatusResponse && (
<div className={styles.downloadButton}>
<Button
variant="secondary"
name={undefined}
onClick={handleDrefImminent}
>
{isPga
? strings.drefDownloadPDFWithPGA
: strings.drefDownloadPDFwithoutPGA}
</Button>
</div>
))
)}
{isDefined(exportStatusResponse)
&& exportStatusResponse.status === EXPORT_STATUS_COMPLETED
&& isDefined(exportStatusResponse.pdf_file) && (
&& isDefined(exportStatusResponse.pdf_file)
&& drefType !== DREF_TYPE_IMMINENT && (
<Message
title={strings.drefExportSuccessfully}
description={strings.drefClickDownloadLink}
Expand Down
6 changes: 6 additions & 0 deletions app/src/components/domain/DrefExportModal/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.download-button {
display: flex;
align-items: center;
flex-direction: column;
padding: var(--go-ui-spacing-md);
}
3 changes: 2 additions & 1 deletion app/src/components/domain/RiskSeasonalMap/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"riskCategoryVeryHigh": "Very High",
"riskSeasonalMapHeading": "Risk Map",
"riskSeasonalCountriesByRiskHeading": "Countries by Risk",
"riskPopupLabel": "Risk"
"riskPopupLabel": "Risk",
"riskDataNotAvailable": "Data not available for selected filters"
}
}
3 changes: 1 addition & 2 deletions app/src/components/domain/RiskSeasonalMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -980,8 +980,7 @@ function RiskSeasonalMap(props: Props) {
{dataPending && <BlockLoading />}
{!dataPending && (isNotDefined(filteredData) || filteredData?.length === 0) && (
<Message
// FIXME: add translations
title="Data not available for selected filters"
title={strings.riskDataNotAvailable}
/>
)}
{/* FIXME: use List */}
Expand Down
1 change: 1 addition & 0 deletions app/src/views/AccountMyFormsDref/ActiveDrefTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ function ActiveDrefTable(props: Props) {
canCreateFinalReport,
hasPermissionToApprove: isRegionCoordinator || userMe?.is_superuser,
onPublishSuccess: refetchActiveDref,
drefType: item.type_of_dref,
};
},
{ columnClassName: styles.actions },
Expand Down
4 changes: 4 additions & 0 deletions app/src/views/AccountMyFormsDref/DrefTableActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
DREF_TYPE_IMMINENT,
DREF_TYPE_LOAN,
type DrefStatus,
type TypeOfDrefEnum,
} from '#utils/constants';
import {
type GoApiBody,
Expand All @@ -53,6 +54,7 @@ export interface Props {
hasPermissionToApprove?: boolean;

onPublishSuccess?: () => void;
drefType: TypeOfDrefEnum | null | undefined;
}

function DrefTableActions(props: Props) {
Expand All @@ -65,6 +67,7 @@ function DrefTableActions(props: Props) {
canCreateFinalReport,
hasPermissionToApprove,
onPublishSuccess,
drefType,
} = props;

const { navigate } = useRouting();
Expand Down Expand Up @@ -497,6 +500,7 @@ function DrefTableActions(props: Props) {
onCancel={setShowExportModalFalse}
id={id}
applicationType={applicationType}
drefType={drefType}
/>
)}
{showShareModal && (
Expand Down
41 changes: 41 additions & 0 deletions app/src/views/DrefApplicationExport/PgaExport/i18n.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"namespace": "drefApplicationExport",
"strings": {
"imminentDREFRequestHeading": "Imminent DREF Request and Obligations",
"requestHeading": "Request:",
"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.",
"nationalSocietyHeading": "National Society Obligations:",
"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.",
"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.",
"nationalSocietyDescriptionThree": "In the event the foreseen disaster materializes, and the National Society requires additional funding from the DREF,",
"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.",
"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.",
"nationalSocietyDescriptionSix": "The DREF application budget shall reflect the full funding needed for the operation, including the activities carried out using the Imminent DREF funding.",
"nationalSocietyDescriptionSeven": "The National Society shall provide the following reports:",
"nationalSocietyDescriptionEight": "two narrative reports:",
"nationalSocietyDescriptionNine": "Operations Update to scale up through response DREF request and update on Imminent DREF implemented activities",
"nationalSocietyDescriptionTen": "Imminent DREF and response DREF report in one common final report",
"nationalSocietyDescriptionEleven": "One financial report of the final Imminent DREF and the response DREF operations.",
"nationalSocietyDescriptionTwelve": "In the event the disaster materializes, however the National Society does not wish to request international support, the National Society shall:",
"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,",
"nationalSocietyDescriptionFourteen": "In the event the disaster does not materialize, the National Society shall:",
"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.",
"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.",
"nationalSocietyBankDetails": "Bank details of the National Society",
"nationalSocietyBankDescription": "to which the IFRC shall transfer the funds will be transferred.",
"nationalSocietyBankName": "Bank Name and Address",
"nationalSocietyBankAccountNumber": "Bank Account Number and Currency",
"nationalSocietySwiftCode": "IBAN / SWIFT Code",
"nationalSocietyAmount": "Amount(CHF)",
"nationalSocietyAmountCHF": "CHF 75,000/CHF 90800",
"nationalSocietyAdvancePayment": "For the Purpose of Advance Payment",
"nationalSocietyBankFooter": "Please find attached letter from the Bank confirming banking relationship details.",
"imminentDrefRequest": "This Imminent DREF request is signed on behalf of:",
"imminentDrefSigned": "SIGNED by the authorised representative of the National Society",
"imminentIFRCSigned": "SIGNED by the authorised representative of the IFRC",
"imminentSignature": "Signature",
"imminentPrintedSignatory": "Printed Signatory's Name",
"imminentTitle": "Title",
"imminentDate": "Date"
}
}
Loading
Loading