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

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 (487) hide show
  1. package/.turbo/turbo-build.log +13 -11
  2. package/dist/1074.js +1 -0
  3. package/dist/1074.js.map +1 -0
  4. package/dist/1084.js +1 -0
  5. package/dist/1084.js.map +1 -0
  6. package/dist/12.js +17 -0
  7. package/dist/12.js.map +1 -0
  8. package/dist/126.js +1 -0
  9. package/dist/126.js.map +1 -0
  10. package/dist/1311.js +1 -0
  11. package/dist/1311.js.map +1 -0
  12. package/dist/1323.js +1 -0
  13. package/dist/1323.js.map +1 -0
  14. package/dist/1469.js +1 -0
  15. package/dist/1469.js.map +1 -0
  16. package/dist/1506.js +13 -0
  17. package/dist/1506.js.map +1 -0
  18. package/dist/1760.js +1 -0
  19. package/dist/1760.js.map +1 -0
  20. package/dist/1780.js +1 -0
  21. package/dist/1780.js.map +1 -0
  22. package/dist/1791.js +1 -0
  23. package/dist/1791.js.map +1 -0
  24. package/dist/1884.js +1 -0
  25. package/dist/1884.js.map +1 -0
  26. package/dist/1972.js +1 -0
  27. package/dist/1972.js.map +1 -0
  28. package/dist/1990.js +1 -0
  29. package/dist/1990.js.map +1 -0
  30. package/dist/2016.js +1 -0
  31. package/dist/2016.js.map +1 -0
  32. package/dist/2024.js +1 -0
  33. package/dist/2024.js.map +1 -0
  34. package/dist/2153.js +1 -0
  35. package/dist/2153.js.map +1 -0
  36. package/dist/216.js +1 -0
  37. package/dist/216.js.map +1 -0
  38. package/dist/2225.js +1 -0
  39. package/dist/2225.js.map +1 -0
  40. package/dist/2294.js +1 -0
  41. package/dist/2294.js.map +1 -0
  42. package/dist/2345.js +1 -0
  43. package/dist/2345.js.map +1 -0
  44. package/dist/2386.js +1 -0
  45. package/dist/2386.js.map +1 -0
  46. package/dist/2438.js +1 -0
  47. package/dist/2438.js.map +1 -0
  48. package/dist/2499.js +1 -0
  49. package/dist/2499.js.map +1 -0
  50. package/dist/2500.js +1 -0
  51. package/dist/2500.js.map +1 -0
  52. package/dist/2586.js +1 -0
  53. package/dist/2586.js.map +1 -0
  54. package/dist/2625.js +1 -0
  55. package/dist/2625.js.map +1 -0
  56. package/dist/2685.js +1 -0
  57. package/dist/2685.js.map +1 -0
  58. package/dist/2757.js +1 -0
  59. package/dist/2757.js.map +1 -0
  60. package/dist/2851.js +1 -0
  61. package/dist/2851.js.map +1 -0
  62. package/dist/2881.js +1 -0
  63. package/dist/2881.js.map +1 -0
  64. package/dist/2948.js +1 -0
  65. package/dist/2948.js.map +1 -0
  66. package/dist/2968.js +1 -0
  67. package/dist/2968.js.map +1 -0
  68. package/dist/2998.js +1 -0
  69. package/dist/2998.js.map +1 -0
  70. package/dist/30.js +1 -0
  71. package/dist/30.js.map +1 -0
  72. package/dist/3089.js +1 -0
  73. package/dist/3089.js.map +1 -0
  74. package/dist/3139.js +1 -0
  75. package/dist/3139.js.map +1 -0
  76. package/dist/3220.js +1 -0
  77. package/dist/3220.js.map +1 -0
  78. package/dist/3265.js +1 -0
  79. package/dist/3265.js.map +1 -0
  80. package/dist/3548.js +1 -0
  81. package/dist/3548.js.map +1 -0
  82. package/dist/3567.js +1 -0
  83. package/dist/3567.js.map +1 -0
  84. package/dist/3571.js +1 -0
  85. package/dist/3571.js.map +1 -0
  86. package/dist/3691.js +1 -0
  87. package/dist/3691.js.map +1 -0
  88. package/dist/3730.js +1 -0
  89. package/dist/3730.js.map +1 -0
  90. package/dist/3923.js +1 -0
  91. package/dist/3923.js.map +1 -0
  92. package/dist/3963.js +1 -0
  93. package/dist/3963.js.map +1 -0
  94. package/dist/4024.js +1 -0
  95. package/dist/4024.js.map +1 -0
  96. package/dist/405.js +1 -0
  97. package/dist/405.js.map +1 -0
  98. package/dist/4296.js +1 -0
  99. package/dist/4296.js.map +1 -0
  100. package/dist/4504.js +1 -0
  101. package/dist/4504.js.map +1 -0
  102. package/dist/4564.js +1 -0
  103. package/dist/4564.js.map +1 -0
  104. package/dist/4581.js +1 -0
  105. package/dist/4581.js.map +1 -0
  106. package/dist/4670.js +1 -0
  107. package/dist/4670.js.map +1 -0
  108. package/dist/4680.js +1 -0
  109. package/dist/4680.js.map +1 -0
  110. package/dist/4682.js +1 -0
  111. package/dist/4682.js.map +1 -0
  112. package/dist/4735.js +1 -0
  113. package/dist/4735.js.map +1 -0
  114. package/dist/4737.js +1 -0
  115. package/dist/4737.js.map +1 -0
  116. package/dist/4744.js +1 -0
  117. package/dist/4744.js.map +1 -0
  118. package/dist/4795.js +1 -0
  119. package/dist/4795.js.map +1 -0
  120. package/dist/4813.js +2 -0
  121. package/dist/4813.js.map +1 -0
  122. package/dist/4818.js +1 -0
  123. package/dist/4818.js.map +1 -0
  124. package/dist/4858.js +1 -0
  125. package/dist/4858.js.map +1 -0
  126. package/dist/487.js +1 -0
  127. package/dist/487.js.map +1 -0
  128. package/dist/4970.js +1 -0
  129. package/dist/4970.js.map +1 -0
  130. package/dist/5047.js +1 -0
  131. package/dist/5047.js.map +1 -0
  132. package/dist/5054.js +1 -0
  133. package/dist/5054.js.map +1 -0
  134. package/dist/5202.js +1 -0
  135. package/dist/5202.js.map +1 -0
  136. package/dist/5491.js +1 -0
  137. package/dist/5491.js.map +1 -0
  138. package/dist/5592.js +1 -0
  139. package/dist/5592.js.map +1 -0
  140. package/dist/5669.js +1 -0
  141. package/dist/5669.js.map +1 -0
  142. package/dist/5787.js +1 -0
  143. package/dist/5787.js.map +1 -0
  144. package/dist/586.js +1 -0
  145. package/dist/586.js.map +1 -0
  146. package/dist/5879.js +1 -0
  147. package/dist/5879.js.map +1 -0
  148. package/dist/5904.js +1 -0
  149. package/dist/5904.js.map +1 -0
  150. package/dist/5986.js +1 -0
  151. package/dist/5986.js.map +1 -0
  152. package/dist/6007.js +11 -0
  153. package/dist/6007.js.map +1 -0
  154. package/dist/6075.js +1 -0
  155. package/dist/6075.js.map +1 -0
  156. package/dist/6258.js +1 -0
  157. package/dist/6258.js.map +1 -0
  158. package/dist/629.js +1 -0
  159. package/dist/629.js.map +1 -0
  160. package/dist/6328.js +1 -0
  161. package/dist/6328.js.map +1 -0
  162. package/dist/6355.js +1 -0
  163. package/dist/6355.js.map +1 -0
  164. package/dist/64.js +1 -0
  165. package/dist/64.js.map +1 -0
  166. package/dist/6445.js +1 -0
  167. package/dist/6445.js.map +1 -0
  168. package/dist/6456.js +1 -0
  169. package/dist/6466.js +3 -0
  170. package/dist/6466.js.map +1 -0
  171. package/dist/6663.js +1 -0
  172. package/dist/6663.js.map +1 -0
  173. package/dist/6720.js +1 -0
  174. package/dist/6720.js.map +1 -0
  175. package/dist/6798.js +66 -0
  176. package/dist/6798.js.map +1 -0
  177. package/dist/6925.js +1 -0
  178. package/dist/6925.js.map +1 -0
  179. package/dist/7201.js +1 -0
  180. package/dist/7201.js.map +1 -0
  181. package/dist/7234.js +1 -0
  182. package/dist/7234.js.map +1 -0
  183. package/dist/7261.js +1 -0
  184. package/dist/7261.js.map +1 -0
  185. package/dist/7326.js +1 -0
  186. package/dist/7359.js +1 -0
  187. package/dist/7405.js +1 -0
  188. package/dist/7405.js.map +1 -0
  189. package/dist/7591.js +1 -0
  190. package/dist/7591.js.map +1 -0
  191. package/dist/7602.js +1 -0
  192. package/dist/7602.js.map +1 -0
  193. package/dist/7607.js +1 -0
  194. package/dist/7701.js +1 -0
  195. package/dist/7701.js.map +1 -0
  196. package/dist/7717.js +1 -0
  197. package/dist/7717.js.map +1 -0
  198. package/dist/7739.js +1 -0
  199. package/dist/7739.js.map +1 -0
  200. package/dist/7788.js +1 -0
  201. package/dist/7788.js.map +1 -0
  202. package/dist/7819.js +1 -0
  203. package/dist/7819.js.map +1 -0
  204. package/dist/7820.js +1 -0
  205. package/dist/7820.js.map +1 -0
  206. package/dist/7844.js +1 -0
  207. package/dist/7844.js.map +1 -0
  208. package/dist/7971.js +1 -0
  209. package/dist/7971.js.map +1 -0
  210. package/dist/807.js +1 -0
  211. package/dist/807.js.map +1 -0
  212. package/dist/8159.js +7 -0
  213. package/dist/8159.js.map +1 -0
  214. package/dist/8338.js +1 -0
  215. package/dist/8338.js.map +1 -0
  216. package/dist/845.js +1 -0
  217. package/dist/845.js.map +1 -0
  218. package/dist/8566.js +1 -0
  219. package/dist/8566.js.map +1 -0
  220. package/dist/8570.js +1 -0
  221. package/dist/8570.js.map +1 -0
  222. package/dist/8613.js +1 -0
  223. package/dist/8613.js.map +1 -0
  224. package/dist/8682.js +1 -0
  225. package/dist/8682.js.map +1 -0
  226. package/dist/87.js +1 -0
  227. package/dist/87.js.map +1 -0
  228. package/dist/8727.js +1 -0
  229. package/dist/8766.js +1 -0
  230. package/dist/8766.js.map +1 -0
  231. package/dist/8799.js +1 -0
  232. package/dist/8799.js.map +1 -0
  233. package/dist/8828.js +1 -0
  234. package/dist/8828.js.map +1 -0
  235. package/dist/8860.js +1 -0
  236. package/dist/8860.js.map +1 -0
  237. package/dist/8911.js +1 -0
  238. package/dist/8911.js.map +1 -0
  239. package/dist/8930.js +1 -0
  240. package/dist/8930.js.map +1 -0
  241. package/dist/8971.js +1 -0
  242. package/dist/8971.js.map +1 -0
  243. package/dist/9011.js +1 -0
  244. package/dist/9011.js.map +1 -0
  245. package/dist/9111.js +1 -0
  246. package/dist/9111.js.map +1 -0
  247. package/dist/9124.js +1 -0
  248. package/dist/9124.js.map +1 -0
  249. package/dist/9157.js +1 -0
  250. package/dist/9157.js.map +1 -0
  251. package/dist/9161.js +1 -0
  252. package/dist/9161.js.map +1 -0
  253. package/dist/9182.js +1 -0
  254. package/dist/921.js +1 -0
  255. package/dist/921.js.map +1 -0
  256. package/dist/9212.js +1 -0
  257. package/dist/9212.js.map +1 -0
  258. package/dist/9255.js +1 -0
  259. package/dist/9255.js.map +1 -0
  260. package/dist/9257.js +1 -0
  261. package/dist/9257.js.map +1 -0
  262. package/dist/9343.js +1 -0
  263. package/dist/9343.js.map +1 -0
  264. package/dist/9404.js +1 -0
  265. package/dist/9404.js.map +1 -0
  266. package/dist/9446.js +1 -0
  267. package/dist/9446.js.map +1 -0
  268. package/dist/9449.js +1 -0
  269. package/dist/9449.js.map +1 -0
  270. package/dist/9488.js +1 -0
  271. package/dist/9488.js.map +1 -0
  272. package/dist/9514.js +1 -0
  273. package/dist/9514.js.map +1 -0
  274. package/dist/9528.js +1 -0
  275. package/dist/9528.js.map +1 -0
  276. package/dist/9535.js +1 -0
  277. package/dist/9535.js.map +1 -0
  278. package/dist/9606.js +1 -0
  279. package/dist/9606.js.map +1 -0
  280. package/dist/9834.js +1 -0
  281. package/dist/9834.js.map +1 -0
  282. package/dist/9845.js +1 -0
  283. package/dist/9845.js.map +1 -0
  284. package/dist/9848.js +1 -0
  285. package/dist/9848.js.map +1 -0
  286. package/dist/kenyaemr-esm-express-workflow-app.js +5 -5
  287. package/dist/kenyaemr-esm-express-workflow-app.js.buildmanifest.json +3394 -173
  288. package/dist/kenyaemr-esm-express-workflow-app.js.map +1 -1
  289. package/dist/main.js +7 -106
  290. package/dist/main.js.map +1 -1
  291. package/dist/routes.json +1 -1
  292. package/package.json +7 -8
  293. package/rspack.config.js +1 -1
  294. package/src/components/accounting/index.tsx +11 -10
  295. package/src/components/admissions/admissions-dashboard.component.tsx +2 -2
  296. package/src/components/admissions/index.tsx +11 -10
  297. package/src/components/anaesthetic/anaesthetic-dashboard.meta.ts +8 -0
  298. package/src/components/anaesthetic/anaesthetic-data-form.component.tsx +442 -0
  299. package/src/components/anaesthetic/anaesthetic-data-form.scss +278 -0
  300. package/src/components/anaesthetic/anaesthetic-link.component.tsx +21 -0
  301. package/src/components/anaesthetic/anaesthetic.component.tsx +618 -0
  302. package/src/components/anaesthetic/anaesthetic.resource.ts +1503 -0
  303. package/src/components/anaesthetic/anaesthetic.scss +1885 -0
  304. package/src/components/anaesthetic/forms/anaesthetic-form.component.tsx +304 -0
  305. package/src/components/anaesthetic/forms/anaesthetic-record-form.component.tsx +707 -0
  306. package/src/components/anaesthetic/forms/icd11-diagnosis-search.component.tsx +178 -0
  307. package/src/components/anaesthetic/forms/icd11-diagnosis-search.scss +126 -0
  308. package/src/components/anaesthetic/forms/index.ts +2 -0
  309. package/src/components/anaesthetic/forms/interoperative-record-drug-given-form.component.tsx +231 -0
  310. package/src/components/anaesthetic/forms/post-operative-summary-form.component.tsx +171 -0
  311. package/src/components/anaesthetic/forms/time-picker-dropdown.component.tsx +202 -0
  312. package/src/components/anaesthetic/forms/time-picker-dropdown.scss +107 -0
  313. package/src/components/anaesthetic/forms/time-picker-with-clock.component.tsx +174 -0
  314. package/src/components/anaesthetic/forms/time-picker-with-clock.scss +178 -0
  315. package/src/components/anaesthetic/forms/useAnaestheticData.ts +16 -0
  316. package/src/components/anaesthetic/graphs/anaesthetic-graph-wrapper.component.tsx +266 -0
  317. package/src/components/anaesthetic/graphs/anaesthetic-graph.component.tsx +185 -0
  318. package/src/components/anaesthetic/graphs/index.ts +2 -0
  319. package/src/components/anaesthetic/graphs/interoperative-record-drug-given-graph-wrapper.component.tsx +197 -0
  320. package/src/components/anaesthetic/graphs/interoperative-record-drug-given-graph.component.tsx +93 -0
  321. package/src/components/anaesthetic/resources/anaesthetic-amniotic-fluid.resource.ts +277 -0
  322. package/src/components/anaesthetic/resources/anaesthetic-form.resource.ts +716 -0
  323. package/src/components/anaesthetic/resources/anaesthetic.resource.ts +378 -0
  324. package/src/components/anaesthetic/types/index.ts +1349 -0
  325. package/src/components/appointments/index.ts +10 -8
  326. package/src/components/consultation/clinical-encounter/clinical-encounter.component.tsx +4 -20
  327. package/src/components/consultation/clinical-encounter/encounter-details.component.tsx +9 -9
  328. package/src/components/consultation/clinical-encounter/encounter-details.test.tsx +19 -18
  329. package/src/components/consultation/consultation-context.tsx +19 -0
  330. package/src/components/consultation/consultation-summary-cards.component.tsx +124 -0
  331. package/src/components/consultation/consultation.component.tsx +41 -268
  332. package/src/components/consultation/consultation.resource.ts +67 -24
  333. package/src/components/consultation/consultation.scss +5 -0
  334. package/src/components/consultation/consultation.utils.tsx +222 -0
  335. package/src/components/consultation/dashboard.component.tsx +0 -2
  336. package/src/components/consultation/index.ts +28 -21
  337. package/src/components/consultation/tabs/index.ts +67 -0
  338. package/src/components/facility-dashboard/components/header/home-header.component.tsx +8 -13
  339. package/src/components/facility-dashboard/index.tsx +10 -9
  340. package/src/components/laboratory/index.ts +22 -10
  341. package/src/components/laboratory/lab-table.component.tsx +40 -12
  342. package/src/components/laboratory/laboratory-tabs.component.tsx +3 -17
  343. package/src/components/mch/dashboard.component.tsx +0 -2
  344. package/src/components/mch/index.tsx +10 -9
  345. package/src/components/mch/mch.component.tsx +1 -3
  346. package/src/components/mch/mch.consultation.component.tsx +27 -15
  347. package/src/components/mch/mch.triage.component.tsx +42 -33
  348. package/src/components/pharmacy/index.ts +21 -19
  349. package/src/components/pharmacy/orders/pharmacy-orders.component.tsx +35 -13
  350. package/src/components/pharmacy/orders/pharmacy-orders.test.tsx +8 -7
  351. package/src/components/pharmacy/pharmacy-tabs.component.tsx +4 -20
  352. package/src/components/pharmacy/tabs/index.ts +21 -0
  353. package/src/components/preauth/index.ts +22 -0
  354. package/src/components/preauth/preauth-dashboard.component.tsx +20 -0
  355. package/src/components/procedures/index.ts +27 -10
  356. package/src/components/procedures/procedure-queues/index.ts +13 -0
  357. package/src/components/procedures/procedure-queues/procedure-form-extras.component.tsx +33 -0
  358. package/src/components/procedures/procedure-queues/procedure-form-extras.scss +5 -0
  359. package/src/components/procedures/procedure-queues/procedure-queues.component.tsx +35 -0
  360. package/src/components/procedures/procedure-queues/procedure-queues.resources.ts +37 -0
  361. package/src/components/procedures/procedure-queues/procedure-room-tabs.component.tsx +80 -0
  362. package/src/components/procedures/procedure-queues/procedure-rooms.scss +13 -0
  363. package/src/components/procedures/procedure-queues/queue-procedure-tabs.component.tsx +34 -0
  364. package/src/components/procedures/procedure-queues/summary-cards.component.tsx +81 -0
  365. package/src/components/procedures/procedure-queues/summary-cards.scss +35 -0
  366. package/src/components/procedures/procedures-table.component.tsx +69 -19
  367. package/src/components/procedures/procedures-tabs.component.test.tsx +57 -0
  368. package/src/components/procedures/procedures-tabs.component.tsx +3 -18
  369. package/src/components/radiology-and-imaging/index.ts +25 -10
  370. package/src/components/radiology-and-imaging/radiology-and-imaging-table.component.tsx +62 -21
  371. package/src/components/radiology-and-imaging/radiology-and-imaging.component.tsx +3 -19
  372. package/src/components/registration/card/HIE-card/hie-card.component.tsx +32 -44
  373. package/src/components/registration/card/Local-card/local-card.component.tsx +22 -24
  374. package/src/components/registration/checkin-form-extra/checkin-form-extra.extension.tsx +8 -2
  375. package/src/components/registration/checkin-form-extra/queue-fields.component.tsx +18 -19
  376. package/src/components/registration/dependants/dependants.component.tsx +37 -60
  377. package/src/components/registration/dependants/dependants.resource.ts +79 -50
  378. package/src/components/registration/end-visit-modal/end-visit-dialog.modal.tsx +320 -0
  379. package/src/components/registration/end-visit-modal/end-visit-dialog.scss +12 -0
  380. package/src/components/registration/end-visit-modal/end-visit.resource.tsx +59 -0
  381. package/src/components/registration/end-visit-modal/sha-end-visit.resource.ts +285 -0
  382. package/src/components/registration/helper/index.ts +4 -0
  383. package/src/components/registration/index.ts +10 -9
  384. package/src/components/registration/search-bar/search-bar.resource.ts +32 -93
  385. package/src/components/registration/start-visit-form/hooks/useDefaultFacilityLocation.tsx +15 -0
  386. package/src/components/registration/start-visit-form/hooks/useDefaultVisitLocation.tsx +24 -0
  387. package/src/components/registration/start-visit-form/hooks/useOfflineVisitType.tsx +18 -0
  388. package/src/components/registration/start-visit-form/hooks/useRecommendedVisitTypes.tsx +36 -0
  389. package/src/components/registration/start-visit-form/hooks/useVisitAttributeType.tsx +102 -0
  390. package/src/components/registration/start-visit-form/overflow-menu-extension/custom-end-active-visit.extension.tsx +44 -0
  391. package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.extension.tsx +57 -0
  392. package/src/components/registration/start-visit-form/overflow-menu-extension/overflow-menu-item.scss +3 -0
  393. package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.component.tsx +126 -0
  394. package/src/components/registration/start-visit-form/start-visit-workspace/base-visit-type.scss +75 -0
  395. package/src/components/registration/start-visit-form/start-visit-workspace/exported-visit-form.workspace.tsx +759 -0
  396. package/src/components/registration/start-visit-form/start-visit-workspace/location-selector.component.tsx +86 -0
  397. package/src/components/registration/start-visit-form/start-visit-workspace/recommended-visit-type.component.tsx +32 -0
  398. package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.component.tsx +257 -0
  399. package/src/components/registration/start-visit-form/start-visit-workspace/visit-attribute-type.scss +5 -0
  400. package/src/components/registration/start-visit-form/start-visit-workspace/visit-date-time.component.tsx +193 -0
  401. package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.resource.ts +389 -0
  402. package/src/components/registration/start-visit-form/start-visit-workspace/visit-form.scss +144 -0
  403. package/src/components/registration/start-visit-form/visit-form-workspace/visit-form.workspace.tsx +48 -0
  404. package/src/components/registration/type/index.ts +101 -0
  405. package/src/components/reports/index.ts +11 -9
  406. package/src/components/triage/dashboard.component.tsx +0 -2
  407. package/src/components/triage/index.ts +10 -9
  408. package/src/components/triage/triage.component.tsx +92 -42
  409. package/src/components/triage/triage.resource.ts +56 -50
  410. package/src/components/triage/triage.scss +6 -0
  411. package/src/config-schema.ts +482 -0
  412. package/src/hooks/useOrders.tsx +2 -2
  413. package/src/hooks/useServiceQueues.tsx +95 -25
  414. package/src/index.ts +84 -28
  415. package/src/routes.json +290 -32
  416. package/src/shared/dashboard-link/dashboard-link.component.tsx +11 -8
  417. package/src/shared/orders/OrderTable.tsx +19 -3
  418. package/src/shared/otp-verification/index.ts +112 -29
  419. package/src/shared/otp-verification/otp-verification.modal.tsx +1110 -122
  420. package/src/shared/otp-verification/otp-verification.scss +374 -0
  421. package/src/shared/patient-chart/patient-summary-dashboard/patient-summary-dashboard.component.tsx +5 -85
  422. package/src/shared/pin-put/pinput.component.test.tsx +7 -6
  423. package/src/shared/queue/queue-entry/queue-entry-table.component.tsx +99 -88
  424. package/src/shared/queue/queue-entry/queue-entry-table.scss +4 -0
  425. package/src/shared/queue/queue-summary-cards.component.tsx +32 -0
  426. package/src/shared/queue/queue-tab.component.tsx +182 -70
  427. package/src/shared/queue/queue-tab.scss +1 -0
  428. package/src/shared/queue/queue-workflow-context.tsx +90 -0
  429. package/src/shared/tabs/create-tab-extension.tsx +33 -0
  430. package/src/shared/tabs/extension-tabs.component.tsx +51 -30
  431. package/src/shared/utils/index.ts +119 -5
  432. package/src/types/index.ts +29 -2
  433. package/translations/am.json +426 -133
  434. package/translations/en.json +312 -19
  435. package/translations/fr.json +351 -63
  436. package/translations/sw.json +330 -37
  437. package/dist/127.js +0 -1
  438. package/dist/200.js +0 -1
  439. package/dist/200.js.map +0 -1
  440. package/dist/24.js +0 -1
  441. package/dist/24.js.map +0 -1
  442. package/dist/267.js +0 -1
  443. package/dist/267.js.map +0 -1
  444. package/dist/285.js +0 -1
  445. package/dist/285.js.map +0 -1
  446. package/dist/329.js +0 -1
  447. package/dist/329.js.map +0 -1
  448. package/dist/40.js +0 -1
  449. package/dist/466.js +0 -1
  450. package/dist/466.js.map +0 -1
  451. package/dist/472.js +0 -66
  452. package/dist/472.js.map +0 -1
  453. package/dist/490.js +0 -1
  454. package/dist/490.js.map +0 -1
  455. package/dist/54.js +0 -1
  456. package/dist/54.js.map +0 -1
  457. package/dist/689.js +0 -1
  458. package/dist/689.js.map +0 -1
  459. package/dist/697.js +0 -1
  460. package/dist/697.js.map +0 -1
  461. package/dist/704.js +0 -1
  462. package/dist/704.js.map +0 -1
  463. package/dist/710.js +0 -1
  464. package/dist/710.js.map +0 -1
  465. package/dist/729.js +0 -17
  466. package/dist/729.js.map +0 -1
  467. package/dist/805.js +0 -37
  468. package/dist/805.js.map +0 -1
  469. package/dist/847.js +0 -1
  470. package/dist/847.js.map +0 -1
  471. package/dist/85.js +0 -1
  472. package/dist/85.js.map +0 -1
  473. package/dist/882.js +0 -1
  474. package/dist/91.js +0 -1
  475. package/dist/91.js.map +0 -1
  476. package/dist/916.js +0 -1
  477. package/dist/994.js +0 -1
  478. package/dist/994.js.map +0 -1
  479. package/dist/998.js +0 -1
  480. package/dist/998.js.map +0 -1
  481. package/jest.config.js +0 -3
  482. package/src/shared/orders/OrdersTabs.tsx +0 -58
  483. package/src/shared/patient-chart/patient-chart.component.tsx +0 -61
  484. package/src/shared/patient-chart/patient-chart.resources.ts +0 -184
  485. package/src/shared/patient-chart/patient-chart.scss +0 -15
  486. package/src/shared/patient-chart/useInitialize.ts +0 -24
  487. /package/src/shared/{patient-chart/patient-summary-dashboard → tabs}/patient-summary-dashboard.scss +0 -0
