@kenyaemr/esm-express-workflow-app 5.4.3 → 5.4.4-pre.100

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 (388) hide show
  1. package/.turbo/turbo-build.log +7 -12
  2. package/dist/1074.js +1 -0
  3. package/dist/1074.js.map +1 -0
  4. package/dist/12.js +17 -0
  5. package/dist/12.js.map +1 -0
  6. package/dist/1311.js +1 -0
  7. package/dist/1311.js.map +1 -0
  8. package/dist/1323.js +1 -0
  9. package/dist/1323.js.map +1 -0
  10. package/dist/1469.js +1 -0
  11. package/dist/1469.js.map +1 -0
  12. package/dist/1506.js +13 -0
  13. package/dist/1506.js.map +1 -0
  14. package/dist/1562.js +1 -0
  15. package/dist/1562.js.map +1 -0
  16. package/dist/1760.js +1 -0
  17. package/dist/1760.js.map +1 -0
  18. package/dist/1780.js +1 -0
  19. package/dist/1780.js.map +1 -0
  20. package/dist/1804.js +1 -0
  21. package/dist/1804.js.map +1 -0
  22. package/dist/1884.js +1 -0
  23. package/dist/1884.js.map +1 -0
  24. package/dist/1972.js +1 -0
  25. package/dist/1972.js.map +1 -0
  26. package/dist/1990.js +1 -0
  27. package/dist/1990.js.map +1 -0
  28. package/dist/2016.js +1 -0
  29. package/dist/2016.js.map +1 -0
  30. package/dist/2024.js +1 -0
  31. package/dist/2024.js.map +1 -0
  32. package/dist/2153.js +1 -0
  33. package/dist/2153.js.map +1 -0
  34. package/dist/216.js +1 -0
  35. package/dist/216.js.map +1 -0
  36. package/dist/2225.js +1 -0
  37. package/dist/2225.js.map +1 -0
  38. package/dist/2294.js +1 -0
  39. package/dist/2294.js.map +1 -0
  40. package/dist/2345.js +1 -0
  41. package/dist/2345.js.map +1 -0
  42. package/dist/2499.js +1 -0
  43. package/dist/2499.js.map +1 -0
  44. package/dist/2500.js +1 -0
  45. package/dist/2500.js.map +1 -0
  46. package/dist/2586.js +1 -0
  47. package/dist/2586.js.map +1 -0
  48. package/dist/2625.js +1 -0
  49. package/dist/2625.js.map +1 -0
  50. package/dist/2685.js +1 -0
  51. package/dist/2685.js.map +1 -0
  52. package/dist/2809.js +1 -0
  53. package/dist/2809.js.map +1 -0
  54. package/dist/2851.js +1 -0
  55. package/dist/2851.js.map +1 -0
  56. package/dist/2881.js +1 -0
  57. package/dist/2881.js.map +1 -0
  58. package/dist/2948.js +1 -0
  59. package/dist/2948.js.map +1 -0
  60. package/dist/2968.js +1 -0
  61. package/dist/2968.js.map +1 -0
  62. package/dist/2978.js +1 -0
  63. package/dist/2978.js.map +1 -0
  64. package/dist/2998.js +1 -0
  65. package/dist/2998.js.map +1 -0
  66. package/dist/3089.js +1 -0
  67. package/dist/3089.js.map +1 -0
  68. package/dist/3548.js +1 -0
  69. package/dist/3548.js.map +1 -0
  70. package/dist/3567.js +1 -0
  71. package/dist/3567.js.map +1 -0
  72. package/dist/3569.js +1 -0
  73. package/dist/3569.js.map +1 -0
  74. package/dist/3571.js +1 -0
  75. package/dist/3571.js.map +1 -0
  76. package/dist/3691.js +1 -0
  77. package/dist/3691.js.map +1 -0
  78. package/dist/3730.js +1 -0
  79. package/dist/3730.js.map +1 -0
  80. package/dist/3923.js +1 -0
  81. package/dist/3923.js.map +1 -0
  82. package/dist/3963.js +1 -0
  83. package/dist/3963.js.map +1 -0
  84. package/dist/4024.js +1 -0
  85. package/dist/4024.js.map +1 -0
  86. package/dist/405.js +1 -0
  87. package/dist/405.js.map +1 -0
  88. package/dist/4071.js +1 -0
  89. package/dist/4071.js.map +1 -0
  90. package/dist/4271.js +1 -0
  91. package/dist/4271.js.map +1 -0
  92. package/dist/4296.js +1 -0
  93. package/dist/4296.js.map +1 -0
  94. package/dist/4337.js +1 -0
  95. package/dist/4337.js.map +1 -0
  96. package/dist/4432.js +1 -0
  97. package/dist/4432.js.map +1 -0
  98. package/dist/4581.js +1 -0
  99. package/dist/4581.js.map +1 -0
  100. package/dist/4637.js +11 -0
  101. package/dist/4637.js.map +1 -0
  102. package/dist/4666.js +1 -0
  103. package/dist/4666.js.map +1 -0
  104. package/dist/4680.js +1 -0
  105. package/dist/4680.js.map +1 -0
  106. package/dist/4735.js +1 -0
  107. package/dist/4735.js.map +1 -0
  108. package/dist/4737.js +1 -0
  109. package/dist/4737.js.map +1 -0
  110. package/dist/4744.js +1 -0
  111. package/dist/4744.js.map +1 -0
  112. package/dist/4795.js +1 -0
  113. package/dist/4795.js.map +1 -0
  114. package/dist/4813.js +2 -0
  115. package/dist/4813.js.map +1 -0
  116. package/dist/4818.js +1 -0
  117. package/dist/4818.js.map +1 -0
  118. package/dist/4858.js +1 -0
  119. package/dist/4858.js.map +1 -0
  120. package/dist/487.js +1 -0
  121. package/dist/487.js.map +1 -0
  122. package/dist/4970.js +1 -0
  123. package/dist/4970.js.map +1 -0
  124. package/dist/5038.js +1 -0
  125. package/dist/5038.js.map +1 -0
  126. package/dist/5202.js +1 -0
  127. package/dist/5202.js.map +1 -0
  128. package/dist/5491.js +1 -0
  129. package/dist/5491.js.map +1 -0
  130. package/dist/5592.js +1 -0
  131. package/dist/5592.js.map +1 -0
  132. package/dist/5669.js +1 -0
  133. package/dist/5669.js.map +1 -0
  134. package/dist/586.js +1 -0
  135. package/dist/586.js.map +1 -0
  136. package/dist/5932.js +1 -0
  137. package/dist/5932.js.map +1 -0
  138. package/dist/5995.js +1 -0
  139. package/dist/5995.js.map +1 -0
  140. package/dist/6258.js +1 -0
  141. package/dist/6258.js.map +1 -0
  142. package/dist/629.js +1 -0
  143. package/dist/629.js.map +1 -0
  144. package/dist/6328.js +1 -0
  145. package/dist/6328.js.map +1 -0
  146. package/dist/6355.js +1 -0
  147. package/dist/6355.js.map +1 -0
  148. package/dist/6419.js +1 -0
  149. package/dist/6419.js.map +1 -0
  150. package/dist/644.js +1 -0
  151. package/dist/644.js.map +1 -0
  152. package/dist/6456.js +1 -0
  153. package/dist/6466.js +3 -0
  154. package/dist/6466.js.map +1 -0
  155. package/dist/655.js +1 -0
  156. package/dist/655.js.map +1 -0
  157. package/dist/6798.js +66 -0
  158. package/dist/6798.js.map +1 -0
  159. package/dist/6910.js +1 -0
  160. package/dist/6910.js.map +1 -0
  161. package/dist/6925.js +1 -0
  162. package/dist/6925.js.map +1 -0
  163. package/dist/70.js +1 -0
  164. package/dist/70.js.map +1 -0
  165. package/dist/7201.js +1 -0
  166. package/dist/7201.js.map +1 -0
  167. package/dist/7234.js +1 -0
  168. package/dist/7234.js.map +1 -0
  169. package/dist/7261.js +1 -0
  170. package/dist/7261.js.map +1 -0
  171. package/dist/7326.js +1 -0
  172. package/dist/7359.js +1 -0
  173. package/dist/7487.js +1 -0
  174. package/dist/7487.js.map +1 -0
  175. package/dist/7591.js +1 -0
  176. package/dist/7591.js.map +1 -0
  177. package/dist/7607.js +1 -0
  178. package/dist/7701.js +1 -0
  179. package/dist/7701.js.map +1 -0
  180. package/dist/7717.js +1 -0
  181. package/dist/7717.js.map +1 -0
  182. package/dist/7739.js +1 -0
  183. package/dist/7739.js.map +1 -0
  184. package/dist/7788.js +1 -0
  185. package/dist/7788.js.map +1 -0
  186. package/dist/7819.js +1 -0
  187. package/dist/7819.js.map +1 -0
  188. package/dist/7971.js +1 -0
  189. package/dist/7971.js.map +1 -0
  190. package/dist/7983.js +1 -0
  191. package/dist/7983.js.map +1 -0
  192. package/dist/807.js +1 -0
  193. package/dist/807.js.map +1 -0
  194. package/dist/8159.js +7 -0
  195. package/dist/8159.js.map +1 -0
  196. package/dist/8338.js +1 -0
  197. package/dist/8338.js.map +1 -0
  198. package/dist/845.js +1 -0
  199. package/dist/845.js.map +1 -0
  200. package/dist/8570.js +1 -0
  201. package/dist/8570.js.map +1 -0
  202. package/dist/8661.js +1 -0
  203. package/dist/8661.js.map +1 -0
  204. package/dist/87.js +1 -0
  205. package/dist/87.js.map +1 -0
  206. package/dist/8727.js +1 -0
  207. package/dist/8766.js +1 -0
  208. package/dist/8766.js.map +1 -0
  209. package/dist/8828.js +1 -0
  210. package/dist/8828.js.map +1 -0
  211. package/dist/8860.js +1 -0
  212. package/dist/8860.js.map +1 -0
  213. package/dist/8911.js +1 -0
  214. package/dist/8911.js.map +1 -0
  215. package/dist/8930.js +1 -0
  216. package/dist/8930.js.map +1 -0
  217. package/dist/8971.js +1 -0
  218. package/dist/8971.js.map +1 -0
  219. package/dist/9124.js +1 -0
  220. package/dist/9124.js.map +1 -0
  221. package/dist/9157.js +1 -0
  222. package/dist/9157.js.map +1 -0
  223. package/dist/9182.js +1 -0
  224. package/dist/921.js +1 -0
  225. package/dist/921.js.map +1 -0
  226. package/dist/9212.js +1 -0
  227. package/dist/9212.js.map +1 -0
  228. package/dist/9255.js +1 -0
  229. package/dist/9255.js.map +1 -0
  230. package/dist/9257.js +1 -0
  231. package/dist/9257.js.map +1 -0
  232. package/dist/9316.js +1 -0
  233. package/dist/9316.js.map +1 -0
  234. package/dist/9333.js +1 -0
  235. package/dist/9333.js.map +1 -0
  236. package/dist/9404.js +1 -0
  237. package/dist/9404.js.map +1 -0
  238. package/dist/9446.js +1 -0
  239. package/dist/9446.js.map +1 -0
  240. package/dist/9447.js +1 -0
  241. package/dist/9447.js.map +1 -0
  242. package/dist/9449.js +1 -0
  243. package/dist/9449.js.map +1 -0
  244. package/dist/9535.js +1 -0
  245. package/dist/9535.js.map +1 -0
  246. package/dist/9606.js +1 -0
  247. package/dist/9606.js.map +1 -0
  248. package/dist/973.js +1 -0
  249. package/dist/973.js.map +1 -0
  250. package/dist/9845.js +1 -0
  251. package/dist/9845.js.map +1 -0
  252. package/dist/kenyaemr-esm-express-workflow-app.js +5 -5
  253. package/dist/kenyaemr-esm-express-workflow-app.js.buildmanifest.json +3004 -175
  254. package/dist/kenyaemr-esm-express-workflow-app.js.map +1 -1
  255. package/dist/main.js +5 -114
  256. package/dist/main.js.map +1 -1
  257. package/dist/routes.json +1 -1
  258. package/package.json +6 -7
  259. package/rspack.config.js +1 -1
  260. package/src/components/accounting/index.tsx +11 -10
  261. package/src/components/admissions/index.tsx +11 -10
  262. package/src/components/appointments/index.ts +10 -8
  263. package/src/components/consultation/clinical-encounter/encounter-details.component.tsx +9 -9
  264. package/src/components/consultation/clinical-encounter/encounter-details.test.tsx +19 -18
  265. package/src/components/consultation/consultation-context.tsx +19 -0
  266. package/src/components/consultation/consultation-summary-cards.component.tsx +124 -0
  267. package/src/components/consultation/consultation.component.tsx +41 -268
  268. package/src/components/consultation/consultation.resource.ts +67 -24
  269. package/src/components/consultation/consultation.scss +5 -0
  270. package/src/components/consultation/consultation.utils.tsx +222 -0
  271. package/src/components/consultation/dashboard.component.tsx +0 -2
  272. package/src/components/consultation/index.ts +27 -20
  273. package/src/components/facility-dashboard/index.tsx +10 -9
  274. package/src/components/laboratory/index.ts +11 -10
  275. package/src/components/laboratory/lab-table.component.tsx +22 -8
  276. package/src/components/laboratory/laboratory-tabs.component.tsx +2 -2
  277. package/src/components/mch/dashboard.component.tsx +0 -2
  278. package/src/components/mch/index.tsx +10 -9
  279. package/src/components/mch/mch.consultation.component.tsx +27 -15
  280. package/src/components/mch/mch.triage.component.tsx +42 -33
  281. package/src/components/pharmacy/index.ts +20 -18
  282. package/src/components/pharmacy/orders/pharmacy-orders.component.tsx +35 -13
  283. package/src/components/pharmacy/orders/pharmacy-orders.test.tsx +8 -7
  284. package/src/components/procedures/index.ts +11 -10
  285. package/src/components/procedures/procedures-table.component.tsx +44 -13
  286. package/src/components/procedures/procedures-tabs.component.tsx +2 -2
  287. package/src/components/radiology-and-imaging/index.ts +14 -10
  288. package/src/components/radiology-and-imaging/radiology-and-imaging-table.component.tsx +35 -15
  289. package/src/components/radiology-and-imaging/radiology-and-imaging.component.tsx +2 -2
  290. package/src/components/registration/card/HIE-card/hie-card.component.tsx +32 -44
  291. package/src/components/registration/card/Local-card/local-card.component.tsx +22 -24
  292. package/src/components/registration/dependants/dependants.component.tsx +32 -60
  293. package/src/components/registration/dependants/dependants.resource.ts +79 -50
  294. package/src/components/registration/helper/index.ts +4 -0
  295. package/src/components/registration/index.ts +10 -9
  296. package/src/components/registration/search-bar/search-bar.resource.ts +32 -93
  297. package/src/components/registration/start-visit-form/hooks/useDefaultFacilityLocation.tsx +15 -0
  298. package/src/components/registration/start-visit-form/hooks/useDefaultVisitLocation.tsx +24 -0
  299. package/src/components/registration/start-visit-form/hooks/useOfflineVisitType.tsx +18 -0
  300. package/src/components/registration/start-visit-form/hooks/useRecommendedVisitTypes.tsx +36 -0
  301. package/src/components/registration/start-visit-form/hooks/useVisitAttributeType.tsx +102 -0
  302. package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.extension.tsx +55 -0
  303. package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.scss +3 -0
  304. package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.component.tsx +126 -0
  305. package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.scss +75 -0
  306. package/src/components/registration/start-visit-form/start-visit-workspace/exported-visit-form.workspace.tsx +743 -0
  307. package/src/components/registration/start-visit-form/start-visit-workspace/location-selector.component.tsx +86 -0
  308. package/src/components/registration/start-visit-form/start-visit-workspace/recommended-visit-type.component.tsx +32 -0
  309. package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.component.tsx +257 -0
  310. package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.scss +5 -0
  311. package/src/components/registration/start-visit-form/start-visit-workspace/visit-date-time.component.tsx +193 -0
  312. package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.resource.ts +383 -0
  313. package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.scss +166 -0
  314. package/src/components/registration/start-visit-form/visit-form-workspace/visit-form.workspace.tsx +55 -0
  315. package/src/components/reports/index.ts +10 -9
  316. package/src/components/triage/dashboard.component.tsx +0 -2
  317. package/src/components/triage/index.ts +10 -9
  318. package/src/components/triage/triage.component.tsx +92 -42
  319. package/src/components/triage/triage.resource.ts +56 -50
  320. package/src/components/triage/triage.scss +6 -0
  321. package/src/config-schema.ts +91 -0
  322. package/src/hooks/useServiceQueues.tsx +95 -25
  323. package/src/index.ts +32 -13
  324. package/src/routes.json +53 -254
  325. package/src/shared/orders/OrdersTabs.tsx +8 -3
  326. package/src/shared/patient-chart/patient-chart.resources.ts +8 -12
  327. package/src/shared/patient-chart/patient-summary-dashboard/patient-summary-dashboard.component.tsx +1 -2
  328. package/src/shared/pin-put/pinput.component.test.tsx +7 -6
  329. package/src/shared/queue/queue-entry/queue-entry-table.component.tsx +99 -88
  330. package/src/shared/queue/queue-entry/queue-entry-table.scss +4 -0
  331. package/src/shared/queue/queue-summary-cards.component.tsx +32 -0
  332. package/src/shared/queue/queue-tab.component.tsx +182 -70
  333. package/src/shared/queue/queue-tab.scss +1 -0
  334. package/src/shared/queue/queue-workflow-context.tsx +90 -0
  335. package/src/shared/tabs/extension-tabs.component.tsx +9 -6
  336. package/src/shared/utils/index.ts +1 -2
  337. package/src/types/index.ts +17 -2
  338. package/translations/am.json +64 -13
  339. package/translations/en.json +59 -8
  340. package/translations/sw.json +58 -7
  341. package/dist/127.js +0 -1
  342. package/dist/200.js +0 -1
  343. package/dist/200.js.map +0 -1
  344. package/dist/24.js +0 -1
  345. package/dist/24.js.map +0 -1
  346. package/dist/267.js +0 -1
  347. package/dist/267.js.map +0 -1
  348. package/dist/285.js +0 -1
  349. package/dist/285.js.map +0 -1
  350. package/dist/329.js +0 -1
  351. package/dist/329.js.map +0 -1
  352. package/dist/40.js +0 -1
  353. package/dist/466.js +0 -1
  354. package/dist/466.js.map +0 -1
  355. package/dist/472.js +0 -66
  356. package/dist/472.js.map +0 -1
  357. package/dist/490.js +0 -1
  358. package/dist/490.js.map +0 -1
  359. package/dist/54.js +0 -1
  360. package/dist/54.js.map +0 -1
  361. package/dist/689.js +0 -1
  362. package/dist/689.js.map +0 -1
  363. package/dist/697.js +0 -1
  364. package/dist/697.js.map +0 -1
  365. package/dist/704.js +0 -1
  366. package/dist/704.js.map +0 -1
  367. package/dist/710.js +0 -1
  368. package/dist/710.js.map +0 -1
  369. package/dist/729.js +0 -17
  370. package/dist/729.js.map +0 -1
  371. package/dist/805.js +0 -37
  372. package/dist/805.js.map +0 -1
  373. package/dist/847.js +0 -1
  374. package/dist/847.js.map +0 -1
  375. package/dist/85.js +0 -1
  376. package/dist/85.js.map +0 -1
  377. package/dist/882.js +0 -1
  378. package/dist/91.js +0 -1
  379. package/dist/91.js.map +0 -1
  380. package/dist/916.js +0 -1
  381. package/dist/994.js +0 -1
  382. package/dist/994.js.map +0 -1
  383. package/dist/998.js +0 -1
  384. package/dist/998.js.map +0 -1
  385. package/jest.config.js +0 -3
  386. package/src/shared/patient-chart/patient-chart.component.tsx +0 -61
  387. package/src/shared/patient-chart/patient-chart.scss +0 -15
  388. package/src/shared/patient-chart/useInitialize.ts +0 -24
