@kenyaemr/esm-morgue-app 5.4.2-pre.2344 → 5.4.2-pre.2347
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +20 -25
- package/dist/1.js +2 -0
- package/dist/1.js.map +1 -0
- package/dist/197.js +2 -1
- package/dist/197.js.map +1 -0
- package/dist/221.js +1 -1
- package/dist/221.js.map +1 -1
- package/dist/293.js +1 -1
- package/dist/294.js +1 -1
- package/dist/300.js +1 -1
- package/dist/340.js +2 -0
- package/dist/340.js.map +1 -0
- package/dist/351.js +1 -0
- package/dist/351.js.map +1 -0
- package/dist/404.js +1 -0
- package/dist/404.js.map +1 -0
- package/dist/441.js +1 -0
- package/dist/441.js.map +1 -0
- package/dist/578.js +1 -0
- package/dist/608.js +1 -0
- package/dist/608.js.map +1 -0
- package/dist/611.js +2 -0
- package/dist/611.js.map +1 -0
- package/dist/632.js +1 -1
- package/dist/632.js.map +1 -1
- package/dist/653.js +1 -1
- package/dist/653.js.map +1 -1
- package/dist/758.js +1 -0
- package/dist/758.js.map +1 -0
- package/dist/805.js +1 -1
- package/dist/805.js.map +1 -1
- package/dist/814.js +2 -0
- package/dist/814.js.LICENSE.txt +5 -0
- package/dist/814.js.map +1 -0
- package/dist/824.js +1 -1
- package/dist/824.js.map +1 -1
- package/dist/845.js +1 -0
- package/dist/845.js.map +1 -0
- package/dist/888.js +1 -0
- package/dist/888.js.map +1 -0
- package/dist/918.js +1 -1
- package/dist/918.js.map +1 -1
- package/dist/990.js +1 -0
- package/dist/990.js.map +1 -0
- package/dist/kenyaemr-esm-morgue-app.js +1 -1
- package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +250 -203
- package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +0 -6
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/bed/bed.component.tsx +63 -134
- package/src/bed/components/deceased-patient-card-header.component.tsx +73 -0
- package/src/bed/components/deceased-patient-info.component.tsx +47 -0
- package/src/bed/components/deceased-patient-status-footer.component.tsx +43 -0
- package/src/bed-layout/admitted/admitted-bed-layout.component.tsx +175 -96
- package/src/bed-layout/awaiting/awaiting-bed-layout.component.tsx +103 -36
- package/src/bed-layout/bed-layout.scss +4 -0
- package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +131 -73
- package/src/bed-linelist-view/admitted/admitted-bed-linelist-view.component.tsx +182 -134
- package/src/bed-linelist-view/awaiting/awaiting-bed-linelist-view.component.tsx +115 -71
- package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +181 -109
- package/src/config-schema.ts +140 -4
- package/src/context/deceased-person-context.tsx +33 -0
- package/src/extension/actionButton.component.tsx +1 -1
- package/src/forms/admit-deceased-person-workspace/admit-deceased-person.resource.ts +84 -166
- package/src/forms/admit-deceased-person-workspace/admit-deceased-person.scss +14 -0
- package/src/forms/admit-deceased-person-workspace/admit-deceased-person.workspace.tsx +504 -334
- package/src/forms/discharge-deceased-person-workspace/discharge-body.resource.ts +0 -1
- package/src/forms/discharge-deceased-person-workspace/discharge-body.scss +15 -0
- package/src/forms/discharge-deceased-person-workspace/discharge-body.workspace.tsx +303 -244
- package/src/helpers/expression-helper.ts +122 -0
- package/src/home/home.component.tsx +23 -4
- package/src/index.ts +0 -2
- package/src/metrics/metrics-card.component.tsx +2 -2
- package/src/routes.json +0 -6
- package/src/schemas/index.ts +243 -51
- package/src/summary/summary.component.tsx +16 -9
- package/src/switcher/content-switcher.component.tsx +61 -35
- package/src/switcher/content-switcher.scss +13 -0
- package/src/types/index.ts +43 -1
- package/translations/am.json +16 -6
- package/translations/en.json +16 -6
- package/translations/sw.json +16 -6
- package/dist/373.js +0 -2
- package/dist/373.js.map +0 -1
- package/dist/398.js +0 -1
- package/dist/398.js.map +0 -1
- package/dist/410.js +0 -1
- package/dist/410.js.map +0 -1
- package/dist/429.js +0 -2
- package/dist/429.js.map +0 -1
- package/dist/467.js +0 -1
- package/dist/467.js.map +0 -1
- package/dist/579.js +0 -2
- package/dist/579.js.map +0 -1
- package/dist/619.js +0 -1
- package/dist/619.js.map +0 -1
- package/dist/633.js +0 -1
- package/dist/633.js.map +0 -1
- package/dist/712.js +0 -1
- package/dist/712.js.map +0 -1
- package/dist/713.js +0 -1
- package/dist/713.js.map +0 -1
- package/dist/723.js +0 -1
- package/dist/723.js.map +0 -1
- package/dist/989.js +0 -2
- package/dist/989.js.map +0 -1
- package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.resource.ts +0 -18
- package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.scss +0 -84
- package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.workspace.tsx +0 -505
- /package/dist/{373.js.LICENSE.txt → 1.js.LICENSE.txt} +0 -0
- /package/dist/{989.js.LICENSE.txt → 197.js.LICENSE.txt} +0 -0
- /package/dist/{579.js.LICENSE.txt → 340.js.LICENSE.txt} +0 -0
- /package/dist/{429.js.LICENSE.txt → 611.js.LICENSE.txt} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { InlineLoading } from '@carbon/react';
|
|
4
|
-
import { launchWorkspace, navigate, useConfig } from '@openmrs/esm-framework';
|
|
3
|
+
import { InlineLoading, Search } from '@carbon/react';
|
|
4
|
+
import { launchWorkspace, navigate, useConfig, useLayoutType } from '@openmrs/esm-framework';
|
|
5
5
|
import styles from '../bed-layout.scss';
|
|
6
6
|
import BedCard from '../../bed/bed.component';
|
|
7
7
|
import { type MortuaryLocationResponse } from '../../types';
|
|
@@ -9,6 +9,9 @@ import EmptyBedCard from '../../bed/empty-bed.component';
|
|
|
9
9
|
import Divider from '../../bed/divider/divider.component';
|
|
10
10
|
import { ConfigObject } from '../../config-schema';
|
|
11
11
|
import { mutate as mutateSWR } from 'swr';
|
|
12
|
+
import EmptyMorgueAdmission from '../../empty-state/empty-morgue-admission.component';
|
|
13
|
+
import { PatientProvider } from '../../context/deceased-person-context';
|
|
14
|
+
import { transformAdmittedPatient } from '../../helpers/expression-helper';
|
|
12
15
|
|
|
13
16
|
interface BedLayoutProps {
|
|
14
17
|
AdmittedDeceasedPatient: MortuaryLocationResponse | null;
|
|
@@ -17,7 +20,6 @@ interface BedLayoutProps {
|
|
|
17
20
|
onPostmortem?: (patientUuid: string) => void;
|
|
18
21
|
onDischarge?: (patientUuid: string) => void;
|
|
19
22
|
onSwapCompartment?: (patientUuid: string, bedId: string) => void;
|
|
20
|
-
onDispose?: (patientUuid: string) => void;
|
|
21
23
|
mutate?: () => void;
|
|
22
24
|
}
|
|
23
25
|
|
|
@@ -27,20 +29,27 @@ const BedLayout: React.FC<BedLayoutProps> = ({
|
|
|
27
29
|
onPostmortem,
|
|
28
30
|
onDischarge,
|
|
29
31
|
onSwapCompartment,
|
|
30
|
-
onDispose,
|
|
31
32
|
mutate,
|
|
32
33
|
}) => {
|
|
33
34
|
const { t } = useTranslation();
|
|
34
35
|
const { autopsyFormUuid } = useConfig<ConfigObject>();
|
|
36
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
37
|
+
const isTablet = useLayoutType() === 'tablet';
|
|
38
|
+
const controlSize = isTablet ? 'md' : 'sm';
|
|
39
|
+
|
|
40
|
+
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
41
|
+
setSearchTerm(event.target.value);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const handlePostmortem = (patientUuid: string, bedInfo?: { bedNumber: string; bedId: number }) => {
|
|
45
|
+
const hasBedInfo = bedInfo?.bedNumber && bedInfo?.bedId;
|
|
35
46
|
|
|
36
|
-
const handlePostmortem = (patientUuid: string) => {
|
|
37
47
|
if (onPostmortem) {
|
|
38
48
|
onPostmortem(patientUuid);
|
|
39
49
|
} else {
|
|
40
50
|
launchWorkspace('mortuary-form-entry', {
|
|
41
51
|
formUuid: autopsyFormUuid,
|
|
42
52
|
workspaceTitle: t('postmortemForm', 'Postmortem form'),
|
|
43
|
-
|
|
44
53
|
patientUuid: patientUuid,
|
|
45
54
|
encounterUuid: '',
|
|
46
55
|
mutateForm: () => {
|
|
@@ -50,9 +59,14 @@ const BedLayout: React.FC<BedLayoutProps> = ({
|
|
|
50
59
|
},
|
|
51
60
|
});
|
|
52
61
|
}
|
|
62
|
+
const base = `${window.getOpenmrsSpaBase()}home/morgue/patient/${patientUuid}`;
|
|
63
|
+
const to = hasBedInfo
|
|
64
|
+
? `${base}/compartment/${bedInfo.bedNumber}/${bedInfo.bedId}/mortuary-chart`
|
|
65
|
+
: `${base}/mortuary-chart`;
|
|
66
|
+
navigate({ to });
|
|
53
67
|
};
|
|
54
68
|
|
|
55
|
-
const handleDischarge = (patientUuid: string, bedId
|
|
69
|
+
const handleDischarge = (patientUuid: string, bedId?: number) => {
|
|
56
70
|
if (onDischarge) {
|
|
57
71
|
onDischarge(patientUuid);
|
|
58
72
|
} else {
|
|
@@ -65,9 +79,9 @@ const BedLayout: React.FC<BedLayoutProps> = ({
|
|
|
65
79
|
}
|
|
66
80
|
};
|
|
67
81
|
|
|
68
|
-
const handleSwapCompartment = (patientUuid: string, bedId
|
|
82
|
+
const handleSwapCompartment = (patientUuid: string, bedId?: number) => {
|
|
69
83
|
if (onSwapCompartment) {
|
|
70
|
-
onSwapCompartment(patientUuid, bedId
|
|
84
|
+
onSwapCompartment(patientUuid, bedId?.toString() || '');
|
|
71
85
|
} else {
|
|
72
86
|
launchWorkspace('swap-unit-form', {
|
|
73
87
|
workspaceTitle: t('swapCompartment', 'Swap compartment'),
|
|
@@ -79,17 +93,55 @@ const BedLayout: React.FC<BedLayoutProps> = ({
|
|
|
79
93
|
}
|
|
80
94
|
};
|
|
81
95
|
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
const handleViewDetails = (patientUuid: string, bedInfo?: { bedNumber: string; bedId: number }) => {
|
|
97
|
+
const hasBedInfo = bedInfo?.bedNumber && bedInfo?.bedId;
|
|
98
|
+
const base = `${window.getOpenmrsSpaBase()}home/morgue/patient/${patientUuid}`;
|
|
99
|
+
const to = hasBedInfo
|
|
100
|
+
? `${base}/compartment/${bedInfo.bedNumber}/${bedInfo.bedId}/mortuary-chart`
|
|
101
|
+
: `${base}/mortuary-chart`;
|
|
102
|
+
navigate({ to });
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const filteredBedLayouts = useMemo(() => {
|
|
106
|
+
if (!AdmittedDeceasedPatient?.bedLayouts || !searchTerm.trim()) {
|
|
107
|
+
return AdmittedDeceasedPatient?.bedLayouts || [];
|
|
92
108
|
}
|
|
109
|
+
|
|
110
|
+
const lowerSearchTerm = searchTerm.toLowerCase().trim();
|
|
111
|
+
|
|
112
|
+
return AdmittedDeceasedPatient.bedLayouts.filter((bedLayout) => {
|
|
113
|
+
const bedNumber = bedLayout.bedNumber?.toString().toLowerCase() || '';
|
|
114
|
+
const bedType = bedLayout.bedType?.displayName?.toLowerCase() || '';
|
|
115
|
+
|
|
116
|
+
if (bedNumber.includes(lowerSearchTerm) || bedType.includes(lowerSearchTerm)) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const patients = bedLayout.patients || [];
|
|
121
|
+
return patients.some((patient) => {
|
|
122
|
+
const patientName = patient.person?.display?.toLowerCase() || '';
|
|
123
|
+
const gender = patient.person?.gender?.toLowerCase() || '';
|
|
124
|
+
const patientId = patient.uuid?.toLowerCase() || '';
|
|
125
|
+
const causeOfDeath = patient.person?.causeOfDeath?.display?.toLowerCase() || '';
|
|
126
|
+
|
|
127
|
+
return (
|
|
128
|
+
patientName.includes(lowerSearchTerm) ||
|
|
129
|
+
gender.includes(lowerSearchTerm) ||
|
|
130
|
+
patientId.includes(lowerSearchTerm) ||
|
|
131
|
+
causeOfDeath.includes(lowerSearchTerm)
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}, [AdmittedDeceasedPatient?.bedLayouts, searchTerm]);
|
|
136
|
+
|
|
137
|
+
const patientContextValue = {
|
|
138
|
+
mortuaryLocation: AdmittedDeceasedPatient,
|
|
139
|
+
isLoading,
|
|
140
|
+
mutate,
|
|
141
|
+
onPostmortem: handlePostmortem,
|
|
142
|
+
onDischarge: handleDischarge,
|
|
143
|
+
onSwapCompartment: handleSwapCompartment,
|
|
144
|
+
onViewDetails: handleViewDetails,
|
|
93
145
|
};
|
|
94
146
|
|
|
95
147
|
if (isLoading) {
|
|
@@ -100,89 +152,116 @@ const BedLayout: React.FC<BedLayoutProps> = ({
|
|
|
100
152
|
);
|
|
101
153
|
}
|
|
102
154
|
|
|
103
|
-
const bedLayouts =
|
|
155
|
+
const bedLayouts = filteredBedLayouts;
|
|
156
|
+
if (!bedLayouts || bedLayouts.length === 0) {
|
|
157
|
+
if (searchTerm.trim()) {
|
|
158
|
+
return (
|
|
159
|
+
<>
|
|
160
|
+
<div className={styles.searchContainer}>
|
|
161
|
+
<Search
|
|
162
|
+
labelText={t('searchDeceasedPatients', 'Search deceased patients')}
|
|
163
|
+
placeholder={t(
|
|
164
|
+
'searchPatientsPlaceholder',
|
|
165
|
+
'Search by name, ID number, gender, compartment, or bed type...',
|
|
166
|
+
)}
|
|
167
|
+
value={searchTerm}
|
|
168
|
+
onChange={handleSearchChange}
|
|
169
|
+
size={controlSize}
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
<EmptyMorgueAdmission
|
|
173
|
+
title={t('noMatchingPatients', 'No matching patients found')}
|
|
174
|
+
subTitle={t('noMatchingPatientsDescription', 'Try adjusting your search terms to find deceased patients.')}
|
|
175
|
+
/>
|
|
176
|
+
</>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return (
|
|
181
|
+
<EmptyMorgueAdmission
|
|
182
|
+
title={t('noAdmittedPatient', 'No deceased patients currently admitted')}
|
|
183
|
+
subTitle={t(
|
|
184
|
+
'noAdmittedPatientsDescription',
|
|
185
|
+
'There are no admitted deceased patients to display at this time.',
|
|
186
|
+
)}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
104
190
|
|
|
105
191
|
return (
|
|
106
|
-
<
|
|
107
|
-
<div className={styles.
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
192
|
+
<PatientProvider value={patientContextValue}>
|
|
193
|
+
<div className={styles.searchContainer}>
|
|
194
|
+
<Search
|
|
195
|
+
labelText={t('searchDeceasedPatients', 'Search deceased patients')}
|
|
196
|
+
placeholder={t('searchPatientsPlaceholder', 'Search by name, ID number, gender, compartment, or bed type...')}
|
|
197
|
+
value={searchTerm}
|
|
198
|
+
onChange={handleSearchChange}
|
|
199
|
+
size="sm"
|
|
200
|
+
/>
|
|
201
|
+
</div>
|
|
202
|
+
<div className={styles.bedLayoutWrapper}>
|
|
203
|
+
<div className={styles.bedLayoutContainer}>
|
|
204
|
+
{bedLayouts.map((bedLayout, index) => {
|
|
205
|
+
const patients = bedLayout.patients || [];
|
|
206
|
+
const isEmpty = bedLayout.status === 'AVAILABLE' || patients.length === 0;
|
|
111
207
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
bedNumber={bedLayout.bedNumber}
|
|
117
|
-
bedType={bedLayout.bedType?.displayName}
|
|
118
|
-
isEmpty={isEmpty}
|
|
119
|
-
/>
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<div
|
|
125
|
-
key={bedLayout.bedUuid}
|
|
126
|
-
className={`${styles.bedContainer} ${patients.length > 1 ? styles.sharedBedContainer : ''}`}>
|
|
127
|
-
{patients.length > 1 ? (
|
|
128
|
-
<div className={styles.horizontalLayout}>
|
|
129
|
-
{patients.map((patient, patientIndex) => (
|
|
130
|
-
<React.Fragment key={patient.uuid}>
|
|
131
|
-
<BedCard
|
|
132
|
-
patientUuid={patient.uuid}
|
|
133
|
-
patientName={patient.person?.display}
|
|
134
|
-
gender={patient.person?.gender}
|
|
135
|
-
age={patient.person?.age}
|
|
136
|
-
causeOfDeath={patient.person?.causeOfDeath?.display}
|
|
137
|
-
dateOfDeath={patient.person?.deathDate}
|
|
138
|
-
bedNumber={bedLayout.bedNumber}
|
|
139
|
-
bedType={bedLayout.bedType?.displayName}
|
|
140
|
-
onPostmortem={() => handlePostmortem(patient.uuid)}
|
|
141
|
-
onDischarge={() => handleDischarge(patient.uuid, bedLayout.bedId)}
|
|
142
|
-
onSwapCompartment={() => handleSwapCompartment(patient.uuid, bedLayout.bedId)}
|
|
143
|
-
onDispose={() => handleDispose(patient.uuid, bedLayout.bedId)}
|
|
144
|
-
onViewDetails={() => {
|
|
145
|
-
const hasBedInfo = bedLayout.bedNumber && bedLayout.bedId;
|
|
146
|
-
const base = `${window.getOpenmrsSpaBase()}home/morgue/patient/${patient.uuid}`;
|
|
147
|
-
const to = hasBedInfo
|
|
148
|
-
? `${base}/compartment/${bedLayout.bedNumber}/${bedLayout.bedId}/mortuary-chart`
|
|
149
|
-
: `${base}/mortuary-chart`;
|
|
150
|
-
navigate({ to });
|
|
151
|
-
}}
|
|
152
|
-
/>
|
|
153
|
-
{patientIndex < patients.length - 1 && <Divider />}
|
|
154
|
-
</React.Fragment>
|
|
155
|
-
))}
|
|
156
|
-
</div>
|
|
157
|
-
) : (
|
|
158
|
-
<BedCard
|
|
159
|
-
patientUuid={patients[0].uuid}
|
|
160
|
-
patientName={patients[0].person?.display}
|
|
161
|
-
gender={patients[0].person?.gender}
|
|
162
|
-
age={patients[0].person?.age}
|
|
163
|
-
causeOfDeath={patients[0].person?.causeOfDeath?.display}
|
|
164
|
-
dateOfDeath={patients[0].person?.deathDate}
|
|
208
|
+
if (isEmpty) {
|
|
209
|
+
return (
|
|
210
|
+
<EmptyBedCard
|
|
211
|
+
key={bedLayout.bedUuid || `empty-bed-${bedLayout.bedId}-${index}`}
|
|
165
212
|
bedNumber={bedLayout.bedNumber}
|
|
166
213
|
bedType={bedLayout.bedType?.displayName}
|
|
167
|
-
|
|
168
|
-
onDischarge={() => handleDischarge(patients[0].uuid, bedLayout.bedId)}
|
|
169
|
-
onSwapCompartment={() => handleSwapCompartment(patients[0].uuid, bedLayout.bedId)}
|
|
170
|
-
onDispose={() => handleDispose(patients[0].uuid, bedLayout.bedId)}
|
|
171
|
-
onViewDetails={() => {
|
|
172
|
-
const hasBedInfo = bedLayout.bedNumber && bedLayout.bedId;
|
|
173
|
-
const base = `${window.getOpenmrsSpaBase()}home/morgue/patient/${patients[0].uuid}`;
|
|
174
|
-
const to = hasBedInfo
|
|
175
|
-
? `${base}/compartment/${bedLayout.bedNumber}/${bedLayout.bedId}/mortuary-chart`
|
|
176
|
-
: `${base}/mortuary-chart`;
|
|
177
|
-
navigate({ to });
|
|
178
|
-
}}
|
|
214
|
+
isEmpty={isEmpty}
|
|
179
215
|
/>
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return (
|
|
220
|
+
<div
|
|
221
|
+
key={bedLayout.bedUuid}
|
|
222
|
+
className={`${styles.bedContainer} ${patients.length > 1 ? styles.sharedBedContainer : ''}`}>
|
|
223
|
+
{patients.length > 1 ? (
|
|
224
|
+
<div className={styles.horizontalLayout}>
|
|
225
|
+
{patients.map((patient, patientIndex) => (
|
|
226
|
+
<React.Fragment key={patient.uuid}>
|
|
227
|
+
<BedCard
|
|
228
|
+
patient={transformAdmittedPatient(patient, {
|
|
229
|
+
bedNumber: bedLayout.bedNumber,
|
|
230
|
+
bedId: bedLayout.bedId,
|
|
231
|
+
bedType: bedLayout.bedType?.displayName,
|
|
232
|
+
})}
|
|
233
|
+
showActions={{
|
|
234
|
+
discharge: true,
|
|
235
|
+
swapCompartment: true,
|
|
236
|
+
postmortem: true,
|
|
237
|
+
viewDetails: true,
|
|
238
|
+
}}
|
|
239
|
+
/>
|
|
240
|
+
{patientIndex < patients.length - 1 && <Divider />}
|
|
241
|
+
</React.Fragment>
|
|
242
|
+
))}
|
|
243
|
+
</div>
|
|
244
|
+
) : (
|
|
245
|
+
<BedCard
|
|
246
|
+
patient={transformAdmittedPatient(patients[0], {
|
|
247
|
+
bedNumber: bedLayout.bedNumber,
|
|
248
|
+
bedId: bedLayout.bedId,
|
|
249
|
+
bedType: bedLayout.bedType?.displayName,
|
|
250
|
+
})}
|
|
251
|
+
showActions={{
|
|
252
|
+
discharge: true,
|
|
253
|
+
swapCompartment: true,
|
|
254
|
+
postmortem: true,
|
|
255
|
+
viewDetails: true,
|
|
256
|
+
}}
|
|
257
|
+
/>
|
|
258
|
+
)}
|
|
259
|
+
</div>
|
|
260
|
+
);
|
|
261
|
+
})}
|
|
262
|
+
</div>
|
|
184
263
|
</div>
|
|
185
|
-
</
|
|
264
|
+
</PatientProvider>
|
|
186
265
|
);
|
|
187
266
|
};
|
|
188
267
|
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useMemo } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { InlineLoading, SkeletonText } from '@carbon/react';
|
|
3
|
+
import { InlineLoading, Search, SkeletonText } from '@carbon/react';
|
|
4
4
|
import styles from '../bed-layout.scss';
|
|
5
|
-
import
|
|
6
|
-
import { MortuaryPatient, MortuaryLocationResponse } from '../../types';
|
|
5
|
+
import { MortuaryPatient, MortuaryLocationResponse, EnhancedPatient } from '../../types';
|
|
7
6
|
import { useAwaitingPatients } from '../../home/home.resource';
|
|
8
|
-
import { launchWorkspace } from '@openmrs/esm-framework';
|
|
7
|
+
import { launchWorkspace, useLayoutType } from '@openmrs/esm-framework';
|
|
9
8
|
import { EmptyState } from '@openmrs/esm-patient-common-lib/src';
|
|
9
|
+
import EmptyMorgueAdmission from '../../empty-state/empty-morgue-admission.component';
|
|
10
|
+
import { getOriginalPatient, transformMortuaryPatient } from '../../helpers/expression-helper';
|
|
11
|
+
import { PatientProvider } from '../../context/deceased-person-context';
|
|
12
|
+
import BedCard from '../../bed/bed.component';
|
|
10
13
|
|
|
11
14
|
interface BedLayoutProps {
|
|
12
15
|
awaitingQueueDeceasedPatients: MortuaryPatient[];
|
|
@@ -22,8 +25,56 @@ const AwaitingBedLayout: React.FC<BedLayoutProps> = ({
|
|
|
22
25
|
mutated,
|
|
23
26
|
}) => {
|
|
24
27
|
const { t } = useTranslation();
|
|
25
|
-
|
|
28
|
+
const [searchTerm, setSearchTerm] = useState('');
|
|
26
29
|
const trulyAwaitingPatients = useAwaitingPatients(awaitingQueueDeceasedPatients);
|
|
30
|
+
const isTablet = useLayoutType() === 'tablet';
|
|
31
|
+
const controlSize = isTablet ? 'md' : 'sm';
|
|
32
|
+
|
|
33
|
+
const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
34
|
+
setSearchTerm(event.target.value);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const filteredPatients = useMemo(() => {
|
|
38
|
+
if (!trulyAwaitingPatients || !searchTerm.trim()) {
|
|
39
|
+
return trulyAwaitingPatients || [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const lowerSearchTerm = searchTerm.toLowerCase().trim();
|
|
43
|
+
return trulyAwaitingPatients.filter((mortuaryPatient) => {
|
|
44
|
+
const patientName = mortuaryPatient?.person?.person?.display?.toLowerCase() || '';
|
|
45
|
+
const gender = mortuaryPatient?.person?.person?.gender?.toLowerCase() || '';
|
|
46
|
+
const patientId = mortuaryPatient?.person?.person?.uuid?.toLowerCase() || '';
|
|
47
|
+
const causeOfDeath = mortuaryPatient?.person?.person?.causeOfDeath?.display?.toLowerCase() || '';
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
patientName.includes(lowerSearchTerm) ||
|
|
51
|
+
gender.includes(lowerSearchTerm) ||
|
|
52
|
+
patientId.includes(lowerSearchTerm) ||
|
|
53
|
+
causeOfDeath.includes(lowerSearchTerm)
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
}, [trulyAwaitingPatients, searchTerm]);
|
|
57
|
+
|
|
58
|
+
const handleAdmit = (enhancedPatient: EnhancedPatient) => {
|
|
59
|
+
// Extract the original MortuaryPatient from the enhanced patient
|
|
60
|
+
const originalPatient = getOriginalPatient(enhancedPatient);
|
|
61
|
+
if (originalPatient && 'patient' in originalPatient) {
|
|
62
|
+
// This is a MortuaryPatient
|
|
63
|
+
launchWorkspace('admit-deceased-person-form', {
|
|
64
|
+
workspaceTitle: t('admissionForm', 'Admission form'),
|
|
65
|
+
patientData: originalPatient,
|
|
66
|
+
mortuaryLocation,
|
|
67
|
+
mutated,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const patientContextValue = {
|
|
73
|
+
mortuaryLocation,
|
|
74
|
+
isLoading,
|
|
75
|
+
mutate: mutated,
|
|
76
|
+
onAdmit: handleAdmit,
|
|
77
|
+
};
|
|
27
78
|
|
|
28
79
|
if (isLoading) {
|
|
29
80
|
return (
|
|
@@ -45,41 +96,57 @@ const AwaitingBedLayout: React.FC<BedLayoutProps> = ({
|
|
|
45
96
|
);
|
|
46
97
|
}
|
|
47
98
|
|
|
48
|
-
const
|
|
49
|
-
launchWorkspace('admit-deceased-person-form', {
|
|
50
|
-
workspaceTitle: t('admissionForm', 'Admission form'),
|
|
51
|
-
patientData,
|
|
52
|
-
mortuaryLocation,
|
|
53
|
-
mutated,
|
|
54
|
-
});
|
|
55
|
-
};
|
|
99
|
+
const patientsToShow = filteredPatients;
|
|
56
100
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
101
|
+
if (searchTerm.trim() && patientsToShow.length === 0) {
|
|
102
|
+
return (
|
|
103
|
+
<>
|
|
104
|
+
<div className={styles.searchContainer}>
|
|
105
|
+
<Search
|
|
106
|
+
labelText={t('searchDeceasedPatients', 'Search deceased patients')}
|
|
107
|
+
placeholder={t(
|
|
108
|
+
'searchPatientsPlaceholder',
|
|
109
|
+
'Search by name, ID number, gender, compartment, or bed type...',
|
|
110
|
+
)}
|
|
111
|
+
value={searchTerm}
|
|
112
|
+
onChange={handleSearchChange}
|
|
113
|
+
size={controlSize}
|
|
114
|
+
/>
|
|
115
|
+
</div>
|
|
116
|
+
<EmptyMorgueAdmission
|
|
117
|
+
title={t('noMatchingAwaitingPatients', 'No matching awaiting patients found')}
|
|
118
|
+
subTitle={t(
|
|
119
|
+
'noMatchingAwaitingPatientsDescription',
|
|
120
|
+
'Try adjusting your search terms to find awaiting patients.',
|
|
121
|
+
)}
|
|
122
|
+
/>
|
|
123
|
+
</>
|
|
124
|
+
);
|
|
125
|
+
}
|
|
67
126
|
|
|
68
|
-
|
|
127
|
+
return (
|
|
128
|
+
<PatientProvider value={patientContextValue}>
|
|
129
|
+
<div className={styles.searchContainer}>
|
|
130
|
+
<Search
|
|
131
|
+
labelText={t('searchDeceasedPatients', 'Search deceased patients')}
|
|
132
|
+
placeholder={t('searchPatientsPlaceholder', 'Search by name, ID number, gender, compartment, or bed type...')}
|
|
133
|
+
value={searchTerm}
|
|
134
|
+
onChange={handleSearchChange}
|
|
135
|
+
size="sm"
|
|
136
|
+
/>
|
|
137
|
+
</div>
|
|
138
|
+
<div className={styles.bedLayoutWrapper}>
|
|
139
|
+
<div className={styles.bedLayoutContainer}>
|
|
140
|
+
{patientsToShow.map((mortuaryPatient) => (
|
|
69
141
|
<BedCard
|
|
70
|
-
key={
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
age={age}
|
|
74
|
-
causeOfDeath={causeOfDeath}
|
|
75
|
-
dateOfDeath={dateOfDeath}
|
|
76
|
-
patientUuid={patientUuid}
|
|
77
|
-
onAdmit={() => handleAdmit(mortuaryPatient)}
|
|
142
|
+
key={mortuaryPatient.person?.person?.uuid}
|
|
143
|
+
patient={transformMortuaryPatient(mortuaryPatient)}
|
|
144
|
+
showActions={{ admit: true }}
|
|
78
145
|
/>
|
|
79
|
-
)
|
|
80
|
-
|
|
146
|
+
))}
|
|
147
|
+
</div>
|
|
81
148
|
</div>
|
|
82
|
-
</
|
|
149
|
+
</PatientProvider>
|
|
83
150
|
);
|
|
84
151
|
};
|
|
85
152
|
|