@@ -1,8 +1,17 @@
1
- import { getSessionLocation, launchWorkspace, openmrsFetch, restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
1
+ import {
2
+ getSessionLocation,
3
+ launchWorkspace2,
4
+ launchWorkspaceGroup2,
5
+ openmrsFetch,
6
+ restBaseUrl,
7
+ showSnackbar,
8
+ type Visit,
9
+ } from '@openmrs/esm-framework';
2
10
  import { DependentPayload, HIEPatient } from '../type';
3
- import { generateIdentifier, getIdentifierTypeUUID } from '../helper';
11
+ import { generateIdentifier, getIdentifierTypeUUID, sanitizeName } from '../helper';
4
12
  import { openmrsId, openmrsIdSource } from '../constant';
5
13
  import { useEffect, useState } from 'react';
14
+ import { VisitFormProps } from '../start-visit-form/visit-form-workspace/visit-form.workspace';
6
15
 
7
16
  export interface PatientRegistrationPayload {
8
17
  name: string;
@@ -12,18 +21,34 @@ export interface PatientRegistrationPayload {
12
21
  type: 'hie-patient' | 'dependent';
13
22
  }
14
23
 
24
+ interface AddressPayload {
25
+ address1: string;
26
+ address2?: string;
27
+ cityVillage: string;
28
+ country: string;
29
+ postalCode: string;
30
+ stateProvince: string;
31
+ countyDistrict?: string;
32
+ }
33
+
15
34
  export async function createPatient(payload: PatientRegistrationPayload, t: any) {
16
35
  try {
17
- const { patientData, type, name, gender, birthDate } = payload;
18
- const locationUuid = (await getSessionLocation()).uuid;
19
-
20
- let identifiers = [];
36
+ const { patientData, type, gender, birthDate } = payload;
37
+ const sessionLocation = await getSessionLocation();
38
+ const locationUuid = sessionLocation?.uuid ?? '';
39
+
40
+ let identifiers: Array<{
41
+ identifier: string;
42
+ identifierType: string;
43
+ location: string;
44
+ preferred: boolean;
45
+ }> = [];
21
46
  let givenName = '';
22
47
  let middleName = '';
23
48
  let familyName = '';
24
49
  let patientBirthDate = birthDate;
25
50
  let patientGender = gender;
26
- let addresses = [];
51
+ let addresses: AddressPayload[] = [];
27
52
 
28
53
  if (type === 'hie-patient') {
29
54
  const hiePatient = patientData as HIEPatient;
@@ -37,13 +62,13 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
37
62
  preferred: false,
38
63
  }))
39
64
  .filter((identifier) => identifier.identifierType) || [];
40
- const crIdentifier = {
65
+
66
+ identifiers.push({
41
67
  identifier: hiePatient?.id,
42
68
  identifierType: getIdentifierTypeUUID('sha-id-number'),
43
69
  location: locationUuid,
44
70
  preferred: false,
45
- };
46
- identifiers.push(crIdentifier);
71
+ });
47
72
 
48
73
  const patientName = hiePatient.name?.[0];
49
74
  if (patientName) {
@@ -85,13 +110,13 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
85
110
  preferred: false,
86
111
  }))
