Skip to content

Commit

Permalink
CM-404: move individual to another group (#36)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan <j.dolkowski@soldevelo.com>
  • Loading branch information
jdolkowski and Jan authored Jan 5, 2024
1 parent d0eb0c7 commit 1ac979e
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 3 deletions.
62 changes: 62 additions & 0 deletions src/components/GroupChangeDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useState } from 'react';
import { injectIntl } from 'react-intl';

import { withTheme, withStyles } from '@material-ui/core/styles';
import {
Button, Dialog, DialogActions, DialogContent, DialogTitle,
} from '@material-ui/core';
import { useTranslations, useModulesManager } from '@openimis/fe-core';
import GroupPicker from '../pickers/GroupPicker';

const styles = (theme) => ({
primaryButton: theme.dialog.primaryButton,
secondaryButton: theme.dialog.secondaryButton,
});

function GroupChangeDialog({
classes,
confirmState,
onClose,
onConfirm,
groupIndividual,
}) {
const modulesManager = useModulesManager();
const { formatMessage, formatMessageWithValues } = useTranslations('individual', modulesManager);
const [groupToBeChanged, setGroupToBeChanged] = useState(null);

const handleConfirm = (groupToBeChanged) => {
onConfirm(groupToBeChanged);
onClose();
};

return (
<Dialog open={confirmState} onClose={onClose}>
<DialogTitle>
{formatMessageWithValues('groupChangeDialog.confirmTitle', {
firstName: groupIndividual?.individual?.firstName, lastName: groupIndividual?.individual?.lastName,
})}
</DialogTitle>
<DialogContent>
<GroupPicker
groupIndividual={groupIndividual}
onChange={setGroupToBeChanged}
/>
</DialogContent>
<DialogActions>
<Button
onClick={() => handleConfirm(groupToBeChanged)}
autoFocus
className={classes.primaryButton}
disabled={!groupToBeChanged}
>
{formatMessage('confirm')}
</Button>
<Button onClick={onClose} className={classes.secondaryButton}>
{formatMessage('cancel')}
</Button>
</DialogActions>
</Dialog>
);
}

