From b05947d999fd91a89205d4c8f92b08bed7bf0126 Mon Sep 17 00:00:00 2001 From: Lucy Jemutai <130601439+lucyjemutai@users.noreply.github.com> Date: Mon, 2 Dec 2024 10:59:56 +0300 Subject: [PATCH] (Refactor) Ensure that Infant status outcomes show for infants on the infant banner (#1935) * code refactor and ensure that Infant status outcomes showing on infant banner * update test * make 'dead' outcome a string --------- Co-authored-by: Lucy Jemutai --- .../banner-tags/.patient-status-tag.test.tsx | 112 ++++-------------- .../patient-status-tag.component.tsx | 48 ++++---- packages/esm-commons-lib/src/index.ts | 5 +- packages/esm-commons-lib/src/routes.json | 5 - packages/esm-ohri-pmtct-app/src/index.ts | 5 + .../banner-tags/banner-tags.component.tsx | 53 +++++++++ .../banner-tags/useInfantFinalOutcome.ts | 0 .../banner-tags/usePatientFamilyNames.ts | 0 packages/esm-ohri-pmtct-app/src/routes.json | 5 +- 9 files changed, 103 insertions(+), 130 deletions(-) create mode 100644 packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/banner-tags.component.tsx rename packages/{esm-commons-lib/src/components => esm-ohri-pmtct-app/src/pmtct/patient-chart}/banner-tags/useInfantFinalOutcome.ts (100%) rename packages/{esm-commons-lib/src/components => esm-ohri-pmtct-app/src/pmtct/patient-chart}/banner-tags/usePatientFamilyNames.ts (100%) diff --git a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx b/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx index ed87b20c7..f4331cec0 100644 --- a/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx +++ b/packages/esm-commons-lib/src/components/banner-tags/.patient-status-tag.test.tsx @@ -3,23 +3,14 @@ import { render, screen } from '@testing-library/react'; import '@testing-library/jest-dom'; import { PatientStatusBannerTag } from './patient-status-tag.component'; import { usePatientHivStatus } from './patientHivStatus'; -import { usePatientOutcome } from './useInfantFinalOutcome'; -import { usePatientFamilyNames } from './usePatientFamilyNames'; jest.mock('./patientHivStatus', () => ({ usePatientHivStatus: jest.fn(), })); -jest.mock('./useInfantFinalOutcome', () => ({ - usePatientOutcome: jest.fn(), -})); - -jest.mock('./usePatientFamilyNames', () => ({ - usePatientFamilyNames: jest.fn(), -})); - describe('PatientStatusBannerTag', () => { const hivPositiveSampleUuid = '138571AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'; + const patientUuid = '22ab3fdb-1510-4675-85aa-f180064de450'; beforeEach(() => { jest.clearAllMocks(); @@ -32,19 +23,6 @@ describe('PatientStatusBannerTag', () => { isError: false, }); - (usePatientOutcome as jest.Mock).mockReturnValue({ - patientOutcome: null, - }); - - (usePatientFamilyNames as jest.Mock).mockReturnValue({ - childrenNames: [], - motherName: null, - patientAge: null, - patientGender: null, - isLoading: true, - isError: false, - }); - const { container } = render(); expect(container.firstChild).toBeNull(); }); @@ -56,22 +34,8 @@ describe('PatientStatusBannerTag', () => { isError: false, }); - (usePatientOutcome as jest.Mock).mockReturnValue({ - patientOutcome: 'Still in Care', - }); - - (usePatientFamilyNames as jest.Mock).mockReturnValue({ - childrenNames: [], - motherName: null, - patientAge: null, - patientGender: null, - isLoading: false, - isError: false, - }); - render(); expect(screen.getByText('HIV Positive')).toBeInTheDocument(); - expect(screen.getByText('Still in Care')).toBeInTheDocument(); }); it('should display the correct tag for HIV negative status', () => { @@ -81,69 +45,33 @@ describe('PatientStatusBannerTag', () => { isError: false, }); - (usePatientOutcome as jest.Mock).mockReturnValue({ - patientOutcome: 'HIV negative infant discharged from PMTCT', - }); - - (usePatientFamilyNames as jest.Mock).mockReturnValue({ - childrenNames: [], - motherName: null, - patientAge: null, - patientGender: null, - isLoading: false, - isError: false, - }); - render(); expect(screen.getByText('HIV Negative')).toBeInTheDocument(); - expect(screen.getByText('HIV negative infant discharged from PMTCT')).toBeInTheDocument(); }); - it('should display mother’s name on the Infant banner', () => { - (usePatientHivStatus as jest.Mock).mockReturnValue({ - hivStatus: 'negative', - isLoading: false, - isError: false, - }); - - (usePatientOutcome as jest.Mock).mockReturnValue({ - patientOutcome: 'Still in Care', - }); - - (usePatientFamilyNames as jest.Mock).mockReturnValue({ - childrenNames: [], - motherName: 'Jane Doe', - patientAge: 10, - patientGender: 'M', - isLoading: false, - isError: false, - }); + it('should display the correct outcome tag', () => { + render(); + expect(screen.getByText('Dead')).toBeInTheDocument(); + }); - render(); + it('should display the mother tag', () => { + render(); expect(screen.getByText('Mother: Jane Doe')).toBeInTheDocument(); }); - it('should show an error message when there is an error fetching data', () => { - (usePatientHivStatus as jest.Mock).mockReturnValue({ - hivStatus: null, - isLoading: false, - isError: false, - }); - - (usePatientOutcome as jest.Mock).mockReturnValue({ - patientOutcome: null, - }); - - (usePatientFamilyNames as jest.Mock).mockReturnValue({ - childrenNames: [], - motherName: null, - patientAge: null, - patientGender: null, - isLoading: false, - isError: true, - }); + it('should not display children tag if childrenNames is empty', () => { + render(); + expect(screen.queryByText('Children:')).toBeNull(); + }); - render(); - expect(screen.getByText('Error fetching family information')).toBeInTheDocument(); + it('should display children tag for female patients', () => { + render( + , + ); + expect(screen.getByText('Children: Mark obadi || Grace Obadi')).toBeInTheDocument(); }); }); diff --git a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx index b47f84d2f..1e5b4e938 100644 --- a/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx +++ b/packages/esm-commons-lib/src/components/banner-tags/patient-status-tag.component.tsx @@ -2,48 +2,40 @@ import React from 'react'; import { Tag } from '@carbon/react'; import { useTranslation } from 'react-i18next'; import { usePatientHivStatus } from './patientHivStatus'; -import { usePatientOutcome } from './useInfantFinalOutcome'; -import { usePatientFamilyNames } from './usePatientFamilyNames'; -export function PatientStatusBannerTag({ patientUuid }) { +interface PatientStatusBannerTagProps { + patientUuid: string; + outcomeTagColor?: string; + mappedOutcome?: string; + motherName?: string; + childrenNames?: string[]; + patientGender?: string; +} + +export const PatientStatusBannerTag: React.FC = ({ + patientUuid, + outcomeTagColor, + mappedOutcome, + motherName, + childrenNames, + patientGender, +}) => { const { t } = useTranslation(); const { hivStatus } = usePatientHivStatus(patientUuid); - const { patientOutcome } = usePatientOutcome(patientUuid); - - const greenOutcomes = ['Still in Care', 'HIV negative infant discharged from PMTCT']; - const redOutcomes = ['Confirmed HIV positive', 'Lost to follow up', 'Dead', 'Transferred out']; - - let outcomeTagColor = ''; - if (greenOutcomes.includes(patientOutcome)) { - outcomeTagColor = 'green'; - } else if (redOutcomes.includes(patientOutcome)) { - outcomeTagColor = 'red'; - } - - const { childrenNames, motherName, patientGender, isLoading, isError } = usePatientFamilyNames(patientUuid); - - if (isLoading) { - return null; - } - - if (isError) { - return
Error fetching family information
; - } - return ( <> {hivStatus === 'positive' && {t('hivPositive', 'HIV Positive')}} {hivStatus === 'negative' && {t('hivNegative', 'HIV Negative')}} - {patientOutcome && outcomeTagColor && {patientOutcome}} + {mappedOutcome && outcomeTagColor && {mappedOutcome}} {motherName && Mother: {motherName}} {patientGender === 'F' && childrenNames.length > 0 && ( - Children: {childrenNames.join(' || ')} + Children: {childrenNames.join(' || ')} )} ); -} +}; diff --git a/packages/esm-commons-lib/src/index.ts b/packages/esm-commons-lib/src/index.ts index 67755c5c3..a82e43add 100644 --- a/packages/esm-commons-lib/src/index.ts +++ b/packages/esm-commons-lib/src/index.ts @@ -1,7 +1,7 @@ import { FormEngine } from '@openmrs/openmrs-form-engine-lib'; import { defineConfigSchema, getSyncLifecycle } from '@openmrs/esm-framework'; -import { PatientStatusBannerTag } from './components/banner-tags/patient-status-tag.component'; import { configSchema } from './config.schema'; +import { PatientStatusBannerTag } from './components/banner-tags/patient-status-tag.component'; export * from './constants'; export * from './api.resource'; @@ -30,6 +30,7 @@ export * from './components/patient-lists/patient-list.component'; export * from './components/tile/ohri-programme-summary-tiles.component'; export * from './components/tile/ohri-summary-tile-tablet.component'; export * from './components/tile/ohri-summary-tile.component'; +export * from './components/banner-tags/patient-status-tag.component'; export * from './utils/compare'; export * from './utils/createOHRIDashboardLink'; export * from './utils/createNewOHRIDashboardLink'; @@ -72,5 +73,3 @@ export function startupApp() { // t('ohriForms', "OHRI Forms") export const ohriFormsWorkspace = getSyncLifecycle(FormEngine, options); - -export const patientStatusBannerTagExtension = getSyncLifecycle(PatientStatusBannerTag, options); diff --git a/packages/esm-commons-lib/src/routes.json b/packages/esm-commons-lib/src/routes.json index dc4ce73aa..a77f4b060 100644 --- a/packages/esm-commons-lib/src/routes.json +++ b/packages/esm-commons-lib/src/routes.json @@ -5,11 +5,6 @@ }, "pages": [], "extensions": [ - { - "name": "patient-status-banner-tag", - "slot": "patient-banner-tags-slot", - "component": "patientStatusBannerTagExtension" - } ], "workspaces": [ { diff --git a/packages/esm-ohri-pmtct-app/src/index.ts b/packages/esm-ohri-pmtct-app/src/index.ts index e021d3b47..d72301f58 100644 --- a/packages/esm-ohri-pmtct-app/src/index.ts +++ b/packages/esm-ohri-pmtct-app/src/index.ts @@ -101,3 +101,8 @@ export const maternalChildDashboard = getSyncLifecycle(OHRIHome, { export const ptrackerReportNavLink = getSyncLifecycle(ptrackerdashboardPath, options); export const patientStatusBannerTagExtension = getSyncLifecycle(PatientStatusBannerTag, options); + +export const pmtctBannerTagExtension = getAsyncLifecycle( + () => import('./pmtct/patient-chart/banner-tags/banner-tags.component'), + options, +) diff --git a/packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/banner-tags.component.tsx b/packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/banner-tags.component.tsx new file mode 100644 index 000000000..8072278a1 --- /dev/null +++ b/packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/banner-tags.component.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { usePatientOutcome } from './useInfantFinalOutcome'; +import { usePatientFamilyNames } from './usePatientFamilyNames'; +import { PatientStatusBannerTag } from '@ohri/openmrs-esm-ohri-commons-lib'; + +interface MotherChildTagProps { + patientUuid: string; +} + +const MotherChildTag: React.FC = ({ patientUuid }) => { + const { t } = useTranslation(); + + const { patientOutcome } = usePatientOutcome(patientUuid); + const { childrenNames, motherName, patientGender, isLoading, isError } = usePatientFamilyNames(patientUuid); + + if (isLoading) { + return null; + } + + if (isError) { + console.error('Error fetching family information'); + return null; + } + + const outcomeColorMapping: { [key: string]: string } = { + 'Still in Care': 'green', + 'HIV negative infant discharged from PMTCT': 'green', + 'Lost to followup': 'red', + 'Dead': 'red', + 'Transferred out': 'red', + 'Transfer in': 'red', + 'Confirmed HIV positive': 'red', + }; + + const outcomeTagColor = outcomeColorMapping[patientOutcome] || 'gray'; + //Not to future self -- transfer in shouldnt be confirmed HIV positive + const mappedOutcome = + patientOutcome === 'Transfer in' ? t('confirmedHivPositive', 'Confirmed HIV Positive') : patientOutcome; + + return ( + + ); +}; + +export default MotherChildTag; diff --git a/packages/esm-commons-lib/src/components/banner-tags/useInfantFinalOutcome.ts b/packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/useInfantFinalOutcome.ts similarity index 100% rename from packages/esm-commons-lib/src/components/banner-tags/useInfantFinalOutcome.ts rename to packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/useInfantFinalOutcome.ts diff --git a/packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts b/packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/usePatientFamilyNames.ts similarity index 100% rename from packages/esm-commons-lib/src/components/banner-tags/usePatientFamilyNames.ts rename to packages/esm-ohri-pmtct-app/src/pmtct/patient-chart/banner-tags/usePatientFamilyNames.ts diff --git a/packages/esm-ohri-pmtct-app/src/routes.json b/packages/esm-ohri-pmtct-app/src/routes.json index 1db566250..7fc7337cc 100644 --- a/packages/esm-ohri-pmtct-app/src/routes.json +++ b/packages/esm-ohri-pmtct-app/src/routes.json @@ -6,10 +6,11 @@ "pages": [], "extensions": [ { - "name": "patient-status-banner-tag", + "name": "pmtct-status-banner-tag", "slot": "patient-banner-tags-slot", - "component": "patientStatusBannerTagExtension" + "component": "pmtctBannerTagExtension" }, + { "name": "maternal-child-health-results-summary", "slot": "homepage-dashboard-slot",