87
112
  .filter((identifier: any) => identifier.identifierType) || [];
88
- const crIdentifier = {
113
+
114
+ identifiers.push({
89
115
  identifier: dependentInfo?.id,
90
116
  identifierType: getIdentifierTypeUUID('sha-id-number'),
91
117
  location: locationUuid,
92
118
  preferred: false,
93
- };
94
- identifiers.push(crIdentifier);
119
+ });
95
120
 
96
121
  const birthdate = dependentInfo.extension?.find(
97
122
  (ext: any) => ext.url === 'https://ts.kenya-hie.health/fhir/StructureDefinition/date_of_birth',
@@ -129,7 +154,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
129
154
  identifiers[0].preferred = true;
130
155
  }
131
156
 
132
- const phoneAttributes = [];
157
+ const phoneAttributes: Array<{ attributeType: string; value: string }> = [];
133
158
  if (type === 'hie-patient') {
134
159
  const phoneContact = patientData.telecom?.find((t: any) => t.system === 'phone');
135
160
  if (phoneContact?.value) {
@@ -140,32 +165,29 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
140
165
  }
141
166
  }
142
167
 
168
+ const defaultAddress: AddressPayload = {
169
+ address1: '',
170
+ cityVillage: '',
171
+ country: '',
172
+ postalCode: '',
173
+ stateProvince: '',
174
+ };
175
+
143
176
  const registrationPayload = {
144
177
  person: {
145
178
  names: [
146
179
  {
147
180
  preferred: true,
148
- givenName: givenName || 'Unknown',
149
- middleName: middleName || '',
150
- familyName: familyName || 'Unknown',
181
+ givenName: sanitizeName(givenName) || 'Unknown',
182
+ middleName: sanitizeName(middleName) || '',
183
+ familyName: sanitizeName(familyName) || 'Unknown',
151
184
  },
152
185
  ],
153
186
  gender: patientGender?.charAt(0).toUpperCase() || 'U',
154
187
  birthdate: patientBirthDate || null,
155
188
  birthdateEstimated: !patientBirthDate,
156
189
  attributes: phoneAttributes,
157
- addresses:
158
- addresses.length > 0
159
- ? addresses
160
- : [
161
- {
162
- address1: '',
163
- cityVillage: '',
164
- country: '',
165
- postalCode: '',
166
- stateProvince: '',
167
- },
168
- ],
190
+ addresses: addresses.length > 0 ? addresses : [defaultAddress],
169
191
  },
170
192
  identifiers: [...identifiers],
171
193
  };
