@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.
Files changed (254) hide show
  1. package/.turbo/turbo-build.log +40 -0
  2. package/LICENSE.md +401 -0
  3. package/README.md +23 -0
  4. package/__mocks__/active-visits.mock.ts +97 -0
  5. package/__mocks__/appointments-data.mock.ts +283 -0
  6. package/__mocks__/search.mock.ts +35 -0
  7. package/__mocks__/visits.mock.ts +42 -0
  8. package/dist/121.js +1 -0
  9. package/dist/121.js.map +1 -0
  10. package/dist/130.js +2 -0
  11. package/dist/130.js.LICENSE.txt +5 -0
  12. package/dist/130.js.map +1 -0
  13. package/dist/176.js +1 -0
  14. package/dist/176.js.map +1 -0
  15. package/dist/227.js +1 -0
  16. package/dist/227.js.map +1 -0
  17. package/dist/242.js +1 -0
  18. package/dist/242.js.map +1 -0
  19. package/dist/252.js +1 -0
  20. package/dist/252.js.map +1 -0
  21. package/dist/286.js +1 -0
  22. package/dist/286.js.map +1 -0
  23. package/dist/308.js +1 -0
  24. package/dist/308.js.map +1 -0
  25. package/dist/319.js +1 -0
  26. package/dist/328.js +1 -0
  27. package/dist/328.js.map +1 -0
  28. package/dist/330.js +1 -0
  29. package/dist/330.js.map +1 -0
  30. package/dist/364.js +1 -0
  31. package/dist/364.js.map +1 -0
  32. package/dist/425.js +1 -0
  33. package/dist/425.js.map +1 -0
  34. package/dist/457.js +1 -0
  35. package/dist/457.js.map +1 -0
  36. package/dist/469.js +1 -0
  37. package/dist/469.js.map +1 -0
  38. package/dist/521.js +1 -0
  39. package/dist/521.js.map +1 -0
  40. package/dist/53.js +1 -0
  41. package/dist/53.js.map +1 -0
  42. package/dist/574.js +1 -0
  43. package/dist/591.js +2 -0
  44. package/dist/591.js.LICENSE.txt +32 -0
  45. package/dist/591.js.map +1 -0
  46. package/dist/610.js +1 -0
  47. package/dist/610.js.map +1 -0
  48. package/dist/611.js +1 -0
  49. package/dist/611.js.map +1 -0
  50. package/dist/616.js +1 -0
  51. package/dist/616.js.map +1 -0
  52. package/dist/644.js +1 -0
  53. package/dist/644.js.map +1 -0
  54. package/dist/670.js +2 -0
  55. package/dist/670.js.LICENSE.txt +57 -0
  56. package/dist/670.js.map +1 -0
  57. package/dist/733.js +1 -0
  58. package/dist/733.js.map +1 -0
  59. package/dist/757.js +1 -0
  60. package/dist/764.js +1 -0
  61. package/dist/764.js.map +1 -0
  62. package/dist/766.js +1 -0
  63. package/dist/766.js.map +1 -0
  64. package/dist/784.js +2 -0
  65. package/dist/784.js.LICENSE.txt +9 -0
  66. package/dist/784.js.map +1 -0
  67. package/dist/788.js +1 -0
  68. package/dist/807.js +1 -0
  69. package/dist/833.js +1 -0
  70. package/dist/86.js +1 -0
  71. package/dist/86.js.map +1 -0
  72. package/dist/981.js +1 -0
  73. package/dist/981.js.map +1 -0
  74. package/dist/main.js +1 -0
  75. package/dist/main.js.map +1 -0
  76. package/dist/openmrs-esm-service-queues-app.js +1 -0
  77. package/dist/openmrs-esm-service-queues-app.js.buildmanifest.json +930 -0
  78. package/dist/openmrs-esm-service-queues-app.js.map +1 -0
  79. package/dist/routes.json +1 -0
  80. package/jest.config.js +3 -0
  81. package/package.json +53 -0
  82. package/src/active-visits/active-visits-tab.component.tsx +71 -0
  83. package/src/active-visits/active-visits-tab.test.tsx +19 -0
  84. package/src/active-visits/active-visits-table.component.tsx +543 -0
  85. package/src/active-visits/active-visits-table.resource.ts +443 -0
  86. package/src/active-visits/active-visits-table.scss +271 -0
  87. package/src/active-visits/active-visits-table.test.tsx +131 -0
  88. package/src/active-visits/change-status-dialog.component.tsx +233 -0
  89. package/src/active-visits/change-status-dialog.scss +32 -0
  90. package/src/active-visits/change-status-dialog.test.tsx +107 -0
  91. package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +218 -0
  92. package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +32 -0
  93. package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +236 -0
  94. package/src/add-provider-queue-room/add-provider-queue-room.resource.tsx +76 -0
  95. package/src/add-provider-queue-room/add-provider-queue-room.scss +17 -0
  96. package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +98 -0
  97. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +74 -0
  98. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.resource.tsx +46 -0
  99. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +15 -0
  100. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +42 -0
  101. package/src/clear-queue-entries-dialog/clear-queue-entries.component.tsx +36 -0
  102. package/src/config-schema.ts +177 -0
  103. package/src/constants.ts +7 -0
  104. package/src/createDashboardLink.tsx +35 -0
  105. package/src/current-visit/current-visit-summary.component.tsx +38 -0
  106. package/src/current-visit/current-visit-summary.test.tsx +47 -0
  107. package/src/current-visit/current-visit.resource.ts +84 -0
  108. package/src/current-visit/current-visit.scss +34 -0
  109. package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +101 -0
  110. package/src/current-visit/visit-details/biometrics-config-schema.ts +14 -0
  111. package/src/current-visit/visit-details/current-visit-details.component.tsx +96 -0
  112. package/src/current-visit/visit-details/triage-note.component.tsx +53 -0
  113. package/src/current-visit/visit-details/triage-note.scss +89 -0
  114. package/src/current-visit/visit-details/vitals-config-schema.ts +17 -0
  115. package/src/current-visit/visit-details/vitals.component.tsx +164 -0
  116. package/src/dashboard.meta.ts +5 -0
  117. package/src/declarations.d.ts +2 -0
  118. package/src/helpers/functions.ts +67 -0
  119. package/src/helpers/helpers.ts +170 -0
  120. package/src/helpers/time-helpers.ts +15 -0
  121. package/src/home.component.tsx +29 -0
  122. package/src/home.test.tsx +58 -0
  123. package/src/index.ts +100 -0
  124. package/src/overlay.component.tsx +46 -0
  125. package/src/overlay.scss +96 -0
  126. package/src/overlay.test.tsx +49 -0
  127. package/src/past-visit/past-visit-details/encounter-list.component.tsx +51 -0
  128. package/src/past-visit/past-visit-details/medications-list.component.tsx +95 -0
  129. package/src/past-visit/past-visit-details/notes-list.component.tsx +40 -0
  130. package/src/past-visit/past-visit-details/past-visit-summary.component.tsx +172 -0
  131. package/src/past-visit/past-visit-details/past-visit-summary.scss +58 -0
  132. package/src/past-visit/past-visit.component.tsx +37 -0
  133. package/src/past-visit/past-visit.resource.ts +83 -0
  134. package/src/past-visit/past-visit.scss +126 -0
  135. package/src/past-visit/past-visit.test.tsx +41 -0
  136. package/src/patient-info/appointment-details.component.tsx +98 -0
  137. package/src/patient-info/appointment-details.scss +34 -0
  138. package/src/patient-info/appointment-details.test.tsx +36 -0
  139. package/src/patient-info/appointments.resource.tsx +43 -0
  140. package/src/patient-info/contact-details.component.tsx +71 -0
  141. package/src/patient-info/contact-details.scss +31 -0
  142. package/src/patient-info/contact-details.test.tsx +94 -0
  143. package/src/patient-info/hooks/usePatientAttributes.tsx +42 -0
  144. package/src/patient-info/patient-info.component.tsx +78 -0
  145. package/src/patient-info/patient-info.scss +60 -0
  146. package/src/patient-info/patient-info.test.tsx +45 -0
  147. package/src/patient-queue-header/patient-queue-header.component.tsx +64 -0
  148. package/src/patient-queue-header/patient-queue-header.scss +88 -0
  149. package/src/patient-queue-header/patient-queue-illustration.component.tsx +22 -0
  150. package/src/patient-queue-metrics/clinic-metrics.component.tsx +93 -0
  151. package/src/patient-queue-metrics/clinic-metrics.resource.tsx +51 -0
  152. package/src/patient-queue-metrics/clinic-metrics.scss +11 -0
  153. package/src/patient-queue-metrics/clinic-metrics.test.tsx +87 -0
  154. package/src/patient-queue-metrics/metrics-card.component.tsx +64 -0
  155. package/src/patient-queue-metrics/metrics-card.scss +80 -0
  156. package/src/patient-queue-metrics/metrics-header.component.tsx +74 -0
  157. package/src/patient-queue-metrics/metrics-header.scss +22 -0
  158. package/src/patient-queue-metrics/queue-metrics.resource.ts +54 -0
  159. package/src/patient-search/advanced-search.component.tsx +190 -0
  160. package/src/patient-search/advanced-search.scss +154 -0
  161. package/src/patient-search/advanced-search.test.tsx +29 -0
  162. package/src/patient-search/basic-search.component.tsx +112 -0
  163. package/src/patient-search/basic-search.scss +139 -0
  164. package/src/patient-search/basic-search.test.tsx +23 -0
  165. package/src/patient-search/empty-data-illustration.component.tsx +41 -0
  166. package/src/patient-search/hooks/useActivePatientEnrollment.tsx +29 -0
  167. package/src/patient-search/hooks/useDefaultLocation.tsx +14 -0
  168. package/src/patient-search/hooks/usePatients.tsx +25 -0
  169. package/src/patient-search/hooks/useQueueLocations.tsx +20 -0
  170. package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +36 -0
  171. package/src/patient-search/hooks/useScheduledVisits.tsx +50 -0
  172. package/src/patient-search/patient-scheduled-visits.component.tsx +350 -0
  173. package/src/patient-search/patient-scheduled-visits.scss +131 -0
  174. package/src/patient-search/patient-scheduled-visits.test.tsx +55 -0
  175. package/src/patient-search/patient-search.component.tsx +64 -0
  176. package/src/patient-search/search-illustration.component.tsx +27 -0
  177. package/src/patient-search/search-results.component.tsx +75 -0
  178. package/src/patient-search/search-results.scss +80 -0
  179. package/src/patient-search/search-results.test.tsx +77 -0
  180. package/src/patient-search/search.resource.ts +10 -0
  181. package/src/patient-search/visit-form/base-visit-type.component.tsx +82 -0
  182. package/src/patient-search/visit-form/base-visit-type.scss +100 -0
  183. package/src/patient-search/visit-form/base-visit-type.test.tsx +41 -0
  184. package/src/patient-search/visit-form/queue.resource.ts +73 -0
  185. package/src/patient-search/visit-form/recommended-visit-type.component.tsx +38 -0
  186. package/src/patient-search/visit-form/visit-form.component.tsx +366 -0
  187. package/src/patient-search/visit-form/visit-form.scss +96 -0
  188. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +160 -0
  189. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +21 -0
  190. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +67 -0
  191. package/src/queue-entry-table-components/actions-menu.component.tsx +51 -0
  192. package/src/queue-entry-table-components/actions-menu.scss +3 -0
  193. package/src/queue-entry-table-components/edit-entry.component.tsx +28 -0
  194. package/src/queue-entry-table-components/edit-entry.scss +14 -0
  195. package/src/queue-entry-table-components/open-chart.component.tsx +33 -0
  196. package/src/queue-entry-table-components/open-chart.resource.tsx +14 -0
  197. package/src/queue-entry-table-components/open-chart.scss +14 -0
  198. package/src/queue-entry-table-components/status-icon.component.tsx +17 -0
  199. package/src/queue-entry-table-components/transition-entry.component.tsx +53 -0
  200. package/src/queue-entry-table-components/transition-entry.scss +22 -0
  201. package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +230 -0
  202. package/src/queue-patient-linelists/queue-linelist-base-table.scss +110 -0
  203. package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +118 -0
  204. package/src/queue-patient-linelists/queue-linelist-filter.component.tsx +172 -0
  205. package/src/queue-patient-linelists/queue-linelist-filter.scss +63 -0
  206. package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +76 -0
  207. package/src/queue-patient-linelists/queue-linelist.component.tsx +29 -0
  208. package/src/queue-patient-linelists/queue-linelist.resource.tsx +84 -0
  209. package/src/queue-patient-linelists/queue-linelist.test.tsx +22 -0
  210. package/src/queue-patient-linelists/queue-services-table.component.tsx +63 -0
  211. package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +300 -0
  212. package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +42 -0
  213. package/src/queue-rooms/queue-room-form.component.tsx +168 -0
  214. package/src/queue-rooms/queue-room-form.test.tsx +65 -0
  215. package/src/queue-rooms/queue-room.resource.tsx +20 -0
  216. package/src/queue-rooms/queue-room.scss +58 -0
  217. package/src/queue-screen/queue-screen.component.tsx +47 -0
  218. package/src/queue-screen/queue-screen.scss +39 -0
  219. package/src/queue-screen/queue-screen.test.tsx +47 -0
  220. package/src/queue-screen/useActiveTickets.tsx +13 -0
  221. package/src/queue-services/queue-service-form.component.tsx +183 -0
  222. package/src/queue-services/queue-service-form.test.tsx +56 -0
  223. package/src/queue-services/queue-service.resource.tsx +38 -0
  224. package/src/queue-services/queue-service.scss +54 -0
  225. package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +95 -0
  226. package/src/remove-queue-entry-dialog/remove-queue-entry.resource.tsx +93 -0
  227. package/src/remove-queue-entry-dialog/remove-queue-entry.scss +8 -0
  228. package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +44 -0
  229. package/src/root.component.tsx +28 -0
  230. package/src/root.scss +15 -0
  231. package/src/root.test.tsx +28 -0
  232. package/src/routes.json +91 -0
  233. package/src/side-menu/nav-group/createNavGroup.tsx +17 -0
  234. package/src/side-menu/nav-group/nav-group.component.tsx +24 -0
  235. package/src/side-menu/nav-group/nav-group.test.tsx +32 -0
  236. package/src/side-menu/nav-group/nav-group.ts +10 -0
  237. package/src/side-menu/side-menu.component.tsx +6 -0
  238. package/src/side-menu/side-menu.test.tsx +17 -0
  239. package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +174 -0
  240. package/src/transition-queue-entry/transition-queue-entry-dialog.scss +12 -0
  241. package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +95 -0
  242. package/src/transition-queue-entry/transition-queue-entry.resource.ts +16 -0
  243. package/src/types/index.ts +434 -0
  244. package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +298 -0
  245. package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +93 -0
  246. package/src/visits-missing-inqueue/visits-missing-inqueue.scss +108 -0
  247. package/translations/am.json +258 -0
  248. package/translations/en.json +258 -0
  249. package/translations/es.json +258 -0
  250. package/translations/fr.json +258 -0
  251. package/translations/he.json +262 -0
  252. package/translations/km.json +258 -0
  253. package/tsconfig.json +5 -0
  254. package/webpack.config.js +1 -0
