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

feat: [DHIS2-18746][DHIS2-18903] Show org. unit in edit event form #3949

Merged
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const TopBar = ({
onResetOrgUnitId={() => resetOrgUnitId()}
isUserInteractionInProgress={isUserInteractionInProgress}
onStartAgain={() => reset()}
isReadOnly={mode === dataEntryKeys.EDIT}
>
<SingleLockedSelect
displayOnly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ import {
resetCategoryOption,
resetAllCategoryOptions,
} from './ViewEventPage.actions';

import { TopBarActions } from '../../TopBarActions';

type TopBarProps = {
isUserInteractionInProgress: boolean,
programId?: string,
orgUnitId?: string,
selectedCategories?: any,
isReadOnly: boolean,
formIsOpen: boolean,
};

export const TopBar = ({
programId,
orgUnitId,
selectedCategories,
isReadOnly,
isUserInteractionInProgress,
formIsOpen,
}: TopBarProps) => {
Expand Down Expand Up @@ -63,6 +64,7 @@ export const TopBar = ({
isUserInteractionInProgress={isUserInteractionInProgress}
formIsOpen={formIsOpen}
onStartAgain={() => reset()}
isReadOnly={isReadOnly}
>
<TopBarActions
selectedProgramId={programId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ import { inMemoryFileStore } from '../../DataEntry/file/inMemoryFileStore';
type Props = {
isUserInteractionInProgress: boolean,
showAddRelationship: boolean,
isReadOnly: boolean,
};

export const ViewEventPageComponent = ({ isUserInteractionInProgress, showAddRelationship }: Props) => {
export const ViewEventPageComponent = ({ isUserInteractionInProgress, showAddRelationship, isReadOnly }: Props) => {
const { serverVersion: { minor } } = useConfig();
useEffect(() => inMemoryFileStore.clear, []);

Expand All @@ -29,6 +30,7 @@ export const ViewEventPageComponent = ({ isUserInteractionInProgress, showAddRel
programId={programId}
orgUnitId={orgUnitId}
selectedCategories={selectedCategories}
isReadOnly={isReadOnly}
isUserInteractionInProgress={isUserInteractionInProgress}
formIsOpen
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { withLoadingIndicator, withErrorMessageHandler } from '../../../HOC';

const mapStateToProps = (state: ReduxState) => {
const eventDetailsSection = state.viewEventPage.eventDetailsSection || {};
const isReadOnly = eventDetailsSection.showEditEvent;
const isUserInteractionInProgress =
(state.currentSelections.complete && eventDetailsSection.showEditEvent)
?
Expand All @@ -17,6 +18,7 @@ const mapStateToProps = (state: ReduxState) => {
error: state.activePage.viewEventLoadError && state.activePage.viewEventLoadError.error,
ready: !state.activePage.lockedSelectorLoads,
isUserInteractionInProgress,
isReadOnly,
showAddRelationship: state.viewEventPage.showAddRelationship,
};
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ import {
updateRulesEffects,
} from '../../../rules';
import { RenderFoundation, Program } from '../../../metaData';
import { getEventDateValidatorContainers } from './fieldValidators/eventDate.validatorContainersGetter';
import { getCategoryOptionsValidatorContainers } from './fieldValidators/categoryOptions.validatorContainersGetter';
import {
getEventDateValidatorContainers,
getOrgUnitValidatorContainers,
getCategoryOptionsValidatorContainers,
} from './fieldValidators';
import {
getConvertGeometryIn,
convertGeometryOut,
Expand Down Expand Up @@ -110,6 +113,11 @@ export const openEventForEditInDataEntry = ({
type: 'DATE',
validatorContainers: getEventDateValidatorContainers(),
},
{
id: 'orgUnit',
type: 'ORGANISATION_UNIT',
validatorContainers: getOrgUnitValidatorContainers(),
},
{
clientId: 'geometry',
dataEntryId: 'geometry',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { from } from 'rxjs';
import { ofType } from 'redux-observable';
import { map, switchMap } from 'rxjs/operators';
import { batchActions } from 'redux-batched-actions';
import type { OrgUnit } from '@dhis2/rules-engine-javascript';
import { rulesExecutedPostUpdateField } from '../../../DataEntry/actions/dataEntry.actions';
import {
batchActionTypes as editEventDataEntryBatchActionTypes,
Expand All @@ -26,13 +25,13 @@ import { getDataEntryKey } from '../../../DataEntry/common/getDataEntryKey';
import { prepareEnrollmentEventsForRulesEngine } from '../../../../events/prepareEnrollmentEvents';
import { getEnrollmentForRulesEngine, getAttributeValuesForRulesEngine } from '../../helpers';
import type { QuerySingleResource } from '../../../../utils/api';
import { getCoreOrgUnitFn, orgUnitFetched } from '../../../../metadataRetrieval/coreOrgUnit';

const runRulesForEditSingleEvent = async ({
store,
dataEntryId,
itemId,
uid,
orgUnit,
fieldData,
programId,
querySingleResource,
Expand All @@ -42,7 +41,6 @@ const runRulesForEditSingleEvent = async ({
itemId: string,
uid: string,
programId: string,
orgUnit: OrgUnit,
fieldData?: ?FieldData,
querySingleResource: QuerySingleResource
}) => {
Expand All @@ -66,6 +64,10 @@ const runRulesForEditSingleEvent = async ({
// $FlowFixMe
const currentEvent = { ...currentEventValues, ...currentEventMainData, eventId };

const { coreOrgUnit, cached } =
// $FlowFixMe
await getCoreOrgUnitFn(querySingleResource)(currentEvent.orgUnit?.id, store.value.organisationUnits);

let effects;
if (program instanceof TrackerProgram) {
const { enrollment, attributeValues } = state.enrollmentDomain;
Expand All @@ -82,7 +84,7 @@ const runRulesForEditSingleEvent = async ({
effects = getApplicableRuleEffectsForTrackerProgram({
program,
stage,
orgUnit,
orgUnit: coreOrgUnit,
currentEvent: { ...currentEvent, createdAt: apiCurrentEventOriginal.createdAt },
otherEvents: prepareEnrollmentEventsForRulesEngine(apiOtherEvents),
enrollmentData: getEnrollmentForRulesEngine(enrollment),
Expand All @@ -91,7 +93,7 @@ const runRulesForEditSingleEvent = async ({
} else {
effects = getApplicableRuleEffectsForEventProgram({
program,
orgUnit,
orgUnit: coreOrgUnit,
currentEvent,
});
}
Expand All @@ -105,6 +107,7 @@ const runRulesForEditSingleEvent = async ({
return batchActions([
updateRulesEffects(effectsWithValidations, formId),
rulesExecutedPostUpdateField(dataEntryId, itemId, uid),
...(coreOrgUnit && !cached ? [orgUnitFetched(coreOrgUnit)] : []),
],
editEventDataEntryBatchActionTypes.RULES_EFFECTS_ACTIONS_BATCH);
};
Expand All @@ -114,20 +117,19 @@ export const runRulesOnUpdateDataEntryFieldForEditSingleEventEpic = (
store: ReduxStore,
{ querySingleResource }: ApiUtils,
) =>
// $FlowSuppress
// $FlowSuppress
action$.pipe(
ofType(editEventDataEntryBatchActionTypes.UPDATE_DATA_ENTRY_FIELD_EDIT_SINGLE_EVENT_ACTION_BATCH),
map(actionBatch =>
actionBatch.payload.find(action => action.type === editEventDataEntryActionTypes.START_RUN_RULES_ON_UPDATE),
),
switchMap((action) => {
const { dataEntryId, itemId, uid, orgUnit, programId } = action.payload;
const { dataEntryId, itemId, uid, programId } = action.payload;
const runRulesForEditSingleEventPromise = runRulesForEditSingleEvent({
store,
dataEntryId,
itemId,
uid,
orgUnit,
programId,
querySingleResource,
});
Expand All @@ -139,7 +141,7 @@ export const runRulesOnUpdateFieldForEditSingleEventEpic = (
store: ReduxStore,
{ querySingleResource }: ApiUtils,
) =>
// $FlowSuppress
// $FlowSuppress
action$.pipe(
ofType(editEventDataEntryBatchActionTypes.UPDATE_FIELD_EDIT_SINGLE_EVENT_ACTION_BATCH),
map(actionBatch =>
Expand All @@ -153,7 +155,6 @@ export const runRulesOnUpdateFieldForEditSingleEventEpic = (
dataEntryId,
itemId,
uid,
orgUnit,
programId,
} = action.payload;
const fieldData: FieldData = {
Expand All @@ -166,7 +167,6 @@ export const runRulesOnUpdateFieldForEditSingleEventEpic = (
dataEntryId,
itemId,
uid,
orgUnit,
fieldData,
programId,
querySingleResource,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
withDefaultFieldContainer,
withDefaultShouldUpdateInterface,
VirtualizedSelectField,
SingleOrgUnitSelectField,
} from '../../FormFields/New';
import { statusTypes, translatedStatusTypes } from '../../../events/statusTypes';
import labelTypeClasses from '../DataEntry/dataEntryFieldLabels.module.css';
Expand All @@ -48,6 +49,7 @@ import {
withDataEntryFields,
} from '../../DataEntryDhis2Helpers/';
import type { UserFormField } from '../../FormFields/UserField';
import { getOrgUnitValidatorContainers } from '../DataEntry/fieldValidators';

const tabMode = Object.freeze({
REPORT: 'REPORT',
Expand Down Expand Up @@ -197,6 +199,47 @@ const buildScheduleDateSettingsFn = () => {
return scheduleDateSettings;
};

const buildOrgUnitSettingsFn = () => {
const orgUnitComponent =
withCalculateMessages(overrideMessagePropNames)(
withFocusSaver()(
withDefaultFieldContainer()(
withDefaultShouldUpdateInterface()(
withLabel({
onGetUseVerticalOrientation: (props: Object) => props.formHorizontal,
onGetCustomFieldLabeClass: (props: Object) =>
`${props.fieldOptions.fieldLabelMediaBasedClass} ${labelTypeClasses.dateLabel}`,
})(
withDisplayMessages()(
withInternalChangeHandler()(
withFilterProps(defaultFilterProps)(SingleOrgUnitSelectField),
),
),
),
),
),
),
);

const orgUnitSettings = {
getComponent: () => orgUnitComponent,
getComponentProps: (props: Object) => createComponentProps(props, {
width: props && props.formHorizontal ? 150 : 350,
label: i18n.t('Organisation unit'),
required: true,
}),
getPropName: () => 'orgUnit',
getValidatorContainers: () => getOrgUnitValidatorContainers(),
getMeta: () => ({
placement: placements.TOP,
section: dataEntrySectionNames.BASICINFO,
}),
};

return orgUnitSettings;
};


const pointComponent = withCalculateMessages(overrideMessagePropNames)(
withFocusSaver()(
withDefaultFieldContainer()(
Expand Down Expand Up @@ -252,15 +295,15 @@ const buildGeometrySettingsFn = () => ({
label: i18n.t('Area'),
dialogLabel: i18n.t('Area'),
required: false,
orgUnitId: props.orgUnit?.id,
orgUnitId: props.orgUnitIdFieldValue,
});
}
return createComponentProps(props, {
width: props && props.formHorizontal ? 150 : '100%',
label: i18n.t('Coordinate'),
dialogLabel: i18n.t('Coordinate'),
required: false,
orgUnitId: props.orgUnit?.id,
orgUnitId: props.orgUnitIdFieldValue,
});
},
getPropName: () => 'geometry',
Expand Down Expand Up @@ -359,7 +402,8 @@ const saveHandlerConfig = {
const AOCFieldBuilderHOC = withAOCFieldBuilder({})(withDataEntryFields(getCategoryOptionsSettingsFn())(DataEntry));
const CleanUpHOC = withCleanUp()(AOCFieldBuilderHOC);
const GeometryField = withDataEntryFieldIfApplicable(buildGeometrySettingsFn())(CleanUpHOC);
const ScheduleDateField = withDataEntryField(buildScheduleDateSettingsFn())(GeometryField);
const OrgUnitField = withDataEntryField(buildOrgUnitSettingsFn())(GeometryField);
const ScheduleDateField = withDataEntryField(buildScheduleDateSettingsFn())(OrgUnitField);
const ReportDateField = withDataEntryField(buildReportDateSettingsFn())(ScheduleDateField);
const SaveableDataEntry = withSaveHandler(saveHandlerConfig)(withMainButton()(ReportDateField));
const CancelableDataEntry = withCancelButton(getCancelOptions)(SaveableDataEntry);
Expand Down Expand Up @@ -398,6 +442,7 @@ type Props = {
enrollmentId?: string,
isCompleted?: boolean,
assignee?: UserFormField | null,
orgUnitFieldValue: ?OrgUnit,
};


Expand Down Expand Up @@ -493,6 +538,7 @@ class EditEventDataEntryPlain extends Component<Props, State> {
dataEntryId,
orgUnit,
programId,
orgUnitFieldValue,
onUpdateDataEntryField,
onUpdateField,
onStartAsyncUpdateField,
Expand All @@ -512,6 +558,7 @@ class EditEventDataEntryPlain extends Component<Props, State> {
onSaveAndCompleteEnrollment={onSaveAndCompleteEnrollment(orgUnit)}
fieldOptions={this.fieldOptions}
dataEntrySections={this.dataEntrySections}
orgUnitIdFieldValue={orgUnitFieldValue?.id}
orgUnit={orgUnit}
orgUnitId={orgUnit?.id}
programId={programId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ const mapStateToProps = (state: ReduxState, props) => {
const itemId = state.dataEntries[props.dataEntryId] && state.dataEntries[props.dataEntryId].itemId;

const dataEntryKey = `${props.dataEntryId}-${itemId}`;
const orgUnitFieldValue = state.dataEntriesFieldsValue[dataEntryKey]?.orgUnit;
const isCompleted = state.dataEntriesFieldsValue[dataEntryKey]?.complete === 'true';

return {
ready: !state.activePage.isDataEntryLoading && !eventDetailsSection.loading,
itemId,
isCompleted,
orgUnitFieldValue,
enrolledAt: state.enrollmentDomain?.enrollment?.enrolledAt,
occurredAt: state.enrollmentDomain?.enrollment?.occurredAt,
eventData: state.enrollmentDomain?.enrollment?.events,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ export const saveEditedEventEpic = (action$: InputObservable, store: ReduxStore,
const serverData = {
events: [{
...mainDataServerValues,
orgUnit: mainDataServerValues.orgUnit.id,
attributeOptionCombo: undefined,
dataValues: formFoundation
.getElements()
Expand Down Expand Up @@ -267,6 +268,7 @@ export const saveEventAndCompleteEnrollmentEpic = (action$: InputObservable, sto

const editEvent = {
...mainDataServerValues,
orgUnit: mainDataServerValues.orgUnit.id,
attributeOptionCombo: undefined,
dataValues: formFoundation
.getElements()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ const buildOrgUnitSettingsFn = () => {
label: i18n.t('Organisation unit'),
valueConverter: value => dataElement.convertValue(value, valueConvertFn),
}),
getPropName: () => 'orgUnitId',
getPropName: () => 'orgUnit',
getMeta: () => ({
placement: placements.TOP,
section: dataEntrySectionNames.BASICINFO,
Expand Down
Loading
Loading