-
Notifications
You must be signed in to change notification settings - Fork 248
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) O3-2843: Ability to re-enroll in completed programs #1720
Conversation
@denniskigen Kindly feel free to review my PR before I proceed with the e2e test. Am not certain if am on the right track since I don't have a design. |
@jwnasambu Thanks for the work. From the gif, why are you editing enrollment date when you want to complete the program? |
@makombe I edited it because I wanted to a certain that the Add button is disabled when all the eligible/available programs are all enrolled and are in active state and confirm the 'Add' button is only activated when a program is marked as completed. Editing the enrolment date was the only way for me to confirm my questions. Thank you for pointing that out. Though that doesn't confirm that one is to edit the form to complete a program. Additionally, please feel free to guide me on the path I am supposed to take since I don't have a design to instruct me on the expected output. |
@makombe kindly what could be the way forward with this ticket please? |
@makombe please help with this |
@makombe that's how you complete a program. @jwnasambu your demo in the gif was good. Could you please resolve the conflicts? Regarding the UI, the only change that is definitely needed is that this banner should not appear if the add button is clickable. It's sending mixed signals to the user. |
Thanks @brandones for the review. Am going to push the fix before end of today. I have been seriously sick again but now am much better. |
Ok, please tag me in a comment when this is ready for re-review. And please include an updated UI screenshot or video. |
@brandones Kindly I updated everything basing on the requests you made. Its ready for review! N/B the second video above is the one with the updated changes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for working on this, @jwnasambu. I've left some suggestions.
const noCompletedPrograms = useMemo(() => { | ||
return enrollments?.every((program) => !program.dateCompleted); | ||
}, [enrollments]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about something like this instead for determining whether a patient is ineligible for new enrollments or re-enrollments to completed programs:
const isEnrolledInAllPrograms = useMemo(() => {
if (!availablePrograms?.length || !enrollments?.length) {
return false;
}
const activeEnrollments = enrollments.filter((enrollment) => !enrollment.dateCompleted);
return activeEnrollments.length === availablePrograms.length;
}, [availablePrograms, enrollments]);
@@ -100,21 +106,21 @@ const ProgramsDetailedSummary: React.FC<ProgramsDetailedSummaryProps> = ({ patie | |||
renderIcon={(props) => <Add size={16} {...props} />} | |||
iconDescription="Add programs" | |||
onClick={launchProgramsForm} | |||
disabled={availablePrograms?.length && eligiblePrograms?.length === 0} | |||
disabled={availablePrograms?.length && eligiblePrograms?.length === 0 && noCompletedPrograms} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
> | ||
{t('add', 'Add')} | ||
</Button> | ||
)} | ||
</CardHeader> | ||
{availablePrograms?.length && eligiblePrograms?.length === 0 ? ( | ||
{showInlineNotification && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{showInlineNotification && ( | |
{isEnrolledInAllPrograms && ( |
: filter( | ||
availablePrograms, | ||
(program) => | ||
!includes(map(enrollments, 'program.uuid'), program.uuid) || | ||
enrollments.some( | ||
(enrollment) => enrollment.program.uuid === program.uuid && enrollment.dateCompleted !== null, | ||
), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And how about doing this here instead:
const eligiblePrograms = currentProgram
? [currentProgram]
: filter(availablePrograms, (program) => {
const existingEnrollment = enrollments.find((enrollment) => enrollment.program.uuid === program.uuid);
return !existingEnrollment || existingEnrollment.dateCompleted !== null;
});
Which cleans up the logic a fair bit and makes it easier to add in custom implementation specific logic in the future for determining eligibility for enrollment.
@brandones, @denniskigen kindly feel free to review my PR please! |
447ffdb
to
8fa3fdb
Compare
8fa3fdb
to
3a8cc42
Compare
@@ -61,6 +61,54 @@ export const mockEnrolledProgramsResponse = [ | |||
}, | |||
]; | |||
|
|||
export const mockEnrolledInAllProgramsResponse = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to test the appearance of an error if there are no more programs left to enroll the patient in.
@@ -187,7 +166,7 @@ const ProgramsForm: React.FC<ProgramsFormProps> = ({ | |||
aria-label="program name" | |||
id="program" | |||
invalidText={t('required', 'Required')} | |||
labelText="" | |||
labelText={t('programName', 'Program name')} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These labels were not previously associated with their inputs correctly.
const onSubmit = React.useCallback( | ||
(data: ProgramsFormData) => { | ||
const onSubmit = useCallback( | ||
async (data: ProgramsFormData) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just cleans up the submit logic using async/await syntax.
export function getPatientProgramByUuid(programUuid: string) { | ||
return openmrsObservableFetch<PatientProgram>(`${restBaseUrl}/programenrollment/${programUuid}`).pipe( | ||
rxjsMap(({ data }) => data), | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this isn't being used anywhere.
export function createProgramEnrollment(payload, abortController) { | ||
if (!payload) { | ||
return null; | ||
} | ||
const { program, patient, dateEnrolled, dateCompleted, location } = payload; | ||
return openmrsObservableFetch(`${restBaseUrl}/programenrollment`, { | ||
return openmrsFetch(`${restBaseUrl}/programenrollment`, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Necessitated by refactoring the submit logic to use async/await syntax.
Thanks for working on this, @jwnasambu. |
Requirements
Summary
I fixed the ability of complete programs being able to be re-enrolled again by adjusting the condition of disabling the
Add
button and setting a condition enrollment.dateCompleted !== null checks whether a program enrollment has a completion date. If it has a completion date (not null), it means the program has been completed.Programs with completed enrollments will be included in eligiblePrograms, allowing them to be considered for re-enrollment.
Screenshots
Video before implementing proposed changes
screencast.2024-03-07.3.AM-36-34.mp4
Video with proposed changes
screencast.2024-07-02.2.PM-18-50.mp4
Related Issue
https://openmrs.atlassian.net/browse/O3-2843
Other