From af083c815df74a3f5c8d64f3200b21a862b08077 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Wed, 23 Oct 2024 08:52:23 +0200 Subject: [PATCH 1/3] OM-345: extend import options by adding group picker --- src/components/WorkerImportDialog.js | 24 ++++++----- src/constants.js | 5 +++ src/pickers/GroupPicker.js | 59 ++++++++++++++++++++++++++++ src/pickers/WorkerMultiplePicker.js | 12 +++++- src/translations/en.json | 4 +- 5 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 src/pickers/GroupPicker.js diff --git a/src/components/WorkerImportDialog.js b/src/components/WorkerImportDialog.js index 71cae87..8542984 100644 --- a/src/components/WorkerImportDialog.js +++ b/src/components/WorkerImportDialog.js @@ -14,7 +14,8 @@ import { import { makeStyles } from '@material-ui/styles'; import { useModulesManager, useTranslations, InfoButton } from '@openimis/fe-core'; -import { MODULE_NAME, WORKER_IMPORT_PLANS } from '../constants'; +import { MODULE_NAME, WORKER_IMPORT_GROUP_OF_WORKERS, WORKER_IMPORT_PLANS } from '../constants'; +import GroupPicker from '../pickers/GroupPicker'; export const useStyles = makeStyles((theme) => ({ primaryButton: theme.dialog.primaryButton, @@ -29,13 +30,15 @@ export const useStyles = makeStyles((theme) => ({ })); function WorkerImportDialog({ - open, onClose, importPlan, setImportPlan, onConfirm, + open, onClose, importPlan, setImportPlan, onConfirm, handleGroupChange, currentGroup, }) { const modulesManager = useModulesManager(); const classes = useStyles(); const { formatMessage } = useTranslations(MODULE_NAME, modulesManager); const radioGroupRef = React.useRef(null); + const importDisabled = !importPlan || (importPlan === WORKER_IMPORT_GROUP_OF_WORKERS && !currentGroup); + return ( @@ -54,12 +57,15 @@ function WorkerImportDialog({ onChange={(event) => setImportPlan(event.target.value)} > {WORKER_IMPORT_PLANS.map(({ value, labelKey }) => ( - } - label={formatMessage(labelKey)} - /> + <> + } + label={formatMessage(labelKey)} + /> + {importPlan === WORKER_IMPORT_GROUP_OF_WORKERS && } + ))} @@ -68,7 +74,7 @@ function WorkerImportDialog({ - diff --git a/src/constants.js b/src/constants.js index ab245f9..73b275a 100644 --- a/src/constants.js +++ b/src/constants.js @@ -84,6 +84,7 @@ export const DEFAULT = { export const WORKER_IMPORT_ALL_WORKERS = 'allWorkers'; export const WORKER_IMPORT_PREVIOUS_WORKERS = 'previousWorkers'; export const WORKER_IMPORT_PREVIOUS_DAY = 'previousDay'; +export const WORKER_IMPORT_GROUP_OF_WORKERS = 'groupOfWorkers'; export const WORKER_IMPORT_PLANS = [ { @@ -98,6 +99,10 @@ export const WORKER_IMPORT_PLANS = [ value: WORKER_IMPORT_PREVIOUS_DAY, labelKey: 'workerVoucher.workerImport.previousDay', }, + { + value: WORKER_IMPORT_GROUP_OF_WORKERS, + labelKey: 'workerVoucher.workerImport.groupOfWorkers', + }, ]; // There are 2 worker upload stages. Depending on the stage, the UI will show different fields/buttons. diff --git a/src/pickers/GroupPicker.js b/src/pickers/GroupPicker.js new file mode 100644 index 0000000..86e514a --- /dev/null +++ b/src/pickers/GroupPicker.js @@ -0,0 +1,59 @@ +import React, { useEffect, useState, useMemo } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; + +import { useModulesManager, useTranslations, Autocomplete } from '@openimis/fe-core'; +import { fetchGroupsAction } from '../actions'; +import { ADMIN_RIGHT, MODULE_NAME } from '../constants'; + +function GroupPicker({ + withLabel = true, withPlaceholder = true, label, onChange, +}) { + const modulesManager = useModulesManager(); + const dispatch = useDispatch(); + const { formatMessage } = useTranslations(MODULE_NAME, modulesManager); + + const { + groups, fetchingGroups, fetchedGroups, errorGroups, + } = useSelector((state) => state.workerVoucher); + const { economicUnit } = useSelector((state) => state.policyHolder); + const rights = useSelector((state) => state.core?.user?.i_user?.rights ?? []); + + const [group, setGroup] = useState(null); + + const isAdmin = useMemo(() => rights.includes(ADMIN_RIGHT), [rights]); + + useEffect(() => { + const actionParams = ['isDeleted: false']; + + if (!isAdmin && economicUnit?.code) { + actionParams.push(`economicUnitCode:"${economicUnit.code}"`); + } + + dispatch(fetchGroupsAction(modulesManager, actionParams)); + }, [isAdmin, economicUnit, modulesManager, dispatch]); + + const groupLabel = (option) => option.name; + + const handleChange = (selectedGroup) => { + onChange(selectedGroup); + setGroup(selectedGroup); + }; + + return ( + {}} + /> + ); +} + +export default GroupPicker; diff --git a/src/pickers/WorkerMultiplePicker.js b/src/pickers/WorkerMultiplePicker.js index c40b02e..33caeb0 100644 --- a/src/pickers/WorkerMultiplePicker.js +++ b/src/pickers/WorkerMultiplePicker.js @@ -12,13 +12,14 @@ import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank'; import CheckBoxIcon from '@material-ui/icons/CheckBox'; import Popper from '@material-ui/core/Popper'; -import { useModulesManager, useTranslations } from '@openimis/fe-core'; +import { useModulesManager, useTranslations, parseData } from '@openimis/fe-core'; import WorkerImportDialog from '../components/WorkerImportDialog'; import { MAX_CELLS, MODULE_NAME, USER_ECONOMIC_UNIT_STORAGE_KEY, WORKER_IMPORT_ALL_WORKERS, + WORKER_IMPORT_GROUP_OF_WORKERS, WORKER_IMPORT_PREVIOUS_DAY, WORKER_IMPORT_PREVIOUS_WORKERS, WORKER_THRESHOLD, @@ -41,6 +42,7 @@ function WorkerMultiplePicker({ const isDisabled = readOnly || isLoading; const [configurationDialogOpen, setConfigurationDialogOpen] = useState(false); const [importPlan, setImportPlan] = useState(undefined); + const [group, setGroup] = useState(null); const yesterday = getYesterdaysDate(); const icon = ; @@ -104,6 +106,8 @@ function WorkerMultiplePicker({ return previousWorkers; case WORKER_IMPORT_PREVIOUS_DAY: return previousDayWorkers; + case WORKER_IMPORT_GROUP_OF_WORKERS: + return parseData(group.groupWorkers)?.map((groupWorker) => groupWorker.insuree); default: return []; } @@ -120,6 +124,10 @@ function WorkerMultiplePicker({ onChange(null, updatedWorkers); }; + const handleGroupChange = (group) => { + setGroup(group); + }; + return (
); diff --git a/src/translations/en.json b/src/translations/en.json index eff61c1..35cc0b3 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -126,6 +126,7 @@ "workerVoucher.workerImport.allWorkers": "Add all workers", "workerVoucher.workerImport.previousWorkers": "Add workers I've worked with", "workerVoucher.workerImport.previousDay": "Add workers from the previous day only", + "workerVoucher.workerImport.groupOfWorkers": "Add workers from the particular group", "workerVoucher.workerImport.cancel": "Cancel", "workerVoucher.workerImport.confirm": "Import", "workerVoucher.printVoucher": "Print", @@ -193,5 +194,6 @@ "workerVoucher.GroupDetailsPage.delete.error": "Something went wrong while deleting the group. {detail}", "workerVoucher.WorkerDateRangePicker.selectDate.moreInfo": "Define the validity period for the selected workers' vouchers. You can add multiple validity periods, but they must not overlap. First, set the period, and then confirm it using the button below.", "workerVoucher.VoucherAssignmentForm.form.moreInfo": "Define the workers to whom you want to assign the non-personal vouchers. You can assign vouchers to multiple workers at once. First, select the workers, and then define periods in which the vouchers will be valid. Confirm the assignment using the top right corner button.", - "workerVoucher.WorkerImportDialog.moreInfo": "By using this feature, you can import your workers immediately. You can choose to import all workers, workers you've worked with, workers from the previous day only or workers from the particular group. Once you've selected the option, click the Import button to proceed." + "workerVoucher.WorkerImportDialog.moreInfo": "By using this feature, you can import your workers immediately. You can choose to import all workers, workers you've worked with, workers from the previous day only or workers from the particular group. Once you've selected the option, click the Import button to proceed.", + "workerVoucher.GroupPicker.label": "Group" } From 50e915f54cbe0d9153b7d411df3b55dc38001767 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Wed, 23 Oct 2024 09:00:21 +0200 Subject: [PATCH 2/3] OM-345: removee redundant state --- src/components/WorkerImportDialog.js | 18 +++++++++--------- src/pickers/GroupPicker.js | 9 +++------ src/pickers/WorkerMultiplePicker.js | 4 ++-- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/components/WorkerImportDialog.js b/src/components/WorkerImportDialog.js index 8542984..234c7c5 100644 --- a/src/components/WorkerImportDialog.js +++ b/src/components/WorkerImportDialog.js @@ -57,16 +57,16 @@ function WorkerImportDialog({ onChange={(event) => setImportPlan(event.target.value)} > {WORKER_IMPORT_PLANS.map(({ value, labelKey }) => ( - <> - } - label={formatMessage(labelKey)} - /> - {importPlan === WORKER_IMPORT_GROUP_OF_WORKERS && } - + } + label={formatMessage(labelKey)} + /> ))} + {importPlan === WORKER_IMPORT_GROUP_OF_WORKERS && ( + + )} diff --git a/src/pickers/GroupPicker.js b/src/pickers/GroupPicker.js index 86e514a..0f51fd0 100644 --- a/src/pickers/GroupPicker.js +++ b/src/pickers/GroupPicker.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState, useMemo } from 'react'; +import React, { useEffect, useMemo } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import { useModulesManager, useTranslations, Autocomplete } from '@openimis/fe-core'; @@ -6,7 +6,7 @@ import { fetchGroupsAction } from '../actions'; import { ADMIN_RIGHT, MODULE_NAME } from '../constants'; function GroupPicker({ - withLabel = true, withPlaceholder = true, label, onChange, + withLabel = true, withPlaceholder = true, label, onChange, currentGroup, }) { const modulesManager = useModulesManager(); const dispatch = useDispatch(); @@ -18,8 +18,6 @@ function GroupPicker({ const { economicUnit } = useSelector((state) => state.policyHolder); const rights = useSelector((state) => state.core?.user?.i_user?.rights ?? []); - const [group, setGroup] = useState(null); - const isAdmin = useMemo(() => rights.includes(ADMIN_RIGHT), [rights]); useEffect(() => { @@ -36,7 +34,6 @@ function GroupPicker({ const handleChange = (selectedGroup) => { onChange(selectedGroup); - setGroup(selectedGroup); }; return ( @@ -48,7 +45,7 @@ function GroupPicker({ options={groups} isLoading={fetchingGroups} isFetched={fetchedGroups} - value={group} + value={currentGroup} getOptionLabel={groupLabel} onChange={handleChange} onInputChange={() => {}} diff --git a/src/pickers/WorkerMultiplePicker.js b/src/pickers/WorkerMultiplePicker.js index 33caeb0..0bb38c8 100644 --- a/src/pickers/WorkerMultiplePicker.js +++ b/src/pickers/WorkerMultiplePicker.js @@ -116,9 +116,9 @@ function WorkerMultiplePicker({ const handleImport = () => { setConfigurationDialogOpen(false); - const currentWorkersSet = new Set(value.map((worker) => worker.id)); + const currentWorkersSet = new Set(value.map((worker) => worker.uuid)); const importedWorkers = importPlanWorkers(importPlan); - const uniqueImportedWorkers = importedWorkers.filter((worker) => !currentWorkersSet.has(worker.id)); + const uniqueImportedWorkers = importedWorkers.filter((worker) => !currentWorkersSet.has(worker.uuid)); const updatedWorkers = [...value, ...uniqueImportedWorkers]; onChange(null, updatedWorkers); From b00b0c1d6d426d9d60b073109504f45dfd189184 Mon Sep 17 00:00:00 2001 From: olewandowski1 Date: Wed, 23 Oct 2024 09:11:41 +0200 Subject: [PATCH 3/3] OM-345: reset value if eu changed --- src/pickers/WorkerMultiplePicker.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pickers/WorkerMultiplePicker.js b/src/pickers/WorkerMultiplePicker.js index 0bb38c8..bc49422 100644 --- a/src/pickers/WorkerMultiplePicker.js +++ b/src/pickers/WorkerMultiplePicker.js @@ -55,6 +55,7 @@ function WorkerMultiplePicker({ useEffect(() => { const loadData = async () => { setIsLoading(true); + setGroup(null); try { const { allAvailableWorkers, previousWorkers, previousDayWorkers } = await fetchAllAvailableWorkers( dispatch,