export default injectIntl(withTheme(withStyles(styles)(GroupChangeDialog)));
46 changes: 45 additions & 1 deletion src/components/GroupIndividualSearcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
Button, Dialog, DialogActions, DialogTitle, IconButton, Tooltip,
} from '@material-ui/core';
import EditIcon from '@material-ui/icons/Edit';
import GroupIcon from '@material-ui/icons/Group';
import DeleteIcon from '@material-ui/icons/Delete';
import {
clearGroupIndividualExport,
Expand All @@ -29,13 +30,14 @@ import {
} from '../actions';
import {
DEFAULT_PAGE_SIZE,
EMPTY_STRING,
EMPTY_STRING, GROUP_INDIVIDUAL_ROLES,
RIGHT_GROUP_INDIVIDUAL_DELETE,
RIGHT_GROUP_INDIVIDUAL_UPDATE,
ROWS_PER_PAGE_OPTIONS,
} from '../constants';
import GroupIndividualFilter from './GroupIndividualFilter';
import GroupIndividualRolePicker from '../pickers/GroupIndividualRolePicker';
import GroupChangeDialog from './GroupChangeDialog';

function GroupIndividualSearcher({
intl,
Expand Down Expand Up @@ -68,6 +70,8 @@ function GroupIndividualSearcher({
const prevSubmittingMutationRef = useRef();
const [updatedGroupIndividuals, setUpdatedGroupIndividuals] = useState([]);
const [refetch, setRefetch] = useState(null);
const [isChangeGroupModalOpen, setIsChangeGroupModalOpen] = useState(false);
const [groupIndividualToGroupChange, setGroupIndividualToGroupChange] = useState(null);

function groupIndividualUpdatePageUrl(groupIndividual) {
return `${modulesManager.getRef('individual.route.individual')}/${groupIndividual.individual?.id}`;
Expand Down Expand Up @@ -124,6 +128,7 @@ function GroupIndividualSearcher({
'individual.lastName',
'individual.dob',
'groupIndividual.individual.role',
'emptyLabel',
];
if (rights.includes(RIGHT_GROUP_INDIVIDUAL_UPDATE)) {
headers.push('emptyLabel');
Expand Down Expand Up @@ -161,13 +166,34 @@ function GroupIndividualSearcher({
}
};

const handleGroupChange = (groupIndividual) => {
setIsChangeGroupModalOpen(true);
setGroupIndividualToGroupChange(groupIndividual);
};

const isRowUpdated = (groupIndividual) => (
updatedGroupIndividuals.some((item) => item.id === groupIndividual.id));

const isRowDeleted = (groupIndividual) => deletedGroupIndividualUuids.includes(groupIndividual.id);

const isRowDisabled = (_, groupIndividual) => isRowDeleted(groupIndividual) || isRowUpdated(groupIndividual);

const onChangeGroupConfirm = (groupToBeChanged) => {
const updateIndividual = {
...groupIndividualToGroupChange,
group: groupToBeChanged,
role: GROUP_INDIVIDUAL_ROLES.RECIPIENT,
};
updateGroupIndividual(
updateIndividual,
formatMessageWithValues(intl, 'individual', 'individual.groupChange.confirm.message', {
individualId: updateIndividual?.individual?.id,
groupId: groupToBeChanged?.id,
}),
);
setRefetch(groupToBeChanged?.id);
};

const itemFormatters = () => {
const formatters = [
(groupIndividual) => groupIndividual.individual.firstName,
Expand All @@ -185,6 +211,18 @@ function GroupIndividualSearcher({
onChange={(role) => handleRoleOnChange(groupIndividual, role)}
/>
) : groupIndividual.role),
(groupIndividual) => (rights.includes(RIGHT_GROUP_INDIVIDUAL_UPDATE) ? (
(
<Tooltip title={formatMessage(intl, 'individual', 'changeGroupButtonTooltip')}>
<IconButton
onClick={() => handleGroupChange(groupIndividual)}
disabled={isRowDeleted(groupIndividual)}
>
<GroupIcon />
</IconButton>
</Tooltip>
)
) : null),
];
if (rights.includes(RIGHT_GROUP_INDIVIDUAL_UPDATE)) {
formatters.push((groupIndividual) => (
Expand Down Expand Up @@ -266,6 +304,12 @@ function GroupIndividualSearcher({

return (
<div>
<GroupChangeDialog
confirmState={isChangeGroupModalOpen}
onClose={() => setIsChangeGroupModalOpen(false)}
onConfirm={onChangeGroupConfirm}
groupIndividual={groupIndividualToGroupChange}
/>
<Searcher
key={refetch}
module="individual"
Expand Down
60 changes: 60 additions & 0 deletions src/pickers/GroupPicker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React, { useEffect, useState } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import {
useModulesManager, useTranslations, Autocomplete,
} from '@openimis/fe-core';
import { fetchGroups } from '../actions';

function GroupPicker(props) {
const {
withLabel = true,
withPlaceholder,
label,
groupIndividual,
onChange,
} = props;

const modulesManager = useModulesManager();
const dispatch = useDispatch();
const { formatMessage } = useTranslations('individual', modulesManager);
const fetchingGroups = useSelector((state) => state.individual.fetchingGroups);
const fetchedGroups = useSelector((state) => state.individual.fetchedGroups);
const errorGroups = useSelector((state) => state.individual.errorGroups);
const groups = useSelector((state) => state.individual.groups);
const [group, setGroup] = useState(null);

useEffect(() => {
if (!fetchingGroups && !fetchedGroups) {
dispatch(fetchGroups({}));
}
}, []);

const groupLabel = (option) => option.id;

const getGroupsWithoutCurrentGroup = (options) => options.filter(
(option) => option?.id !== groupIndividual?.group?.id,
);

const handleChange = (group) => {
onChange(group);
setGroup(group);
};

return (
<Autocomplete
label={label ?? formatMessage('groupPicker.label')}
error={errorGroups}
withLabel={withLabel}
withPlaceholder={withPlaceholder}
options={getGroupsWithoutCurrentGroup(groups)}
isLoading={fetchingGroups}
isFetched={fetchedGroups}
value={group}
getOptionLabel={groupLabel}
onChange={handleChange}
onInputChange={() => null}
/>
);
}

export default GroupPicker;
18 changes: 16 additions & 2 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@
},
"any": "ANY",
"ok": "ok",
"individualChangelog.label": "Change Log"
"individualChangelog.label": "Change Log",
"groupChange": {
"confirm": {
"message": "Individual {individualId} moved to Group {groupId}"
}
}
},
"individualHistory": {
"pageTitle": "Individual {firstName} {lastName}",
Expand Down Expand Up @@ -130,5 +135,14 @@
"groupIndividualRolePicker.RECIPIENT": "RECIPIENT",
"groupIndividualRolePicker": "Role"
},
"groupChangelog.label": "Change Log"
"groupChangelog.label": "Change Log",
"groupPicker": {
"label": "Select a group."
},
"groupChangeDialog": {
"confirmTitle": "Move {firstName} {lastName} to a different group."
},
"confirm": "Confirm",
"cancel": "Cancel",
"changeGroupButtonTooltip": "Move to another group."
}

0 comments on commit 1ac979e

Please sign in to comment.