{mode === dataEntryKeys.VIEW
? i18n.t('Enrollment{{escape}} View Event', { escape: ':' })
@@ -115,68 +233,45 @@ const EnrollmentEditEventPagePain = ({
- {pageStatus === pageStatuses.DEFAULT && programStage && (
-
- )}
- {pageStatus === pageStatuses.MISSING_DATA && (
- {i18n.t('The enrollment event data could not be found')}
- )}
- {pageStatus === pageStatuses.WITHOUT_ORG_UNIT_SELECTED && (
-
- {i18n.t('Choose a registering unit to start reporting')}
-
- )}
+
-
-
-
- {!hideWidgets.feedback && (
-
- )}
- {!hideWidgets.indicator && (
-
- )}
- {addRelationShipContainerElement &&
- {}}
- onLinkedRecordClick={onLinkedRecordClick}
- />
- }
-
-
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.js
index 82ee3b9360..7c3de5ae8b 100644
--- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.js
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.container.js
@@ -17,13 +17,16 @@ import { changeEventFromUrl } from '../ViewEvent/ViewEventComponent/viewEvent.ac
import { buildEnrollmentsAsOptions } from '../../ScopeSelector';
import { convertDateWithTimeForView, convertValue } from '../../../converters/clientToView';
import { dataElementTypes } from '../../../metaData/DataElement';
-import { useEvent } from './hooks';
+import { useEvent, useAssignee, useAssignedUserSaveContext } from './hooks';
import type { Props } from './EnrollmentEditEventPage.types';
import { LoadingMaskForPage } from '../../LoadingMasks';
import { cleanUpDataEntry } from '../../DataEntry';
import { useLinkedRecordClick } from '../common/TEIRelationshipsWidget';
import { pageKeys } from '../../App/withAppUrlSync';
import { withErrorMessageHandler } from '../../../HOC';
+import { getProgramEventAccess } from '../../../metaData';
+import { setAssignee, rollbackAssignee } from './EnrollmentEditEventPage.actions';
+import { convertClientToServer } from '../../../converters';
const getEventDate = (event) => {
const eventDataConvertValue = convertDateWithTimeForView(event?.occurredAt || event?.scheduledAt);
@@ -55,6 +58,8 @@ export const EnrollmentEditEventPage = () => {
const { loading, event } = useEvent(eventId);
const { program: programId, programStage: stageId, trackedEntity: teiId, enrollment: enrollmentId } = event;
const { orgUnitId, eventId: urlEventId, initMode } = useLocationQuery();
+ const enrollmentSite = useCommonEnrollmentDomainData(teiId, enrollmentId, programId).enrollment;
+ const storedEvent = enrollmentSite?.events?.find(item => item.event === eventId);
useEffect(() => {
if (!urlEventId) {
@@ -65,16 +70,17 @@ export const EnrollmentEditEventPage = () => {
}
}, [dispatch, history, eventId, urlEventId, orgUnitId]);
- return (!loading && eventId === urlEventId) || error ? (
+ return ((!loading && eventId === urlEventId) || error) && storedEvent ? (
) :
;
};
@@ -85,11 +91,13 @@ const EnrollmentEditEventPageWithContextPlain = ({
teiId,
enrollmentId,
orgUnitId,
- eventId,
initMode,
+ enrollmentSite,
+ event,
}: Props) => {
const history = useHistory();
const dispatch = useDispatch();
+ const { event: eventId } = event;
const { onLinkedRecordClick } = useLinkedRecordClick();
@@ -119,7 +127,6 @@ const EnrollmentEditEventPageWithContextPlain = ({
}
}, [initMode, enrollmentId, eventId, orgUnitId, history]);
- const { enrollment: enrollmentSite } = useCommonEnrollmentDomainData(teiId, enrollmentId, programId);
const onGoBack = () =>
history.push(`/enrollment?${buildUrlQueryString({ enrollmentId })}`);
@@ -131,12 +138,12 @@ const EnrollmentEditEventPageWithContextPlain = ({
// $FlowFixMe
const { name: trackedEntityName, id: trackedEntityTypeId } = program?.trackedEntityType;
const enrollmentsAsOptions = buildEnrollmentsAsOptions([enrollmentSite || {}], programId);
- const event = enrollmentSite?.events?.find(item => item.event === eventId);
const eventDate = getEventDate(event);
const scheduleDate = getEventScheduleDate(event);
const { currentPageMode } = useEnrollmentEditEventPageMode(event?.status);
const dataEntryKey = `${dataEntryIds.ENROLLMENT_EVENT}-${currentPageMode}`;
const outputEffects = useWidgetDataFromStore(dataEntryKey);
+ const eventAccess = getProgramEventAccess(programId, programStage?.id);
const pageStatus = getPageStatus({
@@ -147,6 +154,20 @@ const EnrollmentEditEventPageWithContextPlain = ({
programStage,
event,
});
+ const assignee = useAssignee(event);
+ const getAssignedUserSaveContext = useAssignedUserSaveContext(event);
+ const onSaveAssignee = (newAssignee) => {
+ // $FlowFixMe dataElementTypes flow error
+ const assignedUser: ApiAssignedUser = convertClientToServer(newAssignee, dataElementTypes.ASSIGNEE);
+ dispatch(setAssignee(assignedUser, newAssignee, eventId));
+ };
+ const onSaveAssigneeError = (prevAssignee) => {
+ const assignedUser: ApiAssignedUser | typeof undefined = prevAssignee
+ // $FlowFixMe dataElementTypes flow error
+ ? convertClientToServer(prevAssignee, dataElementTypes.ASSIGNEE)
+ : undefined;
+ dispatch(rollbackAssignee(assignedUser, prevAssignee, eventId));
+ };
return (
);
};
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js
index 8f269fed00..ed95cad492 100644
--- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/EnrollmentEditEventPage.types.js
@@ -1,6 +1,7 @@
// @flow
import type { ProgramStage } from '../../../metaData';
import type { WidgetEffects, HideWidgets } from '../common/EnrollmentOverviewDomain';
+import type { UserFormField } from '../../FormFields/UserField';
import type { LinkedRecordClick } from '../../WidgetsRelationship/WidgetTrackedEntityRelationship';
export type PlainProps = {|
@@ -28,6 +29,14 @@ export type PlainProps = {|
onHandleScheduleSave: (eventData: Object) => void,
pageStatus: string,
eventStatus?: string,
+ eventAccess: {|
+ read: boolean,
+ write: boolean,
+ |} | null,
+ getAssignedUserSaveContext: () => { event: ApiEnrollmentEvent },
+ assignee: UserFormField | null,
+ onSaveAssignee: (newAssignee: UserFormField) => void,
+ onSaveAssigneeError: (prevAssignee: UserFormField | null) => void,
...CssClasses,
|};
@@ -37,6 +46,7 @@ export type Props = {|
teiId: string,
enrollmentId: string,
orgUnitId: string,
- eventId: string,
+ event: ApiEnrollmentEvent,
+ enrollmentSite: ApiEnrollment,
initMode?: string,
|};
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/index.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/index.js
index 6ed8386853..c3906733fb 100644
--- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/index.js
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/index.js
@@ -1,2 +1,3 @@
// @flow
export { useEvent } from './useEvent';
+export { useAssignee, useAssignedUserSaveContext } from './useAssignedUserSaveContext';
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/useAssignedUserSaveContext.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/useAssignedUserSaveContext.js
new file mode 100644
index 0000000000..3819ec28a6
--- /dev/null
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/hooks/useAssignedUserSaveContext.js
@@ -0,0 +1,11 @@
+// @flow
+import { useMemo, useCallback } from 'react';
+import { dataElementTypes } from '../../../../metaData';
+import { convertServerToClient } from '../../../../converters';
+import type { UserFormField } from '../../../FormFields/UserField';
+
+export const useAssignee = (event: ApiEnrollmentEvent): UserFormField | null =>
+ // $FlowFixMe dataElementTypes flow error
+ useMemo(() => convertServerToClient(event?.assignedUser, dataElementTypes.ASSIGNEE), [event?.assignedUser]);
+
+export const useAssignedUserSaveContext = (event: ApiEnrollmentEvent) => useCallback(() => ({ event }), [event]);
diff --git a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/index.js b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/index.js
index 3ce5e6a217..5a8c768ab0 100644
--- a/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/index.js
+++ b/src/core_modules/capture-core/components/Pages/EnrollmentEditEvent/index.js
@@ -1,3 +1,6 @@
// @flow
export { EnrollmentEditEventPage } from './EnrollmentEditEventPage.container';
export { updateEventSucceededEpic, updateEventFailedEpic } from './EnrollmentEditEventPage.epics';
+export {
+ actionTypes as enrollmentEditEventActionTypes,
+} from './EnrollmentEditEventPage.actions';
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.component.js
deleted file mode 100644
index dde335035b..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.component.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import i18n from '@dhis2/d2-i18n';
-import { IconUser24 } from '@dhis2/ui';
-import { ViewEventSection } from '../../Section/ViewEventSection.component';
-import { ViewEventSectionHeader } from '../../Section/ViewEventSectionHeader.component';
-import { Contents } from './Contents.component';
-import { withLoadingIndicator } from '../../../../../HOC/withLoadingIndicator';
-import { type ProgramStage } from '../../../../../metaData';
-
-const LoadingContents = withLoadingIndicator(null, props => ({ style: props.loadingIndicatorStyle }))(Contents);
-
-type Props = {
- programStage: ProgramStage,
- classes: Object,
-}
-
-const loadingIndicatorStyle = {
- height: 36,
- width: 36,
-};
-
-export class AssigneeSectionComponent extends React.Component
{
- renderHeader = () => (
-
- )
-
- render() {
- const { programStage, ...passOnProps } = this.props;
-
- if (!programStage.enableUserAssignment) {
- return null;
- }
-
- return (
-
- {/* $FlowFixMe[cannot-spread-inexact] automated comment */}
-
-
- );
- }
-}
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.container.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.container.js
index b22b90aa22..4698089e83 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.container.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/AssigneeSection.container.js
@@ -1,25 +1,35 @@
// @flow
-import { connect } from 'react-redux';
-import { AssigneeSectionComponent } from './AssigneeSection.component';
-import { setAssignee } from './assigneeSection.actions';
+import React from 'react';
+import { WidgetAssignee } from '../../../../WidgetAssignee';
+import type { ProgramStage } from '../../../../../metaData';
+import type { UserFormField } from '../../../../FormFields/UserField';
-const mapStateToProps = (state: ReduxState) => {
- const assigneeSection = state.viewEventPage.assigneeSection || {};
+type Props = {|
+ assignee: UserFormField | null,
+ programStage: ?ProgramStage,
+ eventAccess: {|
+ read: boolean,
+ write: boolean,
+ |} | null,
+ getAssignedUserSaveContext: () => { event: ApiEnrollmentEvent },
+ onSaveAssignee: (newAssignee: UserFormField) => void,
+ onSaveAssigneeError: (prevAssignee: UserFormField | null) => void,
+|};
- return {
- assignee: (!assigneeSection.isLoading) ?
- state.viewEventPage.loadedValues.eventContainer.event.assignee :
- undefined,
- ready: !assigneeSection.isLoading,
- };
-};
-
-const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
- onSet: (user: Object) => {
- dispatch(setAssignee(user));
- },
-});
-
-// $FlowSuppress
-// $FlowFixMe[missing-annot] automated comment
-export const AssigneeSection = connect(mapStateToProps, mapDispatchToProps)(AssigneeSectionComponent);
+export const AssigneeSection = ({
+ assignee,
+ programStage,
+ getAssignedUserSaveContext,
+ eventAccess,
+ onSaveAssignee,
+ onSaveAssigneeError,
+}: Props) => (
+
+);
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/Contents.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/Contents.component.js
deleted file mode 100644
index 5d5daf12aa..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/Contents.component.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// @flow
-import * as React from 'react';
-import { DisplayMode } from './DisplayMode.component';
-import { EditMode } from './EditMode.component';
-
-type Props = {
- onSet: (user: Object) => void,
-};
-
-export const Contents = (props: Props) => {
- const { onSet, ...passOnProps } = props;
- const [editMode, setEditMode] = React.useState(false);
-
- const handleSet = React.useCallback((user) => {
- setEditMode(false);
- onSet(user);
- }, [onSet]);
-
- const handleCancelSearch = React.useCallback(() => {
- setEditMode(false);
- }, []);
-
- if (editMode) {
- return (
-
- );
- }
-
- return (
- // $FlowFixMe[cannot-spread-inexact] automated comment
- { setEditMode(true); }}
- {...passOnProps}
- />
- );
-};
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/DisplayMode.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/DisplayMode.component.js
deleted file mode 100644
index 394275ea37..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/DisplayMode.component.js
+++ /dev/null
@@ -1,90 +0,0 @@
-// @flow
-import * as React from 'react';
-import i18n from '@dhis2/d2-i18n';
-import { withStyles, IconButton } from '@material-ui/core';
-import { IconEdit24, Button } from '@dhis2/ui';
-
-const getStyles = () => ({
- container: {
- display: 'flex',
- alignItems: 'center',
- },
- nameContainer: {
- paddingRight: 5,
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- },
- iconContainer: {
- width: 24,
- },
- editButton: {
- color: 'inherit',
- },
- addIcon: {
- paddingRight: 5,
- },
-});
-
-type User = {
- id: string,
- username: string,
- name: string,
-};
-
-type Props = {
- assignee: ?User,
- onEdit: () => void,
- classes: Object,
- eventAccess: { read: boolean, write: boolean },
-};
-
-const DisplayModePlain = (props: Props) => {
- const { eventAccess, assignee, onEdit, classes } = props;
-
- if (!assignee) {
- if (!eventAccess.write) {
- return (
-
- {i18n.t('No one is assigned to this event')}
-
- );
- }
- return (
-
-
-
- );
- }
-
- return (
-
-
- {i18n.t('Event assigned to {{name}}', { name: assignee.name })}
-
-
- {eventAccess.write ?
- (
-
-
-
- ) : null}
-
-
- );
-};
-
-export const DisplayMode = withStyles(getStyles)(DisplayModePlain);
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/EditMode.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/EditMode.component.js
deleted file mode 100644
index 41de1ddd9a..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/EditMode.component.js
+++ /dev/null
@@ -1,61 +0,0 @@
-// @flow
-import * as React from 'react';
-import i18n from '@dhis2/d2-i18n';
-import { Button } from '@dhis2/ui';
-import { withStyles } from '@material-ui/core/styles';
-import { UserSearch } from '../../../../FormFields/UserField/UserSearch.component';
-
-const getStyles = () => ({
- container: {
- display: 'flex',
- alignItems: 'center',
- },
- searchContainer: {
- flexGrow: 1,
- flexShrink: 1,
- paddingRight: 5,
- },
- buttonContainer: {
- flexGrow: 0,
- flexShrink: 0,
- },
-});
-
-type Props = {
- onCancel: Function,
- classes: Object,
-};
-
-const EditModePlain = (props: Props) => {
- const { onCancel, classes, ...passOnProps } = props;
- return (
-
-
- {/* $FlowFixMe[cannot-spread-inexact] automated comment */}
-
-
-
-
-
-
- );
-};
-
-export const EditMode = withStyles(getStyles)(EditModePlain);
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/assigneeSection.actions.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/assigneeSection.actions.js
deleted file mode 100644
index 0bfd4a1db2..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/assigneeSection.actions.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// @flow
-
-import { actionCreator } from '../../../../../actions/actions.utils';
-import { effectMethods } from '../../../../../trackerOffline';
-
-export const actionTypes = {
- VIEW_EVENT_ASSIGNEE_SET: 'ViewEventAssigneeSet',
- VIEW_EVENT_ASSIGNEE_SAVE: 'ViewEventAssigneeSave',
- VIEW_EVENT_ASSIGNEE_SAVE_COMPLETED: 'ViewEventAssigneeSaveCompleted',
- VIEW_EVENT_ASSIGNEE_SAVE_FAILED: 'ViewEventAssigneeSaveFailed',
-};
-
-export const setAssignee = (assignee: Object) =>
- actionCreator(actionTypes.VIEW_EVENT_ASSIGNEE_SET)({ assignee });
-
-export const saveAssignee = (eventId: string, serverData: Object, selections: Object) =>
- actionCreator(actionTypes.VIEW_EVENT_ASSIGNEE_SAVE)({}, {
- offline: {
- effect: {
- url: 'tracker?async=false&importStrategy=UPDATE',
- method: effectMethods.POST,
- data: serverData,
- },
- commit: { type: actionTypes.VIEW_EVENT_ASSIGNEE_SAVE_COMPLETED, meta: { eventId, selections } },
- rollback: { type: actionTypes.VIEW_EVENT_ASSIGNEE_SAVE_FAILED, meta: { eventId, selections } },
- },
- });
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/index.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/index.js
index 5abb01a6c0..9646d16bb6 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/index.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/index.js
@@ -1,4 +1,2 @@
// @flow
-export { actionTypes as assigneeSectionActionTypes } from './assigneeSection.actions';
export { AssigneeSection } from './AssigneeSection.container';
-export { saveAssigneeEpic } from './saveAssignee.epic';
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/saveAssignee.epic.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/saveAssignee.epic.js
deleted file mode 100644
index 99f4a3348b..0000000000
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/AssigneeSection/saveAssignee.epic.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// @flow
-import { ofType } from 'redux-observable';
-import { map } from 'rxjs/operators';
-import { actionTypes, saveAssignee } from './assigneeSection.actions';
-import { getEventProgramThrowIfNotFound } from '../../../../../metaData';
-import { convertValue as convertToServerValue } from '../../../../../converters/clientToServer';
-import { convertMainEventClientToServer } from '../../../../../events/mainConverters';
-
-export const saveAssigneeEpic = (action$: InputObservable, store: ReduxStore) =>
- action$.pipe(
- ofType(actionTypes.VIEW_EVENT_ASSIGNEE_SET),
- map(() => {
- const state = store.value;
- const eventId = state.viewEventPage.eventId;
- const eventContainer = state.viewEventPage.loadedValues.eventContainer;
- const { event: clientMainValues, values: clientValues } = eventContainer;
- const program = getEventProgramThrowIfNotFound(clientMainValues.programId);
- const formFoundation = program.stage.stageForm;
- const formServerValues = formFoundation.convertValues(clientValues, convertToServerValue);
- const mainDataServerValues: Object = convertMainEventClientToServer(clientMainValues);
-
- const serverData = {
- events: [{
- ...mainDataServerValues,
- dataValues: Object
- .keys(formServerValues)
- .map(key => ({
- dataElement: key,
- value: formServerValues[key],
- })),
- }],
- };
-
- const currentSelectionSet = state.currentSelections;
-
- return saveAssignee(eventId, serverData, currentSelectionSet);
- }));
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RightColumnWrapper.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RightColumnWrapper.component.js
index 307d8ccd30..d04213a437 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RightColumnWrapper.component.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/RightColumn/RightColumnWrapper.component.js
@@ -9,7 +9,7 @@ import { FeedbacksSection } from './FeedbacksSection/FeedbacksSection.container'
import { IndicatorsSection } from './IndicatorsSection/IndicatorsSection.container';
import { RelationshipsSection } from './RelationshipsSection/RelationshipsSection.container';
import { NotesSection } from './NotesSection/NotesSection.container';
-import { AssigneeSection } from './AssigneeSection/AssigneeSection.container';
+import { AssigneeSection } from './AssigneeSection';
type Props = {
classes: {
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/ViewEvent.component.js b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/ViewEvent.component.js
index dbb2406dff..de6353d5ea 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/ViewEvent.component.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/ViewEvent.component.js
@@ -8,7 +8,7 @@ import { RightColumnWrapper } from '../RightColumn/RightColumnWrapper.component'
import type { ProgramStage } from '../../../../metaData';
import { DiscardDialog } from '../../../Dialogs/DiscardDialog.component';
import { defaultDialogProps } from '../../../Dialogs/DiscardDialog.constants';
-
+import type { UserFormField } from '../../../FormFields/UserField';
const getStyles = (theme: Theme) => ({
container: {
@@ -48,6 +48,10 @@ type Props = {
header: string,
showAllEvents: string,
},
+ assignee: UserFormField,
+ getAssignedUserSaveContext: () => { event: ApiEnrollmentEvent },
+ onSaveAssignee: (newAssignee: UserFormField) => void,
+ onSaveAssigneeError: (prevAssignee: UserFormField | null) => void,
};
type State = {
@@ -70,7 +74,17 @@ class ViewEventPlain extends Component {
}
render() {
- const { classes, programStage, currentDataEntryKey, eventAccess } = this.props;
+ const {
+ classes,
+ programStage,
+ currentDataEntryKey,
+ eventAccess,
+ assignee,
+ getAssignedUserSaveContext,
+ onSaveAssignee,
+ onSaveAssigneeError,
+ } = this.props;
+
return (
{
const programStageSelector = makeProgramStageSelector();
const eventAccessSelector = makeEventAccessSelector();
+ const assignedUserContextSelector = makeAssignedUserContextSelector();
// $FlowFixMe[not-an-object] automated comment
return (state: ReduxState) => {
@@ -29,6 +31,9 @@ const makeMapStateToProps = () => {
error: state.viewEventPage.loadError,
currentDataEntryKey,
isUserInteractionInProgress,
+ assignee: state.viewEventPage.loadedValues?.eventContainer.event.assignee,
+ getAssignedUserSaveContext: () => assignedUserContextSelector(state),
+ eventId: state.viewEventPage.eventId,
};
};
};
@@ -37,10 +42,26 @@ const mapDispatchToProps = (dispatch: ReduxDispatch) => ({
onBackToAllEvents: () => {
dispatch(startGoBackToMainPage());
},
+ dispatch,
});
+const mergeProps = (stateProps, dispatchProps, ownProps) => {
+ const mergedProps = {
+ onSaveAssignee: (newAssignee) => {
+ dispatchProps.dispatch(setAssignee(newAssignee, stateProps.eventId));
+ },
+ onSaveAssigneeError: (prevAssignee) => {
+ dispatchProps.dispatch(rollbackAssignee(prevAssignee, stateProps.eventId));
+ },
+ };
+
+ return Object.assign({}, ownProps, stateProps, dispatchProps, mergedProps);
+};
+
// $FlowSuppress
// $FlowFixMe[missing-annot] automated comment
-export const ViewEvent = connect(makeMapStateToProps, mapDispatchToProps)(
- withErrorMessageHandler()(ViewEventComponent),
-);
+export const ViewEvent = connect(
+ makeMapStateToProps,
+ mapDispatchToProps,
+ mergeProps,
+)(withErrorMessageHandler()(ViewEventComponent));
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.actions.js b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.actions.js
index 2c4c627067..14413d97bc 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.actions.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.actions.js
@@ -1,6 +1,7 @@
// @flow
import { actionCreator } from 'capture-core/actions/actions.utils';
import type { OrgUnit } from '@dhis2/rules-engine-javascript';
+import type { UserFormField } from '../../../FormFields/UserField';
export const actionTypes = {
VIEW_EVENT_FROM_URL: 'ViewEventFromUrl',
@@ -19,6 +20,8 @@ export const actionTypes = {
UPDATE_WORKING_LIST_PENDING_ON_BACK_TO_MAIN_PAGE: 'UpdateWorkingListPendingOnBackToMainPageForViewEvent',
OPEN_VIEW_EVENT_PAGE_FAILED: 'OpenViewEventPageFailed',
INITIALIZE_WORKING_LISTS_ON_BACK_TO_MAIN_PAGE: 'InitializeWorkingListsOnBackToMainPage',
+ ASSIGNEE_SET: 'SingleEvent.AssigneeSet',
+ ASSIGNEE_SAVE_FAILED: 'SingleEvent.AssigneeSaveFailed',
};
export const viewEventFromUrl = (data: Object) =>
@@ -74,3 +77,10 @@ export const updateEventContainer = (eventContainer: Object, orgUnit: OrgUnit) =
export const openViewEventPageFailed = (error: string) =>
actionCreator(actionTypes.OPEN_VIEW_EVENT_PAGE_FAILED)({ error });
+
+export const setAssignee = (assignee: UserFormField, eventId: string) =>
+ actionCreator(actionTypes.ASSIGNEE_SET)({ assignee, eventId });
+
+export const rollbackAssignee = (assignee: UserFormField, eventId: string) =>
+ actionCreator(actionTypes.ASSIGNEE_SAVE_FAILED)({ assignee, eventId });
+
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.selectors.js b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.selectors.js
index 69cd29f1f6..afb7761610 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.selectors.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/ViewEventComponent/viewEvent.selectors.js
@@ -2,10 +2,12 @@
import { createSelector } from 'reselect';
import { getEventProgramEventAccess, getEventProgramThrowIfNotFound } from '../../../../metaData';
-
+import { convertValue as convertToServerValue } from '../../../../converters/clientToServer';
+import { convertMainEventClientToServer } from '../../../../events/mainConverters';
const programIdSelector = state => state.currentSelections.programId;
const categoriesMetaSelector = state => state.currentSelections.categoriesMeta;
+const eventContainerSelector = state => state.viewEventPage.loadedValues?.eventContainer;
// $FlowFixMe[missing-annot] automated comment
export const makeProgramStageSelector = () => createSelector(
@@ -18,3 +20,23 @@ export const makeEventAccessSelector = () => createSelector(
categoriesMetaSelector,
(programId: string, categoriesMeta: ?Object) => getEventProgramEventAccess(programId, categoriesMeta));
+export const makeAssignedUserContextSelector = () =>
+ // $FlowFixMe[missing-annot]
+ createSelector(eventContainerSelector, (eventContainer) => {
+ const { event: clientMainValues, values: clientValues } = eventContainer;
+ const program = getEventProgramThrowIfNotFound(clientMainValues.programId);
+ const formFoundation = program.stage.stageForm;
+ const formServerValues = formFoundation.convertValues(clientValues, convertToServerValue);
+ const mainDataServerValues: Object = convertMainEventClientToServer(clientMainValues);
+
+ const event =
+ {
+ ...mainDataServerValues,
+ dataValues: Object.keys(formServerValues).map(key => ({
+ dataElement: key,
+ value: formServerValues[key],
+ })),
+ };
+
+ return { event };
+ });
diff --git a/src/core_modules/capture-core/components/Pages/ViewEvent/index.js b/src/core_modules/capture-core/components/Pages/ViewEvent/index.js
index 681239203a..082ff0bd70 100644
--- a/src/core_modules/capture-core/components/Pages/ViewEvent/index.js
+++ b/src/core_modules/capture-core/components/Pages/ViewEvent/index.js
@@ -1,5 +1,3 @@
// @flow
export { actionTypes as editEventDataEntryActionTypes } from '../../WidgetEventEdit/EditEventDataEntry';
-export { assigneeSectionActionTypes } from '../ViewEvent/RightColumn/AssigneeSection';
-
export { ViewEventPage } from './ViewEventPage.container';
diff --git a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData/useCommonEnrollmentDomainData.types.js b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData/useCommonEnrollmentDomainData.types.js
index 688e293955..6a4a067870 100644
--- a/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData/useCommonEnrollmentDomainData.types.js
+++ b/src/core_modules/capture-core/components/Pages/common/EnrollmentOverviewDomain/useCommonEnrollmentDomainData/useCommonEnrollmentDomainData.types.js
@@ -17,9 +17,11 @@ export type Event = {|
program: string,
programStage: string,
status: 'ACTIVE' | 'VISITED' | 'COMPLETED' | 'SCHEDULE' | 'OVERDUE' | 'SKIPPED',
- trackedEntityInstance: string,
+ trackedEntity: string,
notes?: Array
diff --git a/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
index 58c4645463..4075f5d0da 100644
--- a/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
+++ b/src/core_modules/capture-core/components/WidgetEventEdit/WidgetEventEdit.container.js
@@ -58,6 +58,7 @@ export const WidgetEventEditPlain = ({
orgUnitId,
enrollmentId,
teiId,
+ assignee,
}: Props) => {
const dispatch = useDispatch();
const { currentPageMode } = useEnrollmentEditEventPageMode(eventStatus);
@@ -144,6 +145,7 @@ export const WidgetEventEditPlain = ({
allowGenerateNextVisit={programStage.allowGenerateNextVisit}
availableProgramStages={availableProgramStages}
hideDueDate={programStage.hideDueDate}
+ assignee={assignee}
/>
)}