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

DREF Super Ticket 2 #1753

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
@@ -199,14 +199,6 @@ function useImportTemplateSchema() {
validation: 'string',
},

emergency_appeal_planned: {
type: 'select',
label: 'Emergency appeal planned',
optionsKey: '__boolean',
validation: 'boolean',
description: 'Select <b>Yes</b> or <b>No</b> from the drop-down list.',
},

// EVENT DETAIL

did_it_affect_same_area: {
@@ -282,6 +274,22 @@ function useImportTemplateSchema() {
),
},

// FIXME: These are not showing up on the file
complete_child_safeguarding_risk: {
type: 'select',
validation: 'boolean',
optionsKey: '__boolean',
label: 'Did you complete the Child Safeguarding Risk Analysis in previous operations?',
description: 'Select <b>Yes</b> or <b>No</b> from the drop-down list.',
},

child_safeguarding_risk_level: {
type: 'input',
label: 'Child safeguarding risk level',
validation: 'textArea',
description: 'What was the risk level for child safeguarding risk analysis?',
},

event_date: {
headingBefore: 'Description of the Event',
type: 'input',
@@ -297,6 +305,27 @@ function useImportTemplateSchema() {
description: 'People Affected include all those whose lives and livelihoods have been impacted as a direct result of the event.',
},

estimated_number_of_affected_male: {
type: 'input',
validation: 'number',
label: 'Estimated number of affected male',
description: '',
},

estimated_number_of_affected_female: {
type: 'input',
validation: 'number',
label: 'Estimated number of affected female',
description: '',
},

estimated_number_of_affected_minors: {
type: 'input',
validation: 'number',
label: 'Estimated number of affected minors',
description: '',
},

people_in_need: {
type: 'input',
validation: 'number',
@@ -669,6 +698,45 @@ function useImportTemplateSchema() {
),
},

has_anti_fraud_corruption_policy: {
type: 'select',
optionsKey: '__boolean',
validation: 'boolean',
label: 'Does your National Society have anti-fraud and corruption policy?',
description: '',
},

has_sexual_abuse_policy: {
type: 'select',
optionsKey: '__boolean',
validation: 'boolean',
label: 'Does your National Society have prevention of sexual exploitation and abuse policy?',
description: '',
},

has_child_protection_policy: {
type: 'select',
optionsKey: '__boolean',
validation: 'boolean',
label: 'Does your National Society have child protection/child safeguarding policy?',
description: '',
},

has_whistleblower_protection_policy: {
type: 'select',
optionsKey: '__boolean',
validation: 'boolean',
label: 'Does your National Society have whistleblower protection policy?',
description: '',
},

has_anti_sexual_harassment_policy: {
type: 'select',
optionsKey: '__boolean',
validation: 'boolean',
label: 'Does your National Society have anti-sexual harassment policy?',
description: '',
},
has_child_safeguarding_risk_analysis_assessment: {
type: 'select',
optionsKey: '__boolean',
@@ -775,6 +843,13 @@ function useImportTemplateSchema() {
),
},

is_volunteer_team_diverse: {
type: 'input',
validation: 'textArea',
label: 'Does your volunteer team reflect the gender, age, and cultural diversity of the people you’re helping? What gaps exist in your volunteer team’s gender, age, or cultural diversity, and how are you addressing them to ensure inclusive and appropriate support?',
description: 'This question is about making sure your team includes the right mix of people to best support those affected. For example, if you’re helping single female heads of households, it’s important to have enough female volunteers to make everyone feel comfortable and understood. Including team members who share the same language or cultural background as the people you’re helping can also make a big difference in building trust and providing effective support.',
},

is_surge_personnel_deployed: {
type: 'select',
validation: 'boolean',
19 changes: 16 additions & 3 deletions app/src/views/DrefApplicationExport/i18n.json
Original file line number Diff line number Diff line change
@@ -21,7 +21,7 @@
"monthsSuffix": " months",
"operationEndDateLabel": "Operation End Date",
"drefPublishedLabel": "DREF Published",
"targetedAreasLabel": "Targeted Areas",
"targetedAreasLabel": "Targeted Regions",
"eventDescriptionSectionHeading": "Description of the Event",
"approximateDateOfImpactHeading": "Approximate date of impact",
"whatWhereWhenSectionHeading": "What happened, where and when?",
@@ -38,6 +38,11 @@
"nsOperationLabel": "If yes, please specify which operation",
"recurrentEventJustificationLabel": "If you have answered yes to all questions above, justify why the use of DREF for a recurrent event, or how this event should not be considered recurrent",
"lessonsLearnedLabel": "Lessons learned",
"completeChildSafeguardingRiskLabel": "Did you complete the Child Safeguarding Risk Analysis in previous operations, what was risk level?",
"childSafeguardingRiskLevelLabel": "What was the risk level for Child Safeguarding Risk Analysis?",
"estimatedAffectedMale": "Estimated male",
"estimatedAffectedFemale": "Estimated female",
"estimatedAffectedMinors": "Estimated minors",
"currentNationalSocietyActionsHeading": "Current National Society Actions",
"nationalSocietyActionsHeading": "National Society anticipatory actions started",
"drefFormNsResponseStarted": "Start date of National Society actions",
@@ -67,8 +72,8 @@
"ruralLabel": "Rural",
"urbanLabel": "Urban",
"peopleWithDisabilitiesLabel": "People with disabilities (estimated)",
"riskAndSecuritySectionHeading": "Risk and Security Considerations",
"riskSecurityHeading": "Please indicate about potential operation risk for this operations and mitigation actions",
"riskAndSecuritySectionHeading": "Risk and Security Considerations (including \"management\")",
"riskSecurityHeading": "Please analyse and indicate potential risks for this operation, its root causes and mitigation actions.",
"safetyConcernHeading": "Please indicate any security and safety concerns for this operation",
"hasChildRiskCompleted": "Has the child safeguarding risk analysis assessment been completed?",
"plannedInterventionSectionHeading": "Planned Intervention",
@@ -80,6 +85,12 @@
"priorityActionsHeading": "Priority Actions",
"aboutSupportServicesSectionHeading": "About Support Services",
"humanResourcesHeading": "How many staff and volunteers will be involved in this operation. Briefly describe their role.",
"isVolunteerTeamDiverseHeading": "Does your volunteer team reflect the gender, age, and cultural diversity of the people you’re helping? What gaps exist in your volunteer team’s gender, age, or cultural diversity, and how are you addressing them to ensure inclusive and appropriate support?",
"hasAntiFraudPolicy": "Does your National Society have anti-fraud and corruption policy?",
"hasSexualAbusePolicy": "Does your National Society have prevention of sexual exploitation and abuse policy?",
"hasChildProtectionPolicy": "Does your National Society have child protection/child safeguarding policy?",
"hasWhistleblowerProtectionPolicy": "Does your National Society have whistleblower protection policy?",
"hasAntiSexualHarassmentPolicy": "Does your National Society have anti-sexual harassment policy?",
"surgePersonnelDeployedHeading": "Will surge personnel be deployed? Please provide the role profile needed.",
"logisticCapacityHeading": "If there is procurement, will it be done by National Society or IFRC?",
"pmerHeading": "How will this operation be monitored?",
@@ -92,6 +103,8 @@
"projectManagerContactHeading": "IFRC Project Manager",
"focalPointContactHeading": "IFRC focal point for the emergency",
"mediaContactHeading": "Media Contact",
"nationalSocietyIntegrityHeading": "National Societies' Integrity Focal Point",
"nationalSocietyHotlineHeading": "National Society Hotline",
"imageLogoIFRCAlt": "IFRC",
"drefApplicationExportRisk": "Risk",
"drefApplicationExportMitigation": "Mitigation action",
151 changes: 150 additions & 1 deletion app/src/views/DrefApplicationExport/index.tsx
Original file line number Diff line number Diff line change
@@ -204,6 +204,9 @@ export function Component() {
|| isDefined(drefResponse?.event_map_file?.file);

const lessonsLearnedDefined = isTruthyString(drefResponse?.lessons_learned?.trim());
const childSafeguardingRiskLevelDefined = isTruthyString(
drefResponse?.child_safeguarding_risk_level?.trim(),
);
const showPreviousOperations = drefResponse?.type_of_dref !== DREF_TYPE_ASSESSMENT && (
isDefined(drefResponse?.did_it_affect_same_area)
|| isDefined(drefResponse?.did_it_affect_same_population)
@@ -270,11 +273,25 @@ export function Component() {
&& isDefined(drefResponse.risk_security)
&& drefResponse.risk_security.length > 0;
const riskSecurityConcernDefined = isTruthyString(drefResponse?.risk_security_concern?.trim());
const hasAntiFraudPolicy = isDefined(drefResponse?.has_anti_fraud_corruption_policy);
const hasSexualAbusePolicy = isDefined(drefResponse?.has_sexual_abuse_policy);
const hasChildProtectionPolicy = isDefined(drefResponse?.has_child_protection_policy);
const hasWhistleblowerProtectionPolicy = isDefined(
drefResponse?.has_whistleblower_protection_policy,
);
const hasAntiSexualHarassmentPolicy = isDefined(
drefResponse?.has_anti_sexual_harassment_policy,
);
const hasChildrenSafeguardingDefined = isDefined(
drefResponse?.has_child_safeguarding_risk_analysis_assessment,
);
const showRiskAndSecuritySection = riskSecurityDefined
|| riskSecurityConcernDefined
|| hasAntiFraudPolicy
|| hasSexualAbusePolicy
|| hasChildProtectionPolicy
|| hasWhistleblowerProtectionPolicy
|| hasAntiSexualHarassmentPolicy
|| hasChildrenSafeguardingDefined;

const plannedInterventionDefined = isDefined(drefResponse)
@@ -283,6 +300,9 @@ export function Component() {
&& isDefined(plannedInterventions);

const humanResourceDefined = isTruthyString(drefResponse?.human_resource?.trim());
const isVolunteerTeamDiverseDefined = isTruthyString(
drefResponse?.is_volunteer_team_diverse?.trim(),
);
const surgePersonnelDeployedDefined = isTruthyString(
drefResponse?.surge_personnel_deployed?.trim(),
);
@@ -334,11 +354,26 @@ export function Component() {
drefResponse?.media_contact_phone_number,
].filter(isTruthyString).join(', ');
const mediaContactDefined = isTruthyString(mediaContactText);
const nationalSocietyIntegrityContactText = [
drefResponse?.national_society_integrity_contact_name,
drefResponse?.national_society_integrity_contact_title,
drefResponse?.national_society_integrity_contact_email,
drefResponse?.national_society_integrity_contact_phone_number,
].filter(isTruthyString).join(', ');
const nationalSocietyIntegrityContactDefined = isTruthyString(
nationalSocietyIntegrityContactText,
);
const nationalSocietyHotlineDefined = isTruthyString(
drefResponse?.national_society_hotline_phone_number,
);

const showContactsSection = nsContactDefined
|| appealManagerContactDefined
|| projectManagerContactDefined
|| focalPointContactDefined
|| mediaContactDefined;
|| mediaContactDefined
|| nationalSocietyIntegrityContactDefined
|| nationalSocietyHotlineDefined;
return (
<div className={styles.drefApplicationExport}>
<Container childrenContainerClassName={styles.pageTitleSection}>
@@ -431,6 +466,30 @@ export function Component() {
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedMale}
value={drefResponse?.estimated_number_of_affected_male}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedFemale}
value={drefResponse?.estimated_number_of_affected_female}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedMinors}
value={drefResponse?.estimated_number_of_affected_minors}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.budget}
label={strings.peopleTargetedLabel}
@@ -650,6 +709,21 @@ export function Component() {
strongLabel
/>
)}
<BlockTextOutput
label={strings.completeChildSafeguardingRiskLabel}
value={drefResponse?.complete_child_safeguarding_risk}
valueType="boolean"
strongValue
/>
{childSafeguardingRiskLevelDefined && (
<TextOutput
className={styles.childSafeguardingRiskLevel}
label={strings.childSafeguardingRiskLevelLabel}
value={drefResponse?.child_safeguarding_risk_level}
valueType="text"
strongLabel
/>
)}
</Container>
)}
{showNsAction && (
@@ -935,6 +1009,56 @@ export function Component() {
<Heading level={2}>
{strings.riskAndSecuritySectionHeading}
</Heading>
{hasAntiFraudPolicy && (
<Container>
<BlockTextOutput
label={strings.hasAntiFraudPolicy}
value={drefResponse?.has_anti_fraud_corruption_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasSexualAbusePolicy && (
<Container>
<BlockTextOutput
label={strings.hasSexualAbusePolicy}
value={drefResponse?.has_sexual_abuse_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasChildProtectionPolicy && (
<Container>
<BlockTextOutput
label={strings.hasChildProtectionPolicy}
value={drefResponse?.has_child_protection_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasWhistleblowerProtectionPolicy && (
<Container>
<BlockTextOutput
label={strings.hasWhistleblowerProtectionPolicy}
value={drefResponse?.has_whistleblower_protection_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasAntiSexualHarassmentPolicy && (
<Container>
<BlockTextOutput
label={strings.hasAntiSexualHarassmentPolicy}
value={drefResponse?.has_anti_sexual_harassment_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{riskSecurityDefined && (
<Container
heading={strings.riskSecurityHeading}
@@ -1066,6 +1190,15 @@ export function Component() {
</DescriptionText>
</Container>
)}
{isVolunteerTeamDiverseDefined && (
<Container
heading={strings.isVolunteerTeamDiverseHeading}
>
<DescriptionText>
{drefResponse?.is_volunteer_team_diverse}
</DescriptionText>
</Container>
)}
{surgePersonnelDeployedDefined && (
<Container
heading={strings.surgePersonnelDeployedHeading}
@@ -1173,6 +1306,22 @@ export function Component() {
strongLabel
/>
)}
{nationalSocietyIntegrityContactDefined && (
<TextOutput
labelClassName={styles.contactPersonLabel}
label={strings.nationalSocietyIntegrityHeading}
value={nationalSocietyIntegrityContactText}
strongLabel
/>
)}
{nationalSocietyHotlineDefined && (
<TextOutput
labelClassName={styles.contactPersonLabel}
label={strings.nationalSocietyHotlineHeading}
value={drefResponse?.national_society_hotline_phone_number}
strongLabel
/>
)}
</Container>
<Link href="/emergencies">
{strings.drefExportReference}
1 change: 1 addition & 0 deletions app/src/views/DrefApplicationExport/styles.module.css
Original file line number Diff line number Diff line change
@@ -87,6 +87,7 @@
grid-template-columns: 1fr 1fr;

.recurrent-event-justification,
.child-safeguarding-risk-level,
.lessons-learned {
grid-column: span 2;
background-color: var(--pdf-element-bg);
8 changes: 8 additions & 0 deletions app/src/views/DrefApplicationForm/Actions/i18n.json
Original file line number Diff line number Diff line change
@@ -10,6 +10,12 @@
"drefFormDidNationalSocietyStartedImminent": "Did the National Society started any anticipatory actions?",
"drefFormDidNationalSocietyStartedSlow": "Has the National Society started any actions?",
"drefFormGapsInAssessment": "Any identified gaps/limitations in the assessment",
"drefFormGapsInAssessmentDescriptionHeading": "Consider the following:",
"drefFormGapsInAssessmentDescriptionPoint1": "Unmet needs: are there specific sectors (e.g., shelter, WASH, health) where needs remain unmet or only partially addressed?",
"drefFormGapsInAssessmentDescriptionPoint2": "Resource shortages: highlight any shortages in available resources (e.g., funding, personnel, supplies) that limit the ability to meet the identified needs.",
"drefFormGapsInAssessmentDescriptionPoint3": "Operational challenges: mention any operational constraints that are preventing a full response to the needs (e.g., logistical issues, insufficient capacity).",
"drefFormGapsInAssessmentDescriptionPoint4": "Coordination issues: note any challenges in coordinating with other actors or agencies that have resulted in gaps in service delivery or response coverage.",
"drefFormGapsInAssessmentDescriptionPoint5": "Vulnerable groups: identify any specific vulnerable groups whose needs may not have been fully captured or addressed during the assessment (e.g., displaced persons, elderly, people with disabilities).",
"drefFormIcrc": "ICRC",
"drefFormIcrcDescription": "Presence or not of ICRC in country, and support directly provided for this emergency response. Other programs and support provided outside of the scope of this emergency should not be indicated here.",
"drefFormIfrc": "IFRC",
@@ -19,6 +25,7 @@
"ifrcNetworkActionsHeading": "IFRC Network Actions Related To The Current Event",
"icrcActionsHeading": "ICRC Actions Related To The Current Event",
"drefFormNationalAuthorities": "National authorities",
"drefFormNationalAuthoritiesDescription": "Brief description of actions taken by the national authorities.",
"drefFormNationalOtherActors": "Other Actors Actions Related To The Current Event",
"drefFormNationalSocietiesActions": "Current National Society Actions",
"drefFormNationalSocietiesActionsDescription": "Please indicate a description of the ongoing response with if possible: Branches involved, number of volunteers/staff involved in actions, assets deployed/distributed, number of people reach. Impact/added value of the NS in the response already ongoing.",
@@ -29,6 +36,7 @@
"drefFormPartnerNationalSociety": "Participating National Societies",
"drefFormPartnerNationalSocietyDescription": "Briefly set out which PNS are present and give details of PNS contributions/roles on the ground and remotely for this specific operation",
"drefFormUNorOtherActors": "UN or other actors",
"drefFormUNorOtherActorsDescription": "Brief description of actions taken by the UN or other actors.",
"drefFormAddButton": "Add"
}
}
26 changes: 26 additions & 0 deletions app/src/views/DrefApplicationForm/Actions/index.tsx
Original file line number Diff line number Diff line change
@@ -333,6 +333,7 @@ function Actions(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormNationalAuthorities}
description={strings.drefFormNationalAuthoritiesDescription}
>
<TextArea
label={strings.drefFormActionDescription}
@@ -345,6 +346,7 @@ function Actions(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormUNorOtherActors}
description={strings.drefFormUNorOtherActorsDescription}
>
<TextArea
label={strings.drefFormActionDescription}
@@ -454,6 +456,30 @@ function Actions(props: Props) {
{value?.type_of_dref !== TYPE_IMMINENT && (
<InputSection
title={strings.drefFormGapsInAssessment}
description={(
<>
<p>
{strings.drefFormGapsInAssessmentDescriptionHeading}
</p>
<ul>
<li>
{strings.drefFormGapsInAssessmentDescriptionPoint1}
</li>
<li>
{strings.drefFormGapsInAssessmentDescriptionPoint2}
</li>
<li>
{strings.drefFormGapsInAssessmentDescriptionPoint3}
</li>
<li>
{strings.drefFormGapsInAssessmentDescriptionPoint4}
</li>
<li>
{strings.drefFormGapsInAssessmentDescriptionPoint5}
</li>
</ul>
</>
)}
>
<TextArea
label={strings.drefFormActionDescription}
9 changes: 9 additions & 0 deletions app/src/views/DrefApplicationForm/EventDetail/i18n.json
Original file line number Diff line number Diff line change
@@ -13,6 +13,11 @@
"drefFormPeopleInNeed": "People in need (Optional)",
"drefFormPeopleAffected": "Total affected population",
"drefFormRiskPeopleLabel": "Total population at risk",
"drefFormAffectedMaleLabel": "Estimated male",
"drefFormAffectedFemaleLabel": "Estimated female",
"drefFormAffectedMinorsLabel": "Estimated minors",
"drefFormChildSafeguardingRiskAnalysisTitle": "Did you complete the Child Safeguarding Risk Analysis in previous operations, what was risk level?",
"drefFormChildSafeguardingRiskLevelLabel": "Risk Level",
"drefFormPeopleInNeedDescriptionImminent": "Include all those whose physical security, basic rights, dignity, living conditions or livelihoods are threatened or have been disrupted, and whose current level of access to basic services, goods and social protection will be inadequate to re-establish normal living conditions without additional assistance",
"drefFormPeopleInNeedDescriptionSlowSudden": "People in Need (PIN) are those members whose physical security, basic rights, dignity, living conditions or livelihoods are threatened or have been disrupted, and whose current level of access to basic services, goods and social protection is inadequate to re-establish normal living conditions without additional assistance.",
"drefFormPeopleAffectedDescriptionImminent": "Includes all those whose lives and livelihoods are at risk as a direct result of the shock or stress.",
@@ -36,6 +41,10 @@
"drefFormUploadSupportingDocumentButtonLabel": "Upload document",
"drefFormUploadSupportingDocumentDescription": "Here the National Society can upload documentation that substantiates their decision to launch this operation now. For example: seasonal outlooks, forecast information, reports from credible sources...etc.",
"drefFormWhatWhereWhen": "What happened, where and when?",
"drefFormWhatWhereWhenDescriptionHeading": "Clearly Describe:",
"drefFormWhatWhereWhenDescriptionPoint1": "What happened: Briefly explain the nature of the emergency (e.g., flood, earthquake, epidemic). Include key details such as the intensity, and any unique aspects of the event.",
"drefFormWhatWhereWhenDescriptionPoint2": "Where: Specify the geographic location(s) affected. Be as precise as possible, including names of countries, regions, cities, or specific areas impacted by the event.",
"drefFormWhatWhereWhenDescriptionPoint3": "When: Indicate the date and time when the event occurred or began. If the situation is ongoing, mention that and provide relevant updates on the timeframe.",
"drefOperationalLearningPlatformLabel": "To access the Operational Learning Dashboard and check learnings for the country, {clickHereLink}",
"clickHereLinkLabel": "Click Here",
"drefFormSelectImages": "Select images",
61 changes: 61 additions & 0 deletions app/src/views/DrefApplicationForm/EventDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -249,6 +249,25 @@ function EventDetail(props: Props) {
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormChildSafeguardingRiskAnalysisTitle}
>
<BooleanInput
name="complete_child_safeguarding_risk"
value={value.complete_child_safeguarding_risk}
onChange={setFieldValue}
error={error?.complete_child_safeguarding_risk}
disabled={disabled}
/>
<TextArea
label={strings.drefFormChildSafeguardingRiskLevelLabel}
name="child_safeguarding_risk_level"
onChange={setFieldValue}
value={value.child_safeguarding_risk_level}
error={error?.child_safeguarding_risk_level}
disabled={disabled}
/>
</InputSection>
</Container>
)}
<Container
@@ -355,6 +374,30 @@ function EventDetail(props: Props) {
disabled={disabled}
/>
)}
<NumberInput
name="estimated_number_of_affected_male"
label={strings.drefFormAffectedMaleLabel}
value={value?.estimated_number_of_affected_male}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_male}
disabled={disabled}
/>
<NumberInput
name="estimated_number_of_affected_female"
label={strings.drefFormAffectedFemaleLabel}
value={value?.estimated_number_of_affected_female}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_female}
disabled={disabled}
/>
<NumberInput
name="estimated_number_of_affected_minors"
label={strings.drefFormAffectedMinorsLabel}
value={value?.estimated_number_of_affected_minors}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_minors}
disabled={disabled}
/>
{/* FIXME: use grid to fix the empty div issue */}
{/* NOTE: Empty div to preserve the layout */}
<div />
@@ -366,6 +409,24 @@ function EventDetail(props: Props) {
? strings.drefFormWhatWhereWhen
: strings.drefFormImminentDisaster
}
description={value.type_of_dref !== TYPE_IMMINENT && (
<>
<p>
{strings.drefFormWhatWhereWhenDescriptionHeading}
</p>
<ol>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint1}
</li>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint2}
</li>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint3}
</li>
</ol>
</>
)}
>
<TextArea
name="event_description"
74 changes: 64 additions & 10 deletions app/src/views/DrefApplicationForm/Operation/i18n.json

Large diffs are not rendered by default.

294 changes: 282 additions & 12 deletions app/src/views/DrefApplicationForm/Operation/index.tsx

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
"strings": {
"drefFormCopyFRSuccessMessage": "Successfully copied some data from the selected field report",
"drefFormEventDetailsTitle": "Import data from existing field report",
"drefFormEventDescription": "These field reports have already been filtered by the National Society that you have selected. Selecting a field report will pre-fill matching fields in this request, which you can modify.",
"drefFormEventDescription": "If a field report related to this event/operation already exists, you can use it to pre-fill matching fields in this request. To do so, select the relevant field report from the drop-down list and click “Copy”.",
"drefFormSelectFieldReportPlaceholder": "Select field report",
"drefFormCopyButtonLabel": "Copy"
}
4 changes: 3 additions & 1 deletion app/src/views/DrefApplicationForm/Overview/i18n.json
Original file line number Diff line number Diff line change
@@ -7,13 +7,15 @@
"drefFormInstantShareLabel": "Share",
"drefFormEssentialInformation": "Essential Information",
"drefFormNationalSociety": "Name of National Society",
"drefFormNationalSocietyDescription": "Indicate your National Society by selecting it from the drop-down list.",
"drefFormTypeOfDref": "Type of DREF",
"drefFormImminentDisasterDetails": "Hazard Details",
"drefFormDisasterDetails": "Disaster Details",
"drefFormImminentDisasterTypeLabel": "Type of Hazard",
"drefFormDisasterTypeLabel": "Type of Disaster",
"drefFormTypeOfOnsetLabel": "Type of Onset",
"drefFormManMadeEvent": "Is this a man made event?",
"formShareButtonLabel": "Add",
"drefFormImminentDisasterCategoryLabel": "Disaster Category (Optional)",
"drefFormDisasterCategoryLabel": "Disaster Category",
"drefFormAffectedCountryAndProvinceImminent": "Affected Country and Affected Region(s)",
@@ -34,4 +36,4 @@
"drefFormUploadCrisisDocument": "If available please upload Crisis categorization Analysis",
"drefFormUploadDocumentButtonLabel": "Upload document"
}
}
}
79 changes: 60 additions & 19 deletions app/src/views/DrefApplicationForm/Overview/index.tsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,11 @@ import {
type SetStateAction,
useCallback,
} from 'react';
import { WikiHelpSectionLineIcon } from '@ifrc-go/icons';
import { useParams } from 'react-router-dom';
import {
ShareLineIcon,
WikiHelpSectionLineIcon,
} from '@ifrc-go/icons';
import {
BooleanInput,
Button,
@@ -13,9 +17,15 @@ import {
SelectInput,
TextInput,
} from '@ifrc-go/ui';
import { useTranslation } from '@ifrc-go/ui/hooks';
import {
useBooleanState,
useTranslation,
} from '@ifrc-go/ui/hooks';
import { stringValueSelector } from '@ifrc-go/ui/utils';
import { isNotDefined } from '@togglecorp/fujs';
import {
isDefined,
isNotDefined,
} from '@togglecorp/fujs';
import {
type EntriesAsList,
type Error,
@@ -26,6 +36,7 @@ import {
import CountrySelectInput from '#components/domain/CountrySelectInput';
import DisasterTypeSelectInput from '#components/domain/DisasterTypeSelectInput';
import DistrictSearchMultiSelectInput, { type DistrictItem } from '#components/domain/DistrictSearchMultiSelectInput';
import DrefShareModal from '#components/domain/DrefShareModal';
import UserItem from '#components/domain/DrefShareModal/UserItem';
import { type FieldReportItem as FieldReportSearchItem } from '#components/domain/FieldReportSearchSelectInput';
import GoSingleFileInput from '#components/domain/GoSingleFileInput';
@@ -36,11 +47,15 @@ import Link from '#components/Link';
import useCountry from '#hooks/domain/useCountry';
import useDisasterType from '#hooks/domain/useDisasterType';
import useGlobalEnums from '#hooks/domain/useGlobalEnums';
import useInputState from '#hooks/useInputState';
import {
DISASTER_CATEGORY_ORANGE,
DISASTER_CATEGORY_RED,
} from '#utils/constants';
import { type GoApiResponse } from '#utils/restRequest';
import {
type GoApiResponse,
useRequest,
} from '#utils/restRequest';

import {
DISASTER_FIRE,
@@ -84,7 +99,6 @@ interface Props {

fieldReportOptions: FieldReportSearchItem[] | null | undefined;
setFieldReportOptions: Dispatch<SetStateAction<FieldReportSearchItem[] | null | undefined>>;
drefUsers?: User[] | null;
}

const userKeySelector = (item: User) => item.id;
@@ -101,7 +115,6 @@ function Overview(props: Props) {
setDistrictOptions,
fieldReportOptions,
setFieldReportOptions,
drefUsers,
} = props;

const strings = useTranslation(i18n);
@@ -113,6 +126,8 @@ function Overview(props: Props) {
} = useGlobalEnums();

const countryOptions = useCountry();
const { drefId } = useParams<{ drefId: string }>();
const [drefUsers, setDrefUsers] = useInputState<User[] | undefined | null>([]);

const disasterTypes = useDisasterType();

@@ -160,6 +175,29 @@ function Overview(props: Props) {
}), []);

const error = getErrorObject(formError);
const [showShareModal, {
setTrue: setShowShareModalTrue,
setFalse: setShowShareModalFalse,
}] = useBooleanState(false);

const {
retrigger: getDrefUsers,
} = useRequest({
skip: isNotDefined(drefId),
url: '/api/v2/dref-share-user/{id}/',
pathVariables: { id: Number(drefId) },
onSuccess: (response) => {
setDrefUsers(response.users_details);
},
});

const handleUserShareSuccess = useCallback(() => {
setShowShareModalFalse();
getDrefUsers();
}, [
getDrefUsers,
setShowShareModalFalse,
]);

return (
<div className={styles.operationOverview}>
@@ -185,6 +223,21 @@ function Overview(props: Props) {
pending={false}
compact
/>
<Button
name={undefined}
onClick={setShowShareModalTrue}
variant="secondary"
icons={<ShareLineIcon />}
>
{strings.formShareButtonLabel}
</Button>
{showShareModal && isDefined(drefId) && (
<DrefShareModal
onCancel={setShowShareModalFalse}
onSuccess={handleUserShareSuccess}
drefId={Number(drefId)}
/>
)}
</InputSection>
</Container>
<Container
@@ -193,6 +246,7 @@ function Overview(props: Props) {
>
<InputSection
title={strings.drefFormNationalSociety}
description={strings.drefFormNationalSocietyDescription}
numPreferredColumns={2}
withAsteriskOnTitle
>
@@ -387,19 +441,6 @@ function Overview(props: Props) {
</Button>
</div>
</InputSection>
{value?.type_of_dref !== TYPE_LOAN && (
<InputSection
title={strings.drefFormEmergencyAppealPlanned}
>
<BooleanInput
name="emergency_appeal_planned"
value={value?.emergency_appeal_planned}
onChange={setFieldValue}
error={error?.emergency_appeal_planned}
disabled={disabled}
/>
</InputSection>
)}
{value?.type_of_dref !== TYPE_LOAN && (
<InputSection
title={strings.drefFormUploadMap}
7 changes: 7 additions & 0 deletions app/src/views/DrefApplicationForm/Submission/i18n.json
Original file line number Diff line number Diff line change
@@ -31,6 +31,13 @@
"drefFormFocalPointTitle": "Title",
"drefFormFocalPointEmail": "Email",
"drefFormFocalPointPhoneNumber":"Phone Number",
"drefFormNationalSocietyIntegrityTitle": "National Societies' Integrity Focal Point",
"drefFormIntegrityContactNameLabel": "Name",
"drefFormIntegrityContactEmailLabel": "Email",
"drefFormIntegrityContactTitleLabel": "Title",
"drefFormIntegrityContactPhoneNumberLabel": "Phone Number",
"drefFormNationalSocietyHotlineNumberTitle": "National Society Hotline",
"drefFormNationalSocietyHotlineNumberLabel": "Phone Number",
"drefApplicationFormImageAlt": "Image"
}
}
50 changes: 50 additions & 0 deletions app/src/views/DrefApplicationForm/Submission/index.tsx
Original file line number Diff line number Diff line change
@@ -404,6 +404,56 @@ function Submission(props: Props) {
/>
</InputSection>
)}
<InputSection
title={strings.drefFormNationalSocietyIntegrityTitle}
numPreferredColumns={2}
>
<TextInput
label={strings.drefFormIntegrityContactNameLabel}
name="national_society_integrity_contact_name"
value={value.national_society_integrity_contact_name}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_name}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactEmailLabel}
name="national_society_integrity_contact_email"
value={value.national_society_integrity_contact_email}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_email}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactTitleLabel}
name="national_society_integrity_contact_title"
value={value.national_society_integrity_contact_title}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_title}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactPhoneNumberLabel}
name="national_society_integrity_contact_phone_number"
value={value.national_society_integrity_contact_phone_number}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_phone_number}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormNationalSocietyHotlineNumberTitle}
numPreferredColumns={2}
>
<TextInput
label={strings.drefFormNationalSocietyHotlineNumberLabel}
name="national_society_hotline_phone_number"
value={value.national_society_hotline_phone_number}
onChange={setFieldValue}
error={error?.national_society_hotline_phone_number}
disabled={disabled}
/>
</InputSection>
</Container>
</div>
);
17 changes: 16 additions & 1 deletion app/src/views/DrefApplicationForm/common.tsx
Original file line number Diff line number Diff line change
@@ -43,7 +43,6 @@ export const overviewTabFields: (keyof PartialDref)[] = [
'district',
'title_prefix',
'title',
'emergency_appeal_planned',
'event_map_file',
'cover_image_file',
] satisfies (keyof PartialDref)[];
@@ -56,9 +55,14 @@ export const eventDetailTabFields: (keyof PartialDref)[] = [
'ns_request_text',
'dref_recurrent_text',
'lessons_learned',
'child_safeguarding_risk_level',
'complete_child_safeguarding_risk',
'event_date',
'event_text',
'num_affected',
'estimated_number_of_affected_male',
'estimated_number_of_affected_female',
'estimated_number_of_affected_minors',
'people_in_need',
'event_description',
'event_scope',
@@ -102,10 +106,16 @@ export const operationTabFields: (keyof PartialDref)[] = [
'risk_security',
'risk_security_concern',
'has_child_safeguarding_risk_analysis_assessment',
'has_anti_fraud_corruption_policy',
'has_sexual_abuse_policy',
'has_child_protection_policy',
'has_whistleblower_protection_policy',
'has_anti_sexual_harassment_policy',
'budget_file',
'amount_requested',
'planned_interventions',
'human_resource',
'is_volunteer_team_diverse',
'is_surge_personnel_deployed',
'surge_personnel_deployed',
'logistic_capacity_of_ns',
@@ -141,6 +151,11 @@ export const timeframeAndContactsTabFields: (keyof PartialDref)[] = [
'media_contact_name',
'media_contact_email',
'media_contact_phone_number',
'national_society_integrity_contact_name',
'national_society_integrity_contact_title',
'national_society_integrity_contact_email',
'national_society_integrity_contact_phone_number',
'national_society_hotline_phone_number',
'media_contact_title',
] satisfies (keyof PartialDref)[];

1 change: 0 additions & 1 deletion app/src/views/DrefApplicationForm/i18n.json
Original file line number Diff line number Diff line change
@@ -20,7 +20,6 @@
"formLoadingMessage": "Loading DREF Application...",
"formNotAvailableInNonEnglishMessage": "DREF Application is not available in the selected language!",
"formEditNotAvailableInSelectedLanguageMessage": "DREF Application is not available for edit in the selected language!",
"formShareButtonLabel": "Share",
"drefFeedbackForm": "Provide feedback on IFRC DREF"
}
}
91 changes: 26 additions & 65 deletions app/src/views/DrefApplicationForm/index.tsx
Original file line number Diff line number Diff line change
@@ -5,10 +5,7 @@ import {
useState,
} from 'react';
import { useParams } from 'react-router-dom';
import {
DownloadTwoLineIcon,
ShareLineIcon,
} from '@ifrc-go/icons';
import { DownloadTwoLineIcon } from '@ifrc-go/icons';
import {
Button,
Message,
@@ -35,18 +32,15 @@ import {

import { type DistrictItem } from '#components/domain/DistrictSearchMultiSelectInput';
import DrefExportModal from '#components/domain/DrefExportModal';
import DrefShareModal from '#components/domain/DrefShareModal';
import { type FieldReportItem as FieldReportSearchItem } from '#components/domain/FieldReportSearchSelectInput';
import FormFailedToLoadMessage from '#components/domain/FormFailedToLoadMessage';
import LanguageMismatchMessage from '#components/domain/LanguageMismatchMessage';
import NonEnglishFormCreationMessage from '#components/domain/NonEnglishFormCreationMessage';
import { type User } from '#components/domain/UserSearchMultiSelectInput';
import Link from '#components/Link';
import NonFieldError from '#components/NonFieldError';
import Page from '#components/Page';
import useCurrentLanguage from '#hooks/domain/useCurrentLanguage';
import useAlert from '#hooks/useAlert';
import useInputState from '#hooks/useInputState';
import useRouting from '#hooks/useRouting';
import {
type GoApiResponse,
@@ -132,18 +126,13 @@ export function Component() {

const [activeTab, setActiveTab] = useState<TabKeys>('overview');
const [fileIdToUrlMap, setFileIdToUrlMap] = useState<Record<number, string>>({});
const [drefUsers, setDrefUsers] = useInputState<User[] | undefined | null>([]);
const currentLanguage = useCurrentLanguage();

const [
showObsoletePayloadModal,
setShowObsoletePayloadModal,
] = useState(false);

const [showShareModal, {
setTrue: setShowShareModalTrue,
setFalse: setShowShareModalFalse,
}] = useBooleanState(false);
const [showExportModal, {
setTrue: setShowExportModalTrue,
setFalse: setShowExportModalFalse,
@@ -475,17 +464,6 @@ export function Component() {
},
});

const {
retrigger: getDrefUsers,
} = useRequest({
skip: isNotDefined(drefId),
url: '/api/v2/dref-share-user/{id}/',
pathVariables: { id: Number(drefId) },
onSuccess: (response) => {
setDrefUsers(response.users_details);
},
});

const handleFormSubmit = useCallback(
(modifiedAt?: string) => {
formContentRef.current?.scrollIntoView();
@@ -526,14 +504,6 @@ export function Component() {
setActiveTab(newTab);
}, []);

const handleUserShareSuccess = useCallback(() => {
setShowShareModalFalse();
getDrefUsers();
}, [
getDrefUsers,
setShowShareModalFalse,
]);

const nextStep = getNextStep(activeTab, 1, value.type_of_dref);
const prevStep = getNextStep(activeTab, -1, value.type_of_dref);
const saveDrefPending = createDrefPending || updateDrefPending;
@@ -580,24 +550,14 @@ export function Component() {
/>
)}
{isDefined(drefId) && (
<>
<Button
name={undefined}
onClick={setShowShareModalTrue}
variant="secondary"
icons={<ShareLineIcon />}
>
{strings.formShareButtonLabel}
</Button>
<Button
name={undefined}
onClick={setShowExportModalTrue}
icons={<DownloadTwoLineIcon />}
variant="secondary"
>
{strings.formExportLabel}
</Button>
</>
<Button
name={undefined}
onClick={setShowExportModalTrue}
icons={<DownloadTwoLineIcon />}
variant="secondary"
>
{strings.formExportLabel}
</Button>
)}
<Button
name={undefined}
@@ -695,7 +655,6 @@ export function Component() {
setDistrictOptions={setDistrictOptions}
fieldReportOptions={fieldReportOptions}
setFieldReportOptions={setFieldReportOptions}
drefUsers={drefUsers}
/>
</TabPanel>
<TabPanel name="eventDetail">
@@ -746,14 +705,23 @@ export function Component() {
>
{strings.formBackButtonLabel}
</Button>
<Button
name={nextStep ?? activeTab}
onClick={handleTabChange}
disabled={isNotDefined(nextStep)}
variant="secondary"
>
{strings.formContinueButtonLabel}
</Button>
{isDefined(nextStep) ? (
<Button
name={nextStep ?? activeTab}
onClick={handleTabChange}
variant="secondary"
>
{strings.formContinueButtonLabel}
</Button>
) : (
<Button
name={undefined}
onClick={handleFormSubmit}
disabled={disabled}
>
{strings.formSaveButtonLabel}
</Button>
)}
</div>
</div>
</>
@@ -765,13 +733,6 @@ export function Component() {
onCancelButtonClick={setShowObsoletePayloadModal}
/>
)}
{showShareModal && isDefined(drefId) && (
<DrefShareModal
onCancel={setShowShareModalFalse}
onSuccess={handleUserShareSuccess}
drefId={Number(drefId)}
/>
)}
{showExportModal && (
<DrefExportModal
onCancel={setShowExportModalFalse}
28 changes: 25 additions & 3 deletions app/src/views/DrefApplicationForm/schema.ts
Original file line number Diff line number Diff line change
@@ -150,6 +150,9 @@ const schema: DrefFormSchema = {
field_report: {}, // This value is set from CopyFieldReportSection
// EVENT DETAILS
num_affected: { validations: [positiveIntegerCondition] },
estimated_number_of_affected_male: { validations: [positiveIntegerCondition] },
estimated_number_of_affected_female: { validations: [positiveIntegerCondition] },
estimated_number_of_affected_minors: { validations: [positiveIntegerCondition] },

// none

@@ -186,6 +189,11 @@ const schema: DrefFormSchema = {
regional_focal_point_title: {},
regional_focal_point_email: { validations: [emailCondition] },
regional_focal_point_phone_number: {},
national_society_integrity_contact_name: {},
national_society_integrity_contact_title: {},
national_society_integrity_contact_email: { validations: [emailCondition] },
national_society_integrity_contact_phone_number: {},
national_society_hotline_phone_number: {},
};

// Note: Section below include conditional form element only
@@ -212,7 +220,6 @@ const schema: DrefFormSchema = {
);

const overviewDrefTypeRelatedFields = [
'emergency_appeal_planned',
'event_map_file',
'cover_image_file',
] as const;
@@ -227,7 +234,6 @@ const schema: DrefFormSchema = {
overviewDrefTypeRelatedFields,
(val): OverviewDrefTypeRelatedFields => {
const conditionalFields: OverviewDrefTypeRelatedFields = {
emergency_appeal_planned: { forceValue: nullValue },
event_map_file: { forceValue: nullValue }, // NOTE: check if this works
cover_image_file: { forceValue: nullValue },
};
@@ -236,7 +242,6 @@ const schema: DrefFormSchema = {
}
return {
...conditionalFields,
emergency_appeal_planned: {},
event_map_file: {
fields: (): EventMapFileFields => ({
client_id: {},
@@ -264,6 +269,8 @@ const schema: DrefFormSchema = {
'did_ns_respond',
'did_ns_request_fund',
'lessons_learned',
'child_safeguarding_risk_level',
'complete_child_safeguarding_risk',
'event_scope',
'event_text',
'anticipatory_actions',
@@ -291,6 +298,8 @@ const schema: DrefFormSchema = {
did_ns_respond: { forceValue: nullValue },
did_ns_request_fund: { forceValue: nullValue },
lessons_learned: { forceValue: nullValue },
complete_child_safeguarding_risk: {},
child_safeguarding_risk_level: {},
event_scope: { forceValue: nullValue },
source_information: { forceValue: [] },
event_text: { forceValue: nullValue },
@@ -582,9 +591,15 @@ const schema: DrefFormSchema = {
'risk_security',
'risk_security_concern',
'has_child_safeguarding_risk_analysis_assessment',
'has_anti_fraud_corruption_policy',
'has_sexual_abuse_policy',
'has_child_protection_policy',
'has_whistleblower_protection_policy',
'has_anti_sexual_harassment_policy',
'budget_file',
'planned_interventions',
'human_resource',
'is_volunteer_team_diverse',
'is_surge_personnel_deployed',
] as const;
type OperationDrefTypeRelatedFields = Pick<
@@ -618,8 +633,14 @@ const schema: DrefFormSchema = {
risk_security: { forceValue: [] },
risk_security_concern: { forceValue: nullValue },
budget_file: { forceValue: nullValue },
has_anti_fraud_corruption_policy: {},
has_anti_sexual_harassment_policy: {},
has_sexual_abuse_policy: {},
has_whistleblower_protection_policy: {},
has_child_protection_policy: {},
planned_interventions: { forceValue: [] },
human_resource: { forceValue: nullValue },
is_volunteer_team_diverse: { forceValue: nullValue },
is_surge_personnel_deployed: { forceValue: nullValue },
has_child_safeguarding_risk_analysis_assessment: { forceValue: nullValue },
};
@@ -711,6 +732,7 @@ const schema: DrefFormSchema = {
}),
},
human_resource: {},
is_volunteer_team_diverse: {},
is_surge_personnel_deployed: {},
};
if (val?.type_of_dref !== TYPE_ASSESSMENT) {
16 changes: 13 additions & 3 deletions app/src/views/DrefFinalReportExport/i18n.json
Original file line number Diff line number Diff line change
@@ -17,14 +17,22 @@
"glideNumberLabel": "Glide Number",
"peopleAffectedLabel": "People Affected",
"peopleTargetedLabel": "People Targeted",
"estimatedAffectedMale": "Estimated male",
"estimatedAffectedFemale": "Estimated female",
"estimatedAffectedMinors": "Estimated minors",
"hasAntiFraudPolicy": "Does your National Society have anti-fraud and corruption policy?",
"hasSexualAbusePolicy": "Does your National Society have prevention of sexual exploitation and abuse policy?",
"hasChildProtectionPolicy": "Does your National Society have child protection/child safeguarding policy?",
"hasWhistleblowerProtectionPolicy": "Does your National Society have whistleblower protection policy?",
"hasAntiSexualHarassmentPolicy": "Does your National Society have anti-sexual harassment policy?",
"peopleAssistedLabel": "People Assisted",
"peopleSuffix": " people",
"operationStartDateLabel": "Operation Start Date",
"operationTimeframeLabel": "Total Operating Timeframe",
"monthsSuffix": " months",
"operationEndDateLabel": "Operational End Date",
"additionalAllocationRequestedLabel": "Additional Allocation Requested",
"targetedAreasLabel": "Targeted Areas",
"targetedAreasLabel": "Targeted Regions",
"eventDescriptionSectionHeading": "Description of the Event",
"approximateDateOfImpactHeading": "Approximate date of impact",
"whatWhereWhenSectionHeading": "What happened, where and when?",
@@ -62,8 +70,8 @@
"ruralLabel": "Rural",
"urbanLabel": "Urban",
"peopleWithDisabilitiesLabel": "People with disabilities (estimated)",
"riskAndSecuritySectionHeading": "Risk and Security Considerations",
"riskSecurityHeading": "Please indicate about potential operation risk for this operations and mitigation actions",
"riskAndSecuritySectionHeading": "Risk and Security Considerations (including \"management\")",
"riskSecurityHeading": "Please analyse and indicate potential risks for this operation, its root causes and mitigation actions.",
"riskLabel": "Risk",
"mitigationLabel": "Mitigation action",
"safetyConcernHeading": "Please indicate any security and safety concerns for this operation",
@@ -88,6 +96,8 @@
"projectManagerContactHeading": "IFRC Project Manager",
"focalPointContactHeading": "IFRC focal point for the emergency",
"mediaContactHeading": "Media Contact",
"nationalSocietyIntegrityHeading": "National Societies' Integrity Focal Point",
"nationalSocietyHotlineHeading": "National Society Hotline",
"sourceInformationSectionHeading": "Source Information",
"sourceInformationSourceNameTitle": "Source Name",
"sourceInformationSourceLinkTitle": "Source Link"
121 changes: 120 additions & 1 deletion app/src/views/DrefFinalReportExport/index.tsx
Original file line number Diff line number Diff line change
@@ -214,8 +214,22 @@ export function Component() {
const hasChildrenSafeguardingDefined = isDefined(
drefResponse?.has_child_safeguarding_risk_analysis_assessment,
);
const hasAntiFraudPolicy = isDefined(drefResponse?.has_anti_fraud_corruption_policy);
const hasSexualAbusePolicy = isDefined(drefResponse?.has_sexual_abuse_policy);
const hasChildProtectionPolicy = isDefined(drefResponse?.has_child_protection_policy);
const hasWhistleblowerProtectionPolicy = isDefined(
drefResponse?.has_whistleblower_protection_policy,
);
const hasAntiSexualHarassmentPolicy = isDefined(
drefResponse?.has_anti_sexual_harassment_policy,
);
const showRiskAndSecuritySection = riskSecurityDefined
|| riskSecurityConcernDefined
|| hasAntiFraudPolicy
|| hasSexualAbusePolicy
|| hasChildProtectionPolicy
|| hasWhistleblowerProtectionPolicy
|| hasAntiSexualHarassmentPolicy
|| hasChildrenSafeguardingDefined;

const plannedInterventionDefined = isDefined(drefResponse)
@@ -267,11 +281,26 @@ export function Component() {
drefResponse?.media_contact_phone_number,
].filter(isTruthyString).join(', ');
const mediaContactDefined = isTruthyString(mediaContactText);
const nationalSocietyIntegrityContactText = [
drefResponse?.national_society_integrity_contact_name,
drefResponse?.national_society_integrity_contact_title,
drefResponse?.national_society_integrity_contact_email,
drefResponse?.national_society_integrity_contact_phone_number,
].filter(isTruthyString).join(', ');
const nationalSocietyIntegrityContactDefined = isTruthyString(
nationalSocietyIntegrityContactText,
);
const nationalSocietyHotlineDefined = isTruthyString(
drefResponse?.national_society_hotline_phone_number,
);

const showContactsSection = nsContactDefined
|| appealManagerContactDefined
|| projectManagerContactDefined
|| focalPointContactDefined
|| mediaContactDefined;
|| mediaContactDefined
|| nationalSocietyIntegrityContactDefined
|| nationalSocietyHotlineDefined;

return (
<div className={styles.drefFinalReportExport}>
@@ -348,6 +377,30 @@ export function Component() {
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedMale}
value={drefResponse?.estimated_number_of_affected_male}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedFemale}
value={drefResponse?.estimated_number_of_affected_female}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.estimatedAffectedMinors}
value={drefResponse?.estimated_number_of_affected_minors}
valueType="number"
suffix={strings.peopleSuffix}
strongValue
/>
<TextOutput
className={styles.metaItem}
label={strings.peopleTargetedLabel}
@@ -753,6 +806,56 @@ export function Component() {
<Heading level={2}>
{strings.riskAndSecuritySectionHeading}
</Heading>
{hasAntiFraudPolicy && (
<Container>
<BlockTextOutput
label={strings.hasAntiFraudPolicy}
value={drefResponse?.has_anti_fraud_corruption_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasSexualAbusePolicy && (
<Container>
<BlockTextOutput
label={strings.hasSexualAbusePolicy}
value={drefResponse?.has_sexual_abuse_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasChildProtectionPolicy && (
<Container>
<BlockTextOutput
label={strings.hasChildProtectionPolicy}
value={drefResponse?.has_child_protection_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasWhistleblowerProtectionPolicy && (
<Container>
<BlockTextOutput
label={strings.hasWhistleblowerProtectionPolicy}
value={drefResponse?.has_whistleblower_protection_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{hasAntiSexualHarassmentPolicy && (
<Container>
<BlockTextOutput
label={strings.hasAntiSexualHarassmentPolicy}
value={drefResponse?.has_anti_sexual_harassment_policy}
valueType="boolean"
strongLabel
/>
</Container>
)}
{riskSecurityDefined && (
<Container
heading={strings.riskSecurityHeading}
@@ -996,6 +1099,22 @@ export function Component() {
strongLabel
/>
)}
{nationalSocietyIntegrityContactDefined && (
<TextOutput
labelClassName={styles.contactPersonLabel}
label={strings.nationalSocietyIntegrityHeading}
value={nationalSocietyIntegrityContactText}
strongLabel
/>
)}
{nationalSocietyHotlineDefined && (
<TextOutput
labelClassName={styles.contactPersonLabel}
label={strings.nationalSocietyHotlineHeading}
value={drefResponse?.national_society_hotline_phone_number}
strongLabel
/>
)}
</Container>
<Link
href="/emergencies"
6 changes: 2 additions & 4 deletions app/src/views/DrefFinalReportForm/Actions/i18n.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
{
"namespace": "drefFinalReportForm",
"strings": {
"finalReportNationalSocietiesActions": "National Society Actions",
"finalReportHaveNationalSocietyConducted": "Have the National Society conducted any intervention additionally to those part of this DREF Operation?",
"finalReportDescriptionOfAdditionalActivities": "Please provide a brief description of those additional activities",
"drefFormActionFieldsLabel": "Select the needs that apply.",
"drefFormAssessmentReportUploadLabel": "Assessment Report (Optional)",
"drefFormCoordinationMechanism": "Are there major coordination mechanisms in place?",
@@ -18,12 +15,13 @@
"ifrcNetworkActionsHeading": "IFRC Network Actions Related To The Current Event",
"icrcActionsHeading": "ICRC Actions Related To The Current Event",
"drefFormNationalAuthorities": "National authorities",
"drefFormNationalAuthoritiesDescription": "Brief description of actions taken by the national authorities.",
"drefFormNationalOtherActors": "Other Actors Actions Related To The Current Event",
"drefFormNationalSocietiesActionsDescription": "Please indicate a description of the ongoing response with if possible: Branches involved, number of volunteers/staff involved in actions, assets deployed/distributed, number of people reach. Impact/added value of the NS in the response already ongoing.",
"drefFormNeedsIdentified": "Needs (Gaps) Identified",
"drefFormPartnerNationalSociety": "Participating National Societies",
"drefFormPartnerNationalSocietyDescription": "Briefly set out which PNS are present and give details of PNS contributions/roles on the ground and remotely for this specific operation",
"drefFormUNorOtherActors": "UN or other actors",
"drefFormUNorOtherActorsDescription": "Brief description of actions taken by the UN or other actors.",
"drefFormAddButton": "Add"
}
}
29 changes: 2 additions & 27 deletions app/src/views/DrefFinalReportForm/Actions/index.tsx
Original file line number Diff line number Diff line change
@@ -128,33 +128,6 @@ function Actions(props: Props) {

return (
<div className={styles.actions}>
<Container
className={styles.nationalSocietyActions}
heading={strings.finalReportNationalSocietiesActions}
headerDescription={strings.drefFormNationalSocietiesActionsDescription}
>
<InputSection title={strings.finalReportHaveNationalSocietyConducted}>
<BooleanInput
name="has_national_society_conducted"
onChange={setFieldValue}
value={value?.has_national_society_conducted}
error={error?.has_national_society_conducted}
disabled={disabled}
/>
</InputSection>
{value.has_national_society_conducted && (
<InputSection title={strings.finalReportDescriptionOfAdditionalActivities}>
<TextArea
name="national_society_conducted_description"
value={value.national_society_conducted_description}
onChange={setFieldValue}
error={error?.national_society_conducted_description}
disabled={disabled}
/>
</InputSection>
)}
</Container>

<Container
heading={strings.ifrcNetworkActionsHeading}
>
@@ -218,6 +191,7 @@ function Actions(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormNationalAuthorities}
description={strings.drefFormNationalAuthoritiesDescription}
>
<TextArea
label={strings.drefFormActionDescription}
@@ -230,6 +204,7 @@ function Actions(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormUNorOtherActors}
description={strings.drefFormNationalAuthoritiesDescription}
>
<TextArea
label={strings.drefFormActionDescription}
7 changes: 7 additions & 0 deletions app/src/views/DrefFinalReportForm/EventDetail/i18n.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,10 @@
"drefFormDescriptionEvent": "Description of the Event",
"drefFormEventDate": "Date of the Event",
"drefFormImminentDisaster": "Provide any updates in the situation since the field report and explain what is expected to happen.",
"drefFormWhatWhereWhenDescriptionHeading": "Clearly Describe:",
"drefFormWhatWhereWhenDescriptionPoint1": "What happened: Briefly explain the nature of the emergency (e.g., flood, earthquake, epidemic). Include key details such as the intensity, and any unique aspects of the event.",
"drefFormWhatWhereWhenDescriptionPoint2": "Where: Specify the geographic location(s) affected. Be as precise as possible, including names of countries, regions, cities, or specific areas impacted by the event.",
"drefFormWhatWhereWhenDescriptionPoint3": "When: Indicate the date and time when the event occurred or began. If the situation is ongoing, mention that and provide relevant updates on the timeframe.",
"drefFormScopeAndScaleDescription": "Describe the extent this hazard will produce negative impacts on lives, livelihoods, well-being and infrastructure. Explain which people are most likely to experience the impacts of this hazard? Where do they live, and why are they vulnerable? Please explain which groups (e.g elderly, children, people with disabilities, IDPs, Refugees, etc.) are most likely to be affected? Provide historic information on how communities have been affected by the magnitude of this hazard in the past?",
"drefFormScopeAndScaleEvent": "Scope and scale of the event",
"drefFormSlowEventDate": "Date when the trigger was met",
@@ -16,6 +20,9 @@
"drefFormRiskPeopleLabel": "Total population at risk",
"drefFormClickEmergencyResponseFramework": "Click to view Emergency Response Framework",
"drefFormPeopleAffected": "Total affected population",
"drefFormAffectedMaleLabel": "Estimated male",
"drefFormAffectedFemaleLabel": "Estimated female",
"drefFormAffectedMinorsLabel": "Estimated minors",
"drefFormPeopleAffectedDescriptionImminent": "Includes all those whose lives and livelihoods are at risk as a direct result of the shock or stress.",
"drefFormPeopleAffectedDescriptionSlowSudden": "People Affected include all those whose lives and livelihoods have been impacted as a direct result of the shock or stress.",
"drefFormEstimatedPeopleInNeed": "Estimated people in need (Optional)",
42 changes: 42 additions & 0 deletions app/src/views/DrefFinalReportForm/EventDetail/index.tsx
Original file line number Diff line number Diff line change
@@ -185,6 +185,30 @@ function EventDetail(props: Props) {
)}
disabled={disabled}
/>
<NumberInput
name="estimated_number_of_affected_male"
label={strings.drefFormAffectedMaleLabel}
value={value?.estimated_number_of_affected_male}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_male}
disabled={disabled}
/>
<NumberInput
name="estimated_number_of_affected_female"
label={strings.drefFormAffectedFemaleLabel}
value={value?.estimated_number_of_affected_female}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_female}
disabled={disabled}
/>
<NumberInput
name="estimated_number_of_affected_minors"
label={strings.drefFormAffectedMinorsLabel}
value={value?.estimated_number_of_affected_minors}
onChange={setFieldValue}
error={error?.estimated_number_of_affected_minors}
disabled={disabled}
/>
<NumberInput
label={(
<>
@@ -233,6 +257,24 @@ function EventDetail(props: Props) {
? strings.drefFormWhatWhereWhen
: strings.drefFormImminentDisaster
}
description={value.type_of_dref !== TYPE_IMMINENT && (
<>
<p>
{strings.drefFormWhatWhereWhenDescriptionHeading}
</p>
<ol>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint1}
</li>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint2}
</li>
<li>
{strings.drefFormWhatWhereWhenDescriptionPoint3}
</li>
</ol>
</>
)}
>
<TextArea
name="event_description"
Original file line number Diff line number Diff line change
@@ -2,4 +2,10 @@
display: flex;
flex-direction: column;
gap: var(--go-ui-spacing-2xl);

.affected-section {
display: flex;
flex-direction: column;
gap: var(--go-ui-spacing-sm);
}
}
Original file line number Diff line number Diff line change
@@ -65,6 +65,7 @@ function IndicatorInput(props: Props) {
error={error?.title}
disabled={disabled}
withAsterisk
readOnly
/>
<NumberInput
className={styles.numberInput}
@@ -74,6 +75,7 @@ function IndicatorInput(props: Props) {
onChange={onFieldChange}
error={error?.target}
disabled={disabled}
readOnly
/>
<NumberInput
label={strings.drefOperationalUpdateIndicatorActualLabel}
@@ -82,6 +84,7 @@ function IndicatorInput(props: Props) {
onChange={onFieldChange}
error={error?.actual}
disabled={disabled}
withAsterisk
/>
<Button
name={index}
33 changes: 28 additions & 5 deletions app/src/views/DrefFinalReportForm/Operation/i18n.json
Original file line number Diff line number Diff line change
@@ -8,20 +8,43 @@
"finalReportChangeToOperationStrategyExplain": "Explain",
"drefFormDescription": "Description",
"drefFormObjectiveAndStrategy": "Objective and Strategy Rationale",
"drefFormObjectiveOperationDescription": "The objective statement should clearly and concisely describe the primary goal of the operation, focusing on the humanitarian impact and the specific needs the operation aims to address.",
"drefFormObjectiveOperation": "Overall objective of the operation",
"drefFormObjectiveOperationPlaceholder": "This DREF allocation aims at supporting ….. of people in need affected by ……. Disaster, by providing …..(list sectors) support in the ……(list areas/regions) for …. months",
"drefFormObjectiveOperationPlaceholder": "The IFRC-DREF operation aims to [primary action] in order to [desired impact] for [target population] affected by [event/disaster], by providing [key services/interventions] and ensuring [core outcomes such as protection, dignity, and resilience] over [operation period].",
"drefFormPeopleAssistedThroughOperation": "Who was targeted by this operation?",
"drefFormPeopleAssistedThroughOperationDescription": "Explain the logic behind our targets. Which groups are we targeting and why are we targeting these particular groups? Explain how you will target vulnerable groups (e.g., Migrants, refugees, etc.)",
"drefFormPeopleTargetedWithEarlyActions": "Numbers of persons targeted with early actions (if any)",
"drefFormPlannedIntervention": "Planned Intervention",
"drefFormResponseRationale": "Operation strategy rationale",
"drefFormResponseRationaleDescription": "Please describe the strategy to conduct the assessment exercise, main objectives, who will be involved?",
"drefFormResponseRationaleDescription": "Elaborate on the overall plan, strategy and approach of the operation; explain the reasoning behind the chosen strategy for the emergency operation. Explain how the identified needs/gaps and actions taken/plans are linked.",
"drefFormResponseRationaleDescriptionPoint1": "Highlight the most urgent needs the operation aims to address.",
"drefFormResponseRationaleDescriptionPoint2": "Describe the main priorities and explain why these priorities were chosen based on the specific context of the emergency.",
"drefFormResponseRationaleDescriptionPoint3": "Justify why particular methods and actions were selected and how they are expected to achieve the desired outcomes.",
"drefFormResponseRationaleDescriptionPoint4": "Include any key factors that influence the strategy; mention how these factors were considered in shaping the operation.",
"drefFormResponseRationaleForAssessment": "Please describe the strategy to conduct the assessment exercise, main objectives, who will be involved?",
"drefFormResponseRationalePlaceholder": "To address the needs of the targeted population, this DREF will aim at (please briefly describe the planned activities).",
"drefFormRiskSecurity": "Risk and security considerations",
"drefFormRiskSecurity": "Risk and Security Considerations (including \"management\")",
"drefFormRiskDoesNSHaveAntiFraudPolicy": "Does your National Society have anti-fraud and corruption policy?",
"drefFormRiskDoesNSHaveSexualAbusePolicy": "Does your National Society have prevention of sexual exploitation and abuse policy?",
"drefFormRiskDoesNSHaveChildProtectionPolicy": "Does your National Society have child protection/child safeguarding policy?",
"drefFormRiskDoesNSHaveWhistleblowerPolicy": "Does your National Society have whistleblower protection policy?",
"drefFormRiskDoesNSHaveAntiSexualHarassmentPolicy": "Does your National Society have anti-sexual harassment policy?",
"drefFormRiskSecurityAddButton": "Add New Risk",
"drefFormRiskSecurityPotentialRisk": "Please indicate about potential operational risk for this operations and mitigation actions",
"drefFormRiskSecurityPotentialRiskDescription": "Please consider any possible challenges to conduct the assessment, any possible limitations in getting the information required and overall risk to the implementation",
"drefFormRiskSecurityPotentialRisk": "Please analyse and indicate potential risks for this operation, its root causes and mitigation actions.",
"drefFormRiskSecurityPotentialRiskAssessmentDescription": "Please consider any possible challenges to conduct the assessment, any possible limitations in getting the information required and overall risk to the implementation",
"drefFormRiskSecurityPotentialRiskDescription": "When identifying the risks, please review the IFRC Risk Management Policy and Framework including the different risk categories. When possible, make sure that your identification of risks includes some analysis of previous incidents and performance of the NS in previous operations.",
"drefFormRiskSecurityRiskSelectedDescription": "Identify up to 5 key potential risks or threats that could negatively impact the success of the operation. These can range from environmental risks to social or logistical challenges.",
"drefFormRiskSecurityRiskSelectedPoint1": "What are the primary risks that could affect the operation’s implementation?",
"drefFormRiskSecurityRiskSelectedPoint2": "Are there any context-specific risks that need to be considered?",
"drefFormRiskSecurityRiskSelectedPoint3": "How might these risks impact the operation’s objectives, timeline, or resources? Mitigation actions are actions or strategies that will be implemented to reduce or manage the identified risks, ensuring the operation can proceed as planned.",
"drefFormRiskSecurityRiskSelectedPoint4": "What specific measures or strategies will be put in place to mitigate the risks identified?",
"drefFormRiskSecurityRiskSelectedPoint5": "Will contingency plans or additional resources be required to address these risks?",
"drefFormRiskSecurityRiskCategoriesLinkLabel": "Annex III - Risk Categories.pdf",
"drefFormRiskSecuritySafetyConcern": "Please indicate any security and safety concerns for this operation",
"drefFormRiskSecuritySafetyConcernDescription": "Describe any specific security or safety threats that could impact the safety of personnel, volunteers, and communities during the operation.",
"drefFormRiskSecuritySafetyConcernDescriptionPoint1": "Are there any security concerns related to the areas where the operation will take place (e.g., conflict zones, high-crime areas)",
"drefFormRiskSecuritySafetyConcernDescriptionPoint2": "What safety risks could impact the well-being of staff, volunteers, or beneficiaries (e.g., dangerous terrain, health risks)?",
"drefFormRiskSecuritySafetyConcernDescriptionPoint3": "Are there any specific security protocols or measures that need to be established or followed during the operation?",
"drefFormRiskSecurityHasChildRiskCompleted": "Has the child safeguarding risk analysis assessment been completed?",
"drefFormRiskSecurityHasChildRiskCompletedDescription":"The IFRC Child Safeguarding Risk Analysis helps Operations quickly identify and rate their key child safeguarding risks in order to reduce the risk of harm against children, as outlined as a requirement in the IFRC Child Safeguarding Policy. Here are the link to the tool and Q&A",
"drefChildSafeguardingPolicyDescription":"Child Safeguarding Policy",
142 changes: 138 additions & 4 deletions app/src/views/DrefFinalReportForm/Operation/index.tsx
Original file line number Diff line number Diff line change
@@ -196,6 +196,7 @@ function Operation(props: Props) {
>
<InputSection
title={strings.drefFormObjectiveOperation}
description={strings.drefFormObjectiveOperationDescription}
>
<TextArea
name="operation_objective"
@@ -208,8 +209,32 @@ function Operation(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormResponseRationale}
description={value?.type_of_dref === TYPE_ASSESSMENT
&& strings.drefFormResponseRationaleDescription}
description={(
<>
<p>
{strings.drefFormResponseRationaleDescription}
</p>
<ul>
<li>
{strings.drefFormResponseRationaleDescriptionPoint1}
</li>
<li>
{strings.drefFormResponseRationaleDescriptionPoint2}
</li>
<li>
{strings.drefFormResponseRationaleDescriptionPoint3}
</li>
<li>
{strings.drefFormResponseRationaleDescriptionPoint4}
</li>
{value?.type_of_dref === TYPE_ASSESSMENT && (
<li>
{strings.drefFormResponseRationaleForAssessment}
</li>
)}
</ul>
</>
)}
>
<TextArea
name="response_strategy"
@@ -401,10 +426,101 @@ function Operation(props: Props) {
<Container
heading={strings.drefFormRiskSecurity}
>
<InputSection
title={strings.drefFormRiskDoesNSHaveAntiFraudPolicy}
>
<BooleanInput
name="has_anti_fraud_corruption_policy"
value={value.has_anti_fraud_corruption_policy}
onChange={setFieldValue}
error={error?.has_anti_fraud_corruption_policy}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormRiskDoesNSHaveSexualAbusePolicy}
>
<BooleanInput
name="has_sexual_abuse_policy"
value={value.has_sexual_abuse_policy}
onChange={setFieldValue}
error={error?.has_sexual_abuse_policy}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormRiskDoesNSHaveChildProtectionPolicy}
>
<BooleanInput
name="has_child_protection_policy"
value={value.has_child_protection_policy}
onChange={setFieldValue}
error={error?.has_child_protection_policy}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormRiskDoesNSHaveWhistleblowerPolicy}
>
<BooleanInput
name="has_whistleblower_protection_policy"
value={value.has_whistleblower_protection_policy}
onChange={setFieldValue}
error={error?.has_whistleblower_protection_policy}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormRiskDoesNSHaveAntiSexualHarassmentPolicy}
>
<BooleanInput
name="has_anti_sexual_harassment_policy"
value={value.has_anti_sexual_harassment_policy}
onChange={setFieldValue}
error={error?.has_anti_sexual_harassment_policy}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormRiskSecurityPotentialRisk}
description={value?.type_of_dref === TYPE_ASSESSMENT
&& strings.drefFormRiskSecurityPotentialRiskDescription}
description={(
<>
{value?.type_of_dref === TYPE_ASSESSMENT
&& strings.drefFormRiskSecurityPotentialRiskAssessmentDescription}
{strings.drefFormRiskSecurityPotentialRiskDescription}
<Link
href="https://github.com/user-attachments/files/18903662/Annex.III.Risk.Categories.1.pdf"
withLinkIcon
external
>
{strings.drefFormRiskSecurityRiskCategoriesLinkLabel}
</Link>
{(value.risk_security?.length ?? 0) > 0 && (
<>
<p>
{strings.drefFormRiskSecurityRiskSelectedDescription}
</p>
<ul>
<li>
{strings.drefFormRiskSecurityRiskSelectedPoint1}
</li>
<li>
{strings.drefFormRiskSecurityRiskSelectedPoint2}
</li>
<li>
{strings.drefFormRiskSecurityRiskSelectedPoint3}
</li>
<li>
{strings.drefFormRiskSecurityRiskSelectedPoint4}
</li>
<li>
{strings.drefFormRiskSecurityRiskSelectedPoint5}
</li>
</ul>
</>
)}
</>
)}
>
<NonFieldError error={getErrorObject(error?.risk_security)} />
{value.risk_security?.map((rs, i) => (
@@ -431,6 +547,24 @@ function Operation(props: Props) {
</InputSection>
<InputSection
title={strings.drefFormRiskSecuritySafetyConcern}
description={(
<>
<p>
{strings.drefFormRiskSecuritySafetyConcernDescription}
</p>
<ul>
<li>
{strings.drefFormRiskSecuritySafetyConcernDescriptionPoint1}
</li>
<li>
{strings.drefFormRiskSecuritySafetyConcernDescriptionPoint2}
</li>
<li>
{strings.drefFormRiskSecuritySafetyConcernDescriptionPoint3}
</li>
</ul>
</>
)}
>
<TextArea
name="risk_security_concern"
4 changes: 3 additions & 1 deletion app/src/views/DrefFinalReportForm/Overview/i18n.json
Original file line number Diff line number Diff line change
@@ -5,9 +5,11 @@
"drefOperationalShareApplicationLabel": "The DREF Final Report is shared with",
"drefOperationalShareApplicationDescription": "The users will be able to view, edit and add other users.",
"drefFormSharingHeading": "Sharing",
"formShareButtonLabel": "Add",
"drefFormInstantShareLabel": "Create & Share",
"drefFormEssentialInformation": "Essential Information",
"drefFormNationalSociety": "Name of National Society",
"drefFormNationalSocietyDescription": "Indicate your National Society by selecting it from the drop-down list.",
"drefFormTypeOfDref": "Type of DREF",
"drefFormImminentDisasterDetails": "Hazard Details",
"drefFormDisasterDetails": "Disaster Details",
@@ -31,4 +33,4 @@
"drefFormClickEmergencyResponseFrameworkLabel": "Click to view Emergency Response Framework",
"userListEmptyMessage": "The DREF Final report is not shared with anyone."
}
}
}
67 changes: 61 additions & 6 deletions app/src/views/DrefFinalReportForm/Overview/index.tsx
Original file line number Diff line number Diff line change
@@ -3,7 +3,10 @@ import {
type SetStateAction,
useCallback,
} from 'react';
import { WikiHelpSectionLineIcon } from '@ifrc-go/icons';
import {
ShareLineIcon,
WikiHelpSectionLineIcon,
} from '@ifrc-go/icons';
import {
Button,
Container,
@@ -13,9 +16,15 @@ import {
TextArea,
TextInput,
} from '@ifrc-go/ui';
import { useTranslation } from '@ifrc-go/ui/hooks';
import {
useBooleanState,
useTranslation,
} from '@ifrc-go/ui/hooks';
import { stringValueSelector } from '@ifrc-go/ui/utils';
import { isNotDefined } from '@togglecorp/fujs';
import {
isDefined,
isNotDefined,
} from '@togglecorp/fujs';
import {
type EntriesAsList,
type Error,
@@ -26,6 +35,7 @@ import {
import CountrySelectInput from '#components/domain/CountrySelectInput';
import DisasterTypeSelectInput from '#components/domain/DisasterTypeSelectInput';
import DistrictSearchMultiSelectInput, { type DistrictItem } from '#components/domain/DistrictSearchMultiSelectInput';
import DrefShareModal from '#components/domain/DrefShareModal';
import UserItem from '#components/domain/DrefShareModal/UserItem';
import ImageWithCaptionInput from '#components/domain/ImageWithCaptionInput';
import NationalSocietySelectInput from '#components/domain/NationalSocietySelectInput';
@@ -34,7 +44,11 @@ import Link from '#components/Link';
import useCountry from '#hooks/domain/useCountry';
import useDisasterType from '#hooks/domain/useDisasterType';
import useGlobalEnums from '#hooks/domain/useGlobalEnums';
import { type GoApiResponse } from '#utils/restRequest';
import useInputState from '#hooks/useInputState';
import {
type GoApiResponse,
useRequest,
} from '#utils/restRequest';

import {
TYPE_IMMINENT,
@@ -74,7 +88,7 @@ interface Props {
setFileIdToUrlMap?: React.Dispatch<React.SetStateAction<Record<number, string>>>;
districtOptions: DistrictItem[] | null | undefined;
setDistrictOptions: Dispatch<SetStateAction<DistrictItem[] | null | undefined>>;
drefUsers?: User[] | null;
drefId: number | undefined;
}

function Overview(props: Props) {
@@ -87,10 +101,15 @@ function Overview(props: Props) {
disabled,
districtOptions,
setDistrictOptions,
drefUsers,
drefId,
} = props;

const strings = useTranslation(i18n);
const [drefUsers, setDrefUsers] = useInputState<User[] | undefined | null>([]);
const [showShareModal, {
setTrue: setShowShareModalTrue,
setFalse: setShowShareModalFalse,
}] = useBooleanState(false);
const {
dref_dref_dref_type: typeOfDrefOptions,
dref_dref_disaster_category: drefDisasterCategoryOptions,
@@ -137,6 +156,25 @@ function Overview(props: Props) {
(option) => option.key !== TYPE_LOAN,
);

const {
retrigger: getDrefUsers,
} = useRequest({
skip: isNotDefined(drefId),
url: '/api/v2/dref-share-user/{id}/',
pathVariables: { id: Number(drefId) },
onSuccess: (response) => {
setDrefUsers(response.users_details);
},
});

const handleUserShareSuccess = useCallback(() => {
setShowShareModalFalse();
getDrefUsers();
}, [
getDrefUsers,
setShowShareModalFalse,
]);

const error = getErrorObject(formError);

return (
@@ -163,6 +201,15 @@ function Overview(props: Props) {
pending={false}
compact
/>
<Button
name={undefined}
onClick={setShowShareModalTrue}
disabled={isNotDefined(drefId)}
variant="secondary"
icons={<ShareLineIcon />}
>
{strings.formShareButtonLabel}
</Button>
</InputSection>
</Container>
<Container
@@ -171,6 +218,7 @@ function Overview(props: Props) {
>
<InputSection
title={strings.drefFormNationalSociety}
description={strings.drefFormNationalSocietyDescription}
numPreferredColumns={2}
withAsteriskOnTitle
>
@@ -377,6 +425,13 @@ function Overview(props: Props) {
/>
</InputSection>
</Container>
{showShareModal && isDefined(drefId) && (
<DrefShareModal
onCancel={setShowShareModalFalse}
onSuccess={handleUserShareSuccess}
drefId={drefId}
/>
)}
</div>
);
}
7 changes: 7 additions & 0 deletions app/src/views/DrefFinalReportForm/Submission/i18n.json
Original file line number Diff line number Diff line change
@@ -25,6 +25,13 @@
"drefFormFocalPointNameLabel": "Name",
"drefFormFocalPointTitleLabel": "Title",
"drefFromFocalPointEmailLabel": "Email",
"drefFormNationalSocietyIntegrityTitle": "National Societies' Integrity Focal Point",
"drefFormIntegrityContactNameLabel": "Name",
"drefFormIntegrityContactEmailLabel": "Email",
"drefFormIntegrityContactTitleLabel": "Title",
"drefFormIntegrityContactPhoneNumberLabel": "Phone Number",
"drefFormNationalSocietyHotlineNumberTitle": "National Society Hotline",
"drefFormNationalSocietyHotlineNumberLabel": "Phone Number",
"drefFromFocalPointPhoneNumberLabel": "Phone Number"
}
}
50 changes: 50 additions & 0 deletions app/src/views/DrefFinalReportForm/Submission/index.tsx
Original file line number Diff line number Diff line change
@@ -375,6 +375,56 @@ function Submission(props: Props) {
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormNationalSocietyIntegrityTitle}
numPreferredColumns={2}
>
<TextInput
label={strings.drefFormIntegrityContactNameLabel}
name="national_society_integrity_contact_name"
value={value.national_society_integrity_contact_name}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_name}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactEmailLabel}
name="national_society_integrity_contact_email"
value={value.national_society_integrity_contact_email}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_email}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactTitleLabel}
name="national_society_integrity_contact_title"
value={value.national_society_integrity_contact_title}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_title}
disabled={disabled}
/>
<TextInput
label={strings.drefFormIntegrityContactPhoneNumberLabel}
name="national_society_integrity_contact_phone_number"
value={value.national_society_integrity_contact_phone_number}
onChange={setFieldValue}
error={error?.national_society_integrity_contact_phone_number}
disabled={disabled}
/>
</InputSection>
<InputSection
title={strings.drefFormNationalSocietyHotlineNumberTitle}
numPreferredColumns={2}
>
<TextInput
label={strings.drefFormNationalSocietyHotlineNumberLabel}
name="national_society_hotline_phone_number"
value={value.national_society_hotline_phone_number}
onChange={setFieldValue}
error={error?.national_society_hotline_phone_number}
disabled={disabled}
/>
</InputSection>
</Container>
</div>
);
17 changes: 13 additions & 4 deletions app/src/views/DrefFinalReportForm/common.tsx
Original file line number Diff line number Diff line change
@@ -32,16 +32,12 @@ export type TabKeys = 'overview' | 'eventDetail' | 'actions' | 'operation' | 'su
// FORM ERROR

const overviewFields: (keyof PartialFinalReport)[] = [
'number_of_people_affected',
'number_of_people_targeted',
'num_assisted',
'total_dref_allocation',
'main_donors',
'title',
'national_society',
'country',
'district',
'people_in_need',
'disaster_type',
'type_of_onset',
'disaster_category',
@@ -51,9 +47,17 @@ const overviewFields: (keyof PartialFinalReport)[] = [
] satisfies (keyof PartialFinalReport)[];

const eventDetailFields: (keyof PartialFinalReport)[] = [
'number_of_people_affected',
'number_of_people_targeted',
'num_assisted',
'people_in_need',
'estimated_number_of_affected_male',
'estimated_number_of_affected_female',
'estimated_number_of_affected_minors',
'event_description',
'event_scope',
'images_file',
'source_information',
'event_date',
'event_text',
] satisfies (keyof PartialFinalReport)[];
@@ -126,6 +130,11 @@ const submissionFields: (keyof PartialFinalReport)[] = [
'media_contact_name',
'media_contact_email',
'media_contact_phone_number',
'national_society_integrity_contact_name',
'national_society_integrity_contact_title',
'national_society_integrity_contact_email',
'national_society_integrity_contact_phone_number',
'national_society_hotline_phone_number',
'media_contact_title',
] satisfies (keyof PartialFinalReport)[];

1 change: 0 additions & 1 deletion app/src/views/DrefFinalReportForm/i18n.json
Original file line number Diff line number Diff line change
@@ -21,7 +21,6 @@
"formLoadErrorDescription": "There was an error loading the DREF Final Report",
"formLoadErrorHelpText": "Please make sure that the final report with given id exists and you have the permission to view it",
"formBackButtonLabel": "Back",
"formShareButtonLabel": "Share",
"drefFeedbackForm": "Provide feedback on IFRC DREF"
}
}
Loading

Unchanged files with check annotations Beta

# Dynamic configs. Can be changed with containers. (Placeholder values)
ENV APP_TITLE=APP_TITLE_PLACEHOLDER
ENV APP_ENVIRONMENT=APP_ENVIRONMENT_PLACEHOLDER
ENV APP_MAPBOX_ACCESS_TOKEN=APP_MAPBOX_ACCESS_TOKEN_PLACEHOLDER

Check warning on line 35 in nginx-serve/Dockerfile

GitHub Actions / Publish Docker Image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "APP_MAPBOX_ACCESS_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV APP_TINY_API_KEY=APP_TINY_API_KEY_PLACEHOLDER

Check warning on line 36 in nginx-serve/Dockerfile

GitHub Actions / Publish Docker Image

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "APP_TINY_API_KEY") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV APP_API_ENDPOINT=https://APP-API-ENDPOINT-PLACEHOLDER.COM/
ENV APP_RISK_API_ENDPOINT=https://APP-RISK-API-ENDPOINT-PLACEHOLDER.COM/
ENV APP_SENTRY_DSN=https://APP-SENTRY-DSN-PLACEHOLDER.COM