@openmrs/esm-service-queues-app 5.0.1-pre.2087
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 +40 -0
- package/LICENSE.md +401 -0
- package/README.md +23 -0
- package/__mocks__/active-visits.mock.ts +97 -0
- package/__mocks__/appointments-data.mock.ts +283 -0
- package/__mocks__/search.mock.ts +35 -0
- package/__mocks__/visits.mock.ts +42 -0
- package/dist/121.js +1 -0
- package/dist/121.js.map +1 -0
- package/dist/130.js +2 -0
- package/dist/130.js.LICENSE.txt +5 -0
- package/dist/130.js.map +1 -0
- package/dist/176.js +1 -0
- package/dist/176.js.map +1 -0
- package/dist/227.js +1 -0
- package/dist/227.js.map +1 -0
- package/dist/242.js +1 -0
- package/dist/242.js.map +1 -0
- package/dist/252.js +1 -0
- package/dist/252.js.map +1 -0
- package/dist/286.js +1 -0
- package/dist/286.js.map +1 -0
- package/dist/308.js +1 -0
- package/dist/308.js.map +1 -0
- package/dist/319.js +1 -0
- package/dist/328.js +1 -0
- package/dist/328.js.map +1 -0
- package/dist/330.js +1 -0
- package/dist/330.js.map +1 -0
- package/dist/364.js +1 -0
- package/dist/364.js.map +1 -0
- package/dist/425.js +1 -0
- package/dist/425.js.map +1 -0
- package/dist/457.js +1 -0
- package/dist/457.js.map +1 -0
- package/dist/469.js +1 -0
- package/dist/469.js.map +1 -0
- package/dist/521.js +1 -0
- package/dist/521.js.map +1 -0
- package/dist/53.js +1 -0
- package/dist/53.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/591.js +2 -0
- package/dist/591.js.LICENSE.txt +32 -0
- package/dist/591.js.map +1 -0
- package/dist/610.js +1 -0
- package/dist/610.js.map +1 -0
- package/dist/611.js +1 -0
- package/dist/611.js.map +1 -0
- package/dist/616.js +1 -0
- package/dist/616.js.map +1 -0
- package/dist/644.js +1 -0
- package/dist/644.js.map +1 -0
- package/dist/670.js +2 -0
- package/dist/670.js.LICENSE.txt +57 -0
- package/dist/670.js.map +1 -0
- package/dist/733.js +1 -0
- package/dist/733.js.map +1 -0
- package/dist/757.js +1 -0
- package/dist/764.js +1 -0
- package/dist/764.js.map +1 -0
- package/dist/766.js +1 -0
- package/dist/766.js.map +1 -0
- package/dist/784.js +2 -0
- package/dist/784.js.LICENSE.txt +9 -0
- package/dist/784.js.map +1 -0
- package/dist/788.js +1 -0
- package/dist/807.js +1 -0
- package/dist/833.js +1 -0
- package/dist/86.js +1 -0
- package/dist/86.js.map +1 -0
- package/dist/981.js +1 -0
- package/dist/981.js.map +1 -0
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -0
- package/dist/openmrs-esm-service-queues-app.js +1 -0
- package/dist/openmrs-esm-service-queues-app.js.buildmanifest.json +930 -0
- package/dist/openmrs-esm-service-queues-app.js.map +1 -0
- package/dist/routes.json +1 -0
- package/jest.config.js +3 -0
- package/package.json +53 -0
- package/src/active-visits/active-visits-tab.component.tsx +71 -0
- package/src/active-visits/active-visits-tab.test.tsx +19 -0
- package/src/active-visits/active-visits-table.component.tsx +543 -0
- package/src/active-visits/active-visits-table.resource.ts +443 -0
- package/src/active-visits/active-visits-table.scss +271 -0
- package/src/active-visits/active-visits-table.test.tsx +131 -0
- package/src/active-visits/change-status-dialog.component.tsx +233 -0
- package/src/active-visits/change-status-dialog.scss +32 -0
- package/src/active-visits/change-status-dialog.test.tsx +107 -0
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +218 -0
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +32 -0
- package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +236 -0
- package/src/add-provider-queue-room/add-provider-queue-room.resource.tsx +76 -0
- package/src/add-provider-queue-room/add-provider-queue-room.scss +17 -0
- package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +98 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +74 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.resource.tsx +46 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +15 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +42 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries.component.tsx +36 -0
- package/src/config-schema.ts +177 -0
- package/src/constants.ts +7 -0
- package/src/createDashboardLink.tsx +35 -0
- package/src/current-visit/current-visit-summary.component.tsx +38 -0
- package/src/current-visit/current-visit-summary.test.tsx +47 -0
- package/src/current-visit/current-visit.resource.ts +84 -0
- package/src/current-visit/current-visit.scss +34 -0
- package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +101 -0
- package/src/current-visit/visit-details/biometrics-config-schema.ts +14 -0
- package/src/current-visit/visit-details/current-visit-details.component.tsx +96 -0
- package/src/current-visit/visit-details/triage-note.component.tsx +53 -0
- package/src/current-visit/visit-details/triage-note.scss +89 -0
- package/src/current-visit/visit-details/vitals-config-schema.ts +17 -0
- package/src/current-visit/visit-details/vitals.component.tsx +164 -0
- package/src/dashboard.meta.ts +5 -0
- package/src/declarations.d.ts +2 -0
- package/src/helpers/functions.ts +67 -0
- package/src/helpers/helpers.ts +170 -0
- package/src/helpers/time-helpers.ts +15 -0
- package/src/home.component.tsx +29 -0
- package/src/home.test.tsx +58 -0
- package/src/index.ts +100 -0
- package/src/overlay.component.tsx +46 -0
- package/src/overlay.scss +96 -0
- package/src/overlay.test.tsx +49 -0
- package/src/past-visit/past-visit-details/encounter-list.component.tsx +51 -0
- package/src/past-visit/past-visit-details/medications-list.component.tsx +95 -0
- package/src/past-visit/past-visit-details/notes-list.component.tsx +40 -0
- package/src/past-visit/past-visit-details/past-visit-summary.component.tsx +172 -0
- package/src/past-visit/past-visit-details/past-visit-summary.scss +58 -0
- package/src/past-visit/past-visit.component.tsx +37 -0
- package/src/past-visit/past-visit.resource.ts +83 -0
- package/src/past-visit/past-visit.scss +126 -0
- package/src/past-visit/past-visit.test.tsx +41 -0
- package/src/patient-info/appointment-details.component.tsx +98 -0
- package/src/patient-info/appointment-details.scss +34 -0
- package/src/patient-info/appointment-details.test.tsx +36 -0
- package/src/patient-info/appointments.resource.tsx +43 -0
- package/src/patient-info/contact-details.component.tsx +71 -0
- package/src/patient-info/contact-details.scss +31 -0
- package/src/patient-info/contact-details.test.tsx +94 -0
- package/src/patient-info/hooks/usePatientAttributes.tsx +42 -0
- package/src/patient-info/patient-info.component.tsx +78 -0
- package/src/patient-info/patient-info.scss +60 -0
- package/src/patient-info/patient-info.test.tsx +45 -0
- package/src/patient-queue-header/patient-queue-header.component.tsx +64 -0
- package/src/patient-queue-header/patient-queue-header.scss +88 -0
- package/src/patient-queue-header/patient-queue-illustration.component.tsx +22 -0
- package/src/patient-queue-metrics/clinic-metrics.component.tsx +93 -0
- package/src/patient-queue-metrics/clinic-metrics.resource.tsx +51 -0
- package/src/patient-queue-metrics/clinic-metrics.scss +11 -0
- package/src/patient-queue-metrics/clinic-metrics.test.tsx +87 -0
- package/src/patient-queue-metrics/metrics-card.component.tsx +64 -0
- package/src/patient-queue-metrics/metrics-card.scss +80 -0
- package/src/patient-queue-metrics/metrics-header.component.tsx +74 -0
- package/src/patient-queue-metrics/metrics-header.scss +22 -0
- package/src/patient-queue-metrics/queue-metrics.resource.ts +54 -0
- package/src/patient-search/advanced-search.component.tsx +190 -0
- package/src/patient-search/advanced-search.scss +154 -0
- package/src/patient-search/advanced-search.test.tsx +29 -0
- package/src/patient-search/basic-search.component.tsx +112 -0
- package/src/patient-search/basic-search.scss +139 -0
- package/src/patient-search/basic-search.test.tsx +23 -0
- package/src/patient-search/empty-data-illustration.component.tsx +41 -0
- package/src/patient-search/hooks/useActivePatientEnrollment.tsx +29 -0
- package/src/patient-search/hooks/useDefaultLocation.tsx +14 -0
- package/src/patient-search/hooks/usePatients.tsx +25 -0
- package/src/patient-search/hooks/useQueueLocations.tsx +20 -0
- package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +36 -0
- package/src/patient-search/hooks/useScheduledVisits.tsx +50 -0
- package/src/patient-search/patient-scheduled-visits.component.tsx +350 -0
- package/src/patient-search/patient-scheduled-visits.scss +131 -0
- package/src/patient-search/patient-scheduled-visits.test.tsx +55 -0
- package/src/patient-search/patient-search.component.tsx +64 -0
- package/src/patient-search/search-illustration.component.tsx +27 -0
- package/src/patient-search/search-results.component.tsx +75 -0
- package/src/patient-search/search-results.scss +80 -0
- package/src/patient-search/search-results.test.tsx +77 -0
- package/src/patient-search/search.resource.ts +10 -0
- package/src/patient-search/visit-form/base-visit-type.component.tsx +82 -0
- package/src/patient-search/visit-form/base-visit-type.scss +100 -0
- package/src/patient-search/visit-form/base-visit-type.test.tsx +41 -0
- package/src/patient-search/visit-form/queue.resource.ts +73 -0
- package/src/patient-search/visit-form/recommended-visit-type.component.tsx +38 -0
- package/src/patient-search/visit-form/visit-form.component.tsx +366 -0
- package/src/patient-search/visit-form/visit-form.scss +96 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +160 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +21 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +67 -0
- package/src/queue-entry-table-components/actions-menu.component.tsx +51 -0
- package/src/queue-entry-table-components/actions-menu.scss +3 -0
- package/src/queue-entry-table-components/edit-entry.component.tsx +28 -0
- package/src/queue-entry-table-components/edit-entry.scss +14 -0
- package/src/queue-entry-table-components/open-chart.component.tsx +33 -0
- package/src/queue-entry-table-components/open-chart.resource.tsx +14 -0
- package/src/queue-entry-table-components/open-chart.scss +14 -0
- package/src/queue-entry-table-components/status-icon.component.tsx +17 -0
- package/src/queue-entry-table-components/transition-entry.component.tsx +53 -0
- package/src/queue-entry-table-components/transition-entry.scss +22 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +230 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.scss +110 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +118 -0
- package/src/queue-patient-linelists/queue-linelist-filter.component.tsx +172 -0
- package/src/queue-patient-linelists/queue-linelist-filter.scss +63 -0
- package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +76 -0
- package/src/queue-patient-linelists/queue-linelist.component.tsx +29 -0
- package/src/queue-patient-linelists/queue-linelist.resource.tsx +84 -0
- package/src/queue-patient-linelists/queue-linelist.test.tsx +22 -0
- package/src/queue-patient-linelists/queue-services-table.component.tsx +63 -0
- package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +300 -0
- package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +42 -0
- package/src/queue-rooms/queue-room-form.component.tsx +168 -0
- package/src/queue-rooms/queue-room-form.test.tsx +65 -0
- package/src/queue-rooms/queue-room.resource.tsx +20 -0
- package/src/queue-rooms/queue-room.scss +58 -0
- package/src/queue-screen/queue-screen.component.tsx +47 -0
- package/src/queue-screen/queue-screen.scss +39 -0
- package/src/queue-screen/queue-screen.test.tsx +47 -0
- package/src/queue-screen/useActiveTickets.tsx +13 -0
- package/src/queue-services/queue-service-form.component.tsx +183 -0
- package/src/queue-services/queue-service-form.test.tsx +56 -0
- package/src/queue-services/queue-service.resource.tsx +38 -0
- package/src/queue-services/queue-service.scss +54 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +95 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.resource.tsx +93 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.scss +8 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +44 -0
- package/src/root.component.tsx +28 -0
- package/src/root.scss +15 -0
- package/src/root.test.tsx +28 -0
- package/src/routes.json +91 -0
- package/src/side-menu/nav-group/createNavGroup.tsx +17 -0
- package/src/side-menu/nav-group/nav-group.component.tsx +24 -0
- package/src/side-menu/nav-group/nav-group.test.tsx +32 -0
- package/src/side-menu/nav-group/nav-group.ts +10 -0
- package/src/side-menu/side-menu.component.tsx +6 -0
- package/src/side-menu/side-menu.test.tsx +17 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +174 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.scss +12 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +95 -0
- package/src/transition-queue-entry/transition-queue-entry.resource.ts +16 -0
- package/src/types/index.ts +434 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +298 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +93 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.scss +108 -0
- package/translations/am.json +258 -0
- package/translations/en.json +258 -0
- package/translations/es.json +258 -0
- package/translations/fr.json +258 -0
- package/translations/he.json +262 -0
- package/translations/km.json +258 -0
- package/tsconfig.json +5 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { getGlobalStore } from '@openmrs/esm-framework';
|
|
3
|
+
import type { AppointmentSummary } from '../types';
|
|
4
|
+
|
|
5
|
+
export const getServiceCountByAppointmentType = (
|
|
6
|
+
appointmentSummary: Array<AppointmentSummary>,
|
|
7
|
+
appointmentType: string,
|
|
8
|
+
) => {
|
|
9
|
+
return appointmentSummary
|
|
10
|
+
.map((appointment) =>
|
|
11
|
+
Object.entries(appointment.appointmentCountMap).flatMap((appointment) => appointment[1][appointmentType]),
|
|
12
|
+
)
|
|
13
|
+
.flat(1)
|
|
14
|
+
.reduce((count, val) => count + val, 0);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const initialServiceNameState = { serviceName: localStorage.getItem('queueServiceName') };
|
|
18
|
+
const initialServiceUuidState = { serviceUuid: localStorage.getItem('queueServiceUuid') };
|
|
19
|
+
const intialStatusNameState = { status: '' };
|
|
20
|
+
const initialQueueLocationNameState = { queueLocationName: localStorage.getItem('queueLocationName') };
|
|
21
|
+
const initialQueueLocationUuidState = { queueLocationUuid: localStorage.getItem('queueLocationUuid') };
|
|
22
|
+
const initialSelectedQueueRoomTimestamp = { providerQueueRoomTimestamp: new Date() };
|
|
23
|
+
const initialPermanentProviderQueueRoomState = {
|
|
24
|
+
isPermanentProviderQueueRoom: localStorage.getItem('isPermanentProviderQueueRoom'),
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export function getSelectedServiceName() {
|
|
28
|
+
return getGlobalStore<{ serviceName: string }>('queueSelectedServiceName', initialServiceNameState);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getSelectedServiceUuid() {
|
|
32
|
+
return getGlobalStore<{ serviceUuid: string }>('queueSelectedServiceUuid', initialServiceUuidState);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function getSelectedAppointmentStatus() {
|
|
36
|
+
return getGlobalStore<{ status: string }>('appointmentSelectedStatus', intialStatusNameState);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getSelectedQueueLocationName() {
|
|
40
|
+
return getGlobalStore<{ queueLocationName: string }>('queueLocationNameSelected', initialQueueLocationNameState);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function getSelectedQueueLocationUuid() {
|
|
44
|
+
return getGlobalStore<{ queueLocationUuid: string }>('queueLocationUuidSelected', initialQueueLocationUuidState);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getSelectedQueueRoomTimestamp() {
|
|
48
|
+
return getGlobalStore<{ providerQueueRoomTimestamp: Date }>(
|
|
49
|
+
'queueProviderRoomTimestamp',
|
|
50
|
+
initialSelectedQueueRoomTimestamp,
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function getIsPermanentProviderQueueRoom() {
|
|
55
|
+
return getGlobalStore<{ isPermanentProviderQueueRoom: string }>(
|
|
56
|
+
'isPermanentProviderQueueRoom',
|
|
57
|
+
initialPermanentProviderQueueRoomState,
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const updateSelectedServiceName = (currentServiceName: string) => {
|
|
62
|
+
const store = getSelectedServiceName();
|
|
63
|
+
store.setState({ serviceName: currentServiceName });
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const updateSelectedServiceUuid = (currentServiceUuid: string) => {
|
|
67
|
+
const store = getSelectedServiceUuid();
|
|
68
|
+
store.setState({ serviceUuid: currentServiceUuid });
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export const updateSelectedAppointmentStatus = (currentAppointmentStatus: string) => {
|
|
72
|
+
const store = getSelectedAppointmentStatus();
|
|
73
|
+
store.setState({ status: currentAppointmentStatus });
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export const updateSelectedQueueLocationName = (currentLocationName: string) => {
|
|
77
|
+
const store = getSelectedQueueLocationName();
|
|
78
|
+
store.setState({ queueLocationName: currentLocationName });
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const updateSelectedQueueLocationUuid = (currentLocationUuid: string) => {
|
|
82
|
+
const store = getSelectedQueueLocationUuid();
|
|
83
|
+
store.setState({ queueLocationUuid: currentLocationUuid });
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const updatedSelectedQueueRoomTimestamp = (currentProviderRoomTimestamp: Date) => {
|
|
87
|
+
const store = getSelectedQueueRoomTimestamp();
|
|
88
|
+
store.setState({ providerQueueRoomTimestamp: currentProviderRoomTimestamp });
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const updateIsPermanentProviderQueueRoom = (currentIsPermanentProviderQueueRoom) => {
|
|
92
|
+
const store = getIsPermanentProviderQueueRoom();
|
|
93
|
+
store.setState({ isPermanentProviderQueueRoom: currentIsPermanentProviderQueueRoom });
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
export const useSelectedServiceName = () => {
|
|
97
|
+
const [currentServiceName, setCurrentServiceName] = useState(initialServiceNameState.serviceName ?? '');
|
|
98
|
+
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
getSelectedServiceName().subscribe(({ serviceName }) => setCurrentServiceName(serviceName));
|
|
101
|
+
}, []);
|
|
102
|
+
|
|
103
|
+
return currentServiceName;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const useSelectedServiceUuid = () => {
|
|
107
|
+
const [currentServiceUuid, setCurrentServiceUuid] = useState(initialServiceUuidState.serviceUuid);
|
|
108
|
+
|
|
109
|
+
useEffect(() => {
|
|
110
|
+
getSelectedServiceUuid().subscribe(({ serviceUuid }) => setCurrentServiceUuid(serviceUuid));
|
|
111
|
+
}, []);
|
|
112
|
+
return currentServiceUuid;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export const useSelectedAppointmentStatus = () => {
|
|
116
|
+
const [currentAppointmentStatus, setCurrentAppointmentStatus] = useState(intialStatusNameState.status);
|
|
117
|
+
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
getSelectedAppointmentStatus().subscribe(({ status }) => setCurrentAppointmentStatus(status));
|
|
120
|
+
}, []);
|
|
121
|
+
return currentAppointmentStatus;
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
export const useSelectedQueueLocationName = () => {
|
|
125
|
+
const [currentQueueLocationName, setCurrentQueueLocationName] = useState(
|
|
126
|
+
initialQueueLocationNameState.queueLocationName,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
getSelectedQueueLocationName().subscribe(({ queueLocationName }) => setCurrentQueueLocationName(queueLocationName));
|
|
131
|
+
}, []);
|
|
132
|
+
return currentQueueLocationName;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export const useSelectedQueueLocationUuid = () => {
|
|
136
|
+
const [currentQueueLocationUuid, setCurrentQueueLocationUuid] = useState(
|
|
137
|
+
initialQueueLocationUuidState.queueLocationUuid,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
useEffect(() => {
|
|
141
|
+
getSelectedQueueLocationUuid().subscribe(({ queueLocationUuid }) => setCurrentQueueLocationUuid(queueLocationUuid));
|
|
142
|
+
}, []);
|
|
143
|
+
return currentQueueLocationUuid;
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export const useSelectedProviderRoomTimestamp = () => {
|
|
147
|
+
const [currentProviderRoomTimestamp, setCurrentProviderRoomTimestamp] = useState(
|
|
148
|
+
initialSelectedQueueRoomTimestamp.providerQueueRoomTimestamp,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
useEffect(() => {
|
|
152
|
+
getSelectedQueueRoomTimestamp().subscribe(({ providerQueueRoomTimestamp }) =>
|
|
153
|
+
setCurrentProviderRoomTimestamp(providerQueueRoomTimestamp),
|
|
154
|
+
);
|
|
155
|
+
}, []);
|
|
156
|
+
return currentProviderRoomTimestamp;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export const useIsPermanentProviderQueueRoom = () => {
|
|
160
|
+
const [currentIsPermanentProviderQueueRoom, setCurrentIsPermanentProviderQueueRoom] = useState(
|
|
161
|
+
initialPermanentProviderQueueRoomState.isPermanentProviderQueueRoom,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
useEffect(() => {
|
|
165
|
+
getIsPermanentProviderQueueRoom().subscribe(({ isPermanentProviderQueueRoom }) =>
|
|
166
|
+
setCurrentIsPermanentProviderQueueRoom(isPermanentProviderQueueRoom),
|
|
167
|
+
);
|
|
168
|
+
}, []);
|
|
169
|
+
return currentIsPermanentProviderQueueRoom;
|
|
170
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type amPm = 'AM' | 'PM';
|
|
2
|
+
|
|
3
|
+
export const convertTime12to24 = (time12h, timeFormat: amPm) => {
|
|
4
|
+
let [hours, minutes] = time12h.split(':');
|
|
5
|
+
|
|
6
|
+
if (hours === '12' && timeFormat === 'AM') {
|
|
7
|
+
hours = '00';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (timeFormat === 'PM') {
|
|
11
|
+
hours = hours === '12' ? hours : parseInt(hours, 10) + 12;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return [hours, minutes];
|
|
15
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ActiveVisitsTable from './active-visits/active-visits-table.component';
|
|
3
|
+
import ActiveVisitsTabs from './active-visits/active-visits-tab.component';
|
|
4
|
+
import ClinicMetrics from './patient-queue-metrics/clinic-metrics.component';
|
|
5
|
+
import { ConfigObject, useConfig } from '@openmrs/esm-framework';
|
|
6
|
+
import PatientQueueHeader from './patient-queue-header/patient-queue-header.component';
|
|
7
|
+
import QueueScreen from './queue-screen/queue-screen.component';
|
|
8
|
+
|
|
9
|
+
interface HomeProps {}
|
|
10
|
+
|
|
11
|
+
const Home: React.FC<HomeProps> = (props) => {
|
|
12
|
+
const config = useConfig() as ConfigObject;
|
|
13
|
+
const useQueueTableTabs = config.showQueueTableTab;
|
|
14
|
+
const pathName = window.location.pathname;
|
|
15
|
+
const activeTicketScreen = pathName.substring(pathName.lastIndexOf('/') + 1);
|
|
16
|
+
|
|
17
|
+
if (activeTicketScreen === 'screen') {
|
|
18
|
+
return <QueueScreen />;
|
|
19
|
+
}
|
|
20
|
+
return (
|
|
21
|
+
<div>
|
|
22
|
+
<PatientQueueHeader />
|
|
23
|
+
<ClinicMetrics />
|
|
24
|
+
{useQueueTableTabs === true ? <ActiveVisitsTabs /> : <ActiveVisitsTable />}
|
|
25
|
+
</div>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default Home;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import Home from './home.component';
|
|
4
|
+
import { useConfig } from '@openmrs/esm-framework';
|
|
5
|
+
|
|
6
|
+
const mockedUseConfig = useConfig as jest.Mock;
|
|
7
|
+
|
|
8
|
+
jest.mock('@openmrs/esm-framework', () => ({
|
|
9
|
+
...jest.requireActual('@openmrs/esm-framework'),
|
|
10
|
+
useConfig: jest.fn(() => ({
|
|
11
|
+
showQueueTableTab: true,
|
|
12
|
+
concepts: {
|
|
13
|
+
visitQueueNumberAttributeUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
|
|
14
|
+
},
|
|
15
|
+
})),
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
describe('Home Component', () => {
|
|
19
|
+
it('renders PatientQueueHeader, ClinicMetrics, and ActiveVisitsTabs when activeTicketScreen is not "screen"', () => {
|
|
20
|
+
// Mock window.location.pathname
|
|
21
|
+
const originalLocation = window.location;
|
|
22
|
+
delete window.location;
|
|
23
|
+
window.location = { pathname: '/some-path' };
|
|
24
|
+
|
|
25
|
+
render(<Home />);
|
|
26
|
+
|
|
27
|
+
// Assert that the expected components are rendered
|
|
28
|
+
expect(screen.getByTestId('patient-queue-header')).toBeInTheDocument();
|
|
29
|
+
expect(screen.getByTestId('clinic-metrics')).toBeInTheDocument();
|
|
30
|
+
expect(screen.getByTestId('active-visits-tabs')).toBeInTheDocument();
|
|
31
|
+
|
|
32
|
+
// Clean up the mock
|
|
33
|
+
window.location = originalLocation;
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('renders QueueScreen when activeTicketScreen is "screen"', () => {
|
|
37
|
+
const originalLocation = window.location;
|
|
38
|
+
delete window.location;
|
|
39
|
+
window.location = { pathname: '/some-path/screen' };
|
|
40
|
+
|
|
41
|
+
render(<Home />);
|
|
42
|
+
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
|
43
|
+
|
|
44
|
+
window.location = originalLocation;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('renders ActiveVisitsTable when showQueueTableTab is false', () => {
|
|
48
|
+
mockedUseConfig.mockImplementationOnce(() => ({
|
|
49
|
+
showQueueTableTab: false,
|
|
50
|
+
concepts: {
|
|
51
|
+
visitQueueNumberAttributeUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
|
|
52
|
+
},
|
|
53
|
+
}));
|
|
54
|
+
render(<Home />);
|
|
55
|
+
|
|
56
|
+
expect(screen.getByRole('progressbar')).toBeInTheDocument();
|
|
57
|
+
});
|
|
58
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle, registerBreadcrumbs } from '@openmrs/esm-framework';
|
|
2
|
+
import { configSchema } from './config-schema';
|
|
3
|
+
import { createDashboardLink } from './createDashboardLink';
|
|
4
|
+
import { dashboardMeta } from './dashboard.meta';
|
|
5
|
+
|
|
6
|
+
export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
|
|
7
|
+
|
|
8
|
+
const moduleName = '@openmrs/esm-service-queues-app';
|
|
9
|
+
|
|
10
|
+
const options = {
|
|
11
|
+
featureName: 'outpatient',
|
|
12
|
+
moduleName,
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const appointmentsList = getAsyncLifecycle(
|
|
16
|
+
() => import('./queue-patient-linelists/scheduled-appointments-table.component'),
|
|
17
|
+
options,
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const queueList = getAsyncLifecycle(
|
|
21
|
+
() => import('./queue-patient-linelists/queue-services-table.component'),
|
|
22
|
+
options,
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
export const outpatientSideNav = getAsyncLifecycle(() => import('./side-menu/side-menu.component'), options);
|
|
26
|
+
|
|
27
|
+
export const serviceQueuesDashboardLink = getSyncLifecycle(createDashboardLink(dashboardMeta), options);
|
|
28
|
+
|
|
29
|
+
export const homeDashboard = getAsyncLifecycle(() => import('./home.component'), options);
|
|
30
|
+
|
|
31
|
+
export const editQueueEntryStatusModal = getAsyncLifecycle(
|
|
32
|
+
() => import('./active-visits/change-status-dialog.component'),
|
|
33
|
+
{
|
|
34
|
+
featureName: 'edit queue status',
|
|
35
|
+
moduleName,
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
export const patientInfoBannerSlot = getAsyncLifecycle(() => import('./patient-info/patient-info.component'), {
|
|
40
|
+
featureName: 'patient info slot',
|
|
41
|
+
moduleName,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export const addPatientToQueue = getAsyncLifecycle(() => import('./patient-search/visit-form/visit-form.component'), {
|
|
45
|
+
featureName: 'patient info slot',
|
|
46
|
+
moduleName,
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export const removeQueueEntry = getAsyncLifecycle(
|
|
50
|
+
() => import('./remove-queue-entry-dialog/remove-queue-entry.component'),
|
|
51
|
+
{
|
|
52
|
+
featureName: 'remove queue entry and end visit',
|
|
53
|
+
moduleName,
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
export const clearAllQueueEntries = getAsyncLifecycle(
|
|
58
|
+
() => import('./clear-queue-entries-dialog/clear-queue-entries-dialog.component'),
|
|
59
|
+
{
|
|
60
|
+
featureName: 'clear all queue entries and end visits',
|
|
61
|
+
moduleName,
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
export const addVisitToQueueModal = getAsyncLifecycle(
|
|
66
|
+
() => import('./add-patient-toqueue/add-patient-toqueue-dialog.component'),
|
|
67
|
+
{
|
|
68
|
+
featureName: 'add visit to queue',
|
|
69
|
+
moduleName,
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
export const transitionQueueEntryStatusModal = getAsyncLifecycle(
|
|
74
|
+
() => import('./transition-queue-entry/transition-queue-entry-dialog.component'),
|
|
75
|
+
{
|
|
76
|
+
featureName: 'transition queue status',
|
|
77
|
+
moduleName,
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
export const previousVisitSummaryWidget = getAsyncLifecycle(() => import('./past-visit/past-visit.component'), options);
|
|
82
|
+
|
|
83
|
+
export const addProviderToRoomModal = getAsyncLifecycle(
|
|
84
|
+
() => import('./add-provider-queue-room/add-provider-queue-room.component'),
|
|
85
|
+
{
|
|
86
|
+
featureName: 'add provider queue room',
|
|
87
|
+
moduleName,
|
|
88
|
+
},
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
export const addQueueEntryWidget = getAsyncLifecycle(
|
|
92
|
+
() => import('./patient-search/visit-form-queue-fields/visit-form-queue-fields.component'),
|
|
93
|
+
options,
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
export function startupApp() {
|
|
97
|
+
registerBreadcrumbs([]);
|
|
98
|
+
|
|
99
|
+
defineConfigSchema(moduleName, configSchema);
|
|
100
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Button, Header } from '@carbon/react';
|
|
3
|
+
import { ArrowLeft, Close } from '@carbon/react/icons';
|
|
4
|
+
import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
|
|
5
|
+
import styles from './overlay.scss';
|
|
6
|
+
|
|
7
|
+
interface OverlayProps {
|
|
8
|
+
closePanel: () => void;
|
|
9
|
+
header: string;
|
|
10
|
+
children?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const Overlay: React.FC<OverlayProps> = ({ closePanel, children, header }) => {
|
|
14
|
+
const layout = useLayoutType();
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className={isDesktop(layout) ? styles.desktopOverlay : styles.tabletOverlay}>
|
|
18
|
+
{isDesktop(layout) ? (
|
|
19
|
+
<div className={styles.desktopHeader}>
|
|
20
|
+
<div className={styles.headerContent}>{header}</div>
|
|
21
|
+
<Button
|
|
22
|
+
className={styles.closePanelButton}
|
|
23
|
+
onClick={closePanel}
|
|
24
|
+
kind="ghost"
|
|
25
|
+
hasIconOnly
|
|
26
|
+
renderIcon={(props) => <Close size={16} {...props} />}
|
|
27
|
+
iconDescription="Close overlay"
|
|
28
|
+
/>
|
|
29
|
+
</div>
|
|
30
|
+
) : (
|
|
31
|
+
<Header aria-label="Tablet overlay" className={styles.tabletOverlayHeader}>
|
|
32
|
+
<Button
|
|
33
|
+
onClick={closePanel}
|
|
34
|
+
hasIconOnly
|
|
35
|
+
renderIcon={(props) => <ArrowLeft size={16} {...props} />}
|
|
36
|
+
iconDescription="Close overlay"
|
|
37
|
+
/>
|
|
38
|
+
<div className={styles.headerContent}>{header}</div>
|
|
39
|
+
</Header>
|
|
40
|
+
)}
|
|
41
|
+
<div>{children}</div>
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export default Overlay;
|
package/src/overlay.scss
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
@use '@carbon/styles/scss/spacing';
|
|
2
|
+
@use '@carbon/styles/scss/type';
|
|
3
|
+
@import './root.scss';
|
|
4
|
+
|
|
5
|
+
.desktopOverlay {
|
|
6
|
+
position: fixed;
|
|
7
|
+
top: spacing.$spacing-09;
|
|
8
|
+
width: 37rem;
|
|
9
|
+
right: 0;
|
|
10
|
+
bottom: 0;
|
|
11
|
+
border-left: 1px solid $text-03;
|
|
12
|
+
background-color: $ui-01;
|
|
13
|
+
overflow-y: auto;
|
|
14
|
+
height: calc(100vh - 3rem);
|
|
15
|
+
z-index: 99999;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.desktopOverlay::after {
|
|
19
|
+
height: 100%;
|
|
20
|
+
border-left: 1px solid $text-03;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.tabletOverlay {
|
|
24
|
+
position: fixed;
|
|
25
|
+
top: 0;
|
|
26
|
+
bottom: 0;
|
|
27
|
+
left: 0;
|
|
28
|
+
right: 0;
|
|
29
|
+
z-index: 9999;
|
|
30
|
+
background-color: $ui-01;
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
padding-top: spacing.$spacing-09;
|
|
33
|
+
display: grid;
|
|
34
|
+
grid-template-rows: 1fr auto;
|
|
35
|
+
overflow-y: auto;
|
|
36
|
+
height: 100vh;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
.tabletOverlayHeader {
|
|
40
|
+
button {
|
|
41
|
+
@include brand-01(background-color);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.headerContent {
|
|
45
|
+
color: $ui-02;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.desktopHeader {
|
|
50
|
+
display: flex;
|
|
51
|
+
justify-content: space-between;
|
|
52
|
+
align-items: center;
|
|
53
|
+
background-color: $ui-03;
|
|
54
|
+
border-bottom: 1px solid $text-03;
|
|
55
|
+
position: sticky;
|
|
56
|
+
position: -webkit-sticky;
|
|
57
|
+
width: 100%;
|
|
58
|
+
z-index: 1000;
|
|
59
|
+
top: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.headerContent {
|
|
63
|
+
@include type.type-style('heading-compact-02');
|
|
64
|
+
padding: 0 spacing.$spacing-05;
|
|
65
|
+
color: $ui-05;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.closeButton {
|
|
69
|
+
background-color: $ui-background;
|
|
70
|
+
color: $ui-05;
|
|
71
|
+
fill: $ui-05;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Desktop */
|
|
75
|
+
:global(.omrs-breakpoint-gt-tablet) {
|
|
76
|
+
.overlayContent {
|
|
77
|
+
padding: 0 0 0 0;
|
|
78
|
+
overflow-y: auto;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/* Tablet */
|
|
83
|
+
:global(.omrs-breakpoint-lt-desktop) {
|
|
84
|
+
.overlayContent {
|
|
85
|
+
padding: 0 0 0 0;
|
|
86
|
+
overflow-y: auto;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Overriding styles for RTL support
|
|
91
|
+
html[dir='rtl'] {
|
|
92
|
+
.desktopOverlay {
|
|
93
|
+
right: unset;
|
|
94
|
+
left: 0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, fireEvent, screen } from '@testing-library/react';
|
|
3
|
+
import Overlay from './overlay.component';
|
|
4
|
+
import { useLayoutType, isDesktop } from '@openmrs/esm-framework';
|
|
5
|
+
|
|
6
|
+
const mockUseLayoutType = useLayoutType as jest.Mock;
|
|
7
|
+
const mockIsDesktop = isDesktop as jest.Mock;
|
|
8
|
+
|
|
9
|
+
jest.mock('@openmrs/esm-framework');
|
|
10
|
+
|
|
11
|
+
const headerText = 'Test Header';
|
|
12
|
+
|
|
13
|
+
describe('Overlay Component', () => {
|
|
14
|
+
it('renders desktop layout with close button', () => {
|
|
15
|
+
const closePanelMock = jest.fn();
|
|
16
|
+
|
|
17
|
+
mockIsDesktop.mockImplementation(() => true);
|
|
18
|
+
|
|
19
|
+
render(<Overlay closePanel={closePanelMock} header={headerText} />);
|
|
20
|
+
|
|
21
|
+
const headerContent = screen.getByText(headerText);
|
|
22
|
+
const closeButton = screen.getByLabelText('Close overlay');
|
|
23
|
+
|
|
24
|
+
expect(headerContent).toBeInTheDocument();
|
|
25
|
+
expect(closeButton).toBeInTheDocument();
|
|
26
|
+
|
|
27
|
+
fireEvent.click(closeButton);
|
|
28
|
+
expect(closePanelMock).toHaveBeenCalled();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('renders tablet layout with back arrow button and the children', () => {
|
|
32
|
+
const closePanelMock = jest.fn();
|
|
33
|
+
mockIsDesktop.mockImplementation(() => false);
|
|
34
|
+
mockUseLayoutType.mockImplementation(() => 'tablet');
|
|
35
|
+
|
|
36
|
+
render(
|
|
37
|
+
<Overlay closePanel={closePanelMock} header={headerText}>
|
|
38
|
+
<div>Something</div>
|
|
39
|
+
</Overlay>,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const headerContent = screen.getByText(headerText);
|
|
43
|
+
const backButton = screen.getByText('Close overlay');
|
|
44
|
+
|
|
45
|
+
expect(headerContent).toBeInTheDocument();
|
|
46
|
+
expect(backButton).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByText('Something')).toBeInTheDocument();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import {
|
|
4
|
+
StructuredListHead,
|
|
5
|
+
StructuredListCell,
|
|
6
|
+
StructuredListRow,
|
|
7
|
+
StructuredListBody,
|
|
8
|
+
StructuredListWrapper,
|
|
9
|
+
} from '@carbon/react';
|
|
10
|
+
import { formatDatetime, parseDate } from '@openmrs/esm-framework';
|
|
11
|
+
import { FormattedEncounter } from '../../types/index';
|
|
12
|
+
import styles from '../past-visit.scss';
|
|
13
|
+
|
|
14
|
+
interface EncounterListProps {
|
|
15
|
+
encounters: Array<FormattedEncounter>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const EncounterList: React.FC<EncounterListProps> = ({ encounters }) => {
|
|
19
|
+
const { t } = useTranslation();
|
|
20
|
+
|
|
21
|
+
const structuredListBodyRowGenerator = () => {
|
|
22
|
+
return encounters.map((encounter, i) => (
|
|
23
|
+
<StructuredListRow label key={`row-${i}`}>
|
|
24
|
+
<StructuredListCell>{formatDatetime(parseDate(encounter.datetime), { mode: 'wide' })}</StructuredListCell>
|
|
25
|
+
<StructuredListCell className={styles.textColor}>{encounter.encounterType}</StructuredListCell>
|
|
26
|
+
<StructuredListCell>{encounter.provider}</StructuredListCell>
|
|
27
|
+
</StructuredListRow>
|
|
28
|
+
));
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
if (encounters?.length) {
|
|
32
|
+
return (
|
|
33
|
+
<div className={styles.encounterListContainer}>
|
|
34
|
+
<StructuredListWrapper>
|
|
35
|
+
<StructuredListHead>
|
|
36
|
+
<StructuredListRow head>
|
|
37
|
+
<StructuredListCell head>{t('dateTime', 'Date & time')}</StructuredListCell>
|
|
38
|
+
<StructuredListCell head>{t('encounterType', 'Encounter type')}</StructuredListCell>
|
|
39
|
+
<StructuredListCell head>{t('provider', 'Provider')}</StructuredListCell>
|
|
40
|
+
</StructuredListRow>
|
|
41
|
+
</StructuredListHead>
|
|
42
|
+
<StructuredListBody>{structuredListBodyRowGenerator()}</StructuredListBody>
|
|
43
|
+
</StructuredListWrapper>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return <p className={`${styles.bodyLong01} ${styles.text02}`}>{t('noEncountersFound', 'No encounters found')}</p>;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export default EncounterList;
|