From 65a905f9ebf81f83621c45e5580cea1b5d8c91c8 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Sun, 14 Jul 2024 21:08:47 +0200 Subject: [PATCH 01/28] Add flood number in table --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 8 ++++++++ apps/frontend/components/pages/Forms/Search.tsx | 6 +++++- apps/frontend/translations/en.json | 1 + apps/frontend/translations/km.json | 1 + packages/interfaces/src/kobo/mapping/keys.ts | 2 ++ packages/interfaces/src/kobo/utils.ts | 3 ++- 6 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 47a3b617..b334bc25 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -51,9 +51,11 @@ const formatForms = ( export const TableDisplay = ({ forms, isLoading, + isFlood, }: { forms?: DisasterDtoType[]; isLoading: boolean; + isFlood: boolean; }): JSX.Element => { const { user } = useAuth(); const isUserAdmin = Boolean(user && ['admin'].includes(user.roles[0])); @@ -96,6 +98,11 @@ export const TableDisplay = ({ + {isFlood && ( + + + + )} @@ -137,6 +144,7 @@ export const TableDisplay = ({ + {isFlood && {formattedForm.floodN}} {formattedForm.entryName} {formattedForm.phone} diff --git a/apps/frontend/components/pages/Forms/Search.tsx b/apps/frontend/components/pages/Forms/Search.tsx index 6cc7e836..de78b312 100644 --- a/apps/frontend/components/pages/Forms/Search.tsx +++ b/apps/frontend/components/pages/Forms/Search.tsx @@ -51,7 +51,11 @@ export const FormSearch = () => { /> } /> - + ); }; diff --git a/apps/frontend/translations/en.json b/apps/frontend/translations/en.json index 5019955d..f8af96a7 100644 --- a/apps/frontend/translations/en.json +++ b/apps/frontend/translations/en.json @@ -102,6 +102,7 @@ "commune": "Commune", "dis_date": "Disaster Date", "dis_type": "Disaster Type", + "flood_number": "Flood #", "entry_name": "Reporter Name", "phone": "Phone", "entry_date": "Entry Date", diff --git a/apps/frontend/translations/km.json b/apps/frontend/translations/km.json index bbe04ffa..8a738713 100644 --- a/apps/frontend/translations/km.json +++ b/apps/frontend/translations/km.json @@ -111,6 +111,7 @@ "commune": "ឃុំ", "dis_date": "ការបរិច្ឆេទថ្ងៃកើតហេតុ", "dis_type": "ប្រភេទគ្រោះមហន្តរាយ", + "flood_number": "ចំនួនលើកទឹកជំនន់", "entry_name": "ឈ្មោះរបាយការណ៍", "phone": "លេខទូរសព្ឌ័", "entry_date": "ការបរិច្ឆេទបញ្ចូលរបាយការណ៍", diff --git a/packages/interfaces/src/kobo/mapping/keys.ts b/packages/interfaces/src/kobo/mapping/keys.ts index e1a3269e..9fe16ab2 100644 --- a/packages/interfaces/src/kobo/mapping/keys.ts +++ b/packages/interfaces/src/kobo/mapping/keys.ts @@ -1,4 +1,5 @@ import { DROUGHT, FLOOD, INCIDENT } from '../constants'; +import { floodSpecificKeys } from './flood'; export enum KoboCommonKeys { district = 'district', @@ -27,6 +28,7 @@ export const koboKeys = { [KoboCommonKeys.id]: '_id', [KoboCommonKeys.validationStatus]: '_validation_status', [KoboCommonKeys.submissionTime]: '_submission_time', + floodN: floodSpecificKeys.floodN, }, [DROUGHT]: { [KoboCommonKeys.district]: 'group_yu9nq00/District', diff --git a/packages/interfaces/src/kobo/utils.ts b/packages/interfaces/src/kobo/utils.ts index 400d12c5..03633bbb 100644 --- a/packages/interfaces/src/kobo/utils.ts +++ b/packages/interfaces/src/kobo/utils.ts @@ -5,7 +5,7 @@ import { FloodDto } from './FloodDto'; import { IncidentDto } from './IncidentDto'; import { ValidationStatusValue } from './ValidationStatusDto'; import { DisasterDtoType, DROUGHT, FLOOD, INCIDENT } from './constants'; -import { KoboCommonKeys, koboKeys } from './mapping'; +import { FloodSpecific, KoboCommonKeys, koboKeys } from './mapping'; export const computeDisasterTypeFromDistTyp = (distTyp: string) => { if (isNaN(parseInt(distTyp))) throw Error('distTyp must be convertable to integer'); @@ -61,6 +61,7 @@ export const formatCommonFields = (form: DisasterDtoType) => { form[keys.validationStatus].uid ?? ValidationStatusValue.onHold ).toString(), [KoboCommonKeys.submissionTime]: form[keys.submissionTime], + floodN: form[keys.floodN], approvalLink: path.join('/form', FLOOD, form[keys.id].toString()), }; } else if (isDrought(form)) { From 92fdfc21df9e74bd46ddbf4fbd14e3fe98321e74 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Mon, 15 Jul 2024 15:11:35 +0200 Subject: [PATCH 02/28] Update utils.ts --- packages/interfaces/src/kobo/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/interfaces/src/kobo/utils.ts b/packages/interfaces/src/kobo/utils.ts index 03633bbb..5515cd2c 100644 --- a/packages/interfaces/src/kobo/utils.ts +++ b/packages/interfaces/src/kobo/utils.ts @@ -5,7 +5,7 @@ import { FloodDto } from './FloodDto'; import { IncidentDto } from './IncidentDto'; import { ValidationStatusValue } from './ValidationStatusDto'; import { DisasterDtoType, DROUGHT, FLOOD, INCIDENT } from './constants'; -import { FloodSpecific, KoboCommonKeys, koboKeys } from './mapping'; +import { KoboCommonKeys, koboKeys } from './mapping'; export const computeDisasterTypeFromDistTyp = (distTyp: string) => { if (isNaN(parseInt(distTyp))) throw Error('distTyp must be convertable to integer'); From 93bb5fdf75c2f25e4e56a483f247a3cae473ce59 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Mon, 15 Jul 2024 17:33:30 +0200 Subject: [PATCH 03/28] Initialize select logic --- .../components/TableDisplay/TableDisplay.tsx | 285 ++++++++++++------ apps/frontend/translations/en.json | 1 + 2 files changed, 193 insertions(+), 93 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index b334bc25..c817f948 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -1,4 +1,10 @@ import { + Button, + Checkbox, + Dialog, + DialogActions, + DialogContent, + DialogTitle, Paper, Skeleton, Table, @@ -7,6 +13,8 @@ import { TableContainer, TableHead, TableRow, + TextField, + Tooltip, Typography, } from '@mui/material'; import { @@ -14,13 +22,12 @@ import { formatCommonFields, ValidationStatusValue, } from '@wfp-dmp/interfaces'; +import { ValidationIndicator } from 'components/FormValidation/ValidationIndicator'; +import { useAuth } from 'context/auth'; import { orderBy } from 'lodash'; import Link from 'next/link'; -import { useMemo } from 'react'; +import { useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; - -import { ValidationIndicator } from 'components/FormValidation/ValidationIndicator'; -import { useAuth } from 'context/auth'; import { dropNotApproved } from 'utils/dropNotApproved'; import { formatDate } from '../../utils/date'; @@ -59,12 +66,39 @@ export const TableDisplay = ({ }): JSX.Element => { const { user } = useAuth(); const isUserAdmin = Boolean(user && ['admin'].includes(user.roles[0])); - // If user is admin, show all forms, otherwise hide rejected forms + const [batchEditMode, setBatchEditMode] = useState(false); + const [selectedForms, setSelectedForms] = useState([]); + const [newFloodNumber, setNewFloodNumber] = useState(null); + const [dialogOpen, setDialogOpen] = useState(false); + const formattedForms = useMemo( () => formatForms(forms, !isUserAdmin), [forms, isUserAdmin], ); + const handleCheckboxChange = (form: DisasterDtoType) => { + setSelectedForms(prev => + prev.includes(form) + ? prev.filter(f => f.id !== form.id) + : [...prev, form], + ); + }; + + const handleBatchEditClick = () => { + setBatchEditMode(!batchEditMode); + setSelectedForms([]); + }; + + const handleEditFloodNumber = () => { + // Logic to update flood numbers for selected forms + setDialogOpen(false); + setBatchEditMode(false); + }; + + const isSameProvince = selectedForms.every( + form => form.province === selectedForms[0]?.province, + ); + if (!isLoading && formattedForms.length === 0) { return ( @@ -74,99 +108,164 @@ export const TableDisplay = ({ } return ( - - - - - - - - - - - - - - - - - - - - - - - {isFlood && ( + <> + {isUserAdmin && isFlood && ( + + + + )} + {batchEditMode && ( + + You can only batch edit forms from the same province + + )} + +
+ + - + - )} - - - - - - - - - - - - {isLoading ? ( - - {[1, 2, 3].map(id => { - return ( - - - - - - ); - })} - - ) : ( - - {formattedForms.map(formattedForm => ( - - - - - - - - - + + + + + + + + + + + + + + + + {isFlood && ( + + - {formatDate(formattedForm.disasterDate)} - {formatDate(formattedForm.entryDate)} - - + )} + {batchEditMode && ( + + - {isFlood && {formattedForm.floodN}} - {formattedForm.entryName} - {formattedForm.phone} - - - + + + + + + + + + + + {isLoading ? ( + + {[1, 2, 3].map(id => { + return ( + + + + + + ); + })} + + ) : ( + + {formattedForms.map(formattedForm => ( + + + - - - - ))} - + + + + + + + + + {formatDate(formattedForm.disasterDate)} + + {formatDate(formattedForm.entryDate)} + + + + {isFlood && {formattedForm.floodN}} + {batchEditMode && ( + + handleCheckboxChange(formattedForm)} + disabled={ + selectedForms.length > 0 && + !isSameProvince && + !selectedForms.includes(formattedForm) + } + /> + + )} + {formattedForm.entryName} + {formattedForm.phone} + + + + + + + ))} + + )} +
+ {batchEditMode && selectedForms.length > 0 && ( + )} - -
+ setDialogOpen(false)}> + + Edit flood number for {selectedForms.length} selected forms + + + setNewFloodNumber(Number(e.target.value))} + fullWidth + /> + + + + + + + + ); }; diff --git a/apps/frontend/translations/en.json b/apps/frontend/translations/en.json index f8af96a7..f9933c10 100644 --- a/apps/frontend/translations/en.json +++ b/apps/frontend/translations/en.json @@ -103,6 +103,7 @@ "dis_date": "Disaster Date", "dis_type": "Disaster Type", "flood_number": "Flood #", + "select": "Select", "entry_name": "Reporter Name", "phone": "Phone", "entry_date": "Entry Date", From 5548dcb7611167bdcb887d2b84306dff8164a7ff Mon Sep 17 00:00:00 2001 From: ericboucher Date: Mon, 15 Jul 2024 17:52:50 +0200 Subject: [PATCH 04/28] Add dialog to edit flood numbers --- .../components/TableDisplay/TableDisplay.tsx | 62 +++++++++++++------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index c817f948..713a1046 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -1,3 +1,5 @@ +/* eslint-disable complexity, max-lines */ +import EditIcon from '@mui/icons-material/Edit'; import { Button, Checkbox, @@ -5,8 +7,10 @@ import { DialogActions, DialogContent, DialogTitle, + IconButton, Paper, Skeleton, + Stack, Table, TableBody, TableCell, @@ -22,12 +26,13 @@ import { formatCommonFields, ValidationStatusValue, } from '@wfp-dmp/interfaces'; -import { ValidationIndicator } from 'components/FormValidation/ValidationIndicator'; -import { useAuth } from 'context/auth'; import { orderBy } from 'lodash'; import Link from 'next/link'; import { useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; + +import { ValidationIndicator } from 'components/FormValidation/ValidationIndicator'; +import { useAuth } from 'context/auth'; import { dropNotApproved } from 'utils/dropNotApproved'; import { formatDate } from '../../utils/date'; @@ -95,10 +100,6 @@ export const TableDisplay = ({ setBatchEditMode(false); }; - const isSameProvince = selectedForms.every( - form => form.province === selectedForms[0]?.province, - ); - if (!isLoading && formattedForms.length === 0) { return ( @@ -109,18 +110,25 @@ export const TableDisplay = ({ return ( <> - {isUserAdmin && isFlood && ( - - - - )} - {batchEditMode && ( - - You can only batch edit forms from the same province - - )} + )} + {isFlood && ( + + + + )} + {batchEditMode && ( + + You can only batch edit forms from the same province + + )} + @@ -148,6 +156,16 @@ export const TableDisplay = ({ {isFlood && ( + {isUserAdmin && ( + + + + + + )} )} {batchEditMode && ( @@ -212,8 +230,9 @@ export const TableDisplay = ({ onChange={() => handleCheckboxChange(formattedForm)} disabled={ selectedForms.length > 0 && - !isSameProvince && - !selectedForms.includes(formattedForm) + selectedForms.some( + f => f.province !== formattedForm.province, + ) } /> @@ -260,7 +279,10 @@ export const TableDisplay = ({ - From 91e69625512cf9882d09a29ec2104b73afb419b6 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Mon, 15 Jul 2024 17:58:15 +0200 Subject: [PATCH 05/28] Update TableDisplay.tsx --- .../components/TableDisplay/TableDisplay.tsx | 40 ++++++++++--------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 713a1046..f678a93d 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -110,25 +110,27 @@ export const TableDisplay = ({ return ( <> - - {batchEditMode && selectedForms.length > 0 && ( - - )} - {isFlood && ( - - - - )} - {batchEditMode && ( - - You can only batch edit forms from the same province - - )} - + {isFlood && ( + + <> + {batchEditMode && selectedForms.length > 0 && ( + + )} + + + + {batchEditMode && ( + + You can only batch edit forms from the same province + + )} + + + )}
From d4524447ff4c1dea0bee8d04f7a56609b2019c68 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Mon, 15 Jul 2024 18:10:06 +0200 Subject: [PATCH 06/28] Fix FloodForm type --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index f678a93d..77c55e3a 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -60,6 +60,11 @@ const formatForms = ( ); }; +type FloodForm = { + id: string; + province: string; +}; + export const TableDisplay = ({ forms, isLoading, @@ -72,7 +77,7 @@ export const TableDisplay = ({ const { user } = useAuth(); const isUserAdmin = Boolean(user && ['admin'].includes(user.roles[0])); const [batchEditMode, setBatchEditMode] = useState(false); - const [selectedForms, setSelectedForms] = useState([]); + const [selectedForms, setSelectedForms] = useState([]); const [newFloodNumber, setNewFloodNumber] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); @@ -81,7 +86,7 @@ export const TableDisplay = ({ [forms, isUserAdmin], ); - const handleCheckboxChange = (form: DisasterDtoType) => { + const handleCheckboxChange = (form: FloodForm) => { setSelectedForms(prev => prev.includes(form) ? prev.filter(f => f.id !== form.id) From b0959c585e9d0828e8ea620e33515dd0f578ddb9 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 12:00:15 +0200 Subject: [PATCH 07/28] Add icons --- .../components/TableDisplay/TableDisplay.tsx | 38 ++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 77c55e3a..16a239c4 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -1,4 +1,6 @@ /* eslint-disable complexity, max-lines */ +import CancelIcon from '@mui/icons-material/Cancel'; +import CheckIcon from '@mui/icons-material/Check'; import EditIcon from '@mui/icons-material/Edit'; import { Button, @@ -116,9 +118,9 @@ export const TableDisplay = ({ return ( <> {isFlood && ( - + <> - {batchEditMode && selectedForms.length > 0 && ( + {/* {batchEditMode && selectedForms.length > 0 && ( @@ -127,9 +129,9 @@ export const TableDisplay = ({ - + */} {batchEditMode && ( - + You can only batch edit forms from the same province )} @@ -163,23 +165,33 @@ export const TableDisplay = ({ {isFlood && ( - {isUserAdmin && ( - + + + {batchEditMode ? : } + + + + )} + {batchEditMode && ( + + + {selectedForms.length > 0 && ( + setDialogOpen(true)} sx={{ pr: 0, maxWidth: '30px', marginRight: -2 }} > - + )} )} - {batchEditMode && ( - - - - )} From 35f596fde58c03db80c458b819928a3342b1ed12 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 12:08:00 +0200 Subject: [PATCH 08/28] Use floating button --- .../components/TableDisplay/TableDisplay.tsx | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 16a239c4..ced2ed73 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -82,13 +82,21 @@ export const TableDisplay = ({ const [selectedForms, setSelectedForms] = useState([]); const [newFloodNumber, setNewFloodNumber] = useState(null); const [dialogOpen, setDialogOpen] = useState(false); + const [lastCheckboxPosition, setLastCheckboxPosition] = useState<{ + top: number; + left: number; + } | null>(null); const formattedForms = useMemo( () => formatForms(forms, !isUserAdmin), [forms, isUserAdmin], ); - const handleCheckboxChange = (form: FloodForm) => { + const handleCheckboxChange = (form: FloodForm, event: React.MouseEvent) => { + const checkbox = event.target as HTMLElement; + const rect = checkbox.getBoundingClientRect(); + setLastCheckboxPosition({ top: rect.top, left: rect.right }); + setSelectedForms(prev => prev.includes(form) ? prev.filter(f => f.id !== form.id) @@ -246,7 +254,7 @@ export const TableDisplay = ({ handleCheckboxChange(formattedForm)} + onChange={e => handleCheckboxChange(formattedForm, e)} disabled={ selectedForms.length > 0 && selectedForms.some( @@ -278,9 +286,23 @@ export const TableDisplay = ({ )}
- {batchEditMode && selectedForms.length > 0 && ( - )} setDialogOpen(false)}> From a93eae3fccbe71ebddd72b94052ef3293d567544 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 12:09:09 +0200 Subject: [PATCH 09/28] Update TableDisplay.tsx --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index ced2ed73..7f72df2b 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -125,7 +125,7 @@ export const TableDisplay = ({ return ( <> - {isFlood && ( + {isFlood && batchEditMode && ( <> {/* {batchEditMode && selectedForms.length > 0 && ( @@ -138,11 +138,11 @@ export const TableDisplay = ({ {batchEditMode ? 'Cancel Batch Edit' : 'Edit Flood #'} */} - {batchEditMode && ( + { You can only batch edit forms from the same province - )} + } )} From 5fa39ee9db6291e7cbad407e0e5c5bac4d9b1c1a Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 13:36:05 +0200 Subject: [PATCH 10/28] Update TableDisplay.tsx --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 7f72df2b..04bfdaea 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -92,7 +92,10 @@ export const TableDisplay = ({ [forms, isUserAdmin], ); - const handleCheckboxChange = (form: FloodForm, event: React.MouseEvent) => { + const handleCheckboxChange = ( + form: FloodForm, + event: React.ChangeEvent, + ) => { const checkbox = event.target as HTMLElement; const rect = checkbox.getBoundingClientRect(); setLastCheckboxPosition({ top: rect.top, left: rect.right }); From caa5fc1757c596499d7f36df4d7b04ba89b15f62 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 13:49:39 +0200 Subject: [PATCH 11/28] Update button --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 04bfdaea..6cf60431 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -129,7 +129,7 @@ export const TableDisplay = ({ return ( <> {isFlood && batchEditMode && ( - + <> {/* {batchEditMode && selectedForms.length > 0 && ( - )} - - - */} - { - - You can only batch edit forms from the same province - - } - + + You can only batch edit forms from the same province + )} @@ -181,7 +167,16 @@ export const TableDisplay = ({ > {batchEditMode ? : } @@ -195,7 +190,14 @@ export const TableDisplay = ({ setDialogOpen(true)} - sx={{ pr: 0, maxWidth: '30px', marginRight: -2 }} + sx={{ + marginRight: -3, + marginLeft: -0.5, + color: 'green', + '&:hover': { + backgroundColor: 'transparent', + }, + }} > From 11414506a08ade386c700bf167bdef535cd1df5d Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 14:52:52 +0200 Subject: [PATCH 13/28] Split into two files --- .../TableDisplay/BatchEditControls.tsx | 152 +++++++++++ .../components/TableDisplay/TableDisplay.tsx | 249 +++++++----------- 2 files changed, 246 insertions(+), 155 deletions(-) create mode 100644 apps/frontend/components/TableDisplay/BatchEditControls.tsx diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx new file mode 100644 index 00000000..91d7472f --- /dev/null +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -0,0 +1,152 @@ +import CancelIcon from '@mui/icons-material/Cancel'; +import CheckIcon from '@mui/icons-material/Check'; +import EditIcon from '@mui/icons-material/Edit'; +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + IconButton, + Stack, + TextField, + Tooltip, + Typography, +} from '@mui/material'; +import { useState } from 'react'; + +type FloodForm = { + id: string; + province: string; +}; + +export const BatchEditWarning = () => ( + + + You can only batch edit forms from the same province + + +); + +export const BatchEditControl = ({ + batchEditMode, + handleBatchEditClick, +}: { + batchEditMode: boolean; + handleBatchEditClick: () => void; +}) => ( + + + {batchEditMode ? : } + + +); + +export const BatchEditDialog = ({ + batchEditMode, + selectedForms, + handleEditFloodNumber, + lastCheckboxPosition, +}: { + batchEditMode: boolean; + selectedForms: FloodForm[]; + handleEditFloodNumber: (newFloodNumber: number) => void; + lastCheckboxPosition: { top: number; left: number } | null; +}) => { + const [dialogOpen, setDialogOpen] = useState(false); + const [newFloodNumber, setNewFloodNumber] = useState(null); + + const renderSelectButton = () => ( + <> + {selectedForms.length > 0 && ( + + setDialogOpen(true)} + sx={{ + color: 'green', + '&:hover': { + backgroundColor: 'transparent', + }, + }} + > + + + + )} + + ); + + const renderEditButton = () => ( + + ); + + const renderDialog = () => ( + setDialogOpen(false)}> + + Edit flood number for {selectedForms.length} selected forms + + + setNewFloodNumber(Number(e.target.value))} + fullWidth + /> + + + + + + + ); + + return ( + <> + {batchEditMode && renderSelectButton()} + {batchEditMode && + selectedForms.length > 0 && + lastCheckboxPosition && + renderEditButton()} + {renderDialog()} + + ); +}; + +export default BatchEditDialog; diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 85ffce67..9a93459a 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -1,26 +1,14 @@ -/* eslint-disable complexity, max-lines */ -import CancelIcon from '@mui/icons-material/Cancel'; -import CheckIcon from '@mui/icons-material/Check'; -import EditIcon from '@mui/icons-material/Edit'; +/* eslint-disable max-lines */ import { - Button, Checkbox, - Dialog, - DialogActions, - DialogContent, - DialogTitle, - IconButton, Paper, Skeleton, - Stack, Table, TableBody, TableCell, TableContainer, TableHead, TableRow, - TextField, - Tooltip, Typography, } from '@mui/material'; import { @@ -38,6 +26,11 @@ import { useAuth } from 'context/auth'; import { dropNotApproved } from 'utils/dropNotApproved'; import { formatDate } from '../../utils/date'; +import { + BatchEditControl, + BatchEditDialog, + BatchEditWarning, +} from './BatchEditControls'; const formatForms = ( forms: DisasterDtoType[] | undefined, @@ -67,6 +60,75 @@ type FloodForm = { province: string; }; +const TableHeader = ({ + isFlood, + batchEditMode, + handleBatchEditClick, + selectedForms, + handleEditFloodNumber, + lastCheckboxPosition, +}: { + isFlood: boolean; + batchEditMode: boolean; + handleBatchEditClick: () => void; + selectedForms: FloodForm[]; + handleEditFloodNumber: (newFloodNumber: number) => void; + lastCheckboxPosition: { top: number; left: number } | null; + setSelectedForms: (forms: FloodForm[]) => void; +}) => ( + + + + + + + + + + + + + + + + + + + + + {isFlood && ( + + + + + )} + {batchEditMode && ( + + + + + )} + + + + + + + + + + + +); + export const TableDisplay = ({ forms, isLoading, @@ -80,8 +142,6 @@ export const TableDisplay = ({ const isUserAdmin = Boolean(user && ['admin'].includes(user.roles[0])); const [batchEditMode, setBatchEditMode] = useState(false); const [selectedForms, setSelectedForms] = useState([]); - const [newFloodNumber, setNewFloodNumber] = useState(null); - const [dialogOpen, setDialogOpen] = useState(false); const [lastCheckboxPosition, setLastCheckboxPosition] = useState<{ top: number; left: number; @@ -112,9 +172,9 @@ export const TableDisplay = ({ setSelectedForms([]); }; - const handleEditFloodNumber = () => { + const handleEditFloodNumber = (newFloodNumber: number) => { // Logic to update flood numbers for selected forms - setDialogOpen(false); + console.warn({ newFloodNumber }); setBatchEditMode(false); }; @@ -128,105 +188,27 @@ export const TableDisplay = ({ return ( <> - {isFlood && batchEditMode && ( - - - You can only batch edit forms from the same province - - - )} + {batchEditMode && } - - - - - - - - - - - - - - - - - - - - - {isFlood && ( - - - - - {batchEditMode ? : } - - - - )} - {batchEditMode && ( - - - {selectedForms.length > 0 && ( - - setDialogOpen(true)} - sx={{ - marginRight: -3, - marginLeft: -0.5, - color: 'green', - '&:hover': { - backgroundColor: 'transparent', - }, - }} - > - - - - )} - - )} - - - - - - - - - - - + {isLoading ? ( - {[1, 2, 3].map(id => { - return ( - - - - - - ); - })} + {[1, 2, 3].map(id => ( + + + + + + ))} ) : ( @@ -291,49 +273,6 @@ export const TableDisplay = ({ )}
- {batchEditMode && selectedForms.length > 0 && lastCheckboxPosition && ( - - )} - setDialogOpen(false)}> - - Edit flood number for {selectedForms.length} selected forms - - - setNewFloodNumber(Number(e.target.value))} - fullWidth - /> - - - - - -
); From 24c301a21244fb1e59a209d09e40db77514855a2 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 15:07:58 +0200 Subject: [PATCH 14/28] Add translations --- .../TableDisplay/BatchEditControls.tsx | 39 ++++++++++++++----- apps/frontend/translations/en.json | 10 +++++ apps/frontend/translations/km.json | 11 ++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 91d7472f..337b380f 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -14,6 +14,7 @@ import { Typography, } from '@mui/material'; import { useState } from 'react'; +import { FormattedMessage } from 'react-intl'; type FloodForm = { id: string; @@ -22,8 +23,8 @@ type FloodForm = { export const BatchEditWarning = () => ( - - You can only batch edit forms from the same province + + ); @@ -35,7 +36,15 @@ export const BatchEditControl = ({ batchEditMode: boolean; handleBatchEditClick: () => void; }) => ( - + + ) : ( + + ) + } + > ( <> {selectedForms.length > 0 && ( - + } + > setDialogOpen(true)} sx={{ @@ -102,26 +113,36 @@ export const BatchEditDialog = ({ backgroundColor: 'var(--color_buttons_1)', }} > - Edit {selectedForms.length} forms + ); const renderDialog = () => ( setDialogOpen(false)}> - Edit flood number for {selectedForms.length} selected forms + + } value={newFloodNumber} onChange={e => setNewFloodNumber(Number(e.target.value))} fullWidth /> - + diff --git a/apps/frontend/translations/en.json b/apps/frontend/translations/en.json index 566d5a9f..dfd916a4 100644 --- a/apps/frontend/translations/en.json +++ b/apps/frontend/translations/en.json @@ -109,6 +109,16 @@ "phone": "Phone", "entry_date": "Entry Date", "review_link": "Review and Approval" + }, + "batch_edit": { + "start": "Batch edit flood #", + "cancel": "Cancel", + "save": "Save", + "warning": "You can only batch edit forms from the same province", + "dialog_title": "Edit flood number for {count} selected form(s)", + "edit_forms": "Edit {count} form(s)", + "open_dialog": "Open edit dialog", + "new_flood_number": "New flood number" } }, "report_page": { diff --git a/apps/frontend/translations/km.json b/apps/frontend/translations/km.json index da496214..88a319f7 100644 --- a/apps/frontend/translations/km.json +++ b/apps/frontend/translations/km.json @@ -113,10 +113,21 @@ "dis_date": "ការបរិច្ឆេទថ្ងៃកើតហេតុ", "dis_type": "ប្រភេទគ្រោះមហន្តរាយ", "flood_number": "ចំនួនលើកទឹកជំនន់", + "select": "ជ្រើសរើស", "entry_name": "ឈ្មោះរបាយការណ៍", "phone": "លេខទូរសព្ឌ័", "entry_date": "ការបរិច្ឆេទបញ្ចូលរបាយការណ៍", "review_link": "ពិនិត្យ និងឯកភាព" + }, + "batch_edit": { + "start": "កែសម្រួលទឹកជំនន់ជាក្រុម #", + "cancel": "បោះបង់", + "save": "រក្សាទុក", + "warning": "អ្នកអាចកែសម្រួលទម្រង់ជាក្រុមបានតែពីខេត្តដូចគ្នាប៉ុណ្ណោះ", + "dialog_title": "កែសម្រួលចំនួនទឹកជំនន់សម្រាប់ទម្រង់ដែលបានជ្រើសរើស {count}", + "edit_forms": "កែសម្រួលទម្រង់ {count}", + "open_dialog": "បើកប្រអប់សន្ទនា", + "new_flood_number": "ចំនួនទឹកជំនន់ថ្មី" } }, "report_page": { From a41164d75c4e69fc59cd0e84b775679922406e93 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 16:04:53 +0200 Subject: [PATCH 15/28] Add a batch patch function for flood numbers --- .../TableDisplay/BatchEditControls.tsx | 25 +++++++++++----- .../components/TableDisplay/TableDisplay.tsx | 2 +- .../services/api/kobo/usePatchForm.ts | 30 ++++++++++++++++++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 337b380f..68099ebd 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -16,6 +16,8 @@ import { import { useState } from 'react'; import { FormattedMessage } from 'react-intl'; +import { usePatchFloodNumber } from 'services/api/kobo/usePatchForm'; + type FloodForm = { id: string; province: string; @@ -75,6 +77,20 @@ export const BatchEditDialog = ({ const [dialogOpen, setDialogOpen] = useState(false); const [newFloodNumber, setNewFloodNumber] = useState(null); + const formIds = selectedForms.map(form => form.id); + const { trigger: triggerPatch, isMutating } = usePatchFloodNumber( + formIds, + newFloodNumber ?? 0, + ); + + const handleSave = async () => { + if (newFloodNumber !== null && !isMutating) { + await triggerPatch(); // Updated call + handleEditFloodNumber(newFloodNumber); + setDialogOpen(false); + } + }; + const renderSelectButton = () => ( <> {selectedForms.length > 0 && ( @@ -144,13 +160,8 @@ export const BatchEditDialog = ({ diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 9a93459a..a56f117f 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -204,7 +204,7 @@ export const TableDisplay = ({ {[1, 2, 3].map(id => ( - + diff --git a/apps/frontend/services/api/kobo/usePatchForm.ts b/apps/frontend/services/api/kobo/usePatchForm.ts index dcbf68ee..30d85386 100644 --- a/apps/frontend/services/api/kobo/usePatchForm.ts +++ b/apps/frontend/services/api/kobo/usePatchForm.ts @@ -1,4 +1,8 @@ -import { DisasterType, ValidationStatusValue } from '@wfp-dmp/interfaces'; +import { + DisasterType, + floodSpecificKeys, + ValidationStatusValue, +} from '@wfp-dmp/interfaces'; import path from 'path'; import useSWRMutation from 'swr/mutation'; @@ -40,3 +44,27 @@ export const usePatchForm = ( return { trigger, isMutating: isMutating }; }; + +export const usePatchFloodNumber = (formIds: string[], floodNumber: number) => { + const { trigger, isMutating } = useSWRMutation( + [ApiRoutes.form, 'FLOOD'], + async ([relativePath, disasterType]) => { + const results = await Promise.all( + formIds.map(async id => { + const url = path.join(relativePath, disasterType, id); + const { + data: { status }, + } = await apiClient.patch<{ + status: number; + }>(url, { [floodSpecificKeys.floodN]: `${floodNumber}` }); + + return status; + }), + ); + + return results; + }, + ); + + return { trigger, isMutating: isMutating }; +}; From 142f378cbdba53f312e021a6605718ffc0671b75 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Tue, 16 Jul 2024 16:16:54 +0200 Subject: [PATCH 16/28] Update TableDisplay.tsx --- apps/frontend/components/TableDisplay/TableDisplay.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index a56f117f..c9987523 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -173,8 +173,13 @@ export const TableDisplay = ({ }; const handleEditFloodNumber = (newFloodNumber: number) => { - // Logic to update flood numbers for selected forms - console.warn({ newFloodNumber }); + // Update flood numbers for selected forms after batch edit + formattedForms.forEach(form => { + if (selectedForms.some(f => f.id === form.id)) { + form.floodN = `${newFloodNumber}`; + } + }); + setSelectedForms([]); setBatchEditMode(false); }; From de291e03cfff98f316486cf8a08f33bbae1f0006 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 10:30:59 +0200 Subject: [PATCH 17/28] Shrink label and add margins --- .../frontend/components/TableDisplay/BatchEditControls.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 68099ebd..cb63c898 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -150,6 +150,13 @@ export const BatchEditDialog = ({ label={ } + InputLabelProps={{ + shrink: true, + }} + sx={{ + margin: '1rem', + width: '80%', + }} value={newFloodNumber} onChange={e => setNewFloodNumber(Number(e.target.value))} fullWidth From 8ca858c7e416ff6de3951a1b186b4ddfb2020af9 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 11:44:30 +0200 Subject: [PATCH 18/28] Move checkboxes to the Flood column --- .../TableDisplay/BatchEditControls.tsx | 75 ++++++++++--------- .../components/TableDisplay/TableDisplay.tsx | 44 +++++------ 2 files changed, 57 insertions(+), 62 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index cb63c898..ccdd65b7 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -24,53 +24,30 @@ type FloodForm = { }; export const BatchEditWarning = () => ( - + ); -export const BatchEditControl = ({ - batchEditMode, - handleBatchEditClick, -}: { - batchEditMode: boolean; - handleBatchEditClick: () => void; -}) => ( - - ) : ( - - ) - } - > - - {batchEditMode ? : } - - -); - export const BatchEditDialog = ({ batchEditMode, selectedForms, + handleBatchEditClick, handleEditFloodNumber, lastCheckboxPosition, }: { batchEditMode: boolean; selectedForms: FloodForm[]; + handleBatchEditClick: () => void; handleEditFloodNumber: (newFloodNumber: number) => void; lastCheckboxPosition: { top: number; left: number } | null; }) => { @@ -91,15 +68,41 @@ export const BatchEditDialog = ({ } }; - const renderSelectButton = () => ( + const renderButtons = () => ( <> - {selectedForms.length > 0 && ( + + ) : ( + + ) + } + > + + {batchEditMode ? : } + + + + {batchEditMode && ( } > setDialogOpen(true)} sx={{ + marginRight: -3, color: 'green', '&:hover': { backgroundColor: 'transparent', @@ -178,7 +181,7 @@ export const BatchEditDialog = ({ return ( <> - {batchEditMode && renderSelectButton()} + {renderButtons()} {batchEditMode && selectedForms.length > 0 && lastCheckboxPosition && diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index c9987523..2731182d 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -26,11 +26,7 @@ import { useAuth } from 'context/auth'; import { dropNotApproved } from 'utils/dropNotApproved'; import { formatDate } from '../../utils/date'; -import { - BatchEditControl, - BatchEditDialog, - BatchEditWarning, -} from './BatchEditControls'; +import { BatchEditDialog, BatchEditWarning } from './BatchEditControls'; const formatForms = ( forms: DisasterDtoType[] | undefined, @@ -99,18 +95,11 @@ const TableHeader = ({ {isFlood && ( - - - )} - {batchEditMode && ( - - + @@ -241,19 +230,22 @@ export const TableDisplay = ({ id={`disasters.${formattedForm.disTyp}`} /> - {isFlood && {formattedForm.floodN}} - {batchEditMode && ( + {isFlood && ( - handleCheckboxChange(formattedForm, e)} - disabled={ - selectedForms.length > 0 && - selectedForms.some( - f => f.province !== formattedForm.province, - ) - } - /> + {formattedForm.floodN} + {batchEditMode && ( + handleCheckboxChange(formattedForm, e)} + disabled={ + selectedForms.length > 0 && + selectedForms.some( + f => f.province !== formattedForm.province, + ) + } + /> + )} )} {formattedForm.entryName} From b400f0a4a89bc1fbb99c93cdd986e30932fe94c7 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 12:07:30 +0200 Subject: [PATCH 19/28] Move utils --- .../TableDisplay/BatchEditControls.tsx | 71 +++++++------------ .../components/TableDisplay/TableDisplay.tsx | 57 ++++----------- .../frontend/components/TableDisplay/utils.ts | 32 +++++++++ apps/frontend/translations/en.json | 2 +- apps/frontend/translations/km.json | 2 +- 5 files changed, 73 insertions(+), 91 deletions(-) create mode 100644 apps/frontend/components/TableDisplay/utils.ts diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index ccdd65b7..2ea3f00a 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -1,5 +1,4 @@ import CancelIcon from '@mui/icons-material/Cancel'; -import CheckIcon from '@mui/icons-material/Check'; import EditIcon from '@mui/icons-material/Edit'; import { Button, @@ -10,7 +9,6 @@ import { IconButton, Stack, TextField, - Tooltip, Typography, } from '@mui/material'; import { useState } from 'react'; @@ -69,51 +67,32 @@ export const BatchEditDialog = ({ }; const renderButtons = () => ( - <> - - ) : ( - - ) - } - > - - {batchEditMode ? : } - - - - {batchEditMode && ( - } - > - setDialogOpen(true)} - sx={{ - marginRight: -3, - color: 'green', - '&:hover': { - backgroundColor: 'transparent', - }, - }} - > - - - + + {batchEditMode ? ( + + ) : ( + )} - + + ); const renderEditButton = () => ( diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 2731182d..07897b94 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -1,4 +1,3 @@ -/* eslint-disable max-lines */ import { Checkbox, Paper, @@ -11,50 +10,17 @@ import { TableRow, Typography, } from '@mui/material'; -import { - DisasterDtoType, - formatCommonFields, - ValidationStatusValue, -} from '@wfp-dmp/interfaces'; -import { orderBy } from 'lodash'; +import { DisasterDtoType, ValidationStatusValue } from '@wfp-dmp/interfaces'; import Link from 'next/link'; import { useMemo, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { ValidationIndicator } from 'components/FormValidation/ValidationIndicator'; import { useAuth } from 'context/auth'; -import { dropNotApproved } from 'utils/dropNotApproved'; import { formatDate } from '../../utils/date'; import { BatchEditDialog, BatchEditWarning } from './BatchEditControls'; - -const formatForms = ( - forms: DisasterDtoType[] | undefined, - dropRejected: boolean, -) => { - if (forms === undefined || forms.length === 0) { - return []; - } - - // Filter out rejected forms and order by date descending - // using disasterDate then submissionTime. - const formattedForms = (dropRejected ? dropNotApproved(forms) : forms).map( - form => { - return formatCommonFields(form); - }, - ); - - return orderBy( - formattedForms, - ['disasterDate', 'submissionTime'], - ['desc', 'desc'], - ); -}; - -type FloodForm = { - id: string; - province: string; -}; +import { BasicFloodForm, formatForms } from './utils'; const TableHeader = ({ isFlood, @@ -67,10 +33,10 @@ const TableHeader = ({ isFlood: boolean; batchEditMode: boolean; handleBatchEditClick: () => void; - selectedForms: FloodForm[]; + selectedForms: BasicFloodForm[]; handleEditFloodNumber: (newFloodNumber: number) => void; lastCheckboxPosition: { top: number; left: number } | null; - setSelectedForms: (forms: FloodForm[]) => void; + setSelectedForms: (forms: BasicFloodForm[]) => void; }) => ( @@ -95,7 +61,7 @@ const TableHeader = ({ {isFlood && ( - +
([]); + const [selectedForms, setSelectedForms] = useState([]); const [lastCheckboxPosition, setLastCheckboxPosition] = useState<{ top: number; left: number; @@ -142,7 +108,7 @@ export const TableDisplay = ({ ); const handleCheckboxChange = ( - form: FloodForm, + form: BasicFloodForm, event: React.ChangeEvent, ) => { const checkbox = event.target as HTMLElement; @@ -231,11 +197,10 @@ export const TableDisplay = ({ />
{isFlood && ( - + {formattedForm.floodN} {batchEditMode && ( handleCheckboxChange(formattedForm, e)} disabled={ @@ -244,6 +209,12 @@ export const TableDisplay = ({ f => f.province !== formattedForm.province, ) } + sx={{ + color: 'black', + '&.Mui-checked': { + color: 'black', + }, + }} /> )} diff --git a/apps/frontend/components/TableDisplay/utils.ts b/apps/frontend/components/TableDisplay/utils.ts new file mode 100644 index 00000000..9a8faf7e --- /dev/null +++ b/apps/frontend/components/TableDisplay/utils.ts @@ -0,0 +1,32 @@ +import { DisasterDtoType, formatCommonFields } from '@wfp-dmp/interfaces'; +import { orderBy } from 'lodash'; + +import { dropNotApproved } from 'utils/dropNotApproved'; + +export type BasicFloodForm = { + id: string; + province: string; +}; + +export const formatForms = ( + forms: DisasterDtoType[] | undefined, + dropRejected: boolean, +) => { + if (forms === undefined || forms.length === 0) { + return []; + } + + // Filter out rejected forms and order by date descending + // using disasterDate then submissionTime. + const formattedForms = (dropRejected ? dropNotApproved(forms) : forms).map( + form => { + return formatCommonFields(form); + }, + ); + + return orderBy( + formattedForms, + ['disasterDate', 'submissionTime'], + ['desc', 'desc'], + ); +}; diff --git a/apps/frontend/translations/en.json b/apps/frontend/translations/en.json index dfd916a4..9390e5f5 100644 --- a/apps/frontend/translations/en.json +++ b/apps/frontend/translations/en.json @@ -111,7 +111,7 @@ "review_link": "Review and Approval" }, "batch_edit": { - "start": "Batch edit flood #", + "edit": "Edit", "cancel": "Cancel", "save": "Save", "warning": "You can only batch edit forms from the same province", diff --git a/apps/frontend/translations/km.json b/apps/frontend/translations/km.json index 88a319f7..a7328106 100644 --- a/apps/frontend/translations/km.json +++ b/apps/frontend/translations/km.json @@ -120,7 +120,7 @@ "review_link": "ពិនិត្យ និងឯកភាព" }, "batch_edit": { - "start": "កែសម្រួលទឹកជំនន់ជាក្រុម #", + "edit": "កែសម្រួល", "cancel": "បោះបង់", "save": "រក្សាទុក", "warning": "អ្នកអាចកែសម្រួលទម្រង់ជាក្រុមបានតែពីខេត្តដូចគ្នាប៉ុណ្ណោះ", From d859e645bdaabe27647a40e8ed7a3a3904129993 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 12:46:52 +0200 Subject: [PATCH 20/28] Adapt modal --- .../TableDisplay/BatchEditControls.tsx | 86 ++++++++++--------- apps/frontend/translations/en.json | 4 +- apps/frontend/translations/km.json | 4 +- 3 files changed, 51 insertions(+), 43 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 2ea3f00a..3c4e1276 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -11,7 +11,7 @@ import { TextField, Typography, } from '@mui/material'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { FormattedMessage } from 'react-intl'; import { usePatchFloodNumber } from 'services/api/kobo/usePatchForm'; @@ -58,6 +58,14 @@ export const BatchEditDialog = ({ newFloodNumber ?? 0, ); + useEffect(() => { + if (batchEditMode && selectedForms.length > 0) { + setDialogOpen(true); + } else { + setDialogOpen(false); + } + }, [batchEditMode, selectedForms]); + const handleSave = async () => { if (newFloodNumber !== null && !isMutating) { await triggerPatch(); // Updated call @@ -95,31 +103,18 @@ export const BatchEditDialog = ({
); - const renderEditButton = () => ( - - ); - - const renderDialog = () => ( - setDialogOpen(false)}> - + + + + {selectedForms.length} + + + - } - InputLabelProps={{ - shrink: true, - }} - sx={{ - margin: '1rem', - width: '80%', - }} - value={newFloodNumber} - onChange={e => setNewFloodNumber(Number(e.target.value))} - fullWidth - /> + setNewFloodNumber(Number(e.target.value))} + fullWidth + /> + +
@@ -161,10 +173,6 @@ export const BatchEditDialog = ({ return ( <> {renderButtons()} - {batchEditMode && - selectedForms.length > 0 && - lastCheckboxPosition && - renderEditButton()} {renderDialog()} ); diff --git a/apps/frontend/translations/en.json b/apps/frontend/translations/en.json index 9390e5f5..add43c01 100644 --- a/apps/frontend/translations/en.json +++ b/apps/frontend/translations/en.json @@ -115,8 +115,8 @@ "cancel": "Cancel", "save": "Save", "warning": "You can only batch edit forms from the same province", - "dialog_title": "Edit flood number for {count} selected form(s)", - "edit_forms": "Edit {count} form(s)", + "dialog_title": "Batch edit flood number", + "forms_selected": "Forms selected", "open_dialog": "Open edit dialog", "new_flood_number": "New flood number" } diff --git a/apps/frontend/translations/km.json b/apps/frontend/translations/km.json index a7328106..12a63eec 100644 --- a/apps/frontend/translations/km.json +++ b/apps/frontend/translations/km.json @@ -124,8 +124,8 @@ "cancel": "បោះបង់", "save": "រក្សាទុក", "warning": "អ្នកអាចកែសម្រួលទម្រង់ជាក្រុមបានតែពីខេត្តដូចគ្នាប៉ុណ្ណោះ", - "dialog_title": "កែសម្រួលចំនួនទឹកជំនន់សម្រាប់ទម្រង់ដែលបានជ្រើសរើស {count}", - "edit_forms": "កែសម្រួលទម្រង់ {count}", + "dialog_title": "កែសម្រួលចំនួនទឹកជំនន់ជាក្រុម", + "forms_selected": "ទម្រង់ដែលបានជ្រើសរើស", "open_dialog": "បើកប្រអប់សន្ទនា", "new_flood_number": "ចំនួនទឹកជំនន់ថ្មី" } From 59b9cd4ec0f5cd5a17025fd9b66ffd2c6d5c2099 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 13:03:41 +0200 Subject: [PATCH 21/28] Adjust styling --- .../TableDisplay/BatchEditControls.tsx | 33 +++++++++++++++---- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 3c4e1276..2402514e 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -105,15 +105,20 @@ export const BatchEditDialog = ({ const renderDialog = () => ( setDialogOpen(false)} disableScrollLock + disableEnforceFocus slotProps={{ backdrop: { style: { display: 'none' } } }} sx={{ position: 'fixed', - top: lastCheckboxPosition?.top, + top: (lastCheckboxPosition?.top ?? 0) - 500, left: lastCheckboxPosition?.left, }} + PaperProps={{ + sx: { borderRadius: '8px', border: '1px solid #ccc' }, + }} > - + - + {selectedForms.length} @@ -155,14 +160,28 @@ export const BatchEditDialog = ({ - + setDialogOpen(false)} + sx={{ + position: 'absolute', + top: 8, + right: 8, + color: 'black', + }} + > + + From c675d79c63104a44a244d0b3fcdae5192ca8aa7f Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 13:06:00 +0200 Subject: [PATCH 22/28] Update SearchFilters.tsx --- apps/frontend/components/Filters/SearchFilters.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/frontend/components/Filters/SearchFilters.tsx b/apps/frontend/components/Filters/SearchFilters.tsx index d2bd9de7..4884dd22 100644 --- a/apps/frontend/components/Filters/SearchFilters.tsx +++ b/apps/frontend/components/Filters/SearchFilters.tsx @@ -59,7 +59,7 @@ export const SearchFilters = ({
- + {intl.formatMessage({ id: 'validation_search_params.date_range', })} From eb8505791deafeae3ad7a6e7257ca6af3eee74fd Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 14:30:16 +0200 Subject: [PATCH 23/28] Add tooltip --- .../TableDisplay/BatchEditControls.tsx | 42 +++++++++++++------ .../components/TableDisplay/TableDisplay.tsx | 7 ++-- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 2402514e..436b219a 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -9,6 +9,7 @@ import { IconButton, Stack, TextField, + Tooltip, Typography, } from '@mui/material'; import { useEffect, useState } from 'react'; @@ -21,19 +22,36 @@ type FloodForm = { province: string; }; -export const BatchEditWarning = () => ( - ( + + + + } + open={true} + placement="top" + arrow + componentsProps={{ + tooltip: { + sx: { + backgroundColor: 'white', + maxWidth: 'none', + border: '1px solid #D32C38', + }, + }, + arrow: { + sx: { + color: 'white', + '&:before': { + border: '1px solid #D32C38', + }, + }, + }, + }} > - - - - +
+ ); export const BatchEditDialog = ({ diff --git a/apps/frontend/components/TableDisplay/TableDisplay.tsx b/apps/frontend/components/TableDisplay/TableDisplay.tsx index 07897b94..1263cf98 100644 --- a/apps/frontend/components/TableDisplay/TableDisplay.tsx +++ b/apps/frontend/components/TableDisplay/TableDisplay.tsx @@ -19,7 +19,7 @@ import { ValidationIndicator } from 'components/FormValidation/ValidationIndicat import { useAuth } from 'context/auth'; import { formatDate } from '../../utils/date'; -import { BatchEditDialog, BatchEditWarning } from './BatchEditControls'; +import { BatchEditDialog, BatchEditWarningTooltip } from './BatchEditControls'; import { BasicFloodForm, formatForms } from './utils'; const TableHeader = ({ @@ -59,7 +59,8 @@ const TableHeader = ({ {isFlood && ( - + + {batchEditMode && }
- {batchEditMode && } Date: Wed, 17 Jul 2024 14:37:39 +0200 Subject: [PATCH 24/28] Update BatchEditControls.tsx --- apps/frontend/components/TableDisplay/BatchEditControls.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 436b219a..7248f345 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -130,12 +130,14 @@ export const BatchEditDialog = ({ disableEnforceFocus slotProps={{ backdrop: { style: { display: 'none' } } }} sx={{ + width: '400px', position: 'fixed', top: (lastCheckboxPosition?.top ?? 0) - 500, left: lastCheckboxPosition?.left, + zIndex: 9999, }} PaperProps={{ - sx: { borderRadius: '8px', border: '1px solid #ccc' }, + sx: { width: '100%', borderRadius: '8px', border: '1px solid #ccc' }, }} > From 611a60bde312fe19ff667905a70a70f2e5ac2497 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 14:49:13 +0200 Subject: [PATCH 25/28] Update BatchEditControls.tsx --- .../components/TableDisplay/BatchEditControls.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 7248f345..9978e916 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -140,13 +140,13 @@ export const BatchEditDialog = ({ sx: { width: '100%', borderRadius: '8px', border: '1px solid #ccc' }, }} > - + - + - + {selectedForms.length} @@ -170,8 +170,9 @@ export const BatchEditDialog = ({ type="number" label="" sx={{ - width: '30%', + width: '20%', }} + inputProps={{ style: { textAlign: 'center' } }} value={newFloodNumber} onChange={e => setNewFloodNumber(Number(e.target.value))} fullWidth From 0cc08c83749dfdb089cb69d9d5aa8879fe55dd72 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 14:59:27 +0200 Subject: [PATCH 26/28] Cleanup --- .../components/TableDisplay/BatchEditControls.tsx | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 9978e916..008e4bd7 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -77,16 +77,12 @@ export const BatchEditDialog = ({ ); useEffect(() => { - if (batchEditMode && selectedForms.length > 0) { - setDialogOpen(true); - } else { - setDialogOpen(false); - } + setDialogOpen(batchEditMode && selectedForms.length > 0); }, [batchEditMode, selectedForms]); const handleSave = async () => { if (newFloodNumber !== null && !isMutating) { - await triggerPatch(); // Updated call + await triggerPatch(); handleEditFloodNumber(newFloodNumber); setDialogOpen(false); } @@ -134,7 +130,7 @@ export const BatchEditDialog = ({ position: 'fixed', top: (lastCheckboxPosition?.top ?? 0) - 500, left: lastCheckboxPosition?.left, - zIndex: 9999, + zIndex: 1501, }} PaperProps={{ sx: { width: '100%', borderRadius: '8px', border: '1px solid #ccc' }, @@ -168,10 +164,7 @@ export const BatchEditDialog = ({ setNewFloodNumber(Number(e.target.value))} From e0b0b4088a1013cf29c7249df153354723db8068 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 15:01:45 +0200 Subject: [PATCH 27/28] Update BatchEditControls.tsx --- apps/frontend/components/TableDisplay/BatchEditControls.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/frontend/components/TableDisplay/BatchEditControls.tsx b/apps/frontend/components/TableDisplay/BatchEditControls.tsx index 008e4bd7..ba6fc155 100644 --- a/apps/frontend/components/TableDisplay/BatchEditControls.tsx +++ b/apps/frontend/components/TableDisplay/BatchEditControls.tsx @@ -175,7 +175,10 @@ export const BatchEditDialog = ({ setDialogOpen(false)} + onClick={() => { + setDialogOpen(false); + handleBatchEditClick(); + }} sx={{ position: 'absolute', top: 8, From cecd2701fcc3e68e7f844c17819d427eadafb062 Mon Sep 17 00:00:00 2001 From: ericboucher Date: Wed, 17 Jul 2024 16:07:24 +0200 Subject: [PATCH 28/28] Trigger a reload of forms when an update occured --- .../frontend/services/api/kobo/useGetForms.ts | 19 ++++++++++++++++++- .../services/api/kobo/usePatchForm.ts | 2 ++ .../api/kobo/usePatchValidationStatus.ts | 3 +++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/frontend/services/api/kobo/useGetForms.ts b/apps/frontend/services/api/kobo/useGetForms.ts index d24d86e2..ce4f6da6 100644 --- a/apps/frontend/services/api/kobo/useGetForms.ts +++ b/apps/frontend/services/api/kobo/useGetForms.ts @@ -1,4 +1,5 @@ import { DroughtDto, FloodDto, IncidentDto } from '@wfp-dmp/interfaces'; +import { useEffect } from 'react'; import useSWR from 'swr'; import { SearchFormData } from 'components/Filters/SearchFilters'; @@ -19,7 +20,7 @@ export const useGetForms = ({ const inputCommune = inputRegion.commune.length === 0 ? undefined : inputRegion.commune; - const { data, isLoading } = useSWR( + const { data, isLoading, mutate } = useSWR( [ ApiRoutes.forms, inputDisTyps, @@ -48,5 +49,21 @@ export const useGetForms = ({ }, ); + // Trigger a revalidation when the localStorage changes, + // suggesting form data has been updated. + useEffect(() => { + const handleStorageChange = (event: StorageEvent) => { + if (event.key === 'formDataTrigger') { + void mutate(); // Trigger a revalidation + } + }; + + window.addEventListener('storage', handleStorageChange); + + return () => { + window.removeEventListener('storage', handleStorageChange); + }; + }, [mutate]); + return { data, isLoading }; }; diff --git a/apps/frontend/services/api/kobo/usePatchForm.ts b/apps/frontend/services/api/kobo/usePatchForm.ts index 30d85386..54025860 100644 --- a/apps/frontend/services/api/kobo/usePatchForm.ts +++ b/apps/frontend/services/api/kobo/usePatchForm.ts @@ -36,6 +36,8 @@ export const usePatchForm = ( // If the edit was successful, update the validation status to "onHold". if (status === 201) { await validationTrigger(ValidationStatusValue.onHold); + // Notify other tabs that the form data has been updated. + localStorage.setItem('formDataTrigger', JSON.stringify(new Date())); } return status; diff --git a/apps/frontend/services/api/kobo/usePatchValidationStatus.ts b/apps/frontend/services/api/kobo/usePatchValidationStatus.ts index e101cf97..31a6a647 100644 --- a/apps/frontend/services/api/kobo/usePatchValidationStatus.ts +++ b/apps/frontend/services/api/kobo/usePatchValidationStatus.ts @@ -27,6 +27,9 @@ export const usePatchValidationStatus = ( validationStatusValue: arg, }); + // Notify other tabs that the form data has been updated. + localStorage.setItem('formDataTrigger', JSON.stringify(new Date())); + return updatedValidationStatus; }, );