Skip to content

Commit

Permalink
feat: [DHIS2-16527] assign user on first stage registration (#3530)
Browse files Browse the repository at this point in the history
  • Loading branch information
superskip authored Feb 19, 2024
1 parent e288f20 commit 54eef90
Show file tree
Hide file tree
Showing 10 changed files with 75 additions and 19 deletions.
7 changes: 5 additions & 2 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
"POT-Creation-Date: 2024-02-07T10:43:51.606Z\n"
"PO-Revision-Date: 2024-02-07T10:43:51.606Z\n"
"POT-Creation-Date: 2024-02-09T11:22:44.980Z\n"
"PO-Revision-Date: 2024-02-09T11:22:44.980Z\n"

msgid "Choose one or more dates..."
msgstr "Choose one or more dates..."
Expand Down Expand Up @@ -152,6 +152,9 @@ msgstr "Complete event"
msgid "{{ stageName }} - Basic info"
msgstr "{{ stageName }} - Basic info"

msgid "{{ stageName }} - Assignee"
msgstr "{{ stageName }} - Assignee"

msgid "{{ stageName }} - Status"
msgstr "{{ stageName }} - Status"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// @flow
import i18n from '@dhis2/d2-i18n';
import { DataEntry } from '../../../DataEntry';
import { Assignee } from '../../SingleEventRegistrationEntry/DataEntryWrapper/DataEntry/Assignee';
import {
withInternalChangeHandler,
withLabel,
Expand All @@ -23,6 +24,7 @@ import labelTypeClasses from './fieldLabels.module.css';
import { withCleanUp } from './withCleanUp';
import { getEventDateValidatorContainers } from './fieldValidators/eventDate.validatorContainersGetter';
import { stageMainDataIds } from './getDataEntryPropsToInclude';
import { withTransformPropName } from '../../../../HOC';

const overrideMessagePropNames = {
errorMessage: 'validationError',
Expand Down Expand Up @@ -226,6 +228,36 @@ const getReportDateSettingsFn = () => {
return reportDateSettings;
};

const getAssigneeSettingsFn = () => {
const assigneeComponent =
withTransformPropName(['onBlur', 'onSet'])(
withFocusSaver()(
withFilterProps((props: Object) => {
const defaultFiltred = defaultFilterProps(props);
const { validationAttempted, touched, ...passOnProps } = defaultFiltred;
return passOnProps;
})(Assignee),
),
);

return {
isApplicable: (props: Object) => {
const enableUserAssignment = props.firstStageMetaData && props.firstStageMetaData.stage.enableUserAssignment;
return !!enableUserAssignment;
},
getComponent: () => assigneeComponent,
getComponentProps: (props: Object) => createComponentProps({}, {
orientation: getOrientation(props.formHorizontal),
}),
getPropName: () => 'assignee',
getValidatorContainers: () => [],
getMeta: () => ({
section: sectionKeysForFirstStageDataEntry.ASSIGNEE,
}),
};
};

const StageLocationHOC = withDataEntryFieldIfApplicable(getStageGeometrySettings())(withCleanUp()(DataEntry));
const CompleteHOC = withDataEntryFieldIfApplicable(getCompleteFieldSettingsFn())(StageLocationHOC);
export const FirstStageDataEntry = withDataEntryFieldIfApplicable(getReportDateSettingsFn())(CompleteHOC);
const AssigneeHOC = withDataEntryFieldIfApplicable(getAssigneeSettingsFn())(CompleteHOC);
export const FirstStageDataEntry = withDataEntryFieldIfApplicable(getReportDateSettingsFn())(AssigneeHOC);
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export const sectionKeysForFirstStageDataEntry = {
ENROLLMENT: 'enrollment',
STATUS: 'status',
STAGE_BASIC_INFO: 'stageBasicInfo',
ASSIGNEE: 'assignee',
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// @flow
import type { RenderFoundation } from '../../../../metaData';
import type { ProgramStage } from '../../../../metaData';
import { getEventDateValidatorContainers } from './fieldValidators';
import { getConvertGeometryIn, convertGeometryOut, convertStatusIn, convertStatusOut } from '../../converters';

export const stageMainDataIds = {
OCCURRED_AT: 'stageOccurredAt',
COMPLETE: 'stageComplete',
GEOMETRY: 'stageGeometry',
ASSIGNEE: 'assignee',
};

const stageMainDataRulesEngineIds = {
Expand All @@ -17,7 +18,7 @@ const stageMainDataRulesEngineIds = {

export const convertToRulesEngineIds = (id: string) => stageMainDataRulesEngineIds[id];

export const getDataEntryPropsToInclude = (formFoundation: RenderFoundation) => [
export const getDataEntryPropsToInclude = (firstStage: ProgramStage) => [
{
id: stageMainDataIds.OCCURRED_AT,
type: 'DATE',
Expand All @@ -32,8 +33,12 @@ export const getDataEntryPropsToInclude = (formFoundation: RenderFoundation) =>
{
clientId: stageMainDataIds.GEOMETRY,
dataEntryId: stageMainDataIds.GEOMETRY,
onConvertIn: getConvertGeometryIn(formFoundation),
onConvertIn: getConvertGeometryIn(firstStage.stageForm),
onConvertOut: convertGeometryOut,
featureType: formFoundation.featureType,
featureType: firstStage.stageForm.featureType,
},
...(firstStage.enableUserAssignment ? [{
id: stageMainDataIds.ASSIGNEE,
type: 'ASSIGNEE',
}] : []),
];
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export const useDataEntrySections = (stageName: string, beforeSectionId: string)
beforeSectionId,
placement: placements.BEFORE_METADATA_BASED_SECTION,
},
[sectionKeysForFirstStageDataEntry.ASSIGNEE]: {
placement: placements.BOTTOM,
name: i18n.t('{{ stageName }} - Assignee', {
stageName,
}),
},
[sectionKeysForFirstStageDataEntry.STATUS]: {
placement: placements.BOTTOM,
name: i18n.t('{{ stageName }} - Status', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const openDataEntryForNewEnrollmentBatchAsync = async ({
}) => {
const formId = getDataEntryKey(dataEntryId, itemId);
const addFormDataActions = addFormData(`${dataEntryId}-${itemId}`, formValues);
const firstStageDataEntryPropsToInclude = firstStage && getDataEntryPropsToInclude(firstStage.stageForm);
const firstStageDataEntryPropsToInclude = firstStage && getDataEntryPropsToInclude(firstStage);
const defaultDataEntryValues = { enrolledAt: convertDateObjectToDateFormatString(new Date()) };
const dataEntryPropsToInclude = [
...enrollmentDataEntryPropsToInclude,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ export const useBuildEnrollmentPayload = ({
dataEntryFieldsMeta,
formFoundation,
);
const { enrolledAt, occurredAt } = serverValuesForMainValues;
const { enrolledAt, occurredAt, assignee } = serverValuesForMainValues;

const { stages } = getTrackerProgramThrowIfNotFound(programId);

Expand All @@ -140,6 +140,7 @@ export const useBuildEnrollmentPayload = ({
currentEventValues,
fieldsValue: dataEntryFieldValues,
attributeCategoryOptions,
assignee,
});

const autoGenerateEvents = deriveAutoGenerateEvents({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ const getStyles = () => ({
},
label: {
flexBasis: 200,
fontSize: 14,
paddingLeft: 5,
color: 'rgba(0, 0, 0, 0.87)',
},
field: {
flexBasis: 150,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
// @flow
/* eslint-disable no-new-func */
import { convertValue } from '../../../converters/formToClient';
import type { RenderFoundation } from '../../../metaData';

// $FlowSuppress
// $FlowFixMe[prop-missing] automated comment
const getFunctionFromString = (functionAsString: string) => Function(`return ${functionAsString}`)();

Expand All @@ -17,20 +15,21 @@ export function convertDataEntryValuesToClientValues(
}
const eventValues = Object
.keys(dataEntryValues)
// eslint-disable-next-line complexity
.reduce((accEventValues, key) => {
const type = dataEntryValuesMeta[key] && dataEntryValuesMeta[key].type;
const onConvertOut = dataEntryValuesMeta[key] && dataEntryValuesMeta[key].onConvertOut;
const clientIgnore = dataEntryValuesMeta[key] && dataEntryValuesMeta[key].clientIgnore;
const customFeatureType = dataEntryValuesMeta[key] && dataEntryValuesMeta[key].featureType;
const {
type,
onConvertOut,
clientIgnore,
featureType: customFeatureType,
} = dataEntryValuesMeta[key] || {};
if (clientIgnore) {
return accEventValues;
}
if (type) {
const value = dataEntryValues[key];
accEventValues[key] = convertValue(value, type);
} else if (onConvertOut) {
const clientId = dataEntryValuesMeta[key] && dataEntryValuesMeta[key].clientId;
const clientId = dataEntryValuesMeta[key].clientId;
const dataEntryValue = dataEntryValues[key];
const onConvertOutFn = getFunctionFromString(onConvertOut);
accEventValues[clientId] = onConvertOutFn(dataEntryValue, foundation, customFeatureType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ export const deriveFirstStageDuringRegistrationEvent = ({
currentEventValues,
fieldsValue,
attributeCategoryOptions,
assignee,
}: {
firstStageMetadata: ?ProgramStage,
programId: string,
orgUnitId: string,
currentEventValues?: { [id: string]: any },
fieldsValue: { [id: string]: any },
attributeCategoryOptions: { [categoryId: string]: string } | string,
assignee?: ApiAssignedUser,
}) => {
if (!firstStageMetadata) {
return null;
Expand All @@ -32,7 +34,7 @@ export const deriveFirstStageDuringRegistrationEvent = ({
? { attributeCategoryOptions: convertCategoryOptionsToServer(attributeCategoryOptions) }
: {};

const event = {
const event: any = {
status: convertStatusOut(stageComplete),
geometry: standardGeoJson(stageGeometry),
occurredAt: convertFn(stageOccurredAt, dataElementTypes.DATE),
Expand All @@ -49,7 +51,11 @@ export const deriveFirstStageDuringRegistrationEvent = ({
}, []) : undefined;

if (dataValues) {
return { ...event, dataValues };
event.dataValues = dataValues;
}

if (assignee) {
event.assignedUser = assignee;
}
return event;
};

0 comments on commit 54eef90

Please sign in to comment.