@kenyaemr/esm-service-queues-app 7.0.2-pre.65

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 (289) hide show
  1. package/.turbo/turbo-build.log +40 -0
  2. package/README.md +20 -0
  3. package/dist/130.js +2 -0
  4. package/dist/130.js.LICENSE.txt +3 -0
  5. package/dist/130.js.map +1 -0
  6. package/dist/152.js +1 -0
  7. package/dist/152.js.map +1 -0
  8. package/dist/169.js +1 -0
  9. package/dist/169.js.map +1 -0
  10. package/dist/185.js +1 -0
  11. package/dist/185.js.map +1 -0
  12. package/dist/233.js +1 -0
  13. package/dist/233.js.map +1 -0
  14. package/dist/237.js +1 -0
  15. package/dist/237.js.map +1 -0
  16. package/dist/255.js +2 -0
  17. package/dist/255.js.LICENSE.txt +9 -0
  18. package/dist/255.js.map +1 -0
  19. package/dist/271.js +1 -0
  20. package/dist/276.js +1 -0
  21. package/dist/276.js.map +1 -0
  22. package/dist/303.js +1 -0
  23. package/dist/303.js.map +1 -0
  24. package/dist/319.js +1 -0
  25. package/dist/401.js +1 -0
  26. package/dist/401.js.map +1 -0
  27. package/dist/430.js +2 -0
  28. package/dist/430.js.LICENSE.txt +50 -0
  29. package/dist/430.js.map +1 -0
  30. package/dist/460.js +1 -0
  31. package/dist/501.js +1 -0
  32. package/dist/501.js.map +1 -0
  33. package/dist/574.js +1 -0
  34. package/dist/591.js +2 -0
  35. package/dist/591.js.LICENSE.txt +32 -0
  36. package/dist/591.js.map +1 -0
  37. package/dist/644.js +1 -0
  38. package/dist/647.js +1 -0
  39. package/dist/647.js.map +1 -0
  40. package/dist/650.js +1 -0
  41. package/dist/650.js.map +1 -0
  42. package/dist/669.js +1 -0
  43. package/dist/669.js.map +1 -0
  44. package/dist/696.js +1 -0
  45. package/dist/696.js.map +1 -0
  46. package/dist/703.js +1 -0
  47. package/dist/703.js.map +1 -0
  48. package/dist/729.js +1 -0
  49. package/dist/729.js.map +1 -0
  50. package/dist/738.js +1 -0
  51. package/dist/738.js.map +1 -0
  52. package/dist/757.js +1 -0
  53. package/dist/764.js +1 -0
  54. package/dist/764.js.map +1 -0
  55. package/dist/784.js +2 -0
  56. package/dist/784.js.LICENSE.txt +9 -0
  57. package/dist/784.js.map +1 -0
  58. package/dist/788.js +1 -0
  59. package/dist/806.js +1 -0
  60. package/dist/806.js.map +1 -0
  61. package/dist/807.js +1 -0
  62. package/dist/833.js +1 -0
  63. package/dist/877.js +1 -0
  64. package/dist/877.js.map +1 -0
  65. package/dist/917.js +1 -0
  66. package/dist/917.js.map +1 -0
  67. package/dist/940.js +1 -0
  68. package/dist/940.js.map +1 -0
  69. package/dist/981.js +1 -0
  70. package/dist/981.js.map +1 -0
  71. package/dist/kenyaemr-esm-service-queues-app.js +1 -0
  72. package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +965 -0
  73. package/dist/kenyaemr-esm-service-queues-app.js.map +1 -0
  74. package/dist/main.js +2 -0
  75. package/dist/main.js.LICENSE.txt +60 -0
  76. package/dist/main.js.map +1 -0
  77. package/dist/routes.json +1 -0
  78. package/jest.config.js +3 -0
  79. package/package.json +54 -0
  80. package/src/active-visits/active-visits-row-actions.component.tsx +25 -0
  81. package/src/active-visits/active-visits-row-actions.scss +4 -0
  82. package/src/active-visits/active-visits-table.resource.ts +273 -0
  83. package/src/active-visits/change-status-dialog.component.tsx +272 -0
  84. package/src/active-visits/change-status-dialog.scss +47 -0
  85. package/src/active-visits/change-status-dialog.test.tsx +154 -0
  86. package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +228 -0
  87. package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +32 -0
  88. package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +238 -0
  89. package/src/add-provider-queue-room/add-provider-queue-room.resource.ts +76 -0
  90. package/src/add-provider-queue-room/add-provider-queue-room.scss +17 -0
  91. package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +105 -0
  92. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +76 -0
  93. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.resource.ts +7 -0
  94. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +8 -0
  95. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +43 -0
  96. package/src/clear-queue-entries-dialog/clear-queue-entries.component.tsx +43 -0
  97. package/src/config-schema.ts +465 -0
  98. package/src/constants.ts +10 -0
  99. package/src/createDashboardLink.component.tsx +39 -0
  100. package/src/current-visit/current-visit-summary.component.tsx +38 -0
  101. package/src/current-visit/current-visit-summary.test.tsx +43 -0
  102. package/src/current-visit/current-visit.resource.ts +84 -0
  103. package/src/current-visit/current-visit.scss +34 -0
  104. package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +101 -0
  105. package/src/current-visit/visit-details/biometrics-config-schema.ts +14 -0
  106. package/src/current-visit/visit-details/current-visit-details.component.tsx +96 -0
  107. package/src/current-visit/visit-details/triage-note.component.tsx +53 -0
  108. package/src/current-visit/visit-details/triage-note.scss +89 -0
  109. package/src/current-visit/visit-details/vitals-config-schema.ts +17 -0
  110. package/src/current-visit/visit-details/vitals.component.tsx +165 -0
  111. package/src/dashboard.meta.ts +5 -0
  112. package/src/declarations.d.ts +4 -0
  113. package/src/helpers/functions.ts +28 -0
  114. package/src/helpers/helpers.ts +177 -0
  115. package/src/helpers/time-helpers.ts +15 -0
  116. package/src/home.component.tsx +16 -0
  117. package/src/home.test.tsx +48 -0
  118. package/src/hooks/useConcept.ts +13 -0
  119. package/src/hooks/useQueue.ts +10 -0
  120. package/src/hooks/useQueueEntries.ts +187 -0
  121. package/src/hooks/useQueues.ts +22 -0
  122. package/src/hooks/useSystemSetting.ts +18 -0
  123. package/src/index.ts +172 -0
  124. package/src/past-visit/past-visit-details/encounter-list.component.tsx +54 -0
  125. package/src/past-visit/past-visit-details/medications-list.component.tsx +98 -0
  126. package/src/past-visit/past-visit-details/notes-list.component.tsx +41 -0
  127. package/src/past-visit/past-visit-details/past-visit-summary.component.tsx +181 -0
  128. package/src/past-visit/past-visit-details/past-visit-summary.scss +58 -0
  129. package/src/past-visit/past-visit.component.tsx +37 -0
  130. package/src/past-visit/past-visit.resource.ts +83 -0
  131. package/src/past-visit/past-visit.scss +126 -0
  132. package/src/past-visit/past-visit.test.tsx +41 -0
  133. package/src/patient-info/appointment-details.component.tsx +98 -0
  134. package/src/patient-info/appointment-details.scss +34 -0
  135. package/src/patient-info/appointment-details.test.tsx +36 -0
  136. package/src/patient-info/appointments.resource.ts +43 -0
  137. package/src/patient-info/hooks/usePatientAttributes.tsx +42 -0
  138. package/src/patient-info/patient-info.component.tsx +82 -0
  139. package/src/patient-info/patient-info.scss +60 -0
  140. package/src/patient-info/patient-info.test.tsx +43 -0
  141. package/src/patient-queue-header/patient-queue-header.component.tsx +99 -0
  142. package/src/patient-queue-header/patient-queue-header.scss +90 -0
  143. package/src/patient-queue-header/patient-queue-illustration.component.tsx +22 -0
  144. package/src/patient-queue-metrics/clinic-metrics.component.tsx +98 -0
  145. package/src/patient-queue-metrics/clinic-metrics.resource.ts +58 -0
  146. package/src/patient-queue-metrics/clinic-metrics.scss +11 -0
  147. package/src/patient-queue-metrics/clinic-metrics.test.tsx +76 -0
  148. package/src/patient-queue-metrics/metrics-card.component.tsx +68 -0
  149. package/src/patient-queue-metrics/metrics-card.scss +80 -0
  150. package/src/patient-queue-metrics/metrics-header.component.tsx +61 -0
  151. package/src/patient-queue-metrics/metrics-header.scss +26 -0
  152. package/src/patient-queue-metrics/queue-metrics.resource.ts +42 -0
  153. package/src/patient-search/advanced-search.component.tsx +191 -0
  154. package/src/patient-search/advanced-search.scss +154 -0
  155. package/src/patient-search/advanced-search.test.tsx +29 -0
  156. package/src/patient-search/basic-search.component.tsx +112 -0
  157. package/src/patient-search/basic-search.scss +139 -0
  158. package/src/patient-search/basic-search.test.tsx +23 -0
  159. package/src/patient-search/empty-data-illustration.component.tsx +41 -0
  160. package/src/patient-search/hooks/useActivePatientEnrollment.tsx +29 -0
  161. package/src/patient-search/hooks/useDefaultLocation.ts +14 -0
  162. package/src/patient-search/hooks/usePatients.tsx +25 -0
  163. package/src/patient-search/hooks/useQueueLocations.tsx +23 -0
  164. package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +35 -0
  165. package/src/patient-search/hooks/useScheduledVisits.ts +52 -0
  166. package/src/patient-search/patient-scheduled-visits.component.tsx +324 -0
  167. package/src/patient-search/patient-scheduled-visits.scss +131 -0
  168. package/src/patient-search/patient-scheduled-visits.test.tsx +44 -0
  169. package/src/patient-search/patient-search.scss +43 -0
  170. package/src/patient-search/patient-search.workspace.tsx +135 -0
  171. package/src/patient-search/search-illustration.component.tsx +27 -0
  172. package/src/patient-search/search-results.component.tsx +75 -0
  173. package/src/patient-search/search-results.scss +80 -0
  174. package/src/patient-search/search-results.test.tsx +77 -0
  175. package/src/patient-search/search.resource.ts +10 -0
  176. package/src/patient-search/visit-form/existing-visit-form.component.tsx +112 -0
  177. package/src/patient-search/visit-form/queue.resource.ts +64 -0
  178. package/src/patient-search/visit-form/visit-form.component.tsx +344 -0
  179. package/src/patient-search/visit-form/visit-form.scss +73 -0
  180. package/src/patient-search/visit-form/visit-type-selector.component.tsx +155 -0
  181. package/src/patient-search/visit-form/visit-type-selector.scss +100 -0
  182. package/src/patient-search/visit-form/visit-type-selector.test.tsx +83 -0
  183. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +178 -0
  184. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +19 -0
  185. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +63 -0
  186. package/src/queue-entry-table-components/edit-entry.scss +14 -0
  187. package/src/queue-entry-table-components/queue-duration.component.tsx +41 -0
  188. package/src/queue-entry-table-components/queue-priority.component.tsx +38 -0
  189. package/src/queue-entry-table-components/queue-priority.scss +12 -0
  190. package/src/queue-entry-table-components/queue-status.component.tsx +39 -0
  191. package/src/queue-entry-table-components/transition-entry.component.tsx +55 -0
  192. package/src/queue-entry-table-components/transition-entry.scss +22 -0
  193. package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +241 -0
  194. package/src/queue-patient-linelists/queue-linelist-base-table.scss +110 -0
  195. package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +93 -0
  196. package/src/queue-patient-linelists/queue-linelist-filter.scss +63 -0
  197. package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +94 -0
  198. package/src/queue-patient-linelists/queue-linelist-filter.workspace.tsx +185 -0
  199. package/src/queue-patient-linelists/queue-linelist.resource.ts +84 -0
  200. package/src/queue-patient-linelists/queue-services-table.component.tsx +63 -0
  201. package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +305 -0
  202. package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +41 -0
  203. package/src/queue-rooms/queue-room-form.scss +56 -0
  204. package/src/queue-rooms/queue-room-form.test.tsx +80 -0
  205. package/src/queue-rooms/queue-room-form.workspace.tsx +169 -0
  206. package/src/queue-rooms/queue-room.resource.ts +20 -0
  207. package/src/queue-screen/queue-screen.component.tsx +47 -0
  208. package/src/queue-screen/queue-screen.scss +39 -0
  209. package/src/queue-screen/queue-screen.test.tsx +51 -0
  210. package/src/queue-screen/useActiveTickets.tsx +13 -0
  211. package/src/queue-services/queue-service-form.scss +61 -0
  212. package/src/queue-services/queue-service-form.test.tsx +60 -0
  213. package/src/queue-services/queue-service-form.workspace.tsx +179 -0
  214. package/src/queue-services/queue-service.resource.ts +33 -0
  215. package/src/queue-table/cells/columns.resource.ts +135 -0
  216. package/src/queue-table/cells/queue-table-action-cell.component.tsx +88 -0
  217. package/src/queue-table/cells/queue-table-action-cell.scss +7 -0
  218. package/src/queue-table/cells/queue-table-coming-from-cell.component.tsx +13 -0
  219. package/src/queue-table/cells/queue-table-extension-cell.component.tsx +16 -0
  220. package/src/queue-table/cells/queue-table-name-cell.component.tsx +20 -0
  221. package/src/queue-table/cells/queue-table-patient-age-cell.component.tsx +18 -0
  222. package/src/queue-table/cells/queue-table-patient-identifier-cell.component.tsx +25 -0
  223. package/src/queue-table/cells/queue-table-priority-cell.component.tsx +23 -0
  224. package/src/queue-table/cells/queue-table-queue-name-cell.component.tsx +14 -0
  225. package/src/queue-table/cells/queue-table-status-cell.component.tsx +18 -0
  226. package/src/queue-table/cells/queue-table-visit-attribute-queue-number-cell.component.tsx +37 -0
  227. package/src/queue-table/cells/queue-table-visit-start-time-cell.component.tsx +20 -0
  228. package/src/queue-table/cells/queue-table-wait-time-cell.component.tsx +17 -0
  229. package/src/queue-table/default-queue-table.component.tsx +174 -0
  230. package/src/queue-table/default-queue-table.test.tsx +131 -0
  231. package/src/queue-table/queue-entry-actions/edit-queue-entry-modal.component.tsx +52 -0
  232. package/src/queue-table/queue-entry-actions/end-queue-entry-modal.component.tsx +39 -0
  233. package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.component.tsx +362 -0
  234. package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.test.tsx +152 -0
  235. package/src/queue-table/queue-entry-actions/queue-entry-actions.resource.ts +83 -0
  236. package/src/queue-table/queue-entry-actions/queue-entry-actons-modal.scss +36 -0
  237. package/src/queue-table/queue-entry-actions/queue-entry-confirm-action-modal.component.tsx +97 -0
  238. package/src/queue-table/queue-entry-actions/queue-entry-confirm-action-modal.test.tsx +106 -0
  239. package/src/queue-table/queue-entry-actions/queue-entry-undo-actions-modal.test.tsx +76 -0
  240. package/src/queue-table/queue-entry-actions/transition-queue-entry-modal.component.tsx +51 -0
  241. package/src/queue-table/queue-entry-actions/undo-transition-queue-entry-modal.component.tsx +58 -0
  242. package/src/queue-table/queue-entry-actions/void-queue-entry-modal.component.tsx +34 -0
  243. package/src/queue-table/queue-table-by-status-menu.component.tsx +42 -0
  244. package/src/queue-table/queue-table-by-status-menu.scss +11 -0
  245. package/src/queue-table/queue-table-by-status-skeleton.component.tsx +32 -0
  246. package/src/queue-table/queue-table-by-status.component.tsx +96 -0
  247. package/src/queue-table/queue-table-expanded-row.component.tsx +29 -0
  248. package/src/queue-table/queue-table-metrics-card.component.tsx +50 -0
  249. package/src/queue-table/queue-table-metrics-card.scss +48 -0
  250. package/src/queue-table/queue-table-metrics.component.tsx +30 -0
  251. package/src/queue-table/queue-table-metrics.scss +11 -0
  252. package/src/queue-table/queue-table.component.tsx +179 -0
  253. package/src/queue-table/queue-table.scss +192 -0
  254. package/src/queue-table/queue-table.test.tsx +210 -0
  255. package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +87 -0
  256. package/src/remove-queue-entry-dialog/remove-queue-entry.resource.ts +93 -0
  257. package/src/remove-queue-entry-dialog/remove-queue-entry.scss +7 -0
  258. package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +45 -0
  259. package/src/root.component.tsx +28 -0
  260. package/src/root.scss +15 -0
  261. package/src/root.test.tsx +24 -0
  262. package/src/routes.json +133 -0
  263. package/src/side-menu/nav-group/createNavGroup.tsx +17 -0
  264. package/src/side-menu/nav-group/nav-group.component.tsx +24 -0
  265. package/src/side-menu/nav-group/nav-group.test.tsx +32 -0
  266. package/src/side-menu/nav-group/nav-group.ts +10 -0
  267. package/src/side-menu/side-menu.component.tsx +6 -0
  268. package/src/side-menu/side-menu.test.tsx +17 -0
  269. package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +134 -0
  270. package/src/transition-queue-entry/transition-queue-entry-dialog.scss +12 -0
  271. package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +102 -0
  272. package/src/transition-queue-entry/transition-queue-entry.resource.ts +16 -0
  273. package/src/types/index.ts +494 -0
  274. package/src/views/queue-table-by-status-view.component.tsx +25 -0
  275. package/src/views/queue-tables-for-all-statuses.component.tsx +150 -0
  276. package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +277 -0
  277. package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +93 -0
  278. package/src/visits-missing-inqueue/visits-missing-inqueue.scss +108 -0
  279. package/translations/am.json +295 -0
  280. package/translations/ar.json +295 -0
  281. package/translations/en.json +305 -0
  282. package/translations/es.json +295 -0
  283. package/translations/fr.json +295 -0
  284. package/translations/he.json +295 -0
  285. package/translations/km.json +295 -0
  286. package/translations/zh.json +295 -0
  287. package/translations/zh_CN.json +295 -0
  288. package/tsconfig.json +5 -0
  289. package/webpack.config.js +1 -0