@@ -0,0 +1,543 @@
1
+ import React, { useMemo, useState, MouseEvent, AnchorHTMLAttributes, useCallback, useEffect } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import {
4
+ Button,
5
+ DataTable,
6
+ DataTableHeader,
7
+ DataTableSkeleton,
8
+ DefinitionTooltip,
9
+ Dropdown,
10
+ Layer,
11
+ Tab,
12
+ Table,
13
+ TableBody,
14
+ TableCell,
15
+ TableContainer,
16
+ TableExpandedRow,
17
+ TableExpandHeader,
18
+ TableExpandRow,
19
+ TableHead,
20
+ TableHeader,
21
+ TableRow,
22
+ TableToolbar,
23
+ TableToolbarContent,
24
+ TableToolbarSearch,
25
+ Tabs,
26
+ TabPanels,
27
+ TabPanel,
28
+ TabList,
29
+ Tag,
30
+ Tile,
31
+ Pagination,
32
+ } from '@carbon/react';
33
+ import { Add } from '@carbon/react/icons';
34
+ import {
35
+ useLayoutType,
36
+ navigate,
37
+ interpolateUrl,
38
+ isDesktop,
39
+ ExtensionSlot,
40
+ usePagination,
41
+ useConfig,
42
+ ConfigObject,
43
+ useSession,
44
+ showModal,
45
+ } from '@openmrs/esm-framework';
46
+ import {
47
+ useVisitQueueEntries,
48
+ useServices,
49
+ getOriginFromPathName,
50
+ MappedVisitQueueEntry,
51
+ } from './active-visits-table.resource';
52
+ import { SearchTypes } from '../types';
53
+ import {
54
+ updateSelectedServiceName,
55
+ updateSelectedServiceUuid,
56
+ useSelectedServiceName,
57
+ useSelectedQueueLocationUuid,
58
+ useIsPermanentProviderQueueRoom,
59
+ useSelectedServiceUuid,
60
+ } from '../helpers/helpers';
61
+ import { buildStatusString, formatWaitTime, getTagType, timeDiffInMinutes } from '../helpers/functions';
62
+ import { useQueueRooms } from '../add-provider-queue-room/add-provider-queue-room.resource';
63
+ import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
64
+ import ActionsMenu from '../queue-entry-table-components/actions-menu.component';
65
+ import ClearQueueEntries from '../clear-queue-entries-dialog/clear-queue-entries.component';
66
+ import CurrentVisit from '../current-visit/current-visit-summary.component';
67
+ import EditMenu from '../queue-entry-table-components/edit-entry.component';
68
+ import OpenChartMenu from '../queue-entry-table-components/open-chart.component';
69
+ import PatientSearch from '../patient-search/patient-search.component';
70
+ import PastVisit from '../past-visit/past-visit.component';
71
+ import StatusIcon from '../queue-entry-table-components/status-icon.component';
72
+ import TransitionMenu from '../queue-entry-table-components/transition-entry.component';
73
+ import styles from './active-visits-table.scss';
74
+
75
+ type FilterProps = {
76
+ rowIds: Array<string>;
77
+ headers: Array<DataTableHeader>;
78
+ cellsById: any;
79
+ inputValue: string;
80
+ getCellId: (row, key) => string;
81
+ };
82
+
83
+ interface NameLinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
84
+ to: string;
85
+ from: string;
86
+ }
87
+
88
+ interface PaginationData {
89
+ goTo: (page: number) => void;
90
+ results: Array<MappedVisitQueueEntry>;
91
+ currentPage: number;
92
+ }
93
+
94
+ const PatientNameLink: React.FC<NameLinkProps> = ({ from, to, children }) => {
95
+ const handleNameClick = (event: MouseEvent, to: string) => {
96
+ event.preventDefault();
97
+ navigate({ to });
98
+ localStorage.setItem('fromPage', from);
99
+ };
100
+ return (
101
+ <a onClick={(e) => handleNameClick(e, to)} href={interpolateUrl(to)}>
102
+ {children}
103
+ </a>
104
+ );
105
+ };
106
+
107
+ function ActiveVisitsTable() {
108
+ const { t } = useTranslation();
109
+ const currentQueueLocation = useSelectedQueueLocationUuid();
110
+ const { services } = useServices(currentQueueLocation);
111
+ const currentServiceName = useSelectedServiceName();
112
+ const currentLocationUuid = useSelectedQueueLocationUuid();
113
+ const currentServiceUuid = useSelectedServiceUuid();
114
+ const { visitQueueEntries, isLoading } = useVisitQueueEntries(currentServiceName, currentLocationUuid);
115
+ const [showOverlay, setShowOverlay] = useState(false);
116
+ const [view, setView] = useState('');
117
+ const [viewState, setViewState] = useState<{ selectedPatientUuid: string }>(null);
118
+ const layout = useLayoutType();
119
+ const config = useConfig() as ConfigObject;
120
+ const useQueueTableTabs = config.showQueueTableTab;
121
+ const currentUserSession = useSession();
122
+ const providerUuid = currentUserSession?.currentProvider?.uuid;
123
+ const differenceInTime = timeDiffInMinutes(
124
+ new Date(),
125
+ new Date(localStorage.getItem('lastUpdatedQueueRoomTimestamp')),
126
+ );
127
+ const { queueLocations } = useQueueLocations();
128
+ const { rooms, isLoading: loading } = useQueueRooms(queueLocations[0]?.id, currentServiceUuid);
129
+
130
+ const isPermanentProviderQueueRoom = useIsPermanentProviderQueueRoom();
131
+ const currentPathName: string = window.location.pathname;
132
+ const fromPage: string = getOriginFromPathName(currentPathName);
133
+
134
+ const pageSizes = [10, 20, 30, 40, 50];
135
+ const [currentPageSize, setPageSize] = useState(10);
136
+ const [overlayHeader, setOverlayTitle] = useState('');
137
+ const [providerRoomModalShown, setProviderRoomModalShown] = useState(false);
138
+
139
+ const {
140
+ goTo,
141
+ results: paginatedQueueEntries,
142
+ currentPage,
143
+ }: PaginationData = usePagination(visitQueueEntries, currentPageSize);
144
+
145
+ const tableHeaders = useMemo(
146
+ () => [
147
+ {
148
+ id: 0,
149
+ header: t('name', 'Name'),
150
+ key: 'name',
151
+ },
152
+ {
153
+ id: 1,
154
+ header: t('queueNumber', 'QueueNumber'),
155
+ key: 'queueNumber',
156
+ },
157
+ {
158
+ id: 2,
159
+ header: t('priority', 'Priority'),
160
+ key: 'priority',
161
+ },
162
+ {
163
+ id: 3,
164
+ header: t('locationComingFrom', 'Coming from'),
165
+ key: 'locationComingFrom',
166
+ },
167
+ {
168
+ id: 4,
169
+ header: t('status', 'Status'),
170
+ key: 'status',
171
+ },
172
+ {
173
+ id: 5,
174
+ header: t('waitTime', 'Wait time'),
175
+ key: 'waitTime',
176
+ },
177
+ ],
178
+ [t],
179
+ );
180
+
181
+ const handleServiceChange = ({ selectedItem }) => {
182
+ updateSelectedServiceUuid(selectedItem.uuid);
183
+ updateSelectedServiceName(selectedItem.display);
184
+ };
185
+
186
+ const tableRows = useMemo(() => {
187
+ return paginatedQueueEntries?.map((entry) => ({
188
+ ...entry,
189
+ name: {
190
+ content: (
191
+ <PatientNameLink to={`\${openmrsSpaBase}/patient/${entry.patientUuid}/chart`} from={fromPage}>
192
+ {entry.name}
193
+ </PatientNameLink>
194
+ ),
195
+ },
196
+ queueNumber: {
197
+ content: <span className={styles.statusContainer}>{entry?.visitQueueNumber}</span>,
198
+ },
199
+ priority: {
200
+ content: (
201
+ <>
202
+ {entry?.priorityComment ? (
203
+ <DefinitionTooltip className={styles.tooltip} align="bottom-left" definition={entry.priorityComment}>
204
+ <Tag
205
+ role="tooltip"
206
+ className={entry.priority === 'Priority' ? styles.priorityTag : styles.tag}
207
+ type={getTagType(entry.priority as string)}>
208
+ {entry.priority}
209
+ </Tag>
210
+ </DefinitionTooltip>
211
+ ) : (
212
+ <Tag
213
+ className={entry.priority === 'Priority' ? styles.priorityTag : styles.tag}
214
+ type={getTagType(entry.priority as string)}>
215
+ {entry.priority}
216
+ </Tag>
217
+ )}
218
+ </>
219
+ ),
220
+ },
221
+ locationComingFrom: {
222
+ content: <span className={styles.statusContainer}>{entry?.locationComingFrom}</span>,
223
+ },
224
+ status: {
225
+ content: (
226
+ <span className={styles.statusContainer}>
227
+ <StatusIcon status={entry.status.toLowerCase()} />
228
+ <span>{buildStatusString(entry.status.toLowerCase(), entry.service)}</span>
229
+ </span>
230
+ ),
231
+ },
232
+ waitTime: {
233
+ content: <span className={styles.statusContainer}>{formatWaitTime(entry.waitTime, t)}</span>,
234
+ },
235
+ }));
236
+ }, [paginatedQueueEntries]);
237
+
238
+ const handleFilter = ({ rowIds, headers, cellsById, inputValue, getCellId }: FilterProps): Array<string> => {
239
+ return rowIds.filter((rowId) =>
240
+ headers.some(({ key }) => {
241
+ const cellId = getCellId(rowId, key);
242
+ const filterableValue = cellsById[cellId].value;
243
+ const filterTerm = inputValue.toLowerCase();
244
+
245
+ if (typeof filterableValue === 'boolean') {
246
+ return false;
247
+ }
248
+ if (filterableValue.hasOwnProperty('content')) {
249
+ if (Array.isArray(filterableValue.content.props.children)) {
250
+ return ('' + filterableValue.content.props.children[1].props.children).toLowerCase().includes(filterTerm);
251
+ }
252
+ if (typeof filterableValue.content.props.children === 'object') {
253
+ return ('' + filterableValue.content.props.children.props.children).toLowerCase().includes(filterTerm);
254
+ }
255
+ return ('' + filterableValue.content.props.children).toLowerCase().includes(filterTerm);
256
+ }
257
+ return ('' + filterableValue).toLowerCase().includes(filterTerm);
258
+ }),
259
+ );
260
+ };
261
+
262
+ const launchAddProviderRoomModal = useCallback(() => {
263
+ const dispose = showModal('add-provider-to-room-modal', {
264
+ closeModal: () => dispose(),
265
+ providerUuid,
266
+ });
267
+ setProviderRoomModalShown(true);
268
+ }, [providerUuid]);
269
+
270
+ useEffect(() => {
271
+ if (
272
+ !loading &&
273
+ rooms?.length > 0 &&
274
+ differenceInTime >= 1 &&
275
+ (isPermanentProviderQueueRoom == 'false' || isPermanentProviderQueueRoom === null) &&
276
+ !providerRoomModalShown
277
+ ) {
278
+ launchAddProviderRoomModal();
279
+ }
280
+ }, [
281
+ currentServiceUuid,
282
+ rooms,
283
+ providerRoomModalShown,
284
+ loading,
285
+ differenceInTime,
286
+ isPermanentProviderQueueRoom,
287
+ launchAddProviderRoomModal,
288
+ ]);
289
+
290
+ if (isLoading) {
291
+ return <DataTableSkeleton role="progressbar" />;
292
+ }
293
+
294
+ if (visitQueueEntries?.length) {
295
+ return (
296
+ <div className={styles.container}>
297
+ {useQueueTableTabs === false ? (
298
+ <>
299
+ <div className={styles.headerBtnContainer}></div>
300
+ <div className={styles.headerContainer}>
301
+ <div className={!isDesktop(layout) ? styles.tabletHeading : styles.desktopHeading}>
302
+ <h4>{t('patientsCurrentlyInQueue', 'Patients currently in queue')}</h4>
303
+ </div>
304
+ <div className={styles.headerButtons}>
305
+ <ExtensionSlot
306
+ name="patient-search-button-slot"
307
+ state={{
308
+ buttonText: t('addPatientToQueue', 'Add patient to queue'),
309
+ overlayHeader: t('addPatientToQueue', 'Add patient to queue'),
310
+ buttonProps: {
311
+ kind: 'secondary',
312
+ renderIcon: (props) => <Add size={16} {...props} />,
313
+ size: 'sm',
314
+ },
315
+ selectPatientAction: (selectedPatientUuid) => {
316
+ setShowOverlay(true);
317
+ setView(SearchTypes.SCHEDULED_VISITS);
318
+ setViewState({ selectedPatientUuid });
319
+ setOverlayTitle(t('addPatientWithAppointmentToQueue', 'Add patient with appointment to queue'));
320
+ },
321
+ }}
322
+ />
323
+ </div>
324
+ </div>
325
+ </>
326
+ ) : null}
327
+ <DataTable
328
+ data-floating-menu-container
329
+ filterRows={handleFilter}
330
+ headers={tableHeaders}
331
+ overflowMenuOnHover={isDesktop(layout) ? true : false}
332
+ rows={tableRows}
333
+ size="xs"
334
+ useZebraStyles>
335
+ {({ rows, headers, getHeaderProps, getTableProps, getRowProps, getToolbarProps, onInputChange }) => (
336
+ <TableContainer className={styles.tableContainer}>
337
+ <TableToolbar
338
+ {...getToolbarProps()}
339
+ style={{ position: 'static', height: '3rem', overflow: 'visible', backgroundColor: 'color' }}>
340
+ <TableToolbarContent className={styles.toolbarContent}>
341
+ <div className={styles.filterContainer}>
342
+ <Dropdown
343
+ id="serviceFilter"
344
+ titleText={t('showPatientsWaitingFor', 'Show patients waiting for') + ':'}
345
+ label={currentServiceName}
346
+ type="inline"
347
+ items={[{ display: `${t('all', 'All')}` }, ...services]}
348
+ itemToString={(item) => (item ? item.display : '')}
349
+ onChange={handleServiceChange}
350
+ size="sm"
351
+ />
352
+ </div>
353
+ <Layer>
354
+ <TableToolbarSearch
355
+ className={styles.search}
356
+ onChange={onInputChange}
357
+ placeholder={t('searchThisList', 'Search this list')}
358
+ size="sm"
359
+ />
360
+ </Layer>
361
+ <ClearQueueEntries visitQueueEntries={visitQueueEntries} />
362
+ </TableToolbarContent>
363
+ </TableToolbar>
364
+ <Table {...getTableProps()} className={styles.activeVisitsTable}>
365
+ <TableHead>
366
+ <TableRow>
367
+ <TableExpandHeader />
368
+ {headers.map((header) => (
369
+ <TableHeader {...getHeaderProps({ header })}>{header.header}</TableHeader>
370
+ ))}
371
+ <TableExpandHeader />
372
+ </TableRow>
373
+ </TableHead>
374
+ <TableBody>
375
+ {rows.map((row, index) => {
376
+ return (
377
+ <React.Fragment key={row.id}>
378
+ <TableExpandRow {...getRowProps({ row })}>
379
+ {row.cells.map((cell) => (
380
+ <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>
381
+ ))}
382
+ <TableCell className="cds--table-column-menu">
383
+ <TransitionMenu queueEntry={visitQueueEntries?.[index]} closeModal={() => true} />
384
+ </TableCell>
385
+ <TableCell className="cds--table-column-menu">
386
+ <EditMenu queueEntry={visitQueueEntries?.[index]} closeModal={() => true} />
387
+ </TableCell>
388
+ <TableCell className="cds--table-column-menu">
389
+ <OpenChartMenu patientUuid={visitQueueEntries?.[index]?.patientUuid} />
390
+ </TableCell>
391
+ <TableCell className="cds--table-column-menu">
392
+ <ActionsMenu queueEntry={visitQueueEntries?.[index]} closeModal={() => true} />
393
+ </TableCell>
394
+ </TableExpandRow>
395
+ {row.isExpanded ? (
396
+ <TableExpandedRow className={styles.expandedActiveVisitRow} colSpan={headers.length + 2}>
397
+ <>
398
+ <Tabs>
399
+ <TabList>
400
+ <Tab>{t('currentVisit', 'Current visit')}</Tab>
401
+ <Tab>{t('previousVisit', 'Previous visit')} </Tab>
402
+ </TabList>
403
+ <TabPanels>
404
+ <TabPanel>
405
+ <CurrentVisit
406
+ patientUuid={tableRows?.[index]?.patientUuid}
407
+ visitUuid={tableRows?.[index]?.visitUuid}
408
+ />
409
+ </TabPanel>
410
+ <TabPanel>
411
+ <PastVisit patientUuid={tableRows?.[index]?.patientUuid} />
412
+ </TabPanel>
413
+ </TabPanels>
414
+ </Tabs>
415
+ </>
416
+ </TableExpandedRow>
417
+ ) : (
418
+ <TableExpandedRow className={styles.hiddenRow} colSpan={headers.length + 2} />
419
+ )}
420
+ </React.Fragment>
421
+ );
422
+ })}
423
+ </TableBody>
424
+ </Table>
425
+ {rows.length === 0 ? (
426
+ <div className={styles.tileContainer}>
427
+ <Tile className={styles.tile}>
428
+ <div className={styles.tileContent}>
429
+ <p className={styles.content}>{t('noPatientsToDisplay', 'No patients to display')}</p>
430
+ <p className={styles.helper}>{t('checkFilters', 'Check the filters above')}</p>
431
+ </div>
432
+ <p className={styles.separator}>{t('or', 'or')}</p>
433
+ <Button
434
+ kind="ghost"
435
+ size="sm"
436
+ renderIcon={(props) => <Add size={16} {...props} />}
437
+ onClick={() => setShowOverlay(true)}>
438
+ {t('addPatientToList', 'Add patient to list')}
439
+ </Button>
440
+ </Tile>
441
+ </div>
442
+ ) : null}
443
+ <Pagination
444
+ forwardText="Next page"
445
+ backwardText="Previous page"
446
+ page={currentPage}
447
+ pageSize={currentPageSize}
448
+ pageSizes={pageSizes}
449
+ totalItems={visitQueueEntries?.length}
450
+ className={styles.pagination}
451
+ onChange={({ pageSize, page }) => {
452
+ if (pageSize !== currentPageSize) {
453
+ setPageSize(pageSize);
454
+ }
455
+ if (page !== currentPage) {
456
+ goTo(page);
457
+ }
458
+ }}
459
+ />
460
+ </TableContainer>
461
+ )}
462
+ </DataTable>
463
+ {showOverlay && (
464
+ <PatientSearch
465
+ view={view}
466
+ closePanel={() => setShowOverlay(false)}
467
+ viewState={{
468
+ selectedPatientUuid: viewState.selectedPatientUuid,
469
+ }}
470
+ headerTitle={overlayHeader}
471
+ />
472
+ )}
473
+ </div>
474
+ );
475
+ }
476
+
477
+ return (
478
+ <div className={styles.container}>
479
+ {useQueueTableTabs === false ? (
480
+ <>
481
+ <div className={styles.headerContainer}>
482
+ <div className={!isDesktop(layout) ? styles.tabletHeading : styles.desktopHeading}>
483
+ <h4>{t('patientsCurrentlyInQueue', 'Patients currently in queue')}</h4>
484
+ </div>
485
+ <div className={styles.headerButtons}>
486
+ <ExtensionSlot
487
+ name="patient-search-button-slot"
488
+ state={{
489
+ buttonText: t('addPatientToQueue', 'Add patient to queue'),
490
+ overlayHeader: t('addPatientToQueue', 'Add patient to queue'),
491
+ buttonProps: {
492
+ kind: 'secondary',
493
+ renderIcon: (props) => <Add size={16} {...props} />,
494
+ size: 'sm',
495
+ },
496
+ selectPatientAction: (selectedPatientUuid) => {
497
+ setShowOverlay(true);
498
+ setView(SearchTypes.SCHEDULED_VISITS);
499
+ setViewState({ selectedPatientUuid });
500
+ setOverlayTitle(t('addPatientWithAppointmentToQueue', 'Add patient with appointment to queue'));
501
+ },
502
+ }}
503
+ />
504
+ </div>
505
+ </div>
506
+ </>
507
+ ) : null}
508
+ <div className={styles.tileContainer}>
509
+ <Tile className={styles.tile}>
510
+ <p className={styles.content}>{t('noPatientsToDisplay', 'No patients to display')}</p>
511
+ <ExtensionSlot
512
+ name="patient-search-button-slot"
513
+ state={{
514
+ buttonText: t('addPatientToQueue', 'Add patient to queue'),
515
+ overlayHeader: t('addPatientToQueue', 'Add patient to queue'),
516
+ buttonProps: {
517
+ kind: 'ghost',
518
+ renderIcon: (props) => <Add size={16} {...props} />,
519
+ size: 'sm',
520
+ },
521
+ selectPatientAction: (selectedPatientUuid) => {
522
+ setShowOverlay(true);
523
+ setView(SearchTypes.SCHEDULED_VISITS);
524
+ setViewState({ selectedPatientUuid });
525
+ setOverlayTitle(t('addPatientWithAppointmentToQueue', 'Add patient with appointment to queue'));
526
+ },
527
+ }}
528
+ />
529
+ </Tile>
530
+ </div>
531
+ {showOverlay && (
532
+ <PatientSearch
533
+ view={view}
534
+ closePanel={() => setShowOverlay(false)}
535
+ viewState={viewState}
536
+ headerTitle={overlayHeader}
537
+ />
538
+ )}
539
+ </div>
540
+ );
541
+ }
542
+
543
+ export default ActiveVisitsTable;