diff --git a/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature b/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature index f5db1e30e2..faca6d2e4c 100644 --- a/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature +++ b/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage.feature @@ -96,3 +96,8 @@ Feature: The user interacts with the widgets on the enrollment add event page When you click switch tab to Schedule Then you should see Schedule tab And you should see suggested date: 08-01 + + Scenario: You can assign a user when scheduling an event + Given you land on the enrollment edit event page by having typed /#/enrollmentEventNew?enrollmentId=zRfAPUpjoG3&orgUnitId=DiszpKrYNg8&programId=M3xtLkYBlKI&stageId=uvMKOn1oWvd&teiId=S3JjTA4QMNe + When you click switch tab to Schedule + Then you can assign a user when scheduling the event diff --git a/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js b/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js index 1640f4243c..e70a5bbd68 100644 --- a/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js +++ b/cypress/integration/WidgetsForEnrollmentPages/WidgetsForEnrollmentAddEventPage/index.js @@ -2,3 +2,14 @@ import '../sharedSteps'; import '../WidgetEnrollment'; import '../WidgetProfile'; import '../WidgetTab'; + +Then('you can assign a user when scheduling the event', () => { + cy.get('[data-test="assignee-section"]').within(() => { + cy.get('[data-test="capture-ui-input"]').click(); + cy.get('[data-test="capture-ui-input"]').type('Tracker demo'); + cy.contains('Tracker demo User').click(); + }); + cy.get('[data-test="assignee-section"]').within(() => { + cy.get('[data-test="dhis2-uicore-chip"]').contains('Tracker demo User').should('exist'); + }); +}); diff --git a/i18n/en.pot b/i18n/en.pot index e179d736a4..bc3b72d48c 100644 --- a/i18n/en.pot +++ b/i18n/en.pot @@ -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: 2023-09-04T07:07:59.195Z\n" -"PO-Revision-Date: 2023-09-04T07:07:59.195Z\n" +"POT-Creation-Date: 2023-09-25T08:33:17.277Z\n" +"PO-Revision-Date: 2023-09-25T08:33:17.277Z\n" msgid "Choose one or more dates..." msgstr "Choose one or more dates..." diff --git a/src/core_modules/capture-core/components/FormFields/UserField/index.js b/src/core_modules/capture-core/components/FormFields/UserField/index.js index 3e88ffe311..e534c4387a 100644 --- a/src/core_modules/capture-core/components/FormFields/UserField/index.js +++ b/src/core_modules/capture-core/components/FormFields/UserField/index.js @@ -1,2 +1,3 @@ // @flow export { UserField } from './UserField.component'; +export type { User as UserFormField } from './types'; diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.component.js b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.component.js new file mode 100644 index 0000000000..9c92ecf460 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.component.js @@ -0,0 +1,38 @@ +// @flow +import React from 'react'; +import i18n from '@dhis2/d2-i18n'; +import { withStyles } from '@material-ui/core/styles'; +import { UserField } from '../../FormFields/UserField/UserField.component'; +import type { Props } from './Assignee.types'; + +const getStyles = () => ({ + container: { + display: 'flex', + alignItems: 'center', + padding: '8px 8px 8px 12px', + }, + label: { + fontSize: 14, + flexBasis: 200, + color: '#212934', + }, + field: { + flexBasis: 150, + flexGrow: 1, + }, +}); + +const AssigneePlain = (props: Props) => { + const { classes, assignee, ...passOnProps } = props; + return ( +
+
{i18n.t('Assignee')}
+
+ {/* $FlowFixMe[cannot-spread-inexact] automated comment */} + +
+
+ ); +}; + +export const Assignee = withStyles(getStyles)(AssigneePlain); diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.types.js b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.types.js new file mode 100644 index 0000000000..fdbbccd9f2 --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/Assignee.types.js @@ -0,0 +1,7 @@ +// @flow +import type { UserFormField } from '../../FormFields/UserField'; + +export type Props = { + ...CssClasses, + assignee?: UserFormField, +}; diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/index.js b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/index.js new file mode 100644 index 0000000000..0af6b7501f --- /dev/null +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/Assignee/index.js @@ -0,0 +1,2 @@ +// @flow +export { Assignee } from './Assignee.component'; diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.actions.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.actions.js index b1e092d37f..6dc9c0a5bc 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.actions.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.actions.js @@ -21,6 +21,7 @@ export const requestScheduleEvent = ({ onSaveExternal, onSaveSuccessActionType, onSaveErrorActionType, + assignedUser, }: { scheduleDate: string, comments: Array<{value: string}>, @@ -34,6 +35,7 @@ export const requestScheduleEvent = ({ onSaveExternal: (eventServerValues: Object, uid: string) => void, onSaveSuccessActionType?: string, onSaveErrorActionType?: string, + assignedUser?: {uid: string}, }) => actionCreator(scheduleEventWidgetActionTypes.EVENT_SCHEDULE_REQUEST)({ scheduleDate, @@ -48,6 +50,7 @@ export const requestScheduleEvent = ({ onSaveExternal, onSaveSuccessActionType, onSaveErrorActionType, + assignedUser, }); export const scheduleEvent = ( diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js index e68f737994..ca2a1f7fbb 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.component.js @@ -10,7 +10,7 @@ import { ScheduleText } from './ScheduleText'; import { CommentSection } from '../WidgetComment'; import type { Props } from './widgetEventSchedule.types'; import { CategoryOptions } from './CategoryOptions/CategoryOptions.component'; - +import { Assignee } from './Assignee'; const styles = () => ({ wrapper: { @@ -66,9 +66,12 @@ const WidgetEventSchedulePlain = ({ suggestedScheduleDate, comments, programCategory, + enableUserAssignment, selectedCategories, onClickCategoryOption, onResetCategoryOption, + onSetAssignee, + assignee, categoryOptionsError, ...passOnProps }: Props) => ( @@ -119,6 +122,11 @@ const WidgetEventSchedulePlain = ({ handleAddComment={onAddComment} /> + {enableUserAssignment && ( + + + + )} { @@ -119,6 +122,7 @@ export const WidgetEventSchedule = ({ setComments([...comments, newComment]); }; + const onSetAssignee = useCallback(user => setAssignee(user), []); const onClickCategoryOption = useCallback((optionId: string, categoryId: string) => { setSelectedCategories(prevCategoryOptions => ({ ...prevCategoryOptions, @@ -159,11 +163,13 @@ export const WidgetEventSchedule = ({ return ( diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.epics.js b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.epics.js index 62d9ffccf5..4dad5a415f 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.epics.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/WidgetEventSchedule.epics.js @@ -28,6 +28,7 @@ export const scheduleEnrollmentEventEpic = (action$: InputObservable, store: Red onSaveExternal, onSaveSuccessActionType, onSaveErrorActionType, + assignedUser, } = action.payload; const { events } = store.value; @@ -46,6 +47,7 @@ export const scheduleEnrollmentEventEpic = (action$: InputObservable, store: Red programStage: stageId, status: 'SCHEDULE', notes: comments ?? [], + assignedUser, }] }; if (attributeCategoryOptions) { diff --git a/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js b/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js index 85ef3325bb..f42a7e8f87 100644 --- a/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js +++ b/src/core_modules/capture-core/components/WidgetEventSchedule/widgetEventSchedule.types.js @@ -1,5 +1,6 @@ // @flow import type { ProgramCategory, CategoryOption } from './CategoryOptions/CategoryOptions.types'; +import type { UserFormField } from '../FormFields/UserField'; export type ContainerProps = {| programId: string, @@ -38,7 +39,10 @@ export type Props = {| selectedCategories?: ?{ [categoryId: string]: CategoryOption }, programCategory?: ProgramCategory, categoryOptionsError?: ?{[categoryId: string]: { touched: boolean, valid: boolean} }, + enableUserAssignment?: boolean, onSchedule: () => void, + onSetAssignee: (user: UserFormField) => void, + assignee?: UserFormField, onCancel: () => void, setScheduleDate: (date: string) => void, onAddComment: (comment: string) => void,