Skip to content

Commit

Permalink
feat: [DHIS2-17991] Show orgUnit selector in Enter details now (#3824)
Browse files Browse the repository at this point in the history
* feat: add org unit selector

* feat: select org unit for linked event

* feat: add validation
  • Loading branch information
henrikmv authored Oct 21, 2024
1 parent 7404bf5 commit bf2f1ca
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 36 deletions.
7 changes: 0 additions & 7 deletions i18n/en.pot
Original file line number Diff line number Diff line change
Expand Up @@ -1414,13 +1414,6 @@ msgstr "{{ linkableStageLabel }} has no linkable events"
msgid "Ambiguous relationships, contact system administrator"
msgstr "Ambiguous relationships, contact system administrator"

msgid ""
"Enter {{linkableStageLabel}} details in the next step after completing this "
"{{currentStageLabel}}."
msgstr ""
"Enter {{linkableStageLabel}} details in the next step after completing this "
"{{currentStageLabel}}."

msgid "Enter details now"
msgstr "Enter details now"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ const getEventDetailsByLinkMode = ({
}),
);
}

return ({
linkedEvent: {
...baseEventDetails,
Expand All @@ -56,23 +55,34 @@ const getEventDetailsByLinkMode = ({
},
linkedEventId: baseEventDetails.event,
});
} else if (linkMode === RelatedStageModes.ENTER_DATA) {
}

if (linkMode === RelatedStageModes.ENTER_DATA) {
const { orgUnit: linkedEventOrgUnit } = relatedStageDataValues;
if (!linkedEventOrgUnit) {
throw new Error(
errorCreator('Missing required data for creating related stage event')({
linkedEventOrgUnit,
}),
);
}
return ({
linkedEvent: {
...baseEventDetails,
scheduledAt: convertFn(clientRequestEvent.scheduledAt, dataElementTypes.DATE),
orgUnit: clientRequestEvent.orgUnit,
orgUnit: convertFn(linkedEventOrgUnit, dataElementTypes.ORGANISATION_UNIT),
},
linkedEventId: baseEventDetails.event,
});
} else if (linkMode === RelatedStageModes.LINK_EXISTING_RESPONSE) {
}

if (linkMode === RelatedStageModes.LINK_EXISTING_RESPONSE) {
const { linkedEventId } = relatedStageDataValues;
return {
linkedEvent: null,
linkedEventId,
};
}

log.error(errorCreator(`Referral mode ${linkMode} is not supported`)());
return {
linkedEvent: null,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// @flow
import React from 'react';
import i18n from '@dhis2/d2-i18n';
import type { ComponentType } from 'react';
import { withStyles } from '@material-ui/core';
import { colors, spacers, spacersNum, IconInfo16 } from '@dhis2/ui';
import { OrgUnitSelectorForRelatedStages } from '../FormComponents';
import type { ErrorMessagesForRelatedStages } from '../RelatedStagesActions';
import type { RelatedStageDataValueStates } from '../WidgetRelatedStages.types';

const styles = {
wrapper: {
padding: `${spacers.dp16} 0`,
maxWidth: '55.75rem',
},
fieldWrapper: {
display: 'flex',
flexWrap: 'wrap',
alignItems: 'start',
justifyContent: 'space-between',
padding: `${spacers.dp8} ${spacers.dp16}`,
},
fieldLabel: {
color: colors.grey900,
paddingTop: spacersNum.dp12,
paddingRight: spacersNum.dp16,
flexBasis: '200px',
},
fieldContent: {
flexBasis: '150px',
flexGrow: 1,
},
alternateColor: {
backgroundColor: colors.grey100,
},
infoBox: {
margin: '8px 8px',
display: 'flex',
fontSize: '14px',
gap: '5px',
background: colors.grey100,
padding: '12px 8px',
border: `1px solid ${colors.grey600}`,
},
};

type Props = {
linkableStageLabel: string,
relatedStagesDataValues: RelatedStageDataValueStates,
setRelatedStagesDataValues: (() => Object) => void,
currentStageLabel: string,
saveAttempted: boolean,
errorMessages: ErrorMessagesForRelatedStages,
...CssClasses
}

export const EnterDataInOrgUnitPlain = ({
linkableStageLabel,
relatedStagesDataValues,
setRelatedStagesDataValues,
saveAttempted,
errorMessages,
currentStageLabel,
classes,
}: Props) => {
const onSelectOrgUnit = (e: { id: string, displayName: string, path: string }) => {
const orgUnit = {
id: e.id,
name: e.displayName,
path: e.path,
};

setRelatedStagesDataValues(prevValues => ({
...prevValues,
orgUnit,
}));
};

const onDeselectOrgUnit = () => {
setRelatedStagesDataValues(prevValues => ({
...prevValues,
orgUnit: null,
}));
};

return (
<div className={classes.wrapper}>
<div>
<OrgUnitSelectorForRelatedStages
relatedStagesDataValues={relatedStagesDataValues}
onSelectOrgUnit={onSelectOrgUnit}
onDeselectOrgUnit={onDeselectOrgUnit}
errorMessages={errorMessages}
saveAttempted={saveAttempted}
/>
</div>
<div className={classes.infoBox}>
<IconInfo16 />
{i18n.t(
relatedStagesDataValues?.orgUnit?.name
? 'Enter {{linkableStageLabel}} details for {{orgUnitLabel}} in the next step after completing this {{currentStageLabel}}.'
: 'Select organisation unit and enter {{linkableStageLabel}} details in the next step after completing this {{currentStageLabel}}.',
{
linkableStageLabel,
currentStageLabel,
orgUnitLabel: relatedStagesDataValues?.orgUnit?.name,
},
)}
</div>
</div>
);
};

export const EnterDataInOrgUnit: ComponentType<$Diff<Props, CssClasses>> = withStyles(styles)(EnterDataInOrgUnitPlain);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// @flow
export { EnterDataInOrgUnit } from './EnterData.component';
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,4 @@ export const LinkToExistingPlain = ({
);
};

export const LinkToExisting =
withStyles(styles)(LinkToExistingPlain);
export const LinkToExisting = withStyles(styles)(LinkToExistingPlain);
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @flow
import React, { type ComponentType, useMemo } from 'react';
import i18n from '@dhis2/d2-i18n';
import { Button, colors, IconInfo16, Radio, spacers, spacersNum } from '@dhis2/ui';
import { Button, colors, Radio, spacers, spacersNum } from '@dhis2/ui';
import { withStyles } from '@material-ui/core';
import { ConditionalTooltip } from 'capture-core/components/Tooltips/ConditionalTooltip';
import { actions as RelatedStagesActionTypes, mainOptionTranslatedTexts, relatedStageStatus } from '../constants';
Expand All @@ -11,6 +11,7 @@ import { ScheduleInOrgUnit } from '../ScheduleInOrgUnit';
import { useProgramStageInfo } from '../../../metaDataMemoryStores/programCollection/helpers';
import type { Props } from './RelatedStagesActions.types';
import { LinkToExisting } from '../LinkToExisting';
import { EnterDataInOrgUnit } from '../EnterDataInOrgUnit/EnterData.component';

const styles = () => ({
wrapper: {
Expand All @@ -37,15 +38,6 @@ const styles = () => ({
clearSelections: {
padding: spacers.dp8,
},
infoBox: {
margin: '8px 8px',
display: 'flex',
fontSize: '14px',
gap: '5px',
background: colors.grey100,
padding: '12px 8px',
border: `1px solid ${colors.grey600}`,
},
});

export const RelatedStagesActionsPlain = ({
Expand Down Expand Up @@ -171,16 +163,14 @@ export const RelatedStagesActionsPlain = ({
)}

{selectedAction === RelatedStagesActionTypes.ENTER_DATA && (
<div className={classes.infoBox}>
<IconInfo16 />
{i18n.t(
'Enter {{linkableStageLabel}} details in the next step after completing this {{currentStageLabel}}.',
{
linkableStageLabel: programStage.stageForm.name,
currentStageLabel,
},
)}
</div>
<EnterDataInOrgUnit
linkableStageLabel={programStage.stageForm.name}
relatedStagesDataValues={relatedStagesDataValues}
setRelatedStagesDataValues={setRelatedStagesDataValues}
currentStageLabel={currentStageLabel}
saveAttempted={saveAttempted}
errorMessages={errorMessages}
/>
)}

{selectedAction === RelatedStagesActionTypes.LINK_EXISTING_RESPONSE && (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// @flow
export { ScheduleInOrgUnit } from './ScheduleInOrgUnit.container';
export { ScheduleInOrgUnit } from './ScheduleInOrgUnit.component';
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,23 @@ const scheduleInOrgUnit = (props) => {
return scheduledAtIsValid && orgUnitIsValid;
};

const enterData = (props) => {
const { orgUnit, setErrorMessages } = props ?? {};
const orgUnitIsValid = isValidOrgUnit(orgUnit);

if (!orgUnitIsValid) {
setErrorMessages({
orgUnit: i18n.t('Please provide a valid organisation unit'),
});
} else {
setErrorMessages({
orgUnit: null,
});
}

return orgUnitIsValid;
};

const linkToExistingResponse = (props) => {
const { linkedEventId, setErrorMessages } = props ?? {};
const linkedEventIdIsValid = !!linkedEventId;
Expand All @@ -64,7 +81,7 @@ const linkToExistingResponse = (props) => {

export const ValidationFunctionsByLinkMode: { [key: string]: (props: ?Props) => boolean } = {
[RelatedStageModes.SCHEDULE_IN_ORG]: props => scheduleInOrgUnit(props),
[RelatedStageModes.ENTER_DATA]: () => true,
[RelatedStageModes.ENTER_DATA]: props => enterData(props),
[RelatedStageModes.LINK_EXISTING_RESPONSE]: props => linkToExistingResponse(props),
};

0 comments on commit bf2f1ca

Please sign in to comment.