@@ -0,0 +1,277 @@
1
+ import React, { useMemo, useEffect, useState, useCallback, type AnchorHTMLAttributes } from 'react';
2
+ import classNames from 'classnames';
3
+ import {
4
+ DataTable,
5
+ DataTableSkeleton,
6
+ InlineLoading,
7
+ Layer,
8
+ Pagination,
9
+ Search,
10
+ Table,
11
+ TableContainer,
12
+ TableHead,
13
+ TableRow,
14
+ TableHeader,
15
+ TableBody,
16
+ TableCell,
17
+ TableToolbar,
18
+ TableToolbarContent,
19
+ TableExpandRow,
20
+ TableExpandHeader,
21
+ TableExpandedRow,
22
+ Tile,
23
+ Button,
24
+ } from '@carbon/react';
25
+ import {
26
+ useLayoutType,
27
+ isDesktop,
28
+ useConfig,
29
+ usePagination,
30
+ ExtensionSlot,
31
+ formatDatetime,
32
+ parseDate,
33
+ showModal,
34
+ ConfigurableLink,
35
+ } from '@openmrs/esm-framework';
36
+ import { useTranslation } from 'react-i18next';
37
+ import styles from './visits-missing-inqueue.scss';
38
+ import { type ActiveVisit, useMissingQueueEntries } from './visits-missing-inqueue.resource';
39
+ import { Add } from '@carbon/react/icons';
40
+ import { type ConfigObject } from '../config-schema';
41
+
42
+ interface PaginationData {
43
+ goTo: (page: number) => void;
44
+ results: Array<ActiveVisit>;
45
+ currentPage: number;
46
+ }
47
+
48
+ function AddMenu({ visitDetails }: { visitDetails: ActiveVisit }) {
49
+ const { t } = useTranslation();
50
+ const launchAddVisitToQueueModal = useCallback(() => {
51
+ const dispose = showModal('add-visit-to-queue-modal', {
52
+ closeModal: () => dispose(),
53
+ visitDetails,
54
+ });
55
+ }, [visitDetails]);
56
+
57
+ return (
58
+ <Button
59
+ kind="ghost"
60
+ onClick={launchAddVisitToQueueModal}
61
+ iconDescription={t('addisitToQueueTooltip', 'Add to queue')}
62
+ renderIcon={(props) => <Add size={16} {...props} />}>
63
+ {t('addToQueue', 'Add to queue')}
64
+ </Button>
65
+ );
66
+ }
67
+
68
+ const MissingQueueEntries = () => {
69
+ const { t } = useTranslation();
70
+ const config = useConfig<ConfigObject>();
71
+ const layout = useLayoutType();
72
+ const { activeVisits, isLoading, visitsIsValidating } = useMissingQueueEntries();
73
+ const pageSizes = [10, 20, 30, 40, 50];
74
+ const [currentPageSize, setPageSize] = useState(10);
75
+ const [searchString, setSearchString] = useState('');
76
+
77
+ const headerData = useMemo(
78
+ () => [
79
+ {
80
+ id: 0,
81
+ header: t('visitStartTime', 'Visit Time'),
82
+ key: 'visitStartTime',
83
+ },
84
+ {
85
+ id: 1,
86
+ header: t('idNumber', 'ID Number'),
87
+ key: 'idNumber',
88
+ },
89
+ {
90
+ id: 2,
91
+ header: t('name', 'Name'),
92
+ key: 'name',
93
+ },
94
+ {
95
+ id: 3,
96
+ header: t('gender', 'Gender'),
97
+ key: 'gender',
98
+ },
99
+ {
100
+ id: 4,
101
+ header: t('age', 'Age'),
102
+ key: 'age',
103
+ },
104
+ {
105
+ id: 5,
106
+ header: t('visitType', 'Visit Type'),
107
+ key: 'visitType',
108
+ },
109
+ ],
110
+ [t],
111
+ );
112
+
113
+ const rowData = activeVisits.map((visit) => ({
114
+ ...visit,
115
+ visitStartTime: formatDatetime(parseDate(visit.visitStartTime)),
116
+ }));
117
+
118
+ const searchResults = useMemo(() => {
119
+ if (searchString && searchString.trim() !== '') {
120
+ const search = searchString.toLowerCase();
121
+ return rowData.filter((activeVisitRow) =>
122
+ Object.keys(activeVisitRow).some((header) => {
123
+ if (header === 'patientUuid') {
124
+ return false;
125
+ }
126
+ return `${activeVisitRow[header]}`.toLowerCase().includes(search);
127
+ }),
128
+ );
129
+ } else {
130
+ return rowData;
131
+ }
132
+ }, [searchString, rowData]);
133
+
134
+ const {
135
+ goTo,
136
+ results: paginatedActiveVisits,
137
+ currentPage,
138
+ }: PaginationData = usePagination(searchResults, currentPageSize);
139
+
140
+ const handleSearch = useCallback((e) => setSearchString(e.target.value), []);
141
+
142
+ useEffect(() => {
143
+ if (currentPage !== 1) {
144
+ goTo(1);
145
+ }
146
+ }, [searchString, currentPage, goTo]);
147
+
148
+ if (isLoading) {
149
+ return <DataTableSkeleton role="progressbar" />;
150
+ }
151
+ if (activeVisits?.length) {
152
+ return (
153
+ <div className={styles.activeVisitsContainer}>
154
+ <div className={styles.activeVisitsDetailHeaderContainer}>
155
+ <div className={!isDesktop(layout) ? styles.tabletHeading : styles.desktopHeading}>
156
+ <h4>{t('activeVisitsNotInQueue', 'Active visits not in queue')}</h4>
157
+ </div>
158
+ <div className={styles.backgroundDataFetchingIndicator}>
159
+ <span>{visitsIsValidating ? <InlineLoading /> : null}</span>
160
+ </div>
161
+ </div>
162
+ <DataTable
163
+ rows={paginatedActiveVisits}
164
+ headers={headerData}
165
+ size={isDesktop(layout) ? 'xs' : 'md'}
166
+ useZebraStyles={activeVisits?.length > 1 ? true : false}>
167
+ {({ rows, headers, getHeaderProps, getTableProps, getBatchActionProps, getRowProps }) => (
168
+ <TableContainer className={styles.tableContainer}>
169
+ <TableToolbar>
170
+ <TableToolbarContent>
171
+ <Search
172
+ tabIndex={getBatchActionProps().shouldShowBatchActions ? -1 : 0}
173
+ labelText=""
174
+ placeholder={t('filterTable', 'Filter table')}
175
+ onChange={handleSearch}
176
+ />
177
+ </TableToolbarContent>
178
+ </TableToolbar>
179
+ <Table className={styles.activeVisitsTable} {...getTableProps()}>
180
+ <TableHead>
181
+ <TableRow>
182
+ <TableExpandHeader />
183
+ {headers.map((header) => (
184
+ <TableHeader {...getHeaderProps({ header })}>{header.header}</TableHeader>
185
+ ))}
186
+ </TableRow>
187
+ </TableHead>
188
+ <TableBody>
189
+ {rows.map((row, index) => (
190
+ <React.Fragment key={index}>
191
+ <TableExpandRow {...getRowProps({ row })}>
192
+ {row.cells.map((cell) => (
193
+ <TableCell key={cell.id}>
194
+ {cell.info.header === 'name' ? (
195
+ <ConfigurableLink
196
+ to={`\${openmrsSpaBase}/patient/${paginatedActiveVisits?.[index]?.patientUuid}/chart/`}>
197
+ {cell.value}
198
+ </ConfigurableLink>
199
+ ) : (
200
+ cell.value
201
+ )}
202
+ </TableCell>
203
+ ))}
204
+ <TableCell className="cds--table-column-menu">
205
+ <AddMenu visitDetails={paginatedActiveVisits?.[index]} />
206
+ </TableCell>
207
+ </TableExpandRow>
208
+ {row.isExpanded ? (
209
+ <TableRow className={styles.expandedActiveVisitRow}>
210
+ <th colSpan={headers.length + 2}>
211
+ <ExtensionSlot
212
+ className={styles.visitSummaryContainer}
213
+ name="visit-summary-slot"
214
+ state={{
215
+ visitUuid: paginatedActiveVisits[index]?.visitUuid,
216
+ patientUuid: paginatedActiveVisits[index]?.patientUuid,
217
+ }}
218
+ />
219
+ </th>
220
+ </TableRow>
221
+ ) : (
222
+ <TableExpandedRow className={styles.hiddenRow} colSpan={headers.length + 2} />
223
+ )}
224
+ </React.Fragment>
225
+ ))}
226
+ </TableBody>
227
+ </Table>
228
+ {rows.length === 0 && (
229
+ <p
230
+ style={{
231
+ height: isDesktop(layout) ? '2rem' : '3rem',
232
+ margin: '1rem 1.5rem',
233
+ }}
234
+ className={classNames(styles.emptyRow, styles.bodyLong01)}>
235
+ {t('noVisitsNotInQueueFound', 'No visits currently not in queue found')}
236
+ </p>
237
+ )}
238
+ <Pagination
239
+ forwardText="Next page"
240
+ backwardText="Previous page"
241
+ page={currentPage}
242
+ pageSize={currentPageSize}
243
+ pageSizes={pageSizes}
244
+ totalItems={searchResults.length}
245
+ className={styles.pagination}
246
+ onChange={({ pageSize, page }) => {
247
+ if (pageSize !== currentPageSize) {
248
+ setPageSize(pageSize);
249
+ }
250
+ if (page !== currentPage) {
251
+ goTo(page);
252
+ }
253
+ }}
254
+ />
255
+ </TableContainer>
256
+ )}
257
+ </DataTable>
258
+ </div>
259
+ );
260
+ }
261
+ return (
262
+ <div className={styles.activeVisitsContainer}>
263
+ <Layer>
264
+ <Tile className={styles.tile}>
265
+ <div className={!isDesktop(layout) ? styles.tabletHeading : styles.desktopHeading}>
266
+ <h4>{t('activeVisits', 'Active Visits')}</h4>
267
+ </div>
268
+ <p className={styles.content}>
269
+ {t('noActiveVisitsForLocation', 'There are no active visits to display for this location.')}
270
+ </p>
271
+ </Tile>
272
+ </Layer>
273
+ </div>
274
+ );
275
+ };
276
+
277
+ export default MissingQueueEntries;
@@ -0,0 +1,93 @@
1
+ import useSWR from 'swr';
2
+ import dayjs from 'dayjs';
3
+ import isToday from 'dayjs/plugin/isToday';
4
+ import last from 'lodash-es/last';
5
+ import { openmrsFetch, type Visit, useSession, restBaseUrl } from '@openmrs/esm-framework';
6
+ import { type VisitQueueEntry } from '../active-visits/active-visits-table.resource';
7
+
8
+ dayjs.extend(isToday);
9
+
10
+ export interface ActiveVisit {
11
+ age: string;
12
+ id: string;
13
+ idNumber: string;
14
+ gender: string;
15
+ location: string;
16
+ name: string;
17
+ patientUuid: string;
18
+ visitStartTime: string;
19
+ visitType: string;
20
+ visitUuid: string;
21
+ }
22
+
23
+ export function useMissingQueueEntries() {
24
+ const currentUserSession = useSession();
25
+ const startDate = dayjs().format('YYYY-MM-DD');
26
+ const sessionLocation = currentUserSession?.sessionLocation?.uuid;
27
+
28
+ const customRepresentation =
29
+ 'custom:(uuid,patient:(uuid,identifiers:(identifier,uuid),person:(age,display,gender,uuid)),' +
30
+ 'visitType:(uuid,name,display),location:(uuid,name,display),startDatetime,' +
31
+ 'stopDatetime)&fromStartDate=' +
32
+ startDate +
33
+ '&location=' +
34
+ sessionLocation;
35
+ const url = `${restBaseUrl}/visit?includeInactive=false&v=${customRepresentation}`;
36
+ const {
37
+ data: visitsData,
38
+ error: visitsError,
39
+ isValidating: visitsIsValidating,
40
+ } = useSWR<{ data: { results: Array<Visit> } }, Error>(sessionLocation ? url : null, openmrsFetch);
41
+
42
+ const apiUrl = `${restBaseUrl}/visit-queue-entry`;
43
+ const {
44
+ data: queueData,
45
+ error: queueError,
46
+ isValidating: queueIsValidating,
47
+ mutate: mutateQueueEntries,
48
+ } = useSWR<{ data: { results: Array<VisitQueueEntry> } }, Error>(apiUrl, openmrsFetch);
49
+
50
+ const byId = {};
51
+ queueData?.data?.results.forEach((item) => {
52
+ if (item?.queueEntry.patient?.uuid) {
53
+ byId[item?.queueEntry.patient?.uuid] = true;
54
+ }
55
+ });
56
+
57
+ const data = visitsData?.data?.results?.filter((item) => {
58
+ if (byId[item?.patient?.uuid]) {
59
+ return false;
60
+ }
61
+ return true;
62
+ });
63
+
64
+ const mapVisitProperties = (visit: Visit): ActiveVisit => ({
65
+ age: visit?.patient?.person?.age,
66
+ id: visit.uuid,
67
+ idNumber: visit?.patient?.identifiers[0]?.identifier,
68
+ gender: visit?.patient?.person?.gender,
69
+ location: visit?.location?.uuid,
70
+ name: visit?.patient?.person?.display,
71
+ patientUuid: visit?.patient?.uuid,
72
+ visitStartTime: visit?.startDatetime,
73
+ visitType: visit?.visitType?.display,
74
+ visitUuid: visit.uuid,
75
+ });
76
+
77
+ const formattedActiveVisits = data?.length
78
+ ? data.map(mapVisitProperties).filter(({ visitStartTime }) => dayjs(visitStartTime).isToday())
79
+ : [];
80
+
81
+ return {
82
+ activeVisits: formattedActiveVisits,
83
+ isLoading: !data && !visitsError && !queueError,
84
+ isError: !visitsError && !queueError,
85
+ visitsIsValidating,
86
+ mutateQueueEntries,
87
+ };
88
+ }
89
+
90
+ export const getOriginFromPathName = (pathname = '') => {
91
+ const from = pathname.split('/');
92
+ return last(from);
93
+ };
@@ -0,0 +1,108 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+ @import '../root.scss';
4
+
5
+ .activeVisitsContainer {
6
+ background-color: $ui-background;
7
+ border: 1px solid $ui-03;
8
+ width: 100%;
9
+ margin: 0 auto;
10
+ max-width: 95vw;
11
+ }
12
+
13
+ .activeVisitsDetailHeaderContainer {
14
+ display: flex;
15
+ justify-content: space-between;
16
+ align-items: center;
17
+ padding: spacing.$spacing-04 0 spacing.$spacing-04 spacing.$spacing-05;
18
+ background-color: $ui-background;
19
+ }
20
+
21
+ .backgroundDataFetchingIndicator {
22
+ align-items: center;
23
+ display: flex;
24
+ flex: 1 1 0%;
25
+ justify-content: center;
26
+ }
27
+
28
+ .tableContainer section {
29
+ position: relative;
30
+ }
31
+
32
+ .tableContainer a {
33
+ text-decoration: none;
34
+ }
35
+
36
+ .tableContainer {
37
+ :global(.cds--data-table) {
38
+ background-color: $ui-03;
39
+ }
40
+ }
41
+
42
+ .pagination {
43
+ overflow: hidden;
44
+ }
45
+
46
+ .hiddenRow {
47
+ display: none;
48
+ }
49
+
50
+ .emptyRow {
51
+ padding: 0 1rem;
52
+ display: flex;
53
+ align-items: center;
54
+ }
55
+
56
+ .visitSummaryContainer {
57
+ width: 100%;
58
+ max-width: 768px;
59
+ margin: 1rem auto;
60
+ }
61
+
62
+ .expandedActiveVisitRow > td > div {
63
+ max-height: max-content !important;
64
+ }
65
+
66
+ .expandedActiveVisitRow td {
67
+ padding: 0 2rem;
68
+ }
69
+
70
+ .expandedActiveVisitRow th[colspan] td[colspan] > div:first-child {
71
+ padding: 0 1rem;
72
+ }
73
+
74
+ .action {
75
+ margin-bottom: spacing.$spacing-03;
76
+ }
77
+
78
+ .content {
79
+ @include type.type-style('heading-compact-01');
80
+ color: $text-02;
81
+ margin-top: spacing.$spacing-05;
82
+ margin-bottom: spacing.$spacing-03;
83
+ }
84
+
85
+ .desktopHeading,
86
+ .tabletHeading {
87
+ text-align: left;
88
+ text-transform: capitalize;
89
+ margin-bottom: spacing.$spacing-05;
90
+
91
+ h4 {
92
+ @include type.type-style('heading-compact-02');
93
+ color: $text-02;
94
+
95
+ &:after {
96
+ content: '';
97
+ display: block;
98
+ width: 2rem;
99
+ padding-top: 3px;
100
+ border-bottom: 0.375rem solid;
101
+ @include brand-03(border-bottom-color);
102
+ }
103
+ }
104
+ }
105
+
106
+ .tile {
107
+ text-align: center;
108
+ }