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

(fix) Tweaks to the Edit program enrollments flow #2226

Merged
merged 2 commits into from
Feb 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
}

.conditionLabel {
@include type.type-style('label-02');
@include type.type-style('body-compact-02');
}

.errorContainer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ export const ProgramsActionMenu = ({ patientUuid, programEnrollmentId }: Program
const isTablet = useLayoutType() === 'tablet';

const launchEditProgramsForm = useCallback(
() => launchPatientWorkspace('programs-form-workspace', { programEnrollmentId }),
[programEnrollmentId],
() =>
launchPatientWorkspace('programs-form-workspace', {
workspaceTitle: t('editProgramEnrollment', 'Edit program enrollment'),
programEnrollmentId,
}),
[programEnrollmentId, t],
);

const launchDeleteProgramDialog = useCallback(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ describe('ProgramActionsMenu', () => {

expect(launchPatientWorkspace).toHaveBeenCalledWith('programs-form-workspace', {
programEnrollmentId: testProps.programEnrollmentId,
workspaceTitle: 'Edit program enrollment',
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ describe('ProgramsDetailedSummary', () => {

expect(launchPatientWorkspace).toHaveBeenCalledWith('programs-form-workspace', {
programEnrollmentId: mockEnrolledProgramsResponse[0].uuid,
workspaceTitle: 'Edit program enrollment',
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@
min-width: 100%;
padding: 0;
}

.programName {
@include type.type-style('body-compact-02');
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import React, { useCallback, useEffect, useMemo } from 'react';
import classNames from 'classnames';
import { type TFunction, useTranslation } from 'react-i18next';
import dayjs from 'dayjs';
import {
Expand All @@ -8,6 +9,7 @@ import {
DatePickerInput,
Form,
FormGroup,
FormLabel,
InlineLoading,
InlineNotification,
Layer,
Expand All @@ -20,6 +22,7 @@ import { useForm, Controller, useWatch } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { parseDate, showSnackbar, useConfig, useLayoutType, useLocations, useSession } from '@openmrs/esm-framework';
import { type DefaultPatientWorkspaceProps } from '@openmrs/esm-patient-common-lib';
import { type ConfigObject } from '../config-schema';
import {
createProgramEnrollment,
useAvailablePrograms,
Expand Down Expand Up @@ -57,7 +60,8 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
const availableLocations = useLocations();
const { data: availablePrograms } = useAvailablePrograms();
const { data: enrollments, mutateEnrollments } = useEnrollments(patientUuid);
const { showProgramStatusField } = useConfig();
const { showProgramStatusField } = useConfig<ConfigObject>();
const inEditMode = Boolean(programEnrollmentId);

const programsFormSchema = useMemo(() => createProgramsFormSchema(t), [t]);

Expand All @@ -77,10 +81,10 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
});

const getLocationUuid = () => {
if (!currentEnrollment?.location.uuid && session?.sessionLocation?.uuid) {
if (!currentEnrollment?.location?.uuid && session?.sessionLocation?.uuid) {
return session?.sessionLocation?.uuid;
}
return currentEnrollment?.location.uuid ?? null;
return currentEnrollment?.location?.uuid ?? null;
};

const currentState = currentEnrollment ? findLastState(currentEnrollment.states) : null;
Expand Down Expand Up @@ -156,30 +160,34 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
[closeWorkspaceWithSavedChanges, currentEnrollment, currentState, mutateEnrollments, patientUuid, t],
);

const programName = (
<FormGroup legendText={t('programName', 'Program name')}>
<FormLabel className={styles.programName}>{currentProgram?.display}</FormLabel>
</FormGroup>
);

const programSelect = (
<Controller
name="selectedProgram"
control={control}
render={({ field: { onChange, value } }) => (
<>
<Select
aria-label="program name"
id="program"
invalid={!!errors?.selectedProgram}
invalidText={errors?.selectedProgram?.message}
labelText={t('programName', 'Program name')}
onChange={(event) => onChange(event.target.value)}
value={value}
>
<SelectItem text={t('chooseProgram', 'Choose a program')} value="" />
{eligiblePrograms?.length > 0 &&
eligiblePrograms.map((program) => (
<SelectItem key={program.uuid} text={program.display} value={program.uuid}>
{program.display}
</SelectItem>
))}
</Select>
</>
<Select
aria-label="program name"
id="program"
invalid={!!errors?.selectedProgram}
invalidText={errors?.selectedProgram?.message}
labelText={t('programName', 'Program name')}
onChange={(event) => onChange(event.target.value)}
value={value}
>
<SelectItem text={t('chooseProgram', 'Choose a program')} value="" />
{eligiblePrograms?.length > 0 &&
eligiblePrograms.map((program) => (
<SelectItem key={program.uuid} text={program.display} value={program.uuid}>
{program.display}
</SelectItem>
))}
</Select>
)}
/>
);
Expand Down Expand Up @@ -263,34 +271,38 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
name="selectedProgramStatus"
control={control}
render={({ field: { onChange, value } }) => (
<>
<Select
aria-label={t('programStatus', 'Program status')}
id="programStatus"
invalid={!!errors?.selectedProgramStatus}
invalidText={errors?.selectedProgramStatus?.message}
labelText={t('programStatus', 'Program status')}
onChange={(event) => onChange(event.target.value)}
value={value}
>
<SelectItem text={t('chooseStatus', 'Choose a program status')} value="" />
{workflowStates.map((state) => (
<SelectItem key={state.uuid} text={state.concept.display} value={state.uuid}>
{state.concept.display}
</SelectItem>
))}
</Select>
</>
<Select
aria-label={t('programStatus', 'Program status')}
id="programStatus"
invalid={!!errors?.selectedProgramStatus}
invalidText={errors?.selectedProgramStatus?.message}
labelText={t('programStatus', 'Program status')}
onChange={(event) => onChange(event.target.value)}
value={value}
>
<SelectItem text={t('chooseStatus', 'Choose a program status')} value="" />
{workflowStates.map((state) => (
<SelectItem key={state.uuid} text={state.concept.display} value={state.uuid}>
{state.concept.display}
</SelectItem>
))}
</Select>
)}
/>
);

const formGroups = [
{
style: { maxWidth: isTablet && '50%' },
legendText: '',
value: programSelect,
},
inEditMode
? {
style: { maxWidth: isTablet && '50%' },
legendText: '',
value: programName,
}
: {
style: { maxWidth: isTablet && '50%' },
legendText: '',
value: programSelect,
},
{
style: { maxWidth: '50%' },
legendText: '',
Expand Down Expand Up @@ -334,7 +346,7 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({
</FormGroup>
))}
</Stack>
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
<ButtonSet className={classNames(isTablet ? styles.tablet : styles.desktop)}>
<Button className={styles.button} kind="secondary" onClick={closeWorkspace}>
{t('cancel', 'Cancel')}
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import userEvent from '@testing-library/user-event';
import { screen } from '@testing-library/react';
import { screen, within } from '@testing-library/react';
import { openmrsFetch } from '@openmrs/esm-framework';
import { launchPatientWorkspace } from '@openmrs/esm-patient-common-lib';
import { mockCareProgramsResponse, mockEnrolledInAllProgramsResponse, mockEnrolledProgramsResponse } from '__mocks__';
Expand Down Expand Up @@ -77,16 +77,27 @@ describe('ProgramsOverview', () => {
expect(nextPageButton).toBeDisabled();
expect(previousPageButton).toBeInTheDocument();
expect(previousPageButton).toBeDisabled();
expect(screen.getByRole('row', { name: /HIV Care and Treatment/i })).toBeInTheDocument();
const row = screen.getByRole('row', { name: /HIV Care and Treatment/i });
expect(row).toBeInTheDocument();
const actionMenuButton = within(row).getByRole('button', { name: /options$/i });
expect(actionMenuButton).toBeInTheDocument();

// Clicking "Add" launches the programs form in a workspace
expect(addButton).toBeEnabled();
await user.click(addButton);

expect(launchPatientWorkspace).toHaveBeenCalledWith('programs-form-workspace');

await user.click(actionMenuButton);
await user.click(screen.getByText('Edit'));

expect(launchPatientWorkspace).toHaveBeenCalledWith('programs-form-workspace', {
programEnrollmentId: mockEnrolledProgramsResponse[0].uuid,
workspaceTitle: 'Edit program enrollment',
});
});

it('renders a notification when the patient is enrolled in all available programs', async () => {
it('renders a notification if the patient is already enrolled in all available programs', async () => {
mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockEnrolledInAllProgramsResponse } });
mockOpenmrsFetch.mockReturnValueOnce({ data: { results: mockCareProgramsResponse } });

Expand Down
1 change: 1 addition & 0 deletions packages/esm-patient-programs-app/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"deleting": "Deleting",
"edit": "Edit",
"editOrDeleteProgram": "Edit or delete program",
"editProgramEnrollment": "Edit program enrollment",
"enrollmentLocation": "Enrollment location",
"enrollmentNowVisible": "It is now visible in the Programs table",
"enrollmentSaved": "Program enrollment saved",
Expand Down
Loading