-
Notifications
You must be signed in to change notification settings - Fork 246
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
(feat) O3-4040: Add delete ability to program enrollments #2133
base: main
Are you sure you want to change the base?
(feat) O3-4040: Add delete ability to program enrollments #2133
Conversation
…dit" and "delete" options for individual programs
…t button and the new delete button
…ved(clicking on the overflow menu) to get to the "edit" button
@vasharma05 @denniskigen can you please review this for me |
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.
Nice work, @PiusKariuki ! The main thing is to clean up the user-facing text. We don't want to scare users by making them think they might be deleting a whole program, when they are in fact just deleting the patient's enrollment.
packages/esm-patient-programs-app/src/programs/program-actions-menu.scss
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/delete-program.modal.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/delete-program.modal.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/delete-program.modal.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/delete-program.modal.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/delete-program.modal.tsx
Outdated
Show resolved
Hide resolved
@brandones @denniskigen . I resolved the failing E2E and suggestions too. Please review and revert incase of any more feedback |
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.
Thank you @PiusKariuki! A few minor nitpicks
beforeEach(() => { | ||
jest.clearAllMocks(); | ||
}); |
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.
Also please note this.
jest.mock('@openmrs/esm-framework', () => ({ | ||
showSnackbar: jest.fn(), | ||
getCoreTranslation: jest.fn((key, defaultText) => defaultText), | ||
})); |
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 please update the mocks
…to feat/delete-programs-feature
packages/esm-patient-programs-app/src/programs/delete-program-modal.test.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/program-actions-menu.component.test.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/program-actions-menu.component.test.tsx
Outdated
Show resolved
Hide resolved
packages/esm-patient-programs-app/src/programs/program-actions-menu.component.test.tsx
Outdated
Show resolved
Hide resolved
@@ -29,16 +28,12 @@ import { | |||
import { CardHeader, EmptyState, ErrorState, launchPatientWorkspace } from '@openmrs/esm-patient-common-lib'; | |||
import { findLastState, usePrograms } from './programs.resource'; | |||
import styles from './programs-detailed-summary.scss'; | |||
import { ProgramsActionsMenu } from './programs-actions-menu.component'; |
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.
I think the correct name for this component and file should be ProgramsActionMenu
and programs-action-menu.component
respectively.
@@ -158,10 +153,12 @@ const ProgramsDetailedSummary: React.FC<ProgramsDetailedSummaryProps> = ({ patie | |||
{rows.map((row, i) => ( | |||
<TableRow key={row.id}> |
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.
<TableRow key={row.id}> | |
<TableRow key={row.id} {...getRowProps({ row })}> |
@@ -158,10 +153,12 @@ const ProgramsDetailedSummary: React.FC<ProgramsDetailedSummaryProps> = ({ patie | |||
{rows.map((row, i) => ( | |||
<TableRow key={row.id}> | |||
{row.cells.map((cell) => ( | |||
<TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell> | |||
<TableCell className="cds--table-column-menu" key={cell.id}> |
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.
<TableCell className="cds--table-column-menu" key={cell.id}> | |
<TableCell key={cell.id}> |
cds--table-column-menu
isn't strictly necessary here.
))} | ||
<TableCell className="cds--table-column-menu"> | ||
<ProgramEditButton programEnrollmentId={enrollments[i]?.uuid} t={t} /> | ||
<TableCell> |
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.
But it is here to ensure the OverflowMenu takes up the appropriate amount of space.
<TableCell> | |
<TableCell className="cds--table-column-menu"> |
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 and all it's related files should be renamed to programs-action-menu
for consistency.
[programEnrollmentId], | ||
); | ||
|
||
const launchDeleteProgramDialog = () => { |
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.
We can wrap this in a useCallback
.
}; | ||
|
||
return ( | ||
<Layer> |
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.
<Layer> | |
<Layer className={styles.layer}> |
And then the associated styles would look something like this:
.layer {
height: 100%;
:global(.cds--overflow-menu) {
min-height: unset;
}
}
.menuItem {
max-width: none;
}
This will make your UI visually consistent with other flows like the Conditions edit experience.
<OverflowMenu | ||
name={t('editOrDeleteProgram', 'Edit or delete program')} | ||
aria-label={t('editOrDeleteProgram', 'Edit or delete program')} | ||
size={isTablet ? 'lg' : 'sm'} | ||
flipped | ||
> |
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.
<OverflowMenu | |
name={t('editOrDeleteProgram', 'Edit or delete program')} | |
aria-label={t('editOrDeleteProgram', 'Edit or delete program')} | |
size={isTablet ? 'lg' : 'sm'} | |
flipped | |
> | |
<OverflowMenu | |
align="left" | |
aria-label={t('editOrDeleteProgram', 'Edit or delete program')} | |
flipped | |
size={isTablet ? 'lg' : 'sm'} | |
> |
The OverflowMenu
should be left-aligned so it's content does not flow over the width of the datatable. Additionally, we should remove the name
prop as it's not a known prop of the OverflowMenu component.
<OverflowMenuItem id="editProgram" onClick={launchEditProgramsForm} itemText={t('edit', 'Edit')} /> | ||
<OverflowMenuItem id="deleteProgam" onClick={launchDeleteProgramDialog} itemText={t('delete', 'Delete')} /> |
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.
<OverflowMenuItem id="editProgram" onClick={launchEditProgramsForm} itemText={t('edit', 'Edit')} /> | |
<OverflowMenuItem id="deleteProgam" onClick={launchDeleteProgramDialog} itemText={t('delete', 'Delete')} /> | |
<OverflowMenuItem | |
className={styles.menuItem} | |
id="editProgram" | |
onClick={launchEditProgramsForm} | |
itemText={t('edit', 'Edit')} | |
/> | |
<OverflowMenuItem | |
className={styles.menuItem} | |
hasDivider | |
id="deleteProgam" | |
isDelete | |
onClick={launchDeleteProgramDialog} | |
itemText={t('delete', 'Delete')} | |
/> |
<TableCell className="cds--table-column-menu"> | ||
<ProgramEditButton programEnrollmentId={enrollments[i]?.uuid} t={t} /> | ||
<TableCell> | ||
<ProgramsActionsMenu patientUuid={patientUuid} programEnrollmentId={enrollments[i]?.uuid} /> |
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.
We should add this to the ProgramsOverview
component as well for consistency.
showSnackbar({ | ||
isLowContrast: true, | ||
kind: 'success', | ||
title: t('programDeleted', 'Program enrollment deleted'), |
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.
title: t('programDeleted', 'Program enrollment deleted'), | |
title: t('programEnrollmentDeleted', 'Program enrollment deleted'), |
<Button kind="secondary" onClick={closeDeleteModal}> | ||
{getCoreTranslation('cancel', 'Cancel')} | ||
</Button> | ||
<Button kind="danger" onClick={handleDelete} disabled={isDeleting}> |
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.
<Button kind="danger" onClick={handleDelete} disabled={isDeleting}> | |
<Button className={styles.deleteButton} kind="danger" onClick={handleDelete} disabled={isDeleting}> |
And the styles for that would be:
@use '@carbon/layout';
@use '@carbon/type';
.deleteButton {
:global(.cds--inline-loading) {
min-height: layout.$spacing-05;
}
:global(.cds--inline-loading__text) {
@include type.type-style('body-01');
}
}
export function deleteProgramEnrollment(programEnrollmentUuid: string) { | ||
return openmrsFetch(`${restBaseUrl}/programenrollment/${programEnrollmentUuid}`, { | ||
method: 'DELETE', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
}); | ||
} |
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.
export function deleteProgramEnrollment(programEnrollmentUuid: string) { | |
return openmrsFetch(`${restBaseUrl}/programenrollment/${programEnrollmentUuid}`, { | |
method: 'DELETE', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
}); | |
} | |
export function deleteProgramEnrollment(programEnrollmentUuid: string) { | |
const abortController = new AbortController(); | |
return openmrsFetch(`${restBaseUrl}/programenrollment/${programEnrollmentUuid}`, { | |
method: 'DELETE', | |
headers: { | |
'Content-Type': 'application/json', | |
}, | |
signal: abortController.signal | |
}); | |
} |
Requirements
Summary
This PR adds DELETE ability to program enrollments
Screenshots
Related Issue
https://openmrs.atlassian.net/browse/O3-4040
Other