diff --git a/packages/esm-ward-app/src/types/index.ts b/packages/esm-ward-app/src/types/index.ts index f56540aec..9be5407cb 100644 --- a/packages/esm-ward-app/src/types/index.ts +++ b/packages/esm-ward-app/src/types/index.ts @@ -1,5 +1,6 @@ import type { Concept, + DefaultWorkspaceProps, Location, OpenmrsResource, OpenmrsResourceStrict, @@ -9,18 +10,39 @@ import type { } from '@openmrs/esm-framework'; import type React from 'react'; -export type WardPatientCardRow = React.FC; -export type WardPatientCardElement = React.FC; +export type WardPatientCard = React.FC; // WardPatient is a patient admitted to a ward, and/or in a bed on a ward export type WardPatient = { + /** + * The patient and their current visit. These values are taken either + * from either the inpatientAdmission object, the inpatientRequest object + * or the admissionLocation object (which contains the bed) + */ patient: Patient; visit: Visit; - bed?: Bed; - admitted: boolean; - encounterAssigningToCurrentInpatientLocation: Encounter; - firstAdmissionOrTransferEncounter: Encounter; + + /** + * the bed assigned to the patient. This object is only set if the patient + * has a bed assigned + */ + bed: Bed; + + /** + * The admission detail. This object is only set if the patient has been + * admitted to the ward + */ + inpatientAdmission: InpatientAdmission; + + /** + * The admission request. The object is only set if the patient has a + * pending admission / transfer request. + */ + inpatientRequest: InpatientRequest; }; +export interface WardPatientWorkspaceProps extends DefaultWorkspaceProps { + wardPatient: WardPatient; +} // server-side types defined in openmrs-module-bedmanagement: diff --git a/packages/esm-ward-app/src/ward-patient-card/colored-obs-tags-card-row/colored-obs-tags-card-row.extension.tsx b/packages/esm-ward-app/src/ward-patient-card/colored-obs-tags-card-row/colored-obs-tags-card-row.extension.tsx index b846e29ef..5a6178925 100644 --- a/packages/esm-ward-app/src/ward-patient-card/colored-obs-tags-card-row/colored-obs-tags-card-row.extension.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/colored-obs-tags-card-row/colored-obs-tags-card-row.extension.tsx @@ -1,10 +1,10 @@ -import React from 'react'; -import { type WardPatientCardExtensionProps } from '../ward-patient-card.component'; -import WardPatientCodedObsTags from '../row-elements/ward-patient-coded-obs-tags'; import { useConfig } from '@openmrs/esm-framework'; +import React from 'react'; import { type ColoredObsTagsCardRowConfigObject } from '../../config-schema-extension-colored-obs-tags'; +import { type WardPatientCard } from '../../types'; +import WardPatientCodedObsTags from '../row-elements/ward-patient-coded-obs-tags'; -const ColoredObsTagsCardRowExtension: React.FC = ({ patient, visit }) => { +const ColoredObsTagsCardRowExtension: WardPatientCard = ({ patient, visit }) => { const config = useConfig(); return ; diff --git a/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-bed-number.tsx b/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-bed-number.tsx index 48a08018c..389458e03 100644 --- a/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-bed-number.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-bed-number.tsx @@ -1,14 +1,8 @@ import React from 'react'; +import { type Bed } from '../../types'; import styles from '../ward-patient-card.scss'; -import { type WardPatientCardElement } from '../../types'; -export interface WardPatientBedNumberProps { - bed: { - bedNumber: string; - }; -} - -const WardPatientBedNumber: React.FC = ({ bed }) => { +const WardPatientBedNumber: React.FC<{ bed: Bed }> = ({ bed }) => { if (!bed) { return <>; } diff --git a/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-gender.component.tsx b/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-gender.component.tsx index 8127f3c56..ca61d8d30 100644 --- a/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-gender.component.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/row-elements/ward-patient-gender.component.tsx @@ -1,24 +1,27 @@ import { type Patient } from '@openmrs/esm-framework'; +import { type TFunction } from 'i18next'; import React from 'react'; import { useTranslation } from 'react-i18next'; const WardPatientGender: React.FC<{ patient: Patient }> = ({ patient }) => { const { t } = useTranslation(); - const getGender = (gender: string): string => { - switch (gender) { - case 'M': - return t('male', 'Male'); - case 'F': - return t('female', 'Female'); - case 'O': - return t('other', 'Other'); - case 'unknown': - return t('unknown', 'Unknown'); - default: - return gender; - } - }; - return
{getGender(patient?.person?.gender)}
; + + return
{getGender(t, patient?.person?.gender)}
; +}; + +export const getGender = (t: TFunction, gender: string): string => { + switch (gender) { + case 'M': + return t('male', 'Male'); + case 'F': + return t('female', 'Female'); + case 'O': + return t('other', 'Other'); + case 'unknown': + return t('unknown', 'Unknown'); + default: + return gender; + } }; export default WardPatientGender; diff --git a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card-element.component.tsx b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card-element.component.tsx index a690c8982..0f3f07d77 100644 --- a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card-element.component.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card-element.component.tsx @@ -1,34 +1,30 @@ +import { InlineNotification } from '@carbon/react'; +import { useConfig } from '@openmrs/esm-framework'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { InlineNotification } from '@carbon/react'; -import { type Patient, useConfig, type Visit } from '@openmrs/esm-framework'; import { type WardConfigObject } from '../config-schema'; +import { type WardPatient } from '../types'; import WardPatientAge from './row-elements/ward-patient-age'; +import WardPatientAddress from './row-elements/ward-patient-header-address'; +import WardPatientIdentifier from './row-elements/ward-patient-identifier'; +import WardPatientObs from './row-elements/ward-patient-obs'; import WardPatientTimeOnWard from './row-elements/ward-patient-time-on-ward'; import WardPatientTimeSinceAdmission from './row-elements/ward-patient-time-since-admission'; -import WardPatientObs from './row-elements/ward-patient-obs'; -import WardPatientIdentifier from './row-elements/ward-patient-identifier'; -import WardPatientAddress from './row-elements/ward-patient-header-address'; -import { type Encounter } from '../types'; -export interface WardPatientCardElementProps { +export interface WardPatientCardElementProps extends WardPatient { elementId: string; - patient: Patient; - visit: Visit; - encounterAssigningToCurrentInpatientLocation: Encounter; - firstAdmissionOrTransferEncounter: Encounter; } export const WardPatientCardElement: React.FC = ({ elementId, patient, visit, - encounterAssigningToCurrentInpatientLocation, - firstAdmissionOrTransferEncounter, + inpatientAdmission, }) => { const { obsElementDefinitions, identifierElementDefinitions, addressElementDefinitions } = useConfig().wardPatientCards; const { t } = useTranslation(); + const { encounterAssigningToCurrentInpatientLocation, firstAdmissionOrTransferEncounter } = inpatientAdmission ?? {}; switch (elementId) { case 'patient-age': diff --git a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx index 0f828ef67..647fbd747 100644 --- a/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx +++ b/packages/esm-ward-app/src/ward-patient-card/ward-patient-card.component.tsx @@ -1,35 +1,15 @@ -import React, { useMemo } from 'react'; -import { type Bed, type Encounter } from '../types'; -import { WardPatientCardElement } from './ward-patient-card-element.component'; +import { ExtensionSlot, getPatientName, launchWorkspace } from '@openmrs/esm-framework'; +import classNames from 'classnames'; +import React from 'react'; import { useCurrentWardCardConfig } from '../hooks/useCurrentWardCardConfig'; -import styles from './ward-patient-card.scss'; -import { ExtensionSlot, getPatientName, launchWorkspace, type Patient, type Visit } from '@openmrs/esm-framework'; -import WardPatientName from './row-elements/ward-patient-name'; +import { type WardPatientCard, type WardPatientWorkspaceProps } from '../types'; import WardPatientBedNumber from './row-elements/ward-patient-bed-number'; -import classNames from 'classnames'; -import { type WardPatientWorkspaceProps } from '../ward-patient-workspace/types'; - -export interface WardPatientCardProps { - patient: Patient; - visit: Visit; - bed?: Bed; - admitted: boolean; - encounterAssigningToCurrentInpatientLocation: Encounter; - firstAdmissionOrTransferEncounter: Encounter; -} - -export interface WardPatientCardExtensionProps extends WardPatientCardProps { - patientUuid: string; -} +import WardPatientName from './row-elements/ward-patient-name'; +import { WardPatientCardElement } from './ward-patient-card-element.component'; +import styles from './ward-patient-card.scss'; -const WardPatientCard: React.FC = ({ - patient, - visit, - bed, - admitted, - firstAdmissionOrTransferEncounter, - encounterAssigningToCurrentInpatientLocation, -}) => { +const WardPatientCard: WardPatientCard = (wardPatient) => { + const { patient, bed } = wardPatient; const { id, headerRowElements, footerRowElements } = useCurrentWardCardConfig(); const headerExtensionSlotName = @@ -38,14 +18,6 @@ const WardPatientCard: React.FC = ({ const footerExtensionSlotName = id == 'default' ? 'ward-patient-card-footer-slot' : `ward-patient-card-footer-${id}-slot`; - const extensionSlotState = useMemo(() => { - return { - patient, - visit, - bed, - }; - }, [patient, visit, bed]); - return (
@@ -55,17 +27,14 @@ const WardPatientCard: React.FC = ({ ))} - +
@@ -73,25 +42,16 @@ const WardPatientCard: React.FC = ({ ))} - +
); -} +}; + +const PatientWorkspaceTitle: React.FC = ({ patient }) => { + const { t } = useTranslation(); -function PatientWorkspaceTitle({ patient }: { patient: fhir.Patient }) { return ( <> -
{getPatientName(patient)}  
-
·   {patient.gender}
-
·   {age(patient.birthDate)}
+
{patient.person.display}  
+
·   {getGender(t, patient.person?.gender)}
+
·   {age(patient.person?.birthdate)}
); -} +}; diff --git a/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.component.tsx b/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.component.tsx index a68697164..53c7777f6 100644 --- a/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.component.tsx +++ b/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.component.tsx @@ -29,7 +29,7 @@ const AdmissionRequestsBar = () => {
- {t('admissionRequestsCount', '{{count}} admission requests', { + {t('admissionRequestsCount', '{{count}} admission request(s)', { count: inpatientRequests.length, })} diff --git a/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.test.tsx b/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.test.tsx index 058476ffd..e766cdc81 100644 --- a/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.test.tsx +++ b/packages/esm-ward-app/src/ward-view-header/admission-requests-bar.test.tsx @@ -33,6 +33,6 @@ describe('Admission Requests Button', () => { it('there should be one admission request', () => { renderWithSwr(); - expect(screen.getByText('1 admission requests')).toBeInTheDocument(); + expect(screen.getByText('1 admission request(s)')).toBeInTheDocument(); }); }); diff --git a/packages/esm-ward-app/src/ward-view/ward-view.component.tsx b/packages/esm-ward-app/src/ward-view/ward-view.component.tsx index f74abfe39..8bd79d7ca 100644 --- a/packages/esm-ward-app/src/ward-view/ward-view.component.tsx +++ b/packages/esm-ward-app/src/ward-view/ward-view.component.tsx @@ -58,18 +58,19 @@ const WardViewWithBedManagement = () => { const wardBeds = bedLayouts?.map((bedLayout) => { const { patients } = bedLayout; const bed = bedLayoutToBed(bedLayout); - const wardPatients: WardPatient[] = patients.map((patient) => { + const wardPatients: WardPatient[] = patients.map((patient): WardPatient => { const inpatientAdmission = inpatientAdmissionsByPatientUuid.get(patient.uuid); if (inpatientAdmission) { - return { ...inpatientAdmission, admitted: true }; + const { patient, visit } = inpatientAdmission; + return { patient, visit, bed, inpatientAdmission, inpatientRequest: null }; } else { // for some reason this patient is in a bed but not in the list of admitted patients, so we need to use the patient data from the bed endpoint return { patient: patient, visit: null, - admitted: false, - encounterAssigningToCurrentInpatientLocation: null, // populate after BED-13 - firstAdmissionOrTransferEncounter: null, + bed, + inpatientAdmission: null, // populate after BED-13 + inpatientRequest: null, }; } }); @@ -90,9 +91,9 @@ const WardViewWithBedManagement = () => { wardPatient={{ patient: inpatientAdmission.patient, visit: inpatientAdmission.visit, - admitted: true, - encounterAssigningToCurrentInpatientLocation: null, - firstAdmissionOrTransferEncounter: inpatientAdmission.firstAdmissionOrTransferEncounter, + bed: null, + inpatientAdmission, + inpatientRequest: null, }} key={inpatientAdmission.patient.uuid} /> @@ -145,9 +146,10 @@ const WardViewWithoutBedManagement = () => { if (inpatientAdmissions) { const wardPatients = inpatientAdmissions?.map((inpatientAdmission) => { + const { patient, visit } = inpatientAdmission; return ( ); diff --git a/packages/esm-ward-app/src/ward-workspace/admission-request-card/admission-request-card.component.tsx b/packages/esm-ward-app/src/ward-workspace/admission-request-card/admission-request-card.component.tsx index 4621d0a64..9d2a8b42f 100644 --- a/packages/esm-ward-app/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +++ b/packages/esm-ward-app/src/ward-workspace/admission-request-card/admission-request-card.component.tsx @@ -1,16 +1,14 @@ import React from 'react'; -import styles from './admission-request-card.scss'; -import type { InpatientRequest } from '../../types'; -import AdmissionRequestCardHeader from './admission-request-card-header.component'; +import type { WardPatientCard } from '../../types'; import AdmissionRequestCardActions from './admission-request-card-actions.component'; +import AdmissionRequestCardHeader from './admission-request-card-header.component'; +import styles from './admission-request-card.scss'; -interface AdmissionRequestCardProps extends InpatientRequest {} - -const AdmissionRequestCard: React.FC = ({ +const AdmissionRequestCard: WardPatientCard = ({ patient, - dispositionEncounter, - dispositionType, + inpatientRequest, }) => { + const { dispositionEncounter, dispositionType } = inpatientRequest; return (
diff --git a/packages/esm-ward-app/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx b/packages/esm-ward-app/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx index 88b2d6f25..73caccdba 100644 --- a/packages/esm-ward-app/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +++ b/packages/esm-ward-app/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx @@ -46,9 +46,9 @@ const AdmissionRequestsWorkspace: React.FC = () key={`admission-request-card-${i}`} patient={request.patient} visit={request.visit} - disposition={request.disposition} - dispositionEncounter={request.dispositionEncounter} - dispositionType={request.dispositionType} + bed={null} + inpatientRequest={request} + inpatientAdmission={null} /> ))} diff --git a/packages/esm-ward-app/src/ward-workspace/patient-banner/patient-banner.component.tsx b/packages/esm-ward-app/src/ward-workspace/patient-banner/patient-banner.component.tsx index 8eecf30fd..efff96732 100644 --- a/packages/esm-ward-app/src/ward-workspace/patient-banner/patient-banner.component.tsx +++ b/packages/esm-ward-app/src/ward-workspace/patient-banner/patient-banner.component.tsx @@ -8,8 +8,7 @@ import WardPatientName from '../../ward-patient-card/row-elements/ward-patient-n const WardPatientWorkspaceBanner = (props: WardPatient) => { const { headerRowElements } = useCurrentWardCardConfig(); - const { patient, bed, visit, firstAdmissionOrTransferEncounter, encounterAssigningToCurrentInpatientLocation } = - props; + const { patient, bed, visit } = props; if (!(patient && visit)) { console.warn('Patient details and visit details were not received by the workspace'); @@ -24,10 +23,7 @@ const WardPatientWorkspaceBanner = (props: WardPatient) => { ))}
diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes-action-button.extension.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes-action-button.extension.tsx index ce6f9000c..1507b7d93 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes-action-button.extension.tsx +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes-action-button.extension.tsx @@ -1,7 +1,7 @@ +import { ActionMenuButton, launchWorkspace, StickyNoteAddIcon } from '@openmrs/esm-framework'; import React from 'react'; import { useTranslation } from 'react-i18next'; -import { ActionMenuButton, launchWorkspace, StickyNoteAddIcon } from '@openmrs/esm-framework'; -import { type WardPatientNotesWorkspaceProps } from './types'; +import { type WardPatientWorkspaceProps } from '../../types'; export default function WardPatientNotesActionButton() { const { t } = useTranslation(); @@ -11,7 +11,7 @@ export default function WardPatientNotesActionButton() { getIcon={(props) => } label={t('PatientNote', 'Patient Note')} iconDescription={t('PatientNote', 'Patient Note')} - handler={() => launchWorkspace('ward-patient-notes-workspace')} + handler={() => launchWorkspace('ward-patient-notes-workspace')} type={'ward-patient-notes'} /> ); diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx index 06c3abd37..144eb7e31 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/notes.workspace.tsx @@ -1,41 +1,23 @@ -import React, { useMemo } from 'react'; +import React from 'react'; +import { type WardPatientWorkspaceProps } from '../../types'; import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component'; -import { type WardPatientNotesWorkspaceProps } from './types'; import PatientNotesForm from './form/notes-form.component'; import PatientNotesHistory from './history/notes-container.component'; -const WardPatientNotesWorkspace = (props: WardPatientNotesWorkspaceProps) => { - const { - patient, - visit, - bed, - admitted, - encounterAssigningToCurrentInpatientLocation, - firstAdmissionOrTransferEncounter, - ...restWorkspaceProps - } = props; - - const wardPatient = { - patient, - visit, - bed, - admitted, - encounterAssigningToCurrentInpatientLocation, - firstAdmissionOrTransferEncounter, +const WardPatientNotesWorkspace: React.FC = (props) => { + const { wardPatient, ...restWorkspaceProps } = props; + const patientUuid = wardPatient.patient?.uuid; + const { visit } = wardPatient; + const notesFormState = { + patientUuid, + ...restWorkspaceProps, }; - const notesFormState = useMemo( - () => ({ - patientUuid: patient?.uuid, - ...restWorkspaceProps, - }), - [patient, restWorkspaceProps], - ); return (
- +
); }; diff --git a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts index 74d8d8d06..f5077b52d 100644 --- a/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts +++ b/packages/esm-ward-app/src/ward-workspace/ward-patient-notes/types.ts @@ -1,7 +1,4 @@ -import { type Concept, type DefaultWorkspaceProps, type OpenmrsResource } from '@openmrs/esm-framework'; -import { type WardPatient } from '../../types'; - -export interface WardPatientNotesWorkspaceProps extends DefaultWorkspaceProps, WardPatient {} +import { type Concept, type OpenmrsResource } from '@openmrs/esm-framework'; export interface VisitEncountersFetchResponse { results: Array; diff --git a/packages/esm-ward-app/translations/en.json b/packages/esm-ward-app/translations/en.json index e7e8c2dfa..4472a8b99 100644 --- a/packages/esm-ward-app/translations/en.json +++ b/packages/esm-ward-app/translations/en.json @@ -16,7 +16,6 @@ "errorLoadingPatientAdmissionRequests": "Error Loading patient admission requests", "errorLoadingPatients": "Error loading admitted patients", "errorLoadingWardLocation": "Error loading ward location", - "failedToLoadPatientWorkspace": "Ward patient workspace has failed to load.", "female": "Female", "fetchingEmrConfigurationFailed": "Fetching EMR configuration failed. Try refreshing the page or contact your system administrator.", "fetchingPatientNotesFailed": "Fetching patient notes failed. Try refreshing the page or contact your system administrator.", @@ -47,6 +46,5 @@ "unknown": "Unknown", "visitNoteSaved": "Patient note saved", "wardClinicalNotePlaceholder": "Write any notes here", - "wardPatientWorkspaceTitle": "Ward Patient", "wards": "Wards" }