@@ -174,6 +196,10 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
174
196
  const identifierResponse = await generateIdentifier(openmrsIdSource);
175
197
  const location = await getSessionLocation();
176
198
 
199
+ if (!location?.uuid) {
200
+ throw new Error('Could not determine session location');
201
+ }
202
+
177
203
  const openmrsIdentifier = {
178
204
  identifier: identifierResponse.data.identifier,
179
205
  identifierType: openmrsId,
@@ -199,7 +225,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
199
225
  throw new Error('No valid identifiers found for the patient');
200
226
  }
201
227
 
202
- const response = await openmrsFetch(`${restBaseUrl}/patient`, {
228
+ const response = await openmrsFetch<{ uuid: string }>(`${restBaseUrl}/patient`, {
203
229
  method: 'POST',
204
230
  headers: {
205
231
  'Content-Type': 'application/json',
@@ -217,7 +243,7 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
217
243
  });
218
244
 
219
245
  return response.data;
220
- } catch (error) {
246
+ } catch (error: any) {
221
247
  console.error('Error creating patient:', error);
222
248
 
223
249
  const patientType = payload.type === 'hie-patient' ? 'Patient' : 'Dependent';
@@ -243,6 +269,25 @@ export async function createPatient(payload: PatientRegistrationPayload, t: any)
243
269
  }
244
270
  }
245
271
 
272
+ async function launchCheckInWorkspace(patient: any, patientUuid: string) {
273
+ await launchWorkspaceGroup2('ewf-patient-chart', {
274
+ patient,
275
+ patientUuid,
276
+ visitContext: null as unknown as Visit,
277
+ mutateVisitContext: () => {},
278
+ });
279
+
280
+ launchWorkspace2<VisitFormProps, {}, {}>(
281
+ 'custom-start-visit-workspace-form',
282
+ {
283
+ openedFrom: 'registration-check-in',
284
+ showPatientHeader: false,
285
+ },
286
+ {},
287
+ null,
288
+ );
289
+ }
290
+
246
291
  export async function createDependentPatient(dependent: DependentPayload, t: any) {
247
292
  const payload: PatientRegistrationPayload = {
248
293
  name: dependent.name,
@@ -252,14 +297,7 @@ export async function createDependentPatient(dependent: DependentPayload, t: any
252
297
  };
253
298
 
254
299
  const result = await createPatient(payload, t);
255
-
256
- launchWorkspace('start-visit-workspace-form', {
257
- patientUuid: result.uuid,
258
- workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
259
- patientName: dependent.name,
260
- }),
261
- });
262
-
300
+ await launchCheckInWorkspace(result, result.uuid);
263
301
  return result;
264
302
  }