@@ -1,14 +1,13 @@
1
- import { IconButton, InlineLoading } from '@carbon/react';
2
- import { Renew } from '@carbon/react/icons';
3
- import { ExtensionSlot, HomePictogram, PageHeader, PageHeaderContent, useConfig } from '@openmrs/esm-framework';
1
+ import React, { useMemo, useState } from 'react';
4
2
  import capitalize from 'lodash-es/capitalize';
5
- import React, { useCallback, useMemo, useState } from 'react';
6
- import { useTranslation } from 'react-i18next';
7
- import { ExpressWorkflowConfig } from '../../config-schema';
3
+ import { TabsSkeleton } from '@carbon/react';
4
+ import { ExtensionSlot, HomePictogram, PageHeader, PageHeaderContent, useConfig } from '@openmrs/esm-framework';
5
+
6
+ import { type ExpressWorkflowConfig } from '../../config-schema';
8
7
  import { useQueues } from '../../hooks/useServiceQueues';
9
8
  import QueueTab from '../../shared/queue/queue-tab.component';
10
- import { Queue, QueueFilter } from '../../types';
11
- import { useConsultationQueueMetrics, useInvestigationStats, useTotalVisits } from './consultation.resource';
9
+ import ConsultationSummaryCards from './consultation-summary-cards.component';
10
+ import { ConsultationProvider } from './consultation-context';
12
11
  import styles from './consultation.scss';
