@openmrs/esm-ward-app 7.0.1-pre.3621 → 7.0.1-pre.3630
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 +8 -8
- package/dist/574.js +1 -1
- package/dist/589.js +1 -0
- package/dist/589.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-ward-app.js +1 -1
- package/dist/openmrs-esm-ward-app.js.buildmanifest.json +30 -30
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/beds/occupied-bed.component.tsx +3 -3
- package/src/beds/occupied-bed.test.tsx +6 -5
- package/src/hooks/useAdmittedPatients.ts +13 -0
- package/src/hooks/useInpatientRequest.ts +2 -3
- package/src/routes.json +2 -1
- package/src/types/index.ts +23 -0
- package/src/ward-view/ward-bed.component.tsx +4 -4
- package/src/ward-view/ward-view.component.tsx +63 -15
- package/src/ward-view/ward-view.test.tsx +12 -0
- package/src/ward-view-header/admission-requests-bar.component.tsx +11 -9
- package/src/ward-view-header/admission-requests-bar.test.tsx +4 -3
- package/src/ward-view-header/ward-view-header.component.tsx +4 -3
- package/src/ward-workspace/admission-request-workspace.test.tsx +1 -1
- package/translations/en.json +2 -3
- package/dist/369.js +0 -1
- package/dist/369.js.map +0 -1
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"initial": true,
|
|
57
57
|
"entry": true,
|
|
58
58
|
"recorded": false,
|
|
59
|
-
"size":
|
|
59
|
+
"size": 1041847,
|
|
60
60
|
"sizes": {
|
|
61
61
|
"consume-shared": 252,
|
|
62
|
-
"javascript":
|
|
62
|
+
"javascript": 1020949,
|
|
63
63
|
"share-init": 252,
|
|
64
64
|
"runtime": 20394
|
|
65
65
|
},
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"auxiliaryFiles": [
|
|
77
77
|
"main.js.map"
|
|
78
78
|
],
|
|
79
|
-
"hash": "
|
|
79
|
+
"hash": "580650bdf73f4a29",
|
|
80
80
|
"childrenByOrder": {}
|
|
81
81
|
},
|
|
82
82
|
{
|
|
@@ -177,23 +177,26 @@
|
|
|
177
177
|
"initial": false,
|
|
178
178
|
"entry": false,
|
|
179
179
|
"recorded": false,
|
|
180
|
-
"
|
|
180
|
+
"reason": "reused as split chunk (cache group: defaultVendors)",
|
|
181
|
+
"size": 40067,
|
|
181
182
|
"sizes": {
|
|
182
|
-
"javascript":
|
|
183
|
-
"consume-shared": 168
|
|
183
|
+
"javascript": 40067
|
|
184
184
|
},
|
|
185
185
|
"names": [],
|
|
186
|
-
"idHints": [
|
|
186
|
+
"idHints": [
|
|
187
|
+
"vendors"
|
|
188
|
+
],
|
|
187
189
|
"runtime": [
|
|
188
|
-
"@openmrs/esm-ward-app"
|
|
190
|
+
"@openmrs/esm-ward-app",
|
|
191
|
+
"main"
|
|
189
192
|
],
|
|
190
193
|
"files": [
|
|
191
|
-
"
|
|
194
|
+
"443.js"
|
|
192
195
|
],
|
|
193
196
|
"auxiliaryFiles": [
|
|
194
|
-
"
|
|
197
|
+
"443.js.map"
|
|
195
198
|
],
|
|
196
|
-
"hash": "
|
|
199
|
+
"hash": "e4f298771af8e454",
|
|
197
200
|
"childrenByOrder": {}
|
|
198
201
|
},
|
|
199
202
|
{
|
|
@@ -201,26 +204,21 @@
|
|
|
201
204
|
"initial": false,
|
|
202
205
|
"entry": false,
|
|
203
206
|
"recorded": false,
|
|
204
|
-
"
|
|
205
|
-
"size": 40067,
|
|
207
|
+
"size": 441,
|
|
206
208
|
"sizes": {
|
|
207
|
-
"javascript":
|
|
209
|
+
"javascript": 441
|
|
208
210
|
},
|
|
209
211
|
"names": [],
|
|
210
|
-
"idHints": [
|
|
211
|
-
"vendors"
|
|
212
|
-
],
|
|
212
|
+
"idHints": [],
|
|
213
213
|
"runtime": [
|
|
214
214
|
"@openmrs/esm-ward-app",
|
|
215
215
|
"main"
|
|
216
216
|
],
|
|
217
217
|
"files": [
|
|
218
|
-
"
|
|
219
|
-
],
|
|
220
|
-
"auxiliaryFiles": [
|
|
221
|
-
"443.js.map"
|
|
218
|
+
"574.js"
|
|
222
219
|
],
|
|
223
|
-
"
|
|
220
|
+
"auxiliaryFiles": [],
|
|
221
|
+
"hash": "a45ce40d9929be20",
|
|
224
222
|
"childrenByOrder": {}
|
|
225
223
|
},
|
|
226
224
|
{
|
|
@@ -228,21 +226,23 @@
|
|
|
228
226
|
"initial": false,
|
|
229
227
|
"entry": false,
|
|
230
228
|
"recorded": false,
|
|
231
|
-
"size":
|
|
229
|
+
"size": 95923,
|
|
232
230
|
"sizes": {
|
|
233
|
-
"javascript":
|
|
231
|
+
"javascript": 95755,
|
|
232
|
+
"consume-shared": 168
|
|
234
233
|
},
|
|
235
234
|
"names": [],
|
|
236
235
|
"idHints": [],
|
|
237
236
|
"runtime": [
|
|
238
|
-
"@openmrs/esm-ward-app"
|
|
239
|
-
"main"
|
|
237
|
+
"@openmrs/esm-ward-app"
|
|
240
238
|
],
|
|
241
239
|
"files": [
|
|
242
|
-
"
|
|
240
|
+
"589.js"
|
|
243
241
|
],
|
|
244
|
-
"auxiliaryFiles": [
|
|
245
|
-
|
|
242
|
+
"auxiliaryFiles": [
|
|
243
|
+
"589.js.map"
|
|
244
|
+
],
|
|
245
|
+
"hash": "d1b0eb82ce9819e5",
|
|
246
246
|
"childrenByOrder": {}
|
|
247
247
|
},
|
|
248
248
|
{
|
|
@@ -373,7 +373,7 @@
|
|
|
373
373
|
"auxiliaryFiles": [
|
|
374
374
|
"openmrs-esm-ward-app.js.map"
|
|
375
375
|
],
|
|
376
|
-
"hash": "
|
|
376
|
+
"hash": "41c3842415804b54",
|
|
377
377
|
"childrenByOrder": {}
|
|
378
378
|
}
|
|
379
379
|
]
|
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0"},"optionalBackendDependencies":{"bedmanagement":{"version":"^6.0.0 || 6.0.0-SNAPSHOT","feature":{"flagName":"bedmanagement-module","label":"Ward App Patient Service","description":"This module, if installed, provides services for managing patients admitted to the ward."}}},"workspaces":[{"name":"admission-requests-cards","component":"admissionRequestWorkspace","title":"admissionRequests","type":"admission-requests"}],"pages":[{"component":"root","route":"ward"}],"version":"7.0.1-pre.
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0","emrapi":"^2.0.0 || 2.0.0-SNAPSHOT"},"optionalBackendDependencies":{"bedmanagement":{"version":"^6.0.0 || 6.0.0-SNAPSHOT","feature":{"flagName":"bedmanagement-module","label":"Ward App Patient Service","description":"This module, if installed, provides services for managing patients admitted to the ward."}}},"workspaces":[{"name":"admission-requests-cards","component":"admissionRequestWorkspace","title":"admissionRequests","type":"admission-requests"}],"pages":[{"component":"root","route":"ward"}],"version":"7.0.1-pre.3630"}
|
package/package.json
CHANGED
|
@@ -5,11 +5,11 @@ import WardPatientCard from '../ward-patient-card/ward-patient-card';
|
|
|
5
5
|
import { type WardBedProps } from '../ward-view/ward-bed.component';
|
|
6
6
|
import styles from './occupied-bed.scss';
|
|
7
7
|
|
|
8
|
-
const OccupiedBed: React.FC<WardBedProps> = ({
|
|
8
|
+
const OccupiedBed: React.FC<WardBedProps> = ({ wardPatients, bed }) => {
|
|
9
9
|
return (
|
|
10
10
|
<div className={styles.occupiedBed}>
|
|
11
|
-
{
|
|
12
|
-
const last = index ===
|
|
11
|
+
{wardPatients.map(({ patient, visit }, index: number) => {
|
|
12
|
+
const last = index === wardPatients.length - 1;
|
|
13
13
|
return (
|
|
14
14
|
<div key={'occupied-bed-pt-' + patient.uuid}>
|
|
15
15
|
<WardPatientCard patient={patient} visit={visit} bed={bed} />
|
|
@@ -5,6 +5,7 @@ import { mockAdmissionLocation } from '../../../../__mocks__/wards.mock';
|
|
|
5
5
|
import { bedLayoutToBed, filterBeds } from '../ward-view/ward-view.resource';
|
|
6
6
|
import { getDefaultsFromConfigSchema, useConfig } from '@openmrs/esm-framework';
|
|
7
7
|
import { configSchema, defaultPatientCardElementConfig } from '../config-schema';
|
|
8
|
+
import { mockAdmittedPatient } from '../../../../__mocks__/ward-patient';
|
|
8
9
|
|
|
9
10
|
const defaultConfig = getDefaultsFromConfigSchema(configSchema);
|
|
10
11
|
|
|
@@ -18,12 +19,12 @@ jest.replaceProperty(mockBedToUse.patients[0].person, 'preferredName', {
|
|
|
18
19
|
givenName: 'Alice',
|
|
19
20
|
familyName: 'Johnson',
|
|
20
21
|
});
|
|
21
|
-
const mockPatient = mockBedToUse.patients[0];
|
|
22
22
|
const mockBed = bedLayoutToBed(mockBedToUse);
|
|
23
23
|
|
|
24
24
|
describe('Occupied bed: ', () => {
|
|
25
25
|
it('renders a single bed with patient details', () => {
|
|
26
|
-
|
|
26
|
+
const mockPatient = mockAdmittedPatient.patient;
|
|
27
|
+
render(<OccupiedBed wardPatients={[{ ...mockAdmittedPatient, admitted: true }]} bed={mockBed} />);
|
|
27
28
|
const patientName = screen.getByText('Alice Johnson');
|
|
28
29
|
expect(patientName).toBeInTheDocument();
|
|
29
30
|
const patientAge = `${mockPatient.person.age} yrs`;
|
|
@@ -38,9 +39,9 @@ describe('Occupied bed: ', () => {
|
|
|
38
39
|
it('renders a divider for shared patients', () => {
|
|
39
40
|
render(
|
|
40
41
|
<OccupiedBed
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
{
|
|
42
|
+
wardPatients={[
|
|
43
|
+
{ ...mockAdmittedPatient, admitted: true },
|
|
44
|
+
{ ...mockAdmittedPatient, admitted: true },
|
|
44
45
|
]}
|
|
45
46
|
bed={mockBed}
|
|
46
47
|
/>,
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { type AdmittedPatient } from '../types';
|
|
3
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
4
|
+
|
|
5
|
+
export function useAdmittedPatients(locationUuid: string) {
|
|
6
|
+
const apiUrl = `/ws/rest/emrapi/inpatient/visits?currentLocation=${locationUuid}`;
|
|
7
|
+
const { data, ...rest } = useSWR<{ data: AdmittedPatient[] }, Error>(apiUrl, openmrsFetch);
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
admittedPatients: data?.data ?? null,
|
|
11
|
+
...rest,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { openmrsFetch
|
|
1
|
+
import { openmrsFetch } from '@openmrs/esm-framework';
|
|
2
2
|
import useSWR from 'swr';
|
|
3
3
|
import type { InpatientRequest } from '../types';
|
|
4
4
|
|
|
5
|
-
//TODO:The api is still in implementation stage and this is just a placeholder for the api
|
|
6
5
|
export function useInpatientRequest(locationUuid: string) {
|
|
7
|
-
const apiUrl =
|
|
6
|
+
const apiUrl = `/ws/rest/emrapi/inpatient/admissionRequests?admissionLocation=${locationUuid}`;
|
|
8
7
|
const { data, ...rest } = useSWR<{ data: Array<InpatientRequest> }, Error>(apiUrl, openmrsFetch);
|
|
9
8
|
|
|
10
9
|
return {
|
package/src/routes.json
CHANGED
package/src/types/index.ts
CHANGED
|
@@ -28,6 +28,10 @@ export const patientCardElementTypes = [
|
|
|
28
28
|
] as const;
|
|
29
29
|
export type PatientCardElementType = (typeof patientCardElementTypes)[number];
|
|
30
30
|
|
|
31
|
+
// a Ward Patient can either be a patient that is already admitted or a
|
|
32
|
+
// patient that is awaiting admission
|
|
33
|
+
export type WardPatient = (AdmittedPatient & { admitted: true }) | (InpatientRequest & { admitted: false });
|
|
34
|
+
|
|
31
35
|
// server-side types defined in openmrs-module-bedmanagement:
|
|
32
36
|
|
|
33
37
|
export interface AdmissionLocation {
|
|
@@ -79,17 +83,36 @@ interface BedTagMap {
|
|
|
79
83
|
|
|
80
84
|
export type BedStatus = 'AVAILABLE' | 'OCCUPIED';
|
|
81
85
|
|
|
86
|
+
// server-side types defined in openmrs-module-emrapi:
|
|
87
|
+
|
|
82
88
|
export type DispositionType = 'ADMISSION' | 'TRANSFER' | 'DISCHARGE';
|
|
83
89
|
|
|
90
|
+
// InpatientRequest[] returned by:
|
|
91
|
+
// GET /rest/emrapi/inpatient/admissionRequests
|
|
92
|
+
// GET /rest/emrapi/inpatient/transferRequests
|
|
93
|
+
// GET /rest/emrapi/inpatient/admissionAndTransferRequests
|
|
84
94
|
export interface InpatientRequest {
|
|
85
95
|
patient: Patient;
|
|
86
96
|
visit: Visit;
|
|
87
97
|
type: DispositionType;
|
|
98
|
+
|
|
99
|
+
// as of now, these fields are not included in the backend
|
|
88
100
|
encounter?: Encounter;
|
|
89
101
|
dispositionObs?: Observation;
|
|
90
102
|
dispositionLocation?: Location;
|
|
91
103
|
dispositionDate?: Date;
|
|
92
104
|
}
|
|
105
|
+
|
|
106
|
+
// AdmittedPatient[] returned by:
|
|
107
|
+
// GET /rest/emrapi/inpatient/visits
|
|
108
|
+
export interface AdmittedPatient {
|
|
109
|
+
patient: Patient;
|
|
110
|
+
visit: Visit;
|
|
111
|
+
currentLocation: Location;
|
|
112
|
+
timeSinceAdmissionInMinutes: number;
|
|
113
|
+
timeAtInpatientLocationInMinutes: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
93
116
|
// TODO: Move these types to esm-core
|
|
94
117
|
export interface Observation extends OpenmrsResourceStrict {
|
|
95
118
|
concept: OpenmrsResource;
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { type Visit, type Patient } from '@openmrs/esm-framework';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import EmptyBed from '../beds/empty-bed.component';
|
|
4
|
-
import { type Bed } from '../types';
|
|
4
|
+
import { type WardPatient, type Bed } from '../types';
|
|
5
5
|
import OccupiedBed from '../beds/occupied-bed.component';
|
|
6
6
|
export interface WardBedProps {
|
|
7
|
-
|
|
7
|
+
wardPatients: Array<WardPatient>;
|
|
8
8
|
bed: Bed;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
const WardBed: React.FC<WardBedProps> = ({ bed,
|
|
12
|
-
return
|
|
11
|
+
const WardBed: React.FC<WardBedProps> = ({ bed, wardPatients }) => {
|
|
12
|
+
return wardPatients?.length > 0 ? <OccupiedBed bed={bed} wardPatients={wardPatients} /> : <EmptyBed bed={bed} />;
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
export default WardBed;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { InlineNotification } from '@carbon/react';
|
|
2
2
|
import { WorkspaceContainer, useFeatureFlag, useLocations, useSession, type Location } from '@openmrs/esm-framework';
|
|
3
|
-
import React from 'react';
|
|
3
|
+
import React, { useMemo } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { useParams } from 'react-router-dom';
|
|
6
6
|
import EmptyBedSkeleton from '../beds/empty-bed-skeleton';
|
|
@@ -9,6 +9,8 @@ import WardBed from './ward-bed.component';
|
|
|
9
9
|
import { bedLayoutToBed, filterBeds } from './ward-view.resource';
|
|
10
10
|
import styles from './ward-view.scss';
|
|
11
11
|
import WardViewHeader from '../ward-view-header/ward-view-header.component';
|
|
12
|
+
import { type AdmittedPatient, type WardPatient } from '../types';
|
|
13
|
+
import { useAdmittedPatients } from '../hooks/useAdmittedPatients';
|
|
12
14
|
|
|
13
15
|
const WardView = () => {
|
|
14
16
|
const { locationUuid: locationUuidFromUrl } = useParams();
|
|
@@ -35,7 +37,7 @@ const WardView = () => {
|
|
|
35
37
|
/>
|
|
36
38
|
) : (
|
|
37
39
|
<div className={styles.wardView}>
|
|
38
|
-
<WardViewHeader location={location
|
|
40
|
+
<WardViewHeader location={location} />
|
|
39
41
|
<div className={styles.wardViewMain}>
|
|
40
42
|
<WardViewByLocation location={location} />
|
|
41
43
|
</div>
|
|
@@ -45,22 +47,59 @@ const WardView = () => {
|
|
|
45
47
|
};
|
|
46
48
|
|
|
47
49
|
const WardViewByLocation = ({ location }: { location: Location }) => {
|
|
48
|
-
const {
|
|
50
|
+
const {
|
|
51
|
+
admissionLocation,
|
|
52
|
+
isLoading: isLoadingLocation,
|
|
53
|
+
error: errorLoadingLocation,
|
|
54
|
+
} = useAdmissionLocation(location.uuid);
|
|
55
|
+
const {
|
|
56
|
+
admittedPatients,
|
|
57
|
+
isLoading: isLoadingPatients,
|
|
58
|
+
error: errorLoadingPatients,
|
|
59
|
+
} = useAdmittedPatients(location.uuid);
|
|
49
60
|
const { t } = useTranslation();
|
|
61
|
+
const admittedPatientsByUuid = useMemo(() => {
|
|
62
|
+
const map = new Map<string, AdmittedPatient>();
|
|
63
|
+
for (const admittedPatient of admittedPatients ?? []) {
|
|
64
|
+
map.set(admittedPatient.patient.uuid, admittedPatient);
|
|
65
|
+
}
|
|
66
|
+
return map;
|
|
67
|
+
}, [admittedPatients]);
|
|
50
68
|
|
|
51
|
-
if (admissionLocation) {
|
|
69
|
+
if (admissionLocation != null && admittedPatients != null) {
|
|
52
70
|
const bedLayouts = filterBeds(admissionLocation);
|
|
53
71
|
|
|
72
|
+
const wardBeds = bedLayouts.map((bedLayout, i) => {
|
|
73
|
+
const { patients } = bedLayout;
|
|
74
|
+
const bed = bedLayoutToBed(bedLayout);
|
|
75
|
+
const wardPatients: WardPatient[] = patients.map((patient) => {
|
|
76
|
+
const admittedPatient = admittedPatientsByUuid.get(patient.uuid);
|
|
77
|
+
|
|
78
|
+
if (admittedPatient) {
|
|
79
|
+
// ideally, we can just use the patient object within admittedPatient
|
|
80
|
+
// and not need the one from bedLayouts, however, the emr api
|
|
81
|
+
// does not respect custom representation right now and does not return
|
|
82
|
+
// all required fields for the patient object
|
|
83
|
+
return { ...admittedPatient, admitted: true };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// patient assigned a bed but *not* admitted
|
|
87
|
+
// TODO: get the patient's visit and current location
|
|
88
|
+
return {
|
|
89
|
+
patient,
|
|
90
|
+
visit: null,
|
|
91
|
+
admitted: true,
|
|
92
|
+
currentLocation: null,
|
|
93
|
+
timeSinceAdmissionInMinutes: null,
|
|
94
|
+
timeAtInpatientLocationInMinutes: null,
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
return <WardBed key={bed.uuid} bed={bed} wardPatients={wardPatients} />;
|
|
98
|
+
});
|
|
99
|
+
|
|
54
100
|
return (
|
|
55
101
|
<>
|
|
56
|
-
{
|
|
57
|
-
const { patients } = bedLayout;
|
|
58
|
-
const bed = bedLayoutToBed(bedLayout);
|
|
59
|
-
|
|
60
|
-
// TODO: replace visit field with real value fetched from useAdmissionLocation (or replacement API)
|
|
61
|
-
const patientInfos = patients.map((patient) => ({ patient, visit: null }));
|
|
62
|
-
return <WardBed key={bed.uuid} bed={bed} patientInfos={patientInfos} />;
|
|
63
|
-
})}
|
|
102
|
+
{wardBeds}
|
|
64
103
|
{bedLayouts.length == 0 && (
|
|
65
104
|
<InlineNotification
|
|
66
105
|
kind="warning"
|
|
@@ -70,7 +109,7 @@ const WardViewByLocation = ({ location }: { location: Location }) => {
|
|
|
70
109
|
)}
|
|
71
110
|
</>
|
|
72
111
|
);
|
|
73
|
-
} else if (
|
|
112
|
+
} else if (isLoadingLocation || isLoadingPatients) {
|
|
74
113
|
return (
|
|
75
114
|
<>
|
|
76
115
|
{Array(20)
|
|
@@ -80,18 +119,27 @@ const WardViewByLocation = ({ location }: { location: Location }) => {
|
|
|
80
119
|
))}
|
|
81
120
|
</>
|
|
82
121
|
);
|
|
83
|
-
} else {
|
|
122
|
+
} else if (errorLoadingLocation) {
|
|
84
123
|
return (
|
|
85
124
|
<InlineNotification
|
|
86
125
|
kind="error"
|
|
87
126
|
lowContrast={true}
|
|
88
127
|
title={t('errorLoadingWardLocation', 'Error loading ward location')}
|
|
89
128
|
subtitle={
|
|
90
|
-
|
|
129
|
+
errorLoadingLocation?.message ??
|
|
91
130
|
t('invalidWardLocation', 'Invalid ward location: {{location}}', { location: location.display })
|
|
92
131
|
}
|
|
93
132
|
/>
|
|
94
133
|
);
|
|
134
|
+
} else {
|
|
135
|
+
return (
|
|
136
|
+
<InlineNotification
|
|
137
|
+
kind="error"
|
|
138
|
+
lowContrast={true}
|
|
139
|
+
title={t('errorLoadingPatients', 'Error loading admitted patients')}
|
|
140
|
+
subtitle={errorLoadingPatients?.message}
|
|
141
|
+
/>
|
|
142
|
+
);
|
|
95
143
|
}
|
|
96
144
|
};
|
|
97
145
|
|
|
@@ -16,6 +16,7 @@ import { configSchema } from '../config-schema';
|
|
|
16
16
|
import { useAdmissionLocation } from '../hooks/useAdmissionLocation';
|
|
17
17
|
import WardView from './ward-view.component';
|
|
18
18
|
import { mockPatientAlice } from '../../../../__mocks__/patient.mock';
|
|
19
|
+
import { useAdmittedPatients } from '../hooks/useAdmittedPatients';
|
|
19
20
|
|
|
20
21
|
jest.replaceProperty(mockPatientAlice.person as Person, 'preferredName', {
|
|
21
22
|
uuid: '',
|
|
@@ -52,6 +53,10 @@ const mockedUseParams = useParams as jest.Mock;
|
|
|
52
53
|
jest.mock('../hooks/useAdmissionLocation', () => ({
|
|
53
54
|
useAdmissionLocation: jest.fn(),
|
|
54
55
|
}));
|
|
56
|
+
jest.mock('../hooks/useAdmittedPatients', () => ({
|
|
57
|
+
useAdmittedPatients: jest.fn(),
|
|
58
|
+
}));
|
|
59
|
+
|
|
55
60
|
jest.mocked(useAdmissionLocation).mockReturnValue({
|
|
56
61
|
error: undefined,
|
|
57
62
|
mutate: jest.fn(),
|
|
@@ -59,6 +64,13 @@ jest.mocked(useAdmissionLocation).mockReturnValue({
|
|
|
59
64
|
isLoading: false,
|
|
60
65
|
admissionLocation: mockAdmissionLocation,
|
|
61
66
|
});
|
|
67
|
+
jest.mocked(useAdmittedPatients).mockReturnValue({
|
|
68
|
+
error: undefined,
|
|
69
|
+
mutate: jest.fn(),
|
|
70
|
+
isValidating: false,
|
|
71
|
+
isLoading: false,
|
|
72
|
+
admittedPatients: [],
|
|
73
|
+
});
|
|
62
74
|
|
|
63
75
|
describe('WardView:', () => {
|
|
64
76
|
it('renders the session location when no location provided in URL', () => {
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Movement } from '@carbon/react/icons';
|
|
3
|
-
import styles from './admission-requests.scss';
|
|
4
|
-
import { launchWorkspace, showNotification } from '@openmrs/esm-framework';
|
|
5
|
-
import { useInpatientRequest } from '../hooks/useInpatientRequest';
|
|
6
|
-
import { useParams } from 'react-router-dom';
|
|
7
1
|
import { SkeletonIcon } from '@carbon/react';
|
|
2
|
+
import { Movement } from '@carbon/react/icons';
|
|
3
|
+
import { launchWorkspace, showNotification, type Location } from '@openmrs/esm-framework';
|
|
4
|
+
import React from 'react';
|
|
8
5
|
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import { useInpatientRequest } from '../hooks/useInpatientRequest';
|
|
7
|
+
import styles from './admission-requests.scss';
|
|
8
|
+
|
|
9
|
+
interface AdmissionRequestsBarProps {
|
|
10
|
+
location: Location;
|
|
11
|
+
}
|
|
9
12
|
|
|
10
|
-
const AdmissionRequestsBar = () => {
|
|
11
|
-
const {
|
|
12
|
-
const { inpatientRequests, isLoading, error } = useInpatientRequest(locationUuid);
|
|
13
|
+
const AdmissionRequestsBar: React.FC<AdmissionRequestsBarProps> = ({ location }) => {
|
|
14
|
+
const { inpatientRequests, isLoading, error } = useInpatientRequest(location.uuid);
|
|
13
15
|
const admissionRequests = inpatientRequests?.filter((request) => request.type == 'ADMISSION');
|
|
14
16
|
const { t } = useTranslation();
|
|
15
17
|
|
|
@@ -4,8 +4,9 @@ import { screen } from '@testing-library/react';
|
|
|
4
4
|
import { launchWorkspace } from '@openmrs/esm-framework';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import AdmissionRequestsBar from './admission-requests-bar.component';
|
|
7
|
-
import { mockInpatientRequest } from '../../../../__mocks__/
|
|
7
|
+
import { mockInpatientRequest } from '../../../../__mocks__/ward-patient';
|
|
8
8
|
import { useInpatientRequest } from '../hooks/useInpatientRequest';
|
|
9
|
+
import { mockLocationInpatientWard } from '../../../../__mocks__/locations.mock';
|
|
9
10
|
|
|
10
11
|
jest.mock('@openmrs/esm-framework', () => {
|
|
11
12
|
return {
|
|
@@ -29,13 +30,13 @@ jest.mocked(useInpatientRequest).mockReturnValue(mockInpatientRequestResponse);
|
|
|
29
30
|
describe('Admission Requests Button', () => {
|
|
30
31
|
it('call launch workspace when clicked on manage button', async () => {
|
|
31
32
|
const user = userEvent.setup();
|
|
32
|
-
renderWithSwr(<AdmissionRequestsBar />);
|
|
33
|
+
renderWithSwr(<AdmissionRequestsBar location={mockLocationInpatientWard} />);
|
|
33
34
|
await user.click(screen.getByRole('button', { name: /manage/i }));
|
|
34
35
|
expect(launchWorkspace).toHaveBeenCalled();
|
|
35
36
|
});
|
|
36
37
|
|
|
37
38
|
it('there should be one admission request', () => {
|
|
38
|
-
const { getByText } = renderWithSwr(<AdmissionRequestsBar />);
|
|
39
|
+
const { getByText } = renderWithSwr(<AdmissionRequestsBar location={mockLocationInpatientWard} />);
|
|
39
40
|
expect(getByText('1 admission requests')).toBeInTheDocument();
|
|
40
41
|
});
|
|
41
42
|
});
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styles from './ward-view-header.scss';
|
|
3
3
|
import AdmissionRequestsBar from './admission-requests-bar.component';
|
|
4
|
+
import { type Location } from '@openmrs/esm-framework';
|
|
4
5
|
|
|
5
6
|
interface WardViewHeaderProps {
|
|
6
|
-
location:
|
|
7
|
+
location: Location;
|
|
7
8
|
}
|
|
8
9
|
const WardViewHeader: React.FC<WardViewHeaderProps> = ({ location }) => {
|
|
9
10
|
return (
|
|
10
11
|
<div className={styles.wardViewHeader}>
|
|
11
|
-
<h4>{location}</h4>
|
|
12
|
-
<AdmissionRequestsBar />
|
|
12
|
+
<h4>{location.display}</h4>
|
|
13
|
+
<AdmissionRequestsBar location={location} />
|
|
13
14
|
</div>
|
|
14
15
|
);
|
|
15
16
|
};
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
} from '@openmrs/esm-framework';
|
|
11
11
|
import { configSchema } from '../config-schema';
|
|
12
12
|
import { useInpatientRequest } from '../hooks/useInpatientRequest';
|
|
13
|
-
import { mockInpatientRequest } from '../../../../__mocks__/
|
|
13
|
+
import { mockInpatientRequest } from '../../../../__mocks__/ward-patient';
|
|
14
14
|
|
|
15
15
|
jest.replaceProperty(mockInpatientRequest.patient.person as Person, 'preferredName', {
|
|
16
16
|
uuid: '',
|
package/translations/en.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"bedShare": "Bed share",
|
|
3
3
|
"emptyBed": "Empty bed",
|
|
4
|
+
"errorLoadingPatientAdmissionRequests": "Error Loading Patient Admission Requests",
|
|
4
5
|
"errorLoadingWardLocation": "Error loading ward location",
|
|
5
6
|
"invalidLocationSpecified": "Invalid location specified",
|
|
6
7
|
"invalidWardLocation": "Invalid ward location: {{location}}",
|
|
7
8
|
"noBedsConfigured": "No beds configured for this location",
|
|
8
|
-
"unknownLocationUuid": "Unknown location uuid: {{locationUuidFromUrl}}"
|
|
9
|
-
"admissionRequests":"Admission Requests",
|
|
10
|
-
"errorLoadingPatientAdmissionRequests":"Error Loading Patient Admission Requests"
|
|
9
|
+
"unknownLocationUuid": "Unknown location uuid: {{locationUuidFromUrl}}"
|
|
11
10
|
}
|