265
303
 
@@ -278,14 +316,7 @@ export async function createHIEPatient(hiePatient: HIEPatient, t: any) {
278
316
  };
279
317
 
280
318
  const result = await createPatient(payload, t);
281
-
282
- launchWorkspace('start-visit-workspace-form', {
283
- patientUuid: result.uuid,
284
- workspaceTitle: t('startVisitWorkspaceTitle', 'Start Visit for {{patientName}}', {
285
- patientName: patientName,
286
- }),
287
- });
288
-
319
+ await launchCheckInWorkspace(result, result.uuid);
289
320
  return result;
290
321
  }
291
322
 
@@ -321,11 +352,9 @@ export const getDependentsFromContacts = (patient: HIEPatient) => {
321
352
  const shaIdNumber = identifierExtensions.find(
322
353
  (ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'sha-id-number',
323
354
  )?.valueIdentifier?.value;
324
-
325
355
  const nationalId = identifierExtensions.find(
326
356
  (ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'national-id',
327
357
  )?.valueIdentifier?.value;
328
-
329
358
  const birthCertificate = identifierExtensions.find(
330
359
  (ext) => ext.valueIdentifier?.type?.coding?.[0]?.code === 'birth-certificate',
331
360
  )?.valueIdentifier?.value;
@@ -372,7 +401,7 @@ export const useActiveVisit = (patientUuid: string | null) => {
372
401
  const data = await response.json();
373
402
  const visits = data?.results || [];
374
403
  setActiveVisit(visits.length > 0 ? visits[0] : null);
375
- } catch (err) {
404
+ } catch (err: any) {
376
405
  console.warn(`Error fetching active visit for patient ${patientUuid}:`, err);
377
406
  setError(err);
378
407
  setActiveVisit(null);
@@ -0,0 +1,320 @@
1
+ import React, { useState, useCallback, useRef } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { Button, Dropdown, ModalBody, ModalFooter, ModalHeader } from '@carbon/react';
4
+ import { showModal, showSnackbar, useSession, useVisit } from '@openmrs/esm-framework';
5
+ import { extractFetchError, extractUpstreamError } from '../../../shared/utils';
6
+ import styles from './end-visit-dialog.scss';
7
+ import { processVisitInsuranceClaim, sendDischargeOtp, submitVisitClaim } from './end-visit.resource';
8
+ import {
9
+ checkBiometricAuthorizationStatus,
10
+ createSHABiometricAuthorize,
11
+ detectAuthorizingDeviceOS,
12
+ fetchWhitelistStatus,
13
+ rejectBiometricAuthorization,
14
+ submitOtpWhitelist,
15
+ useBiometricAgentStatus,
16
+ useBiometricConfig,
17
+ useOtpWhitelistReasons,
18
+ usePatientCRId,
19
+ usePatientPhone,
20
+ useSHAEligibility,
21
+ useProviderNationalId,
22
+ } from './sha-end-visit.resource';
23
+ import { DISCHARGE_REASONS } from '../type';
24
+
25
+ interface EndVisitDialogProps {
26
+ patientUuid: string;
27
+ closeModal: () => void;
28
+ }
29
+
30
+ const EndVisitDialog: React.FC<EndVisitDialogProps> = ({ patientUuid, closeModal }) => {
31
+ const { t } = useTranslation();
32
+ const { activeVisit } = useVisit(patientUuid);
33
+ const [step, setStep] = useState<'confirm' | 'discharge-reason'>('confirm');
34
+ const [isProcessingClaim, setIsProcessingClaim] = useState(false);
35
+ const [reason, setReason] = useState('');
36
+ const processingClaimRef = useRef(false);
37
+ const serviceTypeRef = useRef('OUTPATIENT');
38
+ const consentTokenRef = useRef<string>('');
39
+ const invoiceNumberRef = useRef<string>('');
40
+ const interventionsRef = useRef<string[]>([]);
41
+ const phoneNumber = usePatientPhone(patientUuid);
42
+ const patientCRId = usePatientCRId(patientUuid);
43
+ const { isPatientWhiteListed, facilityBiometricsEnforced } = useSHAEligibility(patientUuid);
44
+ const { currentProvider } = useSession();
45
+ const { providerNationalid } = useProviderNationalId(currentProvider?.uuid ?? '');
46
+ const { agentUrl } = useBiometricConfig();
47
+ const { workstationId } = useBiometricAgentStatus(agentUrl);
48
+ const deviceOs = detectAuthorizingDeviceOS();
49
+ const { reasons: whitelistReasons } = useOtpWhitelistReasons();
50
+
51
+ const buildBiometricStarter = useCallback(
52
+ (crId: string) => {
53
+ return async () => {
54
+ if (!providerNationalid) {
55
+ throw new Error(
56
+ t(
57
+ 'biometricMissingNationalId',
58
+ 'Provider National ID not configured. Please add it to your provider profile.',
59
+ ),
60
+ );
61
+ }
62
+ if (!workstationId) {
63
+ throw new Error(
64
+ t(
65
+ 'biometricAgentNotReachable',
66
+ 'Biometric agent not running. Please start the agent on this workstation and try again.',
67
+ ),
68
+ );
69
+ }
70
+
71
+ const res = await createSHABiometricAuthorize({
72
+ agent_id: providerNationalid,
73
+ patient_id: crId,
74
+ interventions: interventionsRef.current,
75
+ service_type: serviceTypeRef.current,
76
+ workstation_id: workstationId,
77
+ authorizing_device_os: deviceOs,
78
+ patient_uuid: patientUuid,
79
+ is_biometrics_discharge_authorization: true,
80
+ });
81
+ if (!res.success || !res.embed_url || !res.token || !res.guid) {
82
+ throw new Error(
83
+ extractUpstreamError(res as any, t('biometricStartFailed', 'Could not start biometric session.')),
84
+ );
85
+ }
86
+ return {
87
+ embed_url: res.embed_url,
88
+ authorization_code: res.authorization_code ?? '',
89
+ consent_token: res.consent_token ?? res.token,
90
+ token: res.token,
91
+ guid: res.guid,
92
+ };
93
+ };
94
+ },
95
+ [providerNationalid, workstationId, deviceOs, patientUuid, t],
96
+ );
97
+
98
+ const handleSubmitWhitelist = useCallback(
99
+ async (params: { reasonType: string; reason: string; biometricAttempts: number; attachment: File | null }) => {
100
+ if (!patientCRId) {
101
+ return { success: false, error: t('noCRNumber', 'Patient has no SHA CR number.') };
102
+ }
103
+ return submitOtpWhitelist({
104
+ beneficiaryCrId: patientCRId,
105
+ reasonType: params.reasonType,
106
+ reason: params.reason,
107
+ biometricAttempts: params.biometricAttempts,
108
+ attachment: params.attachment,
109
+ });
110
+ },
111
+ [patientCRId, t],
112
+ );
113
+
114
+ const handleCheckWhitelistStatus = useCallback(async (crId: string) => {
115
+ const status = await fetchWhitelistStatus(crId);
116
+ return {
117
+ is_whitelisted: status.is_whitelisted,
118
+ has_pending: status.has_pending,
119
+ is_rejected: status.is_rejected,
120
+ latest_status: status.latest_status,
121
+ reviewer_note: status.requests?.[0]?.reviewer_note ?? null,
122
+ };
123
+ }, []);
124
+
125
+ const handleEndVisit = async () => {
126
+ if (!activeVisit || processingClaimRef.current) {
127
+ return;
128
+ }
129
+ processingClaimRef.current = true;
130
+ setIsProcessingClaim(true);
131
+
132
+ try {
133
+ const response = await processVisitInsuranceClaim(activeVisit.uuid);
134
+ serviceTypeRef.current = response?.data?.service_type ?? 'OUTPATIENT';
135
+ consentTokenRef.current = String(response?.data?.consentToken ?? '');
136
+ invoiceNumberRef.current = String(response?.data?.invoiceNumber ?? '');
137
+ interventionsRef.current = Array.isArray(response?.data?.intervention_codes)
138
+ ? response?.data?.intervention_codes
139
+ : [];
140
+ setStep('discharge-reason');
141
+ } catch (error) {
142
+ showSnackbar({
143
+ isLowContrast: true,
144
+ kind: 'error',
145
+ title: t('claimProcessingError', 'Error'),
146
+ subtitle: extractFetchError(error, t('insuranceClaimProcessingFailed', 'Insurance claim processing failed')),
147
+ });
148
+ closeModal();
149
+ } finally {
150
+ processingClaimRef.current = false;
151
+ setIsProcessingClaim(false);
152
+ }
153
+ };
154
+
155
+ const handleContinue = useCallback(() => {
156
+ if (!reason || !patientCRId || !activeVisit) {
157
+ return;
158
+ }
159
+
160
+ closeModal();
161
+
162
+ const crId = patientCRId;
163
+ const visitUuid = activeVisit.uuid;
164
+ const dischargeReason = reason;
165
+ const invoiceNumber = invoiceNumberRef.current;
166
+ let settled = false;
167
+
168
+ const settle = (fn?: () => void) => {
169
+ if (!settled) {
170
+ settled = true;
171
+ fn?.();
172
+ }
173
+ };
174
+
175
+ setTimeout(() => {
176
+ const dispose = showModal('otp-verification-modal', {
177
+ onClose: () => {
178
+ settle();
179
+ dispose();
180
+ },
181
+ phoneNumber,
182
+ otpLength: 6,
183
+ expiryMinutes: 5,
184
+ centerBoxes: true,
185
+ authMode: 'multi',
186
+ whitelistedForOTP: isPatientWhiteListed,
187
+ facilityBiometricsEnforced,
188
+ patientCRId: crId,
189
+ visitAction: 'end',
190
+
191
+ onRequestOtp: async () => {
192
+ const res = await sendDischargeOtp(crId, consentTokenRef.current);
193
+ if (res.success === false) {
194
+ throw new Error(res.error ?? t('otpRequestFailed', 'Failed to send OTP. Please try again.'));
195
+ }
196
+ },
197
+
198
+ onVerify: async (otp: string) => {
199
+ const res = await submitVisitClaim({ visitUuid, otp, dischargeReason, invoiceNumber });
200
+ showSnackbar({
201
+ isLowContrast: true,
202
+ kind: res?.success === true ? 'success' : 'error',
203
+ title: t('visitEnded', 'Visit ended'),
204
+ subtitle: res?.message ?? res?.error ?? '',
205
+ });
206
+ },
207
+
208
+ onVerificationSuccess: () => {
209
+ settle(() => {
210
+ dispose();
211
+ });
212
+ },
213
+
214
+ onCleanup: () => {},
215
+
216
+ onStartBiometric: buildBiometricStarter(crId),
217
+ onCheckBiometricStatus: checkBiometricAuthorizationStatus,
218
+
219
+ onBiometricSuccess: async (result: { authorization_code: string; consent_token: string; guid: string }) => {
220
+ const res = await submitVisitClaim({
221
+ visitUuid,
222
+ dischargeAuthGuid: result.guid,
223
+ dischargeReason,
224
+ invoiceNumber,
225
+ });
226
+ showSnackbar({
227
+ isLowContrast: true,
228
+ kind: res?.success === true ? 'success' : 'error',
229
+ title: t('visitEnded', 'Visit ended'),
230
+ subtitle: res?.message ?? res?.error ?? '',
231
+ });
232
+ },
233
+
234
+ onBiometricCancel: async (biometricConsentToken: string | null) => {
235
+ if (biometricConsentToken) {
236
+ try {
237
+ await rejectBiometricAuthorization(biometricConsentToken);
238
+ } catch (err) {
239
+ console.warn('Failed to reject biometric auth:', err);
240
+ }
241
+ }
242
+ },
243
+
244
+ whitelistReasons,
245
+ onSubmitWhitelist: handleSubmitWhitelist,
246
+ onCheckWhitelistStatus: handleCheckWhitelistStatus,
247
+ });
248
+ }, 300);
249
+ }, [
250
+ reason,
251
+ patientCRId,
252
+ activeVisit,
253
+ closeModal,
254
+ phoneNumber,
255
+ isPatientWhiteListed,
256
+ facilityBiometricsEnforced,
257
+ buildBiometricStarter,
258
+ whitelistReasons,
259
+ handleSubmitWhitelist,
260
+ handleCheckWhitelistStatus,
261
+ t,
262
+ ]);
263
+
264
+ if (step === 'discharge-reason') {
265
+ return (
266
+ <div>
267
+ <ModalHeader closeModal={closeModal} title={t('endVisitTitle', 'End Visit')} />
268
+ <ModalBody className={styles.dischargeModalBody}>
269
+ <p className={styles.bodyShort02}>
270
+ {t(
271
+ 'dischargeReasonIntro',
272
+ 'Select the reason for ending this visit. You will then be asked to verify your identity.',
273
+ )}
274
+ </p>
275
+ <Dropdown
276
+ id="discharge-reason-dropdown"
277
+ titleText={t('dischargeReason', 'Discharge reason')}
278
+ label={t('selectDischargeReason', 'Select a reason')}
279
+ items={[...DISCHARGE_REASONS]}
280
+ itemToString={(item) => (item ? item.label : '')}
281
+ selectedItem={DISCHARGE_REASONS.find((r) => r.id === reason) ?? null}
282
+ onChange={({ selectedItem }) => setReason(selectedItem?.id ?? '')}
283
+ />
284
+ </ModalBody>
285
+ <ModalFooter>
286
+ <Button kind="secondary" onClick={closeModal}>
287
+ {t('cancel', 'Cancel')}
288
+ </Button>
289
+ <Button kind="primary" disabled={!reason} onClick={handleContinue}>
290
+ {t('continue', 'Continue')}
291
+ </Button>
292
+ </ModalFooter>
293
+ </div>
294
+ );
295
+ }
296
+
297
+ return (
298
+ <div>
299
+ <ModalHeader
300
+ closeModal={closeModal}
301
+ title={t('endActiveVisitConfirmation', 'Are you sure you want to end this active visit?')}
302
+ />
303
+ <ModalBody>
304
+ <p className={styles.bodyShort02}>
305
+ {t('youWillProcessTheClaim', 'You will process the insurance claim for this visit.')}
306
+ </p>
307
+ </ModalBody>
308
+ <ModalFooter>
309
+ <Button kind="secondary" onClick={closeModal}>
310
+ {t('cancel', 'Cancel')}
311
+ </Button>
312
+ <Button kind="danger" disabled={!activeVisit || isProcessingClaim} onClick={handleEndVisit}>
313
+ {t('endVisit_title', 'End Visit')}
314
+ </Button>
315
+ </ModalFooter>
316
+ </div>
317
+ );
318
+ };
319
+
320
+ export default EndVisitDialog;
@@ -0,0 +1,12 @@
1
+ @use '@carbon/type';
2
+ @use '@carbon/colors';
3
+
4
+ .bodyShort02 {
5
+ @include type.type-style('body-compact-02');
6
+ color: colors.$gray-70;
7
+ }
8
+
9
+ .dischargeModalBody {
10
+ overflow: visible;
11
+ min-height: 14rem;
12
+ }
@@ -0,0 +1,59 @@
1
+ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+
3
+ export type ProcessVisitResponse = {
4
+ service_type: string;
5
+ consentToken?: string;
6
+ invoiceNumber?: string | null;
7
+ interventions?: string[];
8
+ message?: string;
9
+ [key: string]: unknown;
10
+ };
11
+
12
+ export type SubmitVisitResponse = {
13
+ success?: boolean;
14
+ message?: string;
15
+ error?: string;
16
+ };
17
+
18
+ export function processVisitInsuranceClaim(visitUuid: string) {
19
+ return openmrsFetch<ProcessVisitResponse>(`${restBaseUrl}/insuranceclaims/phc/processVisit?visitUuid=${visitUuid}`, {
20
+ method: 'POST',
21
+ headers: { 'Content-Type': 'application/json' },
22
+ });
23
+ }
24
+
25
+ export async function sendDischargeOtp(
26
+ patientCRId: string,
27
+ consentToken: string,
28
+ ): Promise<{ success?: boolean; error?: string }> {
29
+ const params = new URLSearchParams({ patientId: patientCRId, consentToken });
30
+ const response = await openmrsFetch<{ success?: boolean; error?: string }>(
31
+ `${restBaseUrl}/insuranceclaims/phc/sendDischargeOtp?${params.toString()}`,
32
+ { method: 'POST' },
33
+ );
34
+ return response.data;
35
+ }
36
+
37
+ export async function submitVisitClaim(params: {
38
+ visitUuid: string;
39
+ otp?: string;
40
+ dischargeReason?: string;
41
+ dischargeAuthGuid?: string;
42
+ invoiceNumber?: string;
43
+ }): Promise<SubmitVisitResponse> {
44
+ const query = new URLSearchParams({ visitUuid: params.visitUuid, invoiceNumber: params.invoiceNumber ?? '' });
45
+ if (params.otp) {
46
+ query.set('otp', params.otp);
47
+ }
48
+ if (params.dischargeReason) {
49
+ query.set('dischargeReason', params.dischargeReason);
50
+ }
51
+ if (params.dischargeAuthGuid) {
52
+ query.set('dischargeAuthGuid', params.dischargeAuthGuid);
53
+ }
54
+ const response = await openmrsFetch<SubmitVisitResponse>(
55
+ `${restBaseUrl}/insuranceclaims/phc/submitVisit?${query.toString()}`,
56
+ { method: 'POST', headers: { 'Content-Type': 'application/json' } },
57
+ );
58
+ return response.data;
59
+ }