13
12
 
14
13
  type ConsultationProps = {
@@ -16,269 +15,43 @@ type ConsultationProps = {
16
15
  };
17
16
 
18
17
  const Consultation: React.FC<ConsultationProps> = ({ dashboardTitle }) => {
19
- const { t } = useTranslation();
20
- const {
21
- priorities: { emergencyPriorityConceptUuid, urgentPriorityConceptUuid, notUrgentPriorityConceptUuid },
22
- queueServiceConceptUuids,
23
- } = useConfig<ExpressWorkflowConfig>();
24
- const [currQueue, setCurrQueue] = useState<Queue>();
25
- const { queues, isLoading, error } = useQueues();
26
- const [isRefreshing, setIsRefreshing] = useState(false);
27
-
28
- const consultationQueues = queues.filter(
29
- (queue) =>
30
- queue.service.uuid === queueServiceConceptUuids.consultationService &&
31
- !queue.location.display.toLowerCase().includes('mch') &&
32
- queue?.queueRooms?.length > 0,
33
- );
34
- const activeQueue = useMemo(() => currQueue ?? consultationQueues[0], [currQueue, consultationQueues]);
35
- const {
36
- waitingEntries,
37
- isLoading: isLoadingQueuemetrics,
38
- error: waitingError,
39
- emergencyEntries,
40
- urgentEntries,
41
- notUrgentEntries,
42
- } = useConsultationQueueMetrics(activeQueue);
43
- const { data: totalVisits, isLoading: isLoadingTotalVisits } = useTotalVisits();
44
-
45
- // Use the updated investigation stats hook with single refresh function
46
- const {
47
- awaitingCount,
48
- completedCount,
49
- totalCount,
50
- lab,
51
- radiology,
52
- procedures,
53
- isLoading: isLoadingInvestigations,
54
- refresh: refreshInvestigations,
55
- investigationCategorizedEntries,
56
- } = useInvestigationStats(activeQueue);
57
- const [filters, setFilters] = useState<Array<QueueFilter>>([]);
58
- // Single refresh handler for all investigations
59
- const handleRefresh = useCallback(async () => {
60
- setIsRefreshing(true);
61
- try {
62
- await refreshInvestigations();
63
- } catch (error) {
64
- console.error('Error refreshing investigations:', error);
65
- } finally {
66
- setIsRefreshing(false);
67
- }
68
- }, [refreshInvestigations]);
69
-
70
- const cards = useMemo(
71
- () => [
72
- {
73
- title: t('awaitingConsultation', 'Awaiting consultation'),
74
- value: waitingEntries.length.toString(),
75
- categories: [
76
- {
77
- label: t('emergency', 'Emergency'),
78
- value: emergencyEntries.length,
79
- onClick: () => {
80
- setFilters((prevFilters) => [
81
- ...prevFilters.filter((f) => f.key !== 'priority'),
82
- { key: 'priority', value: emergencyPriorityConceptUuid, label: t('emergency', 'Emergency') },
83
- ]);
84
- },
85
- },
86
- {
87
- label: t('urgent', 'Urgent'),
88
- value: urgentEntries.length,
89
- onClick: () => {
90
- setFilters((prevFilters) => [
91
- ...prevFilters.filter((f) => f.key !== 'priority'),
92
- { key: 'priority', value: urgentPriorityConceptUuid, label: t('urgent', 'Urgent') },
93
- ]);
94
- },
95
- },
96
- {
97
- label: t('notUrgent', 'Not Urgent'),
98
- value: notUrgentEntries.length,
99
- onClick: () => {
100
- setFilters((prevFilters) => [
101
- ...prevFilters.filter((f) => f.key !== 'priority'),
102
- { key: 'priority', value: notUrgentPriorityConceptUuid, label: t('notUrgent', 'Not Urgent') },
103
- ]);
104
- },
105
- },
106
- ],
107
- },
108
- {
109
- title: t('investigationAwaiting', 'Investigation Awaiting'),
110
- value: awaitingCount.toString(),
111
- categories: [
112
- {
113
- label: t('lab', 'Lab'),
114
- value: lab.awaiting,
115
- onClick: () => {
116
- setFilters((prevFilters) => [
117
- ...prevFilters.filter((f) => f.key !== 'service_awaiting'),
118
- {
119
- key: 'service_awaiting',
120
- value: investigationCategorizedEntries.newLabOrders.map((entry) => entry.patient.uuid).join(','),
121
- label: t('labAwaiting', 'Lab Awaiting'),
122
- },
123
- ]);
124
- },
125
- },
126
- {
127
- label: t('radiology', 'Radiology'),
128
- value: radiology.awaiting,
129
- onClick: () => {
130
- setFilters((prevFilters) => [
131
- ...prevFilters.filter((f) => f.key !== 'service_awaiting'),
132
- {
133
- key: 'service_awaiting',
134
- value: investigationCategorizedEntries.newRadiologyOrders
135
- .map((entry) => entry.patient.uuid)
136
- .join(','),
137
- label: t('radiologyAwaiting', 'Radiology Awaiting'),
138
- },
139
- ]);
140
- },
141
- },
142
- {
143
- label: t('procedures', 'Procedures'),
144
- value: procedures.awaiting,
145
- onClick: () => {
146
- setFilters((prevFilters) => [
147
- ...prevFilters.filter((f) => f.key !== 'service_awaiting'),
148
- {
149
- key: 'service_awaiting',
150
- value: investigationCategorizedEntries.newProcedureOrders
151
- .map((entry) => entry.patient.uuid)
152
- .join(','),
153
- label: t('proceduresAwaiting', 'Procedures Awaiting'),
154
- },
155
- ]);
156
- },
157
- },
158
- ],
159
- refreshButton:
160
- isRefreshing || isLoadingInvestigations ? (
161
- <InlineLoading description={t('refreshing', 'Refreshing...')} />
162
- ) : (
163
- <IconButton
164
- label={t('refreshInvestigations', 'Refresh investigations')}
165
- kind="ghost"
166
- size="sm"
167
- onClick={handleRefresh}
168
- className={styles.refreshButton}>
169
- <Renew size={16} />
170
- </IconButton>
171
- ),
172
- },
173
- {
174
- title: t('investigationCompleted', 'Investigation Completed'),
175
- value: completedCount.toString(),
176
- categories: [
177
- {
178
- label: t('lab', 'Lab'),
179
- value: lab.completed,
180
- onClick: () => {
181
- setFilters((prevFilters) => [
182
- ...prevFilters.filter((f) => f.key !== 'service_completed'),
183
- {
184
- key: 'service_completed',
185
- value: investigationCategorizedEntries.completedLabOrders
186
- .map((entry) => entry.patient.uuid)
187
- .join(','),
188
- label: t('labCompleted', 'Lab Completed'),
189
- },
190
- ]);
191
- },
192
- },
193
- {
194
- label: t('radiology', 'Radiology'),
195
- value: radiology.completed,
196
- onClick: () => {
197
- setFilters((prevFilters) => [
198
- ...prevFilters.filter((f) => f.key !== 'service_completed'),
199
- {
200
- key: 'service_completed',
201
- value: investigationCategorizedEntries.completedRadiologyOrders
202
- .map((entry) => entry.patient.uuid)
203
- .join(','),
204
- label: t('radiologyCompleted', 'Radiology Completed'),
205
- },
206
- ]);
207
- },
208
- },
209
- {
210
- label: t('procedures', 'Procedures'),
211
- value: procedures.completed,
212
- onClick: () => {
213
- setFilters((prevFilters) => [
214
- ...prevFilters.filter((f) => f.key !== 'service_completed'),
215
- {
216
- key: 'service_completed',
217
- value: investigationCategorizedEntries.completedProcedureOrders
218
- .map((entry) => entry.patient.uuid)
219
- .join(','),
220
- label: t('proceduresCompleted', 'Procedures Completed'),
221
- },
222
- ]);
223
- },
224
- },
225
- ],
226
- },
227
- {
228
- title: t('totalVisits', 'Total Visits'),
229
- value: totalVisits?.length?.toString() ?? '0',
230
- },
231
- ],
232
- [
233
- t,
234
- waitingEntries.length,
235
- emergencyEntries.length,
236
- urgentEntries.length,
237
- notUrgentEntries.length,
238
- awaitingCount,
239
- lab.awaiting,
240
- lab.completed,
241
- radiology.awaiting,
242
- radiology.completed,
243
- procedures.awaiting,
244
- procedures.completed,
245
- isRefreshing,
246
- isLoadingInvestigations,
247
- handleRefresh,
248
- completedCount,
249
- totalVisits?.length,
250
- emergencyPriorityConceptUuid,
251
- urgentPriorityConceptUuid,
252
- notUrgentPriorityConceptUuid,
253
- investigationCategorizedEntries.newLabOrders,
254
- investigationCategorizedEntries.newRadiologyOrders,
255
- investigationCategorizedEntries.newProcedureOrders,
256
- investigationCategorizedEntries.completedLabOrders,
257
- investigationCategorizedEntries.completedRadiologyOrders,
258
- investigationCategorizedEntries.completedProcedureOrders,
259
- ],
18
+ const { queueServiceConceptUuids } = useConfig<ExpressWorkflowConfig>();
19
+ const [, setSummaryCardsLoadingState] = useState({
20
+ isLoading: false,
21
+ isValidating: false,
22
+ });
23
+ const { queues, isLoading: isLoadingQueues } = useQueues();
24
+
25
+ const consultationQueues = useMemo(
26
+ () =>
27
+ queues.filter(
28
+ (queue) =>
29
+ queue.service.uuid === queueServiceConceptUuids.consultationService &&
30
+ !queue.location.display.toLowerCase().includes('mch') &&
31
+ queue?.queueRooms?.length > 0,
32
+ ),
33
+ [queues, queueServiceConceptUuids.consultationService],
260
34
  );
261
35
 
262
- if (isLoading || isLoadingTotalVisits || isLoadingInvestigations || isLoadingQueuemetrics) {
263
- return <InlineLoading description={t('loadingQueues', 'Loading queues...')} />;
264
- }
265
-
266
36
  return (
267
- <div className={`omrs-main-content`}>
268
- <PageHeader className={styles.pageHeader}>
269
- <PageHeaderContent title={capitalize(dashboardTitle)} illustration={<HomePictogram />} />
270
- <ExtensionSlot name="provider-banner-info-slot" />
271
- </PageHeader>
272
- <QueueTab
273
- queues={consultationQueues}
274
- cards={cards}
275
- navigatePath="consultation"
276
- usePatientChart
277
- filters={filters}
278
- onFiltersChanged={setFilters}
279
- onTabChanged={setCurrQueue}
280
- />
281
- </div>
37
+ <ConsultationProvider consultationQueues={consultationQueues}>
38
+ <div className={`omrs-main-content`} style={{ position: 'relative' }}>
39
+ <div>
40
+ <PageHeader className={styles.pageHeader}>
41
+ <PageHeaderContent title={capitalize(dashboardTitle)} illustration={<HomePictogram />} />
42
+ <ExtensionSlot name="provider-banner-info-slot" />
43
+ </PageHeader>
44
+ <ConsultationSummaryCards onLoadingStateChange={setSummaryCardsLoadingState} />
45
+ {isLoadingQueues ? (
46
+ <div className={styles.queueTabPlaceholder}>
47
+ <TabsSkeleton />
48
+ </div>
49
+ ) : (
50
+ <QueueTab queues={consultationQueues} navigatePath="consultation" usePatientChart />
51
+ )}
52
+ </div>
53
+ </div>
54
+ </ConsultationProvider>
282
55
  );
283
56
  };
284
57
 
@@ -13,6 +13,39 @@ export interface UseLabOrdersParams {
13
13
  excludeCanceled?: boolean;
14
14
  }
15
15
 
16
+ function categorizeEntriesByPriority(
17
+ entries: Array<QueueEntry> | undefined | null,
18
+ priorities:
19
+ | {
20
+ emergencyPriorityConceptUuid?: string;
21
+ urgentPriorityConceptUuid?: string;
22
+ notUrgentPriorityConceptUuid?: string;
23
+ }
24
+ | undefined
25
+ | null,
26
+ ): { emergencyEntries: Array<QueueEntry>; urgentEntries: Array<QueueEntry>; notUrgentEntries: Array<QueueEntry> } {
27
+ if (!entries?.length || !priorities) {
28
+ return { emergencyEntries: [], urgentEntries: [], notUrgentEntries: [] };
29
+ }
30
+ const emergencyEntries: Array<QueueEntry> = [];
31
+ const urgentEntries: Array<QueueEntry> = [];
32
+ const notUrgentEntries: Array<QueueEntry> = [];
33
+ for (const entry of entries) {
34
+ const priorityUuid = entry?.priority?.uuid;
35
+ if (!priorityUuid) {
36
+ continue;
37
+ }
38
+ if (priorityUuid === priorities.emergencyPriorityConceptUuid) {
39
+ emergencyEntries.push(entry);
40
+ } else if (priorityUuid === priorities.urgentPriorityConceptUuid) {
41
+ urgentEntries.push(entry);
42
+ } else if (priorityUuid === priorities.notUrgentPriorityConceptUuid) {
43
+ notUrgentEntries.push(entry);
44
+ }
45
+ }
46
+ return { emergencyEntries, urgentEntries, notUrgentEntries };
47
+ }
48
+
16
49
  const getTodayRange = (daysBack: number = 0) => ({
17
50
  start: dayjs().subtract(daysBack, 'day').startOf('day').toISOString(),
18
51
  end: dayjs().endOf('day').toISOString(),
@@ -25,17 +58,22 @@ export const useTotalVisits = () => {
25
58
  'YYYY-MM-DD',
26
59
  )}`;
27
60
 
28
- const { data, error, isLoading, mutate } = useSWR<{ data: { results: Array<Visit> } }>(visitsUrl, openmrsFetch, {
29
- revalidateOnFocus: false,
30
- revalidateOnReconnect: false,
31
- dedupingInterval: 60000,
32
- });
61
+ const { data, error, isLoading, mutate, isValidating } = useSWR<{ data: { results: Array<Visit> } }>(
62
+ visitsUrl,
63
+ openmrsFetch,
64
+ {
65
+ revalidateOnFocus: false,
66
+ revalidateOnReconnect: false,
67
+ dedupingInterval: 60000,
68
+ },
69
+ );
33
70
 
34
71
  return {
35
72
  data: data?.data?.results,
36
73
  error,
37
74
  isLoading,
38
75
  mutate,
76
+ isValidating,
39
77
  };
40
78
  };
41
79
 
@@ -199,7 +237,7 @@ function useProcedureOrders(fulfillerStatus?: string) {
199
237
  }
200
238
 
201
239
  export const useInvestigationStats = (queue?: Queue) => {
202
- const { isLoading: isLoadingQueueMetrics, waitingEntries } = useConsultationQueueMetrics(queue);
240
+ const { isLoading: isLoadingQueueMetrics, waitingEntries, isValidating } = useConsultationQueueMetrics(queue);
203
241
 
204
242
  // Fetch all investigation orders
205
243
  const {
@@ -381,40 +419,45 @@ export const useInvestigationStats = (queue?: Queue) => {
381
419
  isLoading,
382
420
  refresh,
383
421
  investigationCategorizedEntries,
422
+ isValidating,
384
423
  };
385
424
  };
386
425
 
387
- export const useConsultationQueueMetrics = (queue?: Queue) => {
426
+ export const useConsultationQueueMetrics = (queue?: Queue, pageSize?: number) => {
388
427
  const { queueServiceConceptUuids, queueStatusConceptUuids, priorities } = useConfig<ExpressWorkflowConfig>();
389
428
  const {
390
429
  queueEntries: waitingEntries,
391
430
  isLoading: isLoadingWaiting,
431
+ isValidating: isValidatingWaiting,
392
432
  error: waitingError,
393
- } = useQueueEntries({
394
- service: [queueServiceConceptUuids.consultationService],
395
- statuses: [queueStatusConceptUuids.waitingStatus, queueStatusConceptUuids.inServiceStatus],
396
- location: queue?.location?.uuid ? [queue.location.uuid] : undefined,
397
- });
433
+ } = useQueueEntries(
434
+ {
435
+ service: [queueServiceConceptUuids.consultationService],
436
+ statuses: [queueStatusConceptUuids.waitingStatus, queueStatusConceptUuids.inServiceStatus],
437
+ location: queue?.location?.uuid ? [queue.location.uuid] : undefined,
438
+ startedOnOrAfter: dayjs().subtract(24, 'hour').format('YYYY-MM-DD HH:mm:ss'),
439
+ queues: [queue?.uuid],
440
+ },
441
+ pageSize,
442
+ );
398
443
 
399
444
  const _waitingEntries = useMemo(
400
445
  () => waitingEntries.filter((entry) => entry?.queue?.uuid === queue?.uuid),
401
446
  [waitingEntries, queue],
402
447
  );
448
+
449
+ const { emergencyEntries, urgentEntries, notUrgentEntries } = useMemo(
450
+ () => categorizeEntriesByPriority(_waitingEntries, priorities),
451
+ [_waitingEntries, priorities],
452
+ );
453
+
403
454
  return {
404
455
  isLoading: isLoadingWaiting,
405
456
  error: waitingError,
406
457
  waitingEntries: _waitingEntries,
407
- emergencyEntries: useMemo(
408
- () => _waitingEntries.filter((entry) => entry.priority.uuid === priorities?.emergencyPriorityConceptUuid),
409
- [_waitingEntries, priorities?.emergencyPriorityConceptUuid],
410
- ),
411
- urgentEntries: useMemo(
412
- () => _waitingEntries.filter((entry) => entry.priority.uuid === priorities?.urgentPriorityConceptUuid),
413
- [_waitingEntries, priorities?.urgentPriorityConceptUuid],
414
- ),
415
- notUrgentEntries: useMemo(
416
- () => _waitingEntries.filter((entry) => entry.priority.uuid === priorities?.notUrgentPriorityConceptUuid),
417
- [_waitingEntries, priorities?.notUrgentPriorityConceptUuid],
418
- ),
458
+ isValidating: isValidatingWaiting,
459
+ emergencyEntries,
460
+ urgentEntries,
461
+ notUrgentEntries,
419
462
  };
420
463
  };
@@ -16,3 +16,8 @@
16
16
  display: flex;
17
17
  flex-direction: row;
18
18
  }
19
+
20
+ .queueTabPlaceholder {
21
+ padding: layout.$spacing-05;
22
+ min-height: 200px;
23
+ }