Skip to content

Commit

Permalink
CM-406: add change log fe for group (#33)
Browse files Browse the repository at this point in the history
Co-authored-by: Jan <[email protected]>
  • Loading branch information
jdolkowski and Jan authored Dec 29, 2023
1 parent 71af2b0 commit a89928a
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const GROUP_FULL_PROJECTION = [
'dateCreated',
'dateUpdated',
'jsonExt',
'version',
];

export function fetchIndividuals(params) {
Expand Down Expand Up @@ -66,6 +67,11 @@ export function fetchGroup(params) {
return graphql(payload, ACTION_TYPE.GET_GROUP);
}

export function fetchGroupHistory(params) {
const payload = formatPageQueryWithCount('groupHistory', params, GROUP_FULL_PROJECTION);
return graphql(payload, ACTION_TYPE.SEARCH_GROUP_HISTORY);
}

export function deleteIndividual(individual, clientMutationLabel) {
const individualUuids = `ids: ["${individual?.id}"]`;
const mutation = formatMutation('deleteIndividual', individualUuids, clientMutationLabel);
Expand Down
38 changes: 38 additions & 0 deletions src/components/GroupChangelogTab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import React from 'react';
import { Tab } from '@material-ui/core';
import { formatMessage, PublishedComponent } from '@openimis/fe-core';
import { GROUP_CHANGELOG_TAB_VALUE } from '../constants';

function GroupChangelogTabLabel({
intl, onChange, tabStyle, isSelected,
}) {
return (
<Tab
onChange={onChange}
className={tabStyle(GROUP_CHANGELOG_TAB_VALUE)}
selected={isSelected(GROUP_CHANGELOG_TAB_VALUE)}
value={GROUP_CHANGELOG_TAB_VALUE}
label={formatMessage(intl, 'individual', 'groupChangelog.label')}
/>
);
}

function GroupChangelogTabPanel({
value, group,
}) {
return (
<PublishedComponent
pubRef="policyHolder.TabPanel"
module="individual"
index={GROUP_CHANGELOG_TAB_VALUE}
value={value}
>
<PublishedComponent
pubRef="individual.GroupHistorySearcher"
groupId={group?.id}
/>
</PublishedComponent>
);
}

export { GroupChangelogTabLabel, GroupChangelogTabPanel };
58 changes: 58 additions & 0 deletions src/components/GroupHistoryFilter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { injectIntl } from 'react-intl';
import { TextInput } from '@openimis/fe-core';
import { Grid } from '@material-ui/core';
import { withTheme, withStyles } from '@material-ui/core/styles';
import _debounce from 'lodash/debounce';
import { CONTAINS_LOOKUP, DEFAULT_DEBOUNCE_TIME, EMPTY_STRING } from '../constants';
import { defaultFilterStyles } from '../util/styles';

function GroupHistoryFilter({
classes, filters, onChangeFilters,
}) {
const debouncedOnChangeFilters = _debounce(onChangeFilters, DEFAULT_DEBOUNCE_TIME);
const filterTextFieldValue = (filterName) => filters?.[filterName]?.value ?? EMPTY_STRING;

const onChangeStringFilter = (filterName, lookup = null) => (value) => {
if (lookup) {
debouncedOnChangeFilters([
{
id: filterName,
value,
filter: `${filterName}_${lookup}: "${value}"`,
},
]);
} else {
onChangeFilters([
{
id: filterName,
value,
filter: `${filterName}: "${value}"`,
},
]);
}
};

return (
<Grid container className={classes.form}>
<Grid item xs={2} className={classes.item}>
<TextInput
module="individual"
label="groupHistory.id"
value={filterTextFieldValue('firstName')}
onChange={onChangeStringFilter('firstName', CONTAINS_LOOKUP)}
/>
</Grid>
<Grid item xs={2} className={classes.item}>
<TextInput
module="individual"
label="groupHistory.head"
value={filterTextFieldValue('head')}
onChange={onChangeStringFilter('head', CONTAINS_LOOKUP)}
/>
</Grid>
</Grid>
);
}

export default injectIntl(withTheme(withStyles(defaultFilterStyles)(GroupHistoryFilter)));
113 changes: 113 additions & 0 deletions src/components/GroupHistorySearcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { injectIntl } from 'react-intl';
import {
useModulesManager,
useTranslations,
Searcher,
withHistory,
withModulesManager,
} from '@openimis/fe-core';
import { DEFAULT_PAGE_SIZE, EMPTY_STRING, ROWS_PER_PAGE_OPTIONS } from '../constants';
import GroupHistoryFilter from './GroupHistoryFilter';
import { fetchGroupHistory } from '../actions';

function GroupHistorySearcher({
groupId,
}) {
const modulesManager = useModulesManager();
const dispatch = useDispatch();
const { formatDateFromISO, formatMessageWithValues } = useTranslations('individual', modulesManager);

const fetchingGroupHistory = useSelector((state) => state.individual.fetchingGroupHistory);
const fetchedGroupHistory = useSelector((state) => state.individual.fetchedGroupHistory);
const errorGroupHistory = useSelector((state) => state.individual.errorGroupHistory);
const groupHistory = useSelector((state) => state.individual.groupHistory);
const groupHistoryPageInfo = useSelector((state) => state.individual.groupHistoryPageInfo);
const groupHistoryTotalCount = useSelector((state) => state.individual.groupHistoryTotalCount);
const fetch = (params) => dispatch(fetchGroupHistory(params));

const headers = () => [
'groupHistory.id',
'groupHistory.head',
'groupHistory.dateUpdated',
'groupHistory.version',
'groupHistory.jsonExt',
];

const itemFormatters = () => [
(groupHistory) => groupHistory.id,
(groupHistory) => groupHistory.head,
(groupHistory) => (groupHistory.dateUpdated
? formatDateFromISO(groupHistory.dateUpdated) : EMPTY_STRING
),
(groupHistory) => groupHistory.version,
(groupHistory) => groupHistory.jsonExt,
];

const rowIdentifier = (groupHistory) => groupHistory.id;

const sorts = () => [
['id', false],
['head', true],
['dateUpdated', true],
['version', true],
];

const defaultFilters = () => {
const filters = {
isDeleted: {
value: false,
filter: 'isDeleted: false',
},
};
if (groupId !== null && groupId !== undefined) {
filters.groupId = {
value: groupId,
filter: `id: "${groupId}"`,
};
}
return filters;
};

const groupHistoryFilter = (props) => (
<GroupHistoryFilter
intl={props.intl}
classes={props.classes}
filters={props.filters}
onChangeFilters={props.onChangeFilters}
/>
);

return (
<div>
<Searcher
module="individual"
FilterPane={groupHistoryFilter}
fetch={fetch}
items={groupHistory}
itemsPageInfo={groupHistoryPageInfo}
fetchingItems={fetchingGroupHistory}
fetchedItems={fetchedGroupHistory}
errorItems={errorGroupHistory}
tableTitle={formatMessageWithValues('groupHistoryList.searcherResultsTitle', {
groupHistoryTotalCount,
})}
headers={headers}
itemFormatters={itemFormatters}
sorts={sorts}
rowsPerPageOptions={ROWS_PER_PAGE_OPTIONS}
defaultPageSize={DEFAULT_PAGE_SIZE}
defaultOrderBy="id"
rowIdentifier={rowIdentifier}
defaultFilters={defaultFilters()}
cacheFiltersKey="groupHistoryFilterCache"
resetFiltersOnUnmount
/>
</div>
);
}

export default withHistory(
withModulesManager(injectIntl((GroupHistorySearcher))),
);
1 change: 1 addition & 0 deletions src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export const RIGHT_GROUP_DELETE = 180004;

export const BENEFIT_PLANS_LIST_TAB_VALUE = 'BenefitPlansListTab';
export const INDIVIDUALS_LIST_TAB_VALUE = 'IndividualsListTab';
export const GROUP_CHANGELOG_TAB_VALUE = 'GroupChangelogTab';
export const INDIVIDUAL_TABS_LABEL_CONTRIBUTION_KEY = 'individual.TabPanel.label';
export const INDIVIDUAL_TABS_PANEL_CONTRIBUTION_KEY = 'individual.TabPanel.panel';

Expand Down
5 changes: 5 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
IndividualUpdateTaskItemFormatters,
IndividualUpdateTaskTableHeaders,
} from './components/tasks/IndividualUpdateTasks';
import GroupHistorySearcher from './components/GroupHistorySearcher';
import { GroupChangelogTabLabel, GroupChangelogTabPanel } from './components/GroupChangelogTab';

const ROUTE_INDIVIDUALS = 'individuals';
const ROUTE_INDIVIDUAL = 'individuals/individual';
Expand Down Expand Up @@ -48,14 +50,17 @@ const DEFAULT_CONFIG = {
{ key: 'individual.actions.fetchIndividuals', ref: fetchIndividuals },
{ key: 'individual.actions.downloadIndividuals', ref: downloadIndividuals },
{ key: 'individual.actions.clearIndividualExport', ref: clearIndividualExport },
{ key: 'individual.GroupHistorySearcher', ref: GroupHistorySearcher },
],
'individual.TabPanel.label': [
IndividualsListTabLabel,
BenefitPlansListTabLabel,
GroupChangelogTabLabel,
],
'individual.TabPanel.panel': [
IndividualsListTabPanel,
BenefitPlansListTabPanel,
GroupChangelogTabPanel,
],
'individual.BenefitPlansListTabLabel': [BENEFIT_PLAN_TABS_LABEL_REF_KEY],
'individual.BenefitPlansListTabPanel': [BENEFIT_PLAN_TABS_PANEL_REF_KEY],
Expand Down
37 changes: 37 additions & 0 deletions src/reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export const ACTION_TYPE = {
GROUP_EXPORT: 'GROUP_EXPORT',
INDIVIDUAL_EXPORT: 'INDIVIDUAL_EXPORT',
GROUP_INDIVIDUAL_EXPORT: 'GROUP_INDIVIDUAL_EXPORT',
SEARCH_GROUP_HISTORY: 'SEARCH_GROUP_HISTORY',
};

function reducer(
Expand Down Expand Up @@ -78,6 +79,12 @@ function reducer(
groupIndividualsExport: null,
groupIndividualsExportPageInfo: {},
errorGroupIndividualsExport: null,
fetchingGroupHistory: false,
errorGroupHistory: null,
fetchedGroupHistory: false,
groupHistory: [],
groupHistoryPageInfo: {},
groupHistoryTotalCount: 0,
},
action,
) {
Expand Down Expand Up @@ -128,6 +135,16 @@ function reducer(
group: null,
errorGroup: null,
};
case REQUEST(ACTION_TYPE.SEARCH_GROUP_HISTORY):
return {
...state,
fetchingGroupHistory: true,
fetchedGroupHistory: false,
groupHistory: [],
groupHistoryPageInfo: {},
groupHistoryTotalCount: 0,
errorGroupHistory: null,
};
case SUCCESS(ACTION_TYPE.SEARCH_INDIVIDUALS):
return {
...state,
Expand Down Expand Up @@ -184,6 +201,20 @@ function reducer(
groupsTotalCount: action.payload.data.group ? action.payload.data.group.totalCount : null,
errorGroups: formatGraphQLError(action.payload),
};
case SUCCESS(ACTION_TYPE.SEARCH_GROUP_HISTORY):
return {
...state,
fetchingGroupHistory: false,
fetchedGroupHistory: true,
groupHistory: parseData(action.payload.data.groupHistory)?.map((groupHistory) => ({
...groupHistory,
id: decodeId(groupHistory.id),
})),
groupHistoryPageInfo: pageInfo(action.payload.data.groupHistory),
groupHistoryTotalCount: action.payload.data.groupHistory
? action.payload.data.groupHistory.totalCount : null,
errorGroupHistory: formatGraphQLError(action.payload),
};
case SUCCESS(ACTION_TYPE.GET_INDIVIDUAL):
return {
...state,
Expand Down Expand Up @@ -224,6 +255,12 @@ function reducer(
fetchingGroups: false,
errorGroups: formatServerError(action.payload),
};
case ERROR(ACTION_TYPE.SEARCH_GROUP_HISTORY):
return {
...state,
fetchingGroupHistory: false,
errorGroupHistory: formatServerError(action.payload),
};
case ERROR(ACTION_TYPE.GET_INDIVIDUAL):
return {
...state,
Expand Down
18 changes: 17 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@
"mutationLabel": "Delete Group {id}"
}
},
"groupHistory": {
"pageTitle": "Group {id}",
"headPanelTitle": "General Information",
"id": "ID",
"head": "head",
"dateUpdated": "Date Updated",
"version": "Version",
"any": "ANY",
"ok": "ok",
"jsonExt": "Additional fields"
},
"groupHistoryList": {
"pageTitle": "Groups History",
"searcherResultsTitle": "{groupHistoryTotalCount} Historical Records Found"
},
"export": {
"label": "DOWNLOAD",
"dateCreated": "Date Created",
Expand All @@ -93,5 +108,6 @@
"groupIndividualRolePicker.HEAD": "HEAD",
"groupIndividualRolePicker.RECIPIENT": "RECIPIENT",
"groupIndividualRolePicker": "Role"
}
},
"groupChangelog.label": "Change Log"
}

0 comments on commit a89928a

Please sign in to comment.