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

CM-421: added possibility to add new group, fixing move to other group picker #83

Merged
merged 1 commit into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import { ACTION_TYPE } from './reducer';
import {
CLEAR, ERROR, REQUEST, SET, SUCCESS,
} from './util/action-type';
import {ACCEPT, APPROVED, FAILED, REJECT} from "./constants";
import {
ACCEPT, APPROVED, FAILED, REJECT,
} from './constants';

const WORKFLOWS_FULL_PROJECTION = () => [
'name',
Expand Down Expand Up @@ -245,6 +247,13 @@ function formatGroupGQL(group, groupIndividualId = null) {
${groupIndividualId ? `groupIndividualId: "${groupIndividualId}"` : ''}`;
}

function formatCreateGroupGQL(group) {
return `
${group?.code ? `code: "${group.code}"` : ''}
${'individualsData: []'}
`;
}

function formatIndividualGQL(individual) {
return `
${individual?.id ? `id: "${individual.id}"` : ''}
Expand Down Expand Up @@ -370,6 +379,21 @@ export function updateGroup(group, clientMutationLabel) {
);
}

export function createGroup(group, clientMutationLabel) {
const mutation = formatMutation('createGroup', formatCreateGroupGQL(group), clientMutationLabel);
const requestedDateTime = new Date();
return graphql(
mutation.payload,
[REQUEST(ACTION_TYPE.MUTATION), SUCCESS(ACTION_TYPE.CREATE_GROUP), ERROR(ACTION_TYPE.MUTATION)],
{
actionType: ACTION_TYPE.CREATE_GROUP,
clientMutationId: mutation.clientMutationId,
clientMutationLabel,
requestedDateTime,
},
);
}

export function fetchPendingGroupUploads(variables) {
return graphqlWithVariables(
`
Expand Down
4 changes: 2 additions & 2 deletions src/components/GroupHeadPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const styles = (theme) => ({
class GroupHeadPanel extends FormPanel {
render() {
const {
edited, classes, mandatoryFieldsEmpty,
edited, classes, mandatoryFieldsEmpty, readOnly,
} = this.props;
const group = { ...edited };
return (
Expand Down Expand Up @@ -55,7 +55,7 @@ class GroupHeadPanel extends FormPanel {
<Grid container className={classes.item}>
<Grid item xs={3} className={classes.item}>
<TextInput
readOnly
readOnly={readOnly}
module="individual"
label="group.code"
onChange={(v) => this.updateAttribute('code', v)}
Expand Down
2 changes: 2 additions & 0 deletions src/components/GroupTabPanel.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ function GroupTabPanel({
groupIndividualIds,
groupId,
}) {
if (!groupId) return null;

const [activeTab, setActiveTab] = useState(individual ? BENEFIT_PLANS_LIST_TAB_VALUE : INDIVIDUALS_LIST_TAB_VALUE);

const isSelected = (tab) => tab === activeTab;
Expand Down
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const BENEFIT_PLAN_TABS_LABEL_CONTRIBUTION_KEY = 'individual.BenefitPlans
export const BENEFIT_PLAN_TABS_PANEL_CONTRIBUTION_KEY = 'individual.BenefitPlansListTabPanel';
export const TASK_CONTRIBUTION_KEY = 'tasksManagement.tasks';
export const BENEFITS_CONTRIBUTION_KEY = 'payroll.benefitConsumptionPayrollSearcher';
export const GROUP_ROUTE_GROUP = 'individual.route.group';

export const BENEFICIARY_STATUS = {
POTENTIAL: 'POTENTIAL',
Expand Down
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ import IndividualPicker from './pickers/IndividualPicker';
import {
GroupUploadConfirmationPanel,
GroupUploadResolutionItemFormatters,
GroupUploadResolutionTaskTableHeaders
} from "./components/tasks/GroupImportTasks";
GroupUploadResolutionTaskTableHeaders,
} from './components/tasks/GroupImportTasks';
import EnrollmentGroupPage from './pages/EnrollmentGroupPage';
import GroupMenu from './components/dialogs/GroupMenu';

Expand Down
43 changes: 28 additions & 15 deletions src/pages/GroupPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import DeleteIcon from '@material-ui/icons/Delete';
import { RIGHT_GROUP_CREATE, RIGHT_GROUP_SEARCH } from '../constants';
import {
fetchGroup, deleteGroup, updateGroup, clearGroup, createGroupAndMoveIndividual,
createGroup,
} from '../actions';
import GroupHeadPanel from '../components/GroupHeadPanel';
import { ACTION_TYPE } from '../reducer';
Expand All @@ -37,6 +38,7 @@ function GroupPage({
group,
fetchGroup,
deleteGroup,
createGroup,
updateGroup,
coreConfirm,
clearConfirm,
Expand Down Expand Up @@ -108,18 +110,25 @@ function GroupPage({

const handleSave = () => {
setReadOnly(true);
if (editedGroup?.id) {
updateGroup(
editedGroup,
formatMessageWithValues(intl, 'individual', 'group.update.mutationLabel', {
id: group?.id,
}),
);
} else if (editedGroupIndividual?.id) {
createGroupAndMoveIndividual(
if (groupUuid) {
if (editedGroup?.id) {
updateGroup(
editedGroup,
formatMessageWithValues(intl, 'individual', 'group.update.mutationLabel', {
id: group?.id,
}),
);
} else if (editedGroupIndividual?.id) {
createGroupAndMoveIndividual(
editedGroup,
editedGroupIndividual.id,
formatMessageWithValues(intl, 'individual', 'group.createGroupAndMoveIndividual.mutationLabel'),
);
}
} else {
createGroup(
editedGroup,
editedGroupIndividual.id,
formatMessageWithValues(intl, 'individual', 'group.createGroupAndMoveIndividual.mutationLabel'),
formatMessageWithValues(intl, 'socialProtection', 'group.create.mutationLabel', titleParams(editedGroup)),
);
}
};
Expand All @@ -141,7 +150,10 @@ function GroupPage({
);
};

const canAdd = () => rights.includes(RIGHT_GROUP_CREATE) && editedGroupIndividual && !readOnly;
const canAdd = () => {
if (groupUuid) return rights.includes(RIGHT_GROUP_CREATE) && editedGroupIndividual && !readOnly;
return rights.includes(RIGHT_GROUP_CREATE) && !!editedGroup?.code;
};

const actions = [
!!group && {
Expand All @@ -165,8 +177,8 @@ function GroupPage({
onEditedChanged={setEditedGroup}
back={back}
mandatoryFieldsEmpty={isMandatoryFieldsEmpty}
canSave={canSave}
save={groupUuid ? handleSave : null}
canSave={groupUuid ? canSave : canAdd}
save={handleSave}
HeadPanel={GroupHeadPanel}
Panels={[GroupTabPanel]}
rights={rights}
Expand All @@ -176,7 +188,7 @@ function GroupPage({
add={canAdd() ? handleSave : null}
setEditedGroupIndividual={setEditedGroupIndividual}
editedGroupIndividual={editedGroupIndividual}
readOnly={readOnly}
readOnly={!!groupUuid}
groupIndividualIds={groupIndividualIds}
groupId={groupUuid}
/>
Expand All @@ -201,6 +213,7 @@ const mapStateToProps = (state, props) => ({
const mapDispatchToProps = (dispatch) => bindActionCreators({
fetchGroup,
deleteGroup,
createGroup,
updateGroup,
clearGroup,
createGroupAndMoveIndividual,
Expand Down
27 changes: 24 additions & 3 deletions src/pages/GroupsPage.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import React from 'react';
import { Helmet, withModulesManager, formatMessage } from '@openimis/fe-core';
import {
Helmet, withModulesManager, withTooltip, formatMessage, historyPush,
} from '@openimis/fe-core';
import { injectIntl } from 'react-intl';
import { withTheme, withStyles } from '@material-ui/core/styles';
import { connect } from 'react-redux';
import { RIGHT_GROUP_SEARCH } from '../constants';
import { Fab } from '@material-ui/core';
import AddIcon from '@material-ui/icons/Add';
import { GROUP_ROUTE_GROUP, RIGHT_GROUP_CREATE, RIGHT_GROUP_SEARCH } from '../constants';
import GroupSearcher from '../components/GroupSearcher';

const styles = (theme) => ({
Expand All @@ -12,13 +16,30 @@ const styles = (theme) => ({
});

function GroupsPage(props) {
const { intl, classes, rights } = props;
const {
intl, classes, modulesManager, history, rights,
} = props;

const onAdd = () => historyPush(
modulesManager,
history,
GROUP_ROUTE_GROUP,
);

return (
rights.includes(RIGHT_GROUP_SEARCH) && (
<div className={classes.page}>
<Helmet title={formatMessage(intl, 'individual', 'groups.pageTitle')} />
<GroupSearcher rights={rights} isModalEnrollment={false} />
{rights.includes(RIGHT_GROUP_CREATE)
&& withTooltip(
<div className={classes.fab}>
<Fab color="primary" onClick={onAdd}>
<AddIcon />
</Fab>
</div>,
formatMessage(intl, 'individual', 'createButton.tooltip'),
)}
</div>
)
);
Expand Down
1 change: 0 additions & 1 deletion src/pickers/GroupIndividualRecipientTypePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ function GroupIndividualRecipientTypePicker(props) {
const {
required, readOnly, onChange, value, nullLabel, withLabel,
} = props;
console.log(value)
return (
<ConstantBasedPicker
module="individual"
Expand Down
20 changes: 13 additions & 7 deletions src/pickers/GroupPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ function GroupPicker(props) {
const errorGroups = useSelector((state) => state.individual.errorGroups);
const groups = useSelector((state) => state.individual.groups);
const [group, setGroup] = useState(null);
// eslint-disable-next-line no-unused-vars
const [currentString, setCurrentString] = useState('');
const [filters, setFilters] = useState(['isDeleted: false']);

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

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

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

const handleChange = (group) => {
Expand All @@ -48,11 +49,16 @@ function GroupPicker(props) {
withPlaceholder={withPlaceholder}
options={getGroupsWithoutCurrentGroup(groups)}
isLoading={fetchingGroups}
setCurrentString={setCurrentString}
isFetched={fetchedGroups}
value={group}
getOptionLabel={groupLabel}
onChange={handleChange}
onInputChange={() => null}
onInputChange={
(search) => {
if (search !== undefined) setFilters([`code_Icontains: "${search}"`, 'isDeleted: false']);
}
}
/>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/pickers/IndividualPicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TextField, Tooltip } from '@material-ui/core';
import {
Autocomplete, useModulesManager,
useTranslations, useGraphqlQuery,
decodeId
decodeId,
} from '@openimis/fe-core';
import { INDIVIDUALS_QUANTITY_LIMIT } from '../constants';

Expand Down
3 changes: 3 additions & 0 deletions src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const ACTION_TYPE = {
UPDATE_INDIVIDUAL: 'INDIVIDUAL_UPDATE_INDIVIDUAL',
UPDATE_GROUP_INDIVIDUAL: 'GROUP_INDIVIDUAL_UPDATE_GROUP_INDIVIDUAL',
UPDATE_GROUP: 'GROUP_UPDATE_GROUP',
CREATE_GROUP: 'CREATE_GROUP',
CREATE_GROUP_AND_MOVE_INDIVIDUAL: 'CREATE_GROUP_AND_MOVE_INDIVIDUAL',
GROUP_EXPORT: 'GROUP_EXPORT',
INDIVIDUAL_EXPORT: 'INDIVIDUAL_EXPORT',
Expand Down Expand Up @@ -654,6 +655,8 @@ function reducer(
return dispatchMutationResp(state, 'deleteGroup', action);
case SUCCESS(ACTION_TYPE.UPDATE_GROUP):
return dispatchMutationResp(state, 'updateGroup', action);
case SUCCESS(ACTION_TYPE.CREATE_GROUP):
return dispatchMutationResp(state, 'createGroup', action);
case SUCCESS(ACTION_TYPE.CREATE_GROUP_AND_MOVE_INDIVIDUAL):
return dispatchMutationResp(state, 'createGroupAndMoveIndividual', action);
case SUCCESS(ACTION_TYPE.RESOLVE_TASK):
Expand Down
3 changes: 3 additions & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@
"id": "ID",
"head": "Head",
"code": "Code",
"create": {
"mutationLabel": "Created Group {id}"
},
"noHeadSpecified": "head not specified",
"individual.firstName": "Individual First Name",
"individual.lastName": "Individual Last Name",
Expand Down
Loading