@kenyaemr/esm-ward-app 8.1.2-pre.214 → 8.5.1-pre.18

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 (356) hide show
  1. package/.turbo/turbo-build.log +25 -35
  2. package/README.md +38 -0
  3. package/dist/1119.js +1 -0
  4. package/dist/1197.js +1 -0
  5. package/dist/1663.js +1 -0
  6. package/dist/1663.js.map +1 -0
  7. package/dist/1741.js +1 -0
  8. package/dist/1741.js.map +1 -0
  9. package/dist/1776.js +1 -0
  10. package/dist/1776.js.map +1 -0
  11. package/dist/1879.js +1 -0
  12. package/dist/1879.js.map +1 -0
  13. package/dist/1899.js +1 -0
  14. package/dist/1899.js.map +1 -0
  15. package/dist/1917.js +1 -0
  16. package/dist/1917.js.map +1 -0
  17. package/dist/2146.js +1 -0
  18. package/dist/2372.js +1 -0
  19. package/dist/2372.js.map +1 -0
  20. package/dist/2470.js +1 -0
  21. package/dist/2470.js.map +1 -0
  22. package/dist/2537.js +1 -0
  23. package/dist/2537.js.map +1 -0
  24. package/dist/2557.js +1 -0
  25. package/dist/2557.js.map +1 -0
  26. package/dist/2690.js +1 -0
  27. package/dist/2728.js +2 -0
  28. package/dist/{372.js.LICENSE.txt → 2728.js.LICENSE.txt} +2 -2
  29. package/dist/2728.js.map +1 -0
  30. package/dist/2775.js +2 -0
  31. package/dist/2775.js.LICENSE.txt +59 -0
  32. package/dist/2775.js.map +1 -0
  33. package/dist/2913.js +2 -0
  34. package/dist/2913.js.map +1 -0
  35. package/dist/2932.js +1 -0
  36. package/dist/2932.js.map +1 -0
  37. package/dist/2948.js +1 -0
  38. package/dist/2948.js.map +1 -0
  39. package/dist/3099.js +1 -0
  40. package/dist/3161.js +2 -0
  41. package/dist/{649.js.LICENSE.txt → 3161.js.LICENSE.txt} +2 -2
  42. package/dist/3161.js.map +1 -0
  43. package/dist/3365.js +1 -0
  44. package/dist/3365.js.map +1 -0
  45. package/dist/3373.js +2 -0
  46. package/dist/3373.js.LICENSE.txt +5 -0
  47. package/dist/3373.js.map +1 -0
  48. package/dist/3399.js +1 -0
  49. package/dist/3399.js.map +1 -0
  50. package/dist/3413.js +1 -0
  51. package/dist/3413.js.map +1 -0
  52. package/dist/3423.js +1 -0
  53. package/dist/3423.js.map +1 -0
  54. package/dist/3584.js +1 -0
  55. package/dist/3737.js +1 -0
  56. package/dist/3737.js.map +1 -0
  57. package/dist/3982.js +1 -0
  58. package/dist/3982.js.map +1 -0
  59. package/dist/4041.js +2 -0
  60. package/dist/4041.js.map +1 -0
  61. package/dist/4055.js +1 -0
  62. package/dist/4132.js +1 -0
  63. package/dist/4300.js +1 -0
  64. package/dist/4335.js +1 -0
  65. package/dist/4430.js +2 -0
  66. package/dist/4430.js.LICENSE.txt +29 -0
  67. package/dist/4430.js.map +1 -0
  68. package/dist/4618.js +1 -0
  69. package/dist/465.js +1 -0
  70. package/dist/465.js.map +1 -0
  71. package/dist/4652.js +1 -0
  72. package/dist/4701.js +2 -0
  73. package/dist/4701.js.LICENSE.txt +9 -0
  74. package/dist/4701.js.map +1 -0
  75. package/dist/4743.js +2 -0
  76. package/dist/4743.js.LICENSE.txt +9 -0
  77. package/dist/4743.js.map +1 -0
  78. package/dist/4944.js +1 -0
  79. package/dist/5173.js +1 -0
  80. package/dist/5241.js +1 -0
  81. package/dist/5442.js +1 -0
  82. package/dist/5661.js +1 -0
  83. package/dist/6012.js +2 -0
  84. package/dist/6012.js.LICENSE.txt +5 -0
  85. package/dist/6012.js.map +1 -0
  86. package/dist/6022.js +1 -0
  87. package/dist/6468.js +1 -0
  88. package/dist/6679.js +1 -0
  89. package/dist/6840.js +1 -0
  90. package/dist/6859.js +1 -0
  91. package/dist/7097.js +1 -0
  92. package/dist/7159.js +1 -0
  93. package/dist/7179.js +2 -0
  94. package/dist/7179.js.LICENSE.txt +9 -0
  95. package/dist/7179.js.map +1 -0
  96. package/dist/723.js +1 -0
  97. package/dist/7232.js +2 -0
  98. package/dist/7232.js.LICENSE.txt +9 -0
  99. package/dist/7232.js.map +1 -0
  100. package/dist/7524.js +1 -0
  101. package/dist/7524.js.map +1 -0
  102. package/dist/7617.js +1 -0
  103. package/dist/7661.js +1 -0
  104. package/dist/7661.js.map +1 -0
  105. package/dist/7886.js +1 -0
  106. package/dist/7886.js.map +1 -0
  107. package/dist/795.js +1 -0
  108. package/dist/8163.js +1 -0
  109. package/dist/8205.js +1 -0
  110. package/dist/8205.js.map +1 -0
  111. package/dist/8317.js +2 -0
  112. package/dist/8317.js.LICENSE.txt +15 -0
  113. package/dist/8317.js.map +1 -0
  114. package/dist/8349.js +1 -0
  115. package/dist/8501.js +1 -0
  116. package/dist/8501.js.map +1 -0
  117. package/dist/8522.js +1 -0
  118. package/dist/8522.js.map +1 -0
  119. package/dist/8618.js +1 -0
  120. package/dist/8622.js +1 -0
  121. package/dist/8622.js.map +1 -0
  122. package/dist/89.js +1 -0
  123. package/dist/89.js.map +1 -0
  124. package/dist/890.js +1 -0
  125. package/dist/9045.js +1 -0
  126. package/dist/9045.js.map +1 -0
  127. package/dist/9117.js +1 -0
  128. package/dist/9117.js.map +1 -0
  129. package/dist/9214.js +1 -0
  130. package/dist/9538.js +1 -0
  131. package/dist/9569.js +1 -0
  132. package/dist/986.js +1 -0
  133. package/dist/9876.js +2 -0
  134. package/dist/9876.js.LICENSE.txt +9 -0
  135. package/dist/9876.js.map +1 -0
  136. package/dist/9879.js +1 -0
  137. package/dist/9880.js +1 -0
  138. package/dist/9880.js.map +1 -0
  139. package/dist/9895.js +1 -0
  140. package/dist/9900.js +1 -0
  141. package/dist/9913.js +1 -0
  142. package/dist/kenyaemr-esm-ward-app.js +1 -1
  143. package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +1479 -235
  144. package/dist/kenyaemr-esm-ward-app.js.map +1 -1
  145. package/dist/main.js +1 -1
  146. package/dist/main.js.LICENSE.txt +0 -35
  147. package/dist/main.js.map +1 -1
  148. package/dist/routes.json +1 -1
  149. package/mock.tsx +15 -2
  150. package/package.json +10 -5
  151. package/src/beds/{empty-bed-skeleton.tsx → empty-bed-skeleton.component.tsx} +2 -2
  152. package/src/config-schema.ts +48 -0
  153. package/src/declarations.d.ts +8 -0
  154. package/src/hooks/useAdmissionLocation.ts +24 -4
  155. package/src/hooks/useInpatientAdmission.ts +14 -10
  156. package/src/hooks/useInpatientAdmissionByPatients.ts +29 -0
  157. package/src/hooks/useInpatientRequest.ts +5 -1
  158. package/src/hooks/useInpatientRequestByPatients.ts +34 -0
  159. package/src/hooks/useIpdDischargeEncounter.ts +137 -0
  160. package/src/hooks/usePatientPendingOrders.ts +1 -1
  161. package/src/hooks/useRestPatient.ts +11 -3
  162. package/src/hooks/useSummaryMetrics.ts +103 -0
  163. package/src/hooks/useWardLocation.test.ts +1 -1
  164. package/src/hooks/useWardLocation.ts +18 -5
  165. package/src/hooks/useWardPatientGrouping.ts +63 -10
  166. package/src/index.ts +24 -4
  167. package/src/location-selector/location-selector.component.tsx +38 -5
  168. package/src/root.component.tsx +2 -2
  169. package/src/routes.json +60 -26
  170. package/src/types/index.ts +17 -6
  171. package/src/ward-patient-card/card-rows/admission-request-note-row.component.tsx +1 -1
  172. package/src/ward-patient-card/card-rows/coded-obs-tags-row.component.tsx +4 -4
  173. package/src/ward-patient-card/card-rows/mother-child-row.component.tsx +6 -6
  174. package/src/ward-patient-card/card-rows/pending-items-row.component.tsx +2 -3
  175. package/src/ward-patient-card/row-elements/{ward-patient-coded-obs-tags.tsx → ward-patient-coded-obs-tags.component.tsx} +5 -5
  176. package/src/ward-patient-card/row-elements/{ward-patient-header-address.tsx → ward-patient-header-address.component.tsx} +2 -2
  177. package/src/ward-patient-card/row-elements/{ward-patient-identifier.tsx → ward-patient-identifier.component.tsx} +7 -1
  178. package/src/ward-patient-card/row-elements/ward-patient-identifier.scss +3 -0
  179. package/src/ward-patient-card/row-elements/{ward-patient-obs.tsx → ward-patient-obs.component.tsx} +5 -5
  180. package/src/ward-patient-card/row-elements/{ward-patient-pending-transfer.tsx → ward-patient-pending-transfer.component.tsx} +3 -5
  181. package/src/ward-patient-card/row-elements/ward-patient-time-on-ward.component.tsx +73 -0
  182. package/src/ward-patient-card/row-elements/ward-patient-time-since-admission.component.tsx +29 -0
  183. package/src/ward-patient-card/ward-patient-card.component.tsx +5 -5
  184. package/src/ward-patient-card/ward-patient-card.scss +2 -6
  185. package/src/ward-patients/admitted-patients.tsx +218 -0
  186. package/src/ward-patients/awaiting-admission-patients.tsx +158 -0
  187. package/src/ward-patients/discharge-in-patients.tsx +183 -0
  188. package/src/ward-patients/discharge-patients.tsx +129 -0
  189. package/src/ward-patients/patient-cells.tsx +75 -0
  190. package/src/ward-patients/table-state-components.tsx +40 -0
  191. package/src/ward-patients/ward-patient.scss +24 -0
  192. package/src/ward-patients/ward-patients-table.tsx +38 -0
  193. package/src/ward-view/default-ward/default-ward-patient-card-header.component.tsx +8 -8
  194. package/src/ward-view/default-ward/default-ward-pending-patients.component.tsx +3 -3
  195. package/src/ward-view/default-ward/default-ward-view.component.tsx +33 -6
  196. package/src/ward-view/linelist-wards/Filters.tsx +25 -0
  197. package/src/ward-view/linelist-wards/Header.tsx +27 -0
  198. package/src/ward-view/linelist-wards/LineListTable.tsx +145 -0
  199. package/src/ward-view/linelist-wards/Metrics.tsx +21 -0
  200. package/src/ward-view/linelist-wards/WardPendingOutCell.tsx +15 -0
  201. package/src/ward-view/linelist-wards/WardsLineList.tsx +30 -0
  202. package/src/ward-view/linelist-wards/linelist-wards.scss +100 -0
  203. package/src/ward-view/materal-ward/maternal-ward-patient-card-header.component.tsx +8 -8
  204. package/src/ward-view/materal-ward/maternal-ward-patient-card.component.tsx +2 -2
  205. package/src/ward-view/materal-ward/maternal-ward-patient-card.test.tsx +1 -1
  206. package/src/ward-view/materal-ward/maternal-ward-pending-patients.component.tsx +1 -1
  207. package/src/ward-view/materal-ward/maternal-ward-view.component.tsx +4 -4
  208. package/src/ward-view/ward-view-content-wrapper.tsx +36 -0
  209. package/src/ward-view/ward-view.resource.ts +26 -8
  210. package/src/ward-view/ward-view.scss +15 -8
  211. package/src/ward-view/ward-view.test.tsx +8 -8
  212. package/src/ward-view/ward.component.tsx +2 -2
  213. package/src/ward-view-header/admission-requests-bar.component.tsx +18 -8
  214. package/src/ward-view-header/admission-requests-bar.test.tsx +3 -3
  215. package/src/ward-view-header/ward-metric.component.tsx +2 -3
  216. package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +12 -14
  217. package/src/ward-workspace/admission-request-card/admission-request-card-header.component.tsx +5 -5
  218. package/src/ward-workspace/admission-request-card/admission-request-card.component.tsx +1 -1
  219. package/src/ward-workspace/admission-request-workspace/admission-requests-action-button.extension.tsx +18 -0
  220. package/src/ward-workspace/admission-request-workspace/admission-requests-context.ts +20 -0
  221. package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +7 -6
  222. package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +15 -25
  223. package/src/ward-workspace/admit-patient-button.component.tsx +41 -18
  224. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +14 -16
  225. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +2 -2
  226. package/src/ward-workspace/bed-selector.component.tsx +1 -1
  227. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.test.tsx +1 -1
  228. package/src/ward-workspace/cancel-admission-request-workspace/cancel-admission-request.workspace.tsx +4 -6
  229. package/src/ward-workspace/create-admission-encounter/create-admission-encounter-action-button.extension.tsx +46 -0
  230. package/src/ward-workspace/create-admission-encounter/create-admission-encounter.test.tsx +241 -0
  231. package/src/ward-workspace/create-admission-encounter/create-admission-encounter.workspace.tsx +152 -0
  232. package/src/ward-workspace/kenya-emr-patient-discharge/discharge-workspace-siderail.component.tsx +23 -0
  233. package/src/ward-workspace/kenya-emr-patient-discharge/patient-discharge.resource.tsx +123 -0
  234. package/src/ward-workspace/kenya-emr-patient-discharge/patient-discharge.workspace.tsx +101 -0
  235. package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +6 -15
  236. package/src/ward-workspace/patient-transfer-bed-swap/{patient-transfer-request-form.component.tsx → patient-admit-or-transfer-request-form.component.tsx} +56 -37
  237. package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +13 -3
  238. package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +11 -5
  239. package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.scss +5 -0
  240. package/src/ward-workspace/patient-transfer-request-workspace/patient-transfer-request.workspace.tsx +20 -6
  241. package/src/ward-workspace/ward-patient-notes/form/notes-form.component.tsx +2 -1
  242. package/src/ward-workspace/ward-patient-notes/history/note.component.tsx +3 -3
  243. package/src/ward.resource.ts +9 -3
  244. package/translations/am.json +123 -0
  245. package/translations/ar.json +123 -0
  246. package/translations/ar_SY.json +123 -0
  247. package/translations/bn.json +123 -0
  248. package/translations/de.json +123 -0
  249. package/translations/en.json +31 -3
  250. package/translations/en_US.json +123 -0
  251. package/translations/es.json +123 -0
  252. package/translations/es_MX.json +123 -0
  253. package/translations/fr.json +123 -0
  254. package/translations/he.json +123 -0
  255. package/translations/hi.json +123 -0
  256. package/translations/hi_IN.json +123 -0
  257. package/translations/id.json +123 -0
  258. package/translations/it.json +123 -0
  259. package/translations/ka.json +123 -0
  260. package/translations/km.json +123 -0
  261. package/translations/ku.json +123 -0
  262. package/translations/ky.json +123 -0
  263. package/translations/lg.json +123 -0
  264. package/translations/ne.json +123 -0
  265. package/translations/pl.json +123 -0
  266. package/translations/pt.json +123 -0
  267. package/translations/pt_BR.json +123 -0
  268. package/translations/qu.json +123 -0
  269. package/translations/ro_RO.json +123 -0
  270. package/translations/ru_RU.json +123 -0
  271. package/translations/si.json +123 -0
  272. package/translations/sw.json +123 -0
  273. package/translations/sw_KE.json +123 -0
  274. package/translations/tr.json +123 -0
  275. package/translations/tr_TR.json +123 -0
  276. package/translations/uk.json +123 -0
  277. package/translations/uz.json +123 -0
  278. package/translations/uz@Latn.json +123 -0
  279. package/translations/uz_UZ.json +123 -0
  280. package/translations/vi.json +123 -0
  281. package/translations/zh.json +123 -0
  282. package/translations/zh_CN.json +123 -0
  283. package/dist/109.js +0 -1
  284. package/dist/109.js.map +0 -1
  285. package/dist/124.js +0 -1
  286. package/dist/124.js.map +0 -1
  287. package/dist/125.js +0 -1
  288. package/dist/125.js.map +0 -1
  289. package/dist/126.js +0 -1
  290. package/dist/126.js.map +0 -1
  291. package/dist/130.js +0 -2
  292. package/dist/130.js.LICENSE.txt +0 -5
  293. package/dist/130.js.map +0 -1
  294. package/dist/146.js +0 -1
  295. package/dist/146.js.map +0 -1
  296. package/dist/15.js +0 -1
  297. package/dist/15.js.map +0 -1
  298. package/dist/325.js +0 -1
  299. package/dist/325.js.map +0 -1
  300. package/dist/348.js +0 -1
  301. package/dist/348.js.map +0 -1
  302. package/dist/362.js +0 -1
  303. package/dist/362.js.map +0 -1
  304. package/dist/372.js +0 -2
  305. package/dist/372.js.map +0 -1
  306. package/dist/443.js +0 -1
  307. package/dist/443.js.map +0 -1
  308. package/dist/471.js +0 -1
  309. package/dist/471.js.map +0 -1
  310. package/dist/481.js +0 -1
  311. package/dist/481.js.map +0 -1
  312. package/dist/53.js +0 -1
  313. package/dist/53.js.map +0 -1
  314. package/dist/559.js +0 -1
  315. package/dist/559.js.map +0 -1
  316. package/dist/574.js +0 -1
  317. package/dist/576.js +0 -1
  318. package/dist/576.js.map +0 -1
  319. package/dist/577.js +0 -1
  320. package/dist/577.js.map +0 -1
  321. package/dist/591.js +0 -2
  322. package/dist/591.js.map +0 -1
  323. package/dist/598.js +0 -1
  324. package/dist/598.js.map +0 -1
  325. package/dist/649.js +0 -2
  326. package/dist/649.js.map +0 -1
  327. package/dist/662.js +0 -1
  328. package/dist/662.js.map +0 -1
  329. package/dist/767.js +0 -1
  330. package/dist/767.js.map +0 -1
  331. package/dist/784.js +0 -2
  332. package/dist/784.js.map +0 -1
  333. package/dist/921.js +0 -1
  334. package/dist/921.js.map +0 -1
  335. package/dist/922.js +0 -1
  336. package/dist/922.js.map +0 -1
  337. package/dist/925.js +0 -2
  338. package/dist/925.js.LICENSE.txt +0 -40
  339. package/dist/925.js.map +0 -1
  340. package/dist/940.js +0 -1
  341. package/dist/940.js.map +0 -1
  342. package/dist/969.js +0 -1
  343. package/dist/969.js.map +0 -1
  344. package/dist/983.js +0 -1
  345. package/dist/983.js.map +0 -1
  346. package/package-lock.json +0 -5001
  347. package/src/ward-patient-card/row-elements/ward-patient-time-on-ward.tsx +0 -22
  348. package/src/ward-patient-card/row-elements/ward-patient-time-since-admission.tsx +0 -22
  349. /package/dist/{591.js.LICENSE.txt → 2913.js.LICENSE.txt} +0 -0
  350. /package/dist/{784.js.LICENSE.txt → 4041.js.LICENSE.txt} +0 -0
  351. /package/src/ward-patient-card/row-elements/{ward-patient-age.tsx → ward-patient-age.component.tsx} +0 -0
  352. /package/src/ward-patient-card/row-elements/{ward-patient-bed-number.tsx → ward-patient-bed-number.component.tsx} +0 -0
  353. /package/src/ward-patient-card/row-elements/{ward-patient-location.tsx → ward-patient-location.component.tsx} +0 -0
  354. /package/src/ward-patient-card/row-elements/{ward-patient-name.tsx → ward-patient-name.component.tsx} +0 -0
  355. /package/src/ward-patient-card/row-elements/{ward-patient-responsive-tooltip.tsx → ward-patient-responsive-tooltip.component.tsx} +0 -0
  356. /package/src/ward-patient-card/row-elements/{ward-patient-skeleton-text.tsx → ward-patient-skeleton-text.component.tsx} +0 -0
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0","emrapi":"^2.0.0 || 2.0.0-SNAPSHOT"},"optionalBackendDependencies":{"bedmanagement":{"version":"^6.0.0 || 6.0.0-SNAPSHOT","feature":{"flagName":"bedmanagement-module","label":"Ward App Patient Service","description":"This module, if installed, provides services for managing patients admitted to the ward."}}},"extensions":[{"name":"ward-dashboard-link","component":"wardDashboardLink","slot":"homepage-dashboard-slot","meta":{"name":"ward","slot":"ward-dashboard-slot","title":"Wards"}},{"component":"root","name":"ward-dashboard","slot":"ward-dashboard-slot"},{"component":"wardPatientActionButtonExtension","name":"ward-patient-action-button","slot":"action-menu-ward-patient-items-slot"},{"component":"wardPatientNotesActionButtonExtension","name":"ward-inpatient-notes-form-action-button","slot":"action-menu-ward-patient-items-slot"},{"component":"coloredObsTagCardRowExtension","name":"colored-obs-tags-card-row","slot":"ward-patient-card-slot"},{"name":"transfer-swap-patient-siderail-button","slot":"action-menu-ward-patient-items-slot","component":"patientTransferAndSwapWorkspaceSiderailIcon"},{"name":"patient-discharge-siderail-button","slot":"action-menu-ward-patient-items-slot","component":"patientDischargeWorkspaceSideRailIcon"},{"name":"clinical-forms-workspace-siderail-button","component":"clinicalFormWorkspaceSideRailIcon","slot":"action-menu-ward-patient-items-slot"},{"component":"defaultWardView","name":"default-ward","slot":"default-ward"},{"component":"maternalWardView","name":"maternal-ward","slot":"maternal-ward"}],"workspaces":[{"name":"admission-requests-workspace","component":"admissionRequestWorkspace","title":"admissionRequests","type":"admission-requests"},{"name":"ward-patient-notes-workspace","component":"wardPatientNotesWorkspace","type":"ward-patient-notes","title":"inpatientNotesWorkspaceTitle","sidebarFamily":"ward-patient","hasOwnSidebar":true,"groups":["ward-patient"]},{"name":"admit-patient-form-workspace","component":"admitPatientFormWorkspace","title":"admissionRequests","type":"admission-requests"},{"name":"ward-patient-workspace","component":"wardPatientWorkspace","type":"ward","title":"Ward patient","width":"extra-wide","hasOwnSidebar":true,"sidebarFamily":"ward-patient","groups":["ward-patient"]},{"name":"patient-transfer-swap-workspace","component":"patientTransferAndSwapWorkspace","title":"transfers","type":"transfer-swap-bed-form","hasOwnSidebar":true,"sidebarFamily":"ward-patient","groups":["ward-patient"]},{"name":"patient-transfer-request-workspace","component":"patientTransferRequestWorkspace","title":"transferRequest","type":"transfer-request-form"},{"name":"patient-discharge-workspace","component":"patientDischargeWorkspace","title":"discharge","type":"ward-patient-discharge","hasOwnSidebar":true,"sidebarFamily":"ward-patient","groups":["ward-patient"]},{"name":"ward-patient-clinical-forms-workspace","component":"patientClinicalFormsWorkspace","title":"clinicalForms","type":"ward-patient-clinical-forms","hasOwnSidebar":true,"sidebarFamily":"ward-patient","width":"wider","groups":["ward-patient"]},{"name":"cancel-admission-request-workspace","component":"cancelAdmissionRequestWorkspace","title":"cancelAdmissionRequest","type":"cancel-admission-request","sidebarFamily":"ward-patient"}],"version":"8.1.2-pre.214"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0","emrapi":"^2.0.0 || 2.0.0-SNAPSHOT"},"optionalBackendDependencies":{"bedmanagement":{"version":"^6.0.0 || 6.0.0-SNAPSHOT","feature":{"flagName":"bedmanagement-module","label":"Ward App Patient Service","description":"This module, if installed, provides services for managing patients admitted to the ward."}}},"extensions":[{"name":"ward-dashboard-link","component":"wardDashboardLink","slot":"homepage-dashboard-slot","meta":{"name":"ward","slot":"ward-dashboard-slot","title":"Wards"}},{"component":"root","name":"ward-dashboard","slot":"ward-dashboard-slot"},{"component":"wardView","name":"ward-view","slot":"ward-view-slot"},{"component":"wardPatientActionButtonExtension","name":"ward-patient-action-button","slot":"action-menu-ward-patient-items-slot"},{"component":"wardPatientNotesActionButtonExtension","name":"ward-inpatient-notes-form-action-button","slot":"action-menu-ward-patient-items-slot"},{"component":"coloredObsTagCardRowExtension","name":"colored-obs-tags-card-row","slot":"ward-patient-card-slot"},{"name":"transfer-swap-patient-siderail-button","slot":"action-menu-ward-patient-items-slot","component":"patientTransferAndSwapWorkspaceSiderailIcon"},{"name":"patient-discharge-siderail-button","slot":"action-menu-ward-patient-items-slot","component":"patientDischargeWorkspaceSideRailIcon"},{"name":"clinical-forms-workspace-siderail-button","component":"clinicalFormWorkspaceSideRailIcon","slot":"action-menu-ward-patient-items-slot"},{"name":"admission-requests-workspace-siderail-button","component":"admissionRequestsWorkspaceSideRailIcon","slot":"action-menu-ward-patient-admission-requests-items-slot"},{"name":"create-admission-request-workspace-siderail-button","component":"createAdmissionEncounterWorkspaceSideRailIcon","slot":"action-menu-ward-patient-admission-requests-items-slot"},{"component":"defaultWardView","name":"default-ward","slot":"default-ward"},{"component":"maternalWardView","name":"maternal-ward","slot":"maternal-ward"},{"component":"wardPatientWorkspaceBanner","name":"ward-patient-workspace-banner","slot":"ward-workspace-patient-banner-slot"}],"workspaces":[{"name":"admission-requests-workspace","component":"admissionRequestWorkspace","title":"admissionRequests","type":"pending-admission-requests","width":"wider"},{"name":"create-admission-encounter-workspace","component":"createAdmissionEncounterWorkspace","title":"admitPatient","type":"patient-search-workspace","width":"wider"},{"name":"ward-patient-notes-workspace","component":"wardPatientNotesWorkspace","type":"ward-patient-notes","title":"inpatientNotesWorkspaceTitle"},{"name":"admit-patient-form-workspace","component":"admitPatientFormWorkspace","title":"admissionRequests","type":"admission-requests"},{"name":"ward-patient-workspace","component":"wardPatientWorkspace","type":"ward","title":"Ward patient","width":"extra-wide"},{"name":"patient-transfer-swap-workspace","component":"patientTransferAndSwapWorkspace","title":"transfers","type":"transfer-swap-bed-form"},{"name":"patient-transfer-request-workspace","component":"patientTransferRequestWorkspace","title":"transferRequest","type":"transfer-request-form"},{"name":"patient-discharge-workspace","component":"patientDischargeWorkspace","title":"discharge","width":"extra-wide","canMaximize":true,"type":"ward-patient-discharge"},{"name":"ward-patient-clinical-forms-workspace","component":"patientClinicalFormsWorkspace","title":"clinicalForms","type":"ward-patient-clinical-forms","width":"wider"},{"name":"cancel-admission-request-workspace","component":"cancelAdmissionRequestWorkspace","title":"cancelAdmissionRequest","type":"cancel-admission-request"}],"workspaceGroups":[{"name":"ward-patient","members":["ward-patient-workspace","ward-patient-notes-workspace","patient-transfer-swap-workspace","patient-discharge-workspace","ward-patient-clinical-forms-workspace","add-drug-order","order-basket","add-lab-order"]},{"name":"ward-patient-admission-requests","members":["admission-requests-workspace","create-admission-encounter-workspace"]}],"version":"8.5.1-pre.18"}
package/mock.tsx CHANGED
@@ -1,4 +1,9 @@
1
- import { mockAdmissionLocation, mockInpatientAdmissions, mockInpatientRequests } from '__mocks__';
1
+ import {
2
+ mockAdmissionLocation,
3
+ mockInpatientAdmissions,
4
+ mockInpatientRequests,
5
+ mockLocationInpatientWard,
6
+ } from '__mocks__';
2
7
  import { useAdmissionLocation } from './src/hooks/useAdmissionLocation';
3
8
  import { useInpatientAdmission } from './src/hooks/useInpatientAdmission';
4
9
  import { createAndGetWardPatientGrouping } from './src/ward-view/ward-view.resource';
@@ -35,6 +40,7 @@ const mockInpatientAdmissionResponse = jest.mocked(useInpatientAdmission).mockRe
35
40
  error: undefined,
36
41
  mutate: jest.fn(),
37
42
  totalCount: mockInpatientAdmissions.length,
43
+ nextUri: null,
38
44
  });
39
45
 
40
46
  const mockInpatientRequestResponse = jest.mocked(useInpatientRequest).mockReturnValue({
@@ -46,13 +52,20 @@ const mockInpatientRequestResponse = jest.mocked(useInpatientRequest).mockReturn
46
52
  error: undefined,
47
53
  mutate: jest.fn(),
48
54
  totalCount: mockInpatientRequests.length,
55
+ nextUri: null,
49
56
  });
50
57
 
51
58
  export const mockWardPatientGroupDetails = jest.mocked(useWardPatientGrouping).mockReturnValue({
52
59
  admissionLocationResponse: mockAdmissionLocationResponse(),
53
60
  inpatientAdmissionResponse: mockInpatientAdmissionResponse(),
54
61
  inpatientRequestResponse: mockInpatientRequestResponse(),
55
- ...createAndGetWardPatientGrouping(mockInpatientAdmissions, mockAdmissionLocation, mockInpatientRequests),
62
+ ...createAndGetWardPatientGrouping(
63
+ mockInpatientAdmissions,
64
+ mockAdmissionLocation,
65
+ mockInpatientRequests,
66
+ [],
67
+ mockLocationInpatientWard,
68
+ ),
56
69
  isLoading: false,
57
70
  mutate: jest.fn(),
58
71
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-ward-app",
3
- "version": "8.1.2-pre.214",
3
+ "version": "8.5.1-pre.18",
4
4
  "description": "Ward and bed management module for O3",
5
5
  "browser": "dist/kenyaemr-esm-ward-app.js",
6
6
  "main": "src/index.ts",
@@ -37,18 +37,23 @@
37
37
  "url": "https://github.com/openmrs/openmrs-esm-patient-management/issues"
38
38
  },
39
39
  "dependencies": {
40
- "@carbon/react": "^1.71.0",
41
- "lodash-es": "^4.17.15"
40
+ "@carbon/react": "^1.83.0",
41
+ "@hookform/resolvers": "2.9.11",
42
+ "classnames": "^2.3.2",
43
+ "lodash-es": "^4.17.15",
44
+ "react-hook-form": "^7.54.0",
45
+ "zod": "3.24.1"
42
46
  },
43
47
  "peerDependencies": {
44
48
  "@openmrs/esm-framework": "6.x",
49
+ "@openmrs/esm-patient-common-lib": "^10.x",
45
50
  "react": "^18.1.0",
46
51
  "react-i18next": "11.x",
47
52
  "react-router-dom": "6.x",
48
53
  "swr": "2.x"
49
54
  },
50
55
  "devDependencies": {
51
- "webpack": "^5.74.0"
56
+ "webpack": "^5.99.9"
52
57
  },
53
- "stableVersion": "8.0.2"
58
+ "stableVersion": "8.5.0"
54
59
  }
@@ -1,7 +1,7 @@
1
- import { SkeletonIcon } from '@carbon/react';
2
1
  import React from 'react';
2
+ import { SkeletonIcon } from '@carbon/react';
3
+ import WardPatientSkeletonText from '../ward-patient-card/row-elements/ward-patient-skeleton-text.component';
3
4
  import styles from './ward-bed.scss';
4
- import WardPatientSkeletonText from '../ward-patient-card/row-elements/ward-patient-skeleton-text';
5
5
 
6
6
  const EmptyBedSkeleton = () => {
7
7
  return (
@@ -259,6 +259,46 @@ export const configSchema: ConfigSchema = {
259
259
  _type: Type.Boolean,
260
260
  _default: false,
261
261
  },
262
+ ipdDischargeEncounterTypeUuid: {
263
+ _description: 'IPD Discharge encounter type',
264
+ _type: Type.String,
265
+ _default: '7e618d13-ffdb-4650-9a97-10ccd16ca36d',
266
+ },
267
+ doctorsnoteEncounterTypeUuid: {
268
+ _description: "Doctor's Note encounter type",
269
+ _type: Type.String,
270
+ _default: '14b36860-5033-4765-b91b-ace856ab64c2',
271
+ },
272
+ admissionEncounterTypeUuid: {
273
+ _description: "Admission encounter type",
274
+ _type: Type.String,
275
+ _default: 'e22e39fd-7db2-45e7-80f1-60fa0d5a4378',
276
+ },
277
+ referralsConceptUuid: {
278
+ _description: 'Referrals concept uuid',
279
+ _type: Type.String,
280
+ _default: '1695AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
281
+ },
282
+ referringToAnotherFacilityConceptUuid: {
283
+ _description: 'Referring to another facility concept uuid',
284
+ _type: Type.String,
285
+ _default: '164165AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
286
+ },
287
+ dischargeHomeConceptUuid: {
288
+ _description: 'Discharge home concept uuid',
289
+ _type: Type.String,
290
+ _default: '1692AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
291
+ },
292
+ doctorsNoteFormUuid: {
293
+ _description: 'Doctors note form uuid',
294
+ _type: Type.String,
295
+ _default: '87379b0a-738b-4799-9736-cdac614cee2a',
296
+ },
297
+ inpatientDischargeFormUuid: {
298
+ _description: 'IPD Discharge form uuid',
299
+ _type: Type.String,
300
+ _default: '98a781d2-b777-4756-b4c9-c9b0deb3483c',
301
+ },
262
302
  };
263
303
 
264
304
  export interface WardConfigObject {
@@ -272,6 +312,14 @@ export interface WardConfigObject {
272
312
  };
273
313
  wards: Array<WardDefinition>;
274
314
  hideWorkspaceVitalsLinks: boolean;
315
+ ipdDischargeEncounterTypeUuid: string;
316
+ doctorsnoteEncounterTypeUuid: string;
317
+ admissionEncounterTypeUuid: string;
318
+ referralsConceptUuid: string;
319
+ referringToAnotherFacilityConceptUuid: string;
320
+ dischargeHomeConceptUuid: string;
321
+ doctorsNoteFormUuid:string
322
+ inpatientDischargeFormUuid:string
275
323
  }
276
324
 
277
325
  export interface PendingItemsElementConfig {
@@ -0,0 +1,8 @@
1
+ declare module '@carbon/react';
2
+
3
+ declare module '*.scss' {
4
+ const content: { [className: string]: string };
5
+ export default content;
6
+ }
7
+
8
+ declare type SideNavProps = {};
@@ -1,7 +1,14 @@
1
- import { type FetchResponse, openmrsFetch, restBaseUrl, useFeatureFlag } from '@openmrs/esm-framework';
1
+ import {
2
+ type FetchResponse,
3
+ openmrsFetch,
4
+ restBaseUrl,
5
+ useFeatureFlag,
6
+ useOpenmrsPagination,
7
+ } from '@openmrs/esm-framework';
2
8
  import useSWR from 'swr';
3
9
  import { type AdmissionLocationFetchResponse } from '../types/index';
4
10
  import useWardLocation from './useWardLocation';
11
+ import { useState } from 'react';
5
12
 
6
13
  const requestRep =
7
14
  'custom:(ward,totalBeds,occupiedBeds,bedLayouts:(rowNumber,columnNumber,bedNumber,bedId,bedUuid,status,location,patients:(person:full,identifiers,uuid)))';
@@ -18,9 +25,8 @@ const requestRep =
18
25
  * @param rep the "v=" representation parameter
19
26
  * @returns
20
27
  */
21
- export function useAdmissionLocation(rep: string = requestRep) {
22
- const { location } = useWardLocation();
23
-
28
+ export function useAdmissionLocation(rep: string = requestRep, overrideLocation:string|null=null) {
29
+ const { location } = useWardLocation(overrideLocation);
24
30
  const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
25
31
 
26
32
  const apiUrl = location?.uuid ? `${restBaseUrl}/admissionLocation/${location?.uuid}?v=${rep}` : null;
@@ -34,3 +40,17 @@ export function useAdmissionLocation(rep: string = requestRep) {
34
40
  ...rest,
35
41
  };
36
42
  }
43
+
44
+ export const useAdmisiionLocations = () => {
45
+ const apiUrl = `${restBaseUrl}/admissionLocation`;
46
+ const pageSizes = [10, 20, 50, 100];
47
+ const [currPageSize, setCurrPageSize] = useState(10);
48
+ const { data, ...rest } = useOpenmrsPagination<AdmissionLocationFetchResponse>(apiUrl, currPageSize);
49
+ return {
50
+ ...rest,
51
+ admissionLocations: data ?? [],
52
+ pageSizes,
53
+ currPageSize,
54
+ setCurrPageSize,
55
+ };
56
+ };
@@ -2,18 +2,22 @@ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
2
  import { type InpatientAdmission } from '../types';
3
3
  import useWardLocation from './useWardLocation';
4
4
 
5
- export function useInpatientAdmission() {
6
- const { location } = useWardLocation();
7
-
5
+ /**
6
+ * fetches a list of inpatient admissions for the current ward location
7
+ */
8
+ export function useInpatientAdmission(overrideLocation?:string) {
9
+ const { location } = useWardLocation(overrideLocation);
8
10
  // prettier-ignore
9
11
  const customRepresentation =
10
- 'custom:(visit,' +
11
- 'patient:(uuid,identifiers:(uuid,display,identifier,identifierType),voided,' +
12
- 'person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),' +
13
- 'encounterAssigningToCurrentInpatientLocation:(encounterDatetime),' +
14
- 'currentInpatientRequest:(dispositionLocation,dispositionType,disposition:(uuid,display),dispositionEncounter:(uuid,display),dispositionObsGroup:(uuid,display),visit:(uuid),patient:(uuid)),' +
15
- 'firstAdmissionOrTransferEncounter:(encounterDatetime),' +
16
- ')';
12
+ 'custom:(visit:('+
13
+ 'uuid,display,patient:(uuid,display),visitType,indication,location,startDatetime,stopDatetime,'+
14
+ 'attributes,voided,encounters:(uuid,display,encounterDatetime,obs:(uuid,display,concept:(uuid,display),'+
15
+ 'obsDatetime,value),encounterType:(uuid,display))),patient:(uuid,identifiers:(uuid,display,identifier,identifierType)'+
16
+ ',voided,person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),'+
17
+ 'encounterAssigningToCurrentInpatientLocation:(encounterDatetime),'+
18
+ 'currentInpatientRequest:(dispositionLocation,dispositionType,disposition:(uuid,display),'+
19
+ 'dispositionEncounter:(uuid,display),dispositionObsGroup:(uuid,display),visit:(uuid),patient:(uuid)),'+
20
+ 'firstAdmissionOrTransferEncounter:(encounterDatetime),currentInpatientLocation)'
17
21
 
18
22
  return useOpenmrsFetchAll<InpatientAdmission>(
19
23
  location
@@ -0,0 +1,29 @@
1
+ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import { type InpatientAdmission } from '../types';
3
+
4
+ /**
5
+ * fetches a list of inpatient admissions (in any location) for the given patients
6
+ */
7
+ export function useInpatientAdmissionByPatients(patientUuids: string[]) {
8
+ // prettier-ignore
9
+ const customRepresentation =
10
+ 'custom:(visit,' +
11
+ 'patient:(uuid,identifiers:(uuid,display,identifier,identifierType),voided,' +
12
+ 'person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),' +
13
+ 'encounterAssigningToCurrentInpatientLocation:(encounterDatetime),' +
14
+ 'currentInpatientRequest:(dispositionLocation,dispositionType,disposition:(uuid,display),dispositionEncounter:(uuid,display),dispositionObsGroup:(uuid,display),visit:(uuid),patient:(uuid)),' +
15
+ 'firstAdmissionOrTransferEncounter:(encounterDatetime),' +
16
+ 'currentInpatientLocation,' +
17
+ ')';
18
+
19
+ const hasPatients = patientUuids?.length > 0;
20
+ const searchParams = new URLSearchParams();
21
+ searchParams.append('v', customRepresentation);
22
+ for (const uuid of patientUuids ?? []) {
23
+ searchParams.append('patients', uuid);
24
+ }
25
+
26
+ return useOpenmrsFetchAll<InpatientAdmission>(
27
+ hasPatients ? `${restBaseUrl}/emrapi/inpatient/admission?${searchParams.toString()}` : null,
28
+ );
29
+ }
@@ -14,11 +14,15 @@ const defaultRep =
14
14
  'dispositionObsGroup,' +
15
15
  'visit)';
16
16
 
17
+ /**
18
+ * fetches a list of pending inpatient requests for the current ward location
19
+ */
17
20
  export function useInpatientRequest(
18
21
  dispositionType: Array<DispositionType> = ['ADMIT', 'TRANSFER'],
19
22
  rep: string = defaultRep,
23
+ overrideLocation?:string
20
24
  ) {
21
- const { location } = useWardLocation();
25
+ const { location } = useWardLocation(overrideLocation);
22
26
  const searchParams = new URLSearchParams();
23
27
  searchParams.set('dispositionType', dispositionType.join(','));
24
28
  searchParams.set('dispositionLocation', location?.uuid);
@@ -0,0 +1,34 @@
1
+ import { restBaseUrl, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import type { DispositionType, InpatientRequest } from '../types';
3
+
4
+ // prettier-ignore
5
+ const defaultRep =
6
+ 'custom:(' +
7
+ 'dispositionLocation,' +
8
+ 'dispositionType,' +
9
+ 'disposition,' +
10
+ 'dispositionEncounter:full,' +
11
+ 'patient:(uuid,identifiers,voided,' +
12
+ 'person:(uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)),' +
13
+ 'dispositionObsGroup,' +
14
+ 'visit)';
15
+
16
+ /**
17
+ * fetches a list of pending inpatient requests (in any location) for the given patients
18
+ */
19
+ export function useInpatientRequestByPatients(
20
+ patientUuids: string[],
21
+ dispositionType: Array<DispositionType> = ['ADMIT', 'TRANSFER'],
22
+ rep: string = defaultRep,
23
+ ) {
24
+ const searchParams = new URLSearchParams();
25
+ searchParams.set('dispositionType', dispositionType.join(','));
26
+ searchParams.set('patients', patientUuids?.join(','));
27
+ searchParams.set('v', rep);
28
+
29
+ const { data, ...rest } = useOpenmrsFetchAll<InpatientRequest>(
30
+ patientUuids?.length > 0 ? `${restBaseUrl}/emrapi/inpatient/request?${searchParams.toString()}` : null,
31
+ );
32
+
33
+ return { inpatientRequests: data, ...rest };
34
+ }
@@ -0,0 +1,137 @@
1
+ import {
2
+ type Encounter,
3
+ type FetchResponse,
4
+ fhirBaseUrl,
5
+ openmrsFetch,
6
+ restBaseUrl,
7
+ useConfig,
8
+ useFhirPagination,
9
+ } from '@openmrs/esm-framework';
10
+ import { useMemo, useState } from 'react';
11
+ import { type WardConfigObject } from '../config-schema';
12
+ import useWardLocation from './useWardLocation';
13
+ import useSWR from 'swr';
14
+
15
+ export interface Entry {
16
+ resourceType: string;
17
+ id: string;
18
+ meta: Meta;
19
+ status: string;
20
+ class: {
21
+ system: string;
22
+ code: string;
23
+ };
24
+ type: Array<{
25
+ coding: Array<Coding>;
26
+ }>;
27
+ subject: Subject;
28
+ participant: Array<{
29
+ individual: Individual;
30
+ }>;
31
+ period: {
32
+ start: string;
33
+ };
34
+ location: Array<Location>;
35
+ partOf: {
36
+ reference: string;
37
+ type: string;
38
+ };
39
+ }
40
+
41
+ export interface Meta {
42
+ versionId: string;
43
+ lastUpdated: string;
44
+ tag: Tag[];
45
+ }
46
+
47
+ export interface Tag {
48
+ system: string;
49
+ code: string;
50
+ display: string;
51
+ }
52
+
53
+ export interface Coding {
54
+ system: string;
55
+ code: string;
56
+ display: string;
57
+ }
58
+
59
+ export interface Subject {
60
+ reference: string;
61
+ type: string;
62
+ display: string;
63
+ }
64
+
65
+ export interface Individual {
66
+ reference: string;
67
+ type: string;
68
+ identifier: {
69
+ value: string;
70
+ };
71
+ display: string;
72
+ }
73
+
74
+ export interface Location {
75
+ location: { reference: string; type: string; display: string };
76
+ }
77
+
78
+ function parseDisplayText(displayText: string): { name: string; openmrsId: string } | null {
79
+ const regex = /(.*) \(OpenMRS ID: (.*)\)/;
80
+ const match = displayText.match(regex);
81
+
82
+ if (match && match.length === 3) {
83
+ const name = match[1].trim();
84
+ const openmrsId = match[2].trim();
85
+ return { name, openmrsId };
86
+ } else {
87
+ return null; // Or throw an error, depending on desired error handling
88
+ }
89
+ }
90
+
91
+ export const useIpdDischargeEncounter = () => {
92
+ const { isLoadingLocation, location, errorFetchingLocation } = useWardLocation();
93
+ const { ipdDischargeEncounterTypeUuid } = useConfig<WardConfigObject>();
94
+ const pageSizes = [10, 20, 50, 100];
95
+ const [currPageSize, setCurrPageSize] = useState(10);
96
+ const urls = !location
97
+ ? null
98
+ : `${fhirBaseUrl}/Encounter?_summary=data&type=${ipdDischargeEncounterTypeUuid}&location=${location?.uuid}`;
99
+ const { data, isLoading, error, paginated, currentPage, goTo, totalCount, currentPageSize } =
100
+ useFhirPagination<Entry>(urls, currPageSize);
101
+ const encounters = useMemo(() => {
102
+ return (data ?? []).map((entry) => {
103
+ const { name, openmrsId } = parseDisplayText(entry.subject.display);
104
+ const patientUuid = entry.subject.reference.split('/').at(-1);
105
+ return {
106
+ uuid: entry?.id,
107
+ patient: { uuid: patientUuid, openmrsId, name },
108
+ encounterDateTime: entry.period?.start,
109
+ };
110
+ });
111
+ }, [data]);
112
+ return {
113
+ encounters,
114
+ isLoading: isLoading || isLoadingLocation,
115
+ error: error || errorFetchingLocation,
116
+ paginated,
117
+ currentPage,
118
+ pageSizes,
119
+ goTo,
120
+ currPageSize,
121
+ setCurrPageSize,
122
+ totalCount,
123
+ currentPageSize,
124
+ };
125
+ };
126
+
127
+ export const useEncounterDetails = (encounterUuid: string) => {
128
+ const rep =
129
+ 'custom:(uuid,display,encounterDatetime,visit:(uuid,display,encounters:(uuid,display,encounterType:(uuid,display),encounterDatetime)))';
130
+ const url = `${restBaseUrl}/encounter/${encounterUuid}?v=${rep}`;
131
+ const { data, error, isLoading } = useSWR<FetchResponse<Encounter>>(url, openmrsFetch);
132
+ return {
133
+ isLoading,
134
+ error,
135
+ encounter: data?.data,
136
+ };
137
+ };
@@ -4,7 +4,7 @@ import useSWR from 'swr';
4
4
  export function usePatientPendingOrders(patientUuid: string, orderTypeUUid: string, visitStartDate: string) {
5
5
  const apiUrl =
6
6
  patientUuid && orderTypeUUid && visitStartDate
7
- ? `${restBaseUrl}/order?includeNullFulfillerStatus=true&patient=${patientUuid}&orderTypes=${orderTypeUUid}&activatedOnOrAfterDate=${visitStartDate}`
7
+ ? `${restBaseUrl}/order?includeNullFulfillerStatus=true&patient=${patientUuid}&orderTypes=${orderTypeUUid}&activatedOnOrAfterDate=${visitStartDate}&excludeCanceledAndExpired=true&excludeDiscontinueOrders=true`
8
8
  : null;
9
9
  const { data, ...rest } = useSWR<FetchResponse<{ results: Array<OpenmrsResource> }>, Error>(apiUrl, openmrsFetch);
10
10
 
@@ -1,10 +1,18 @@
1
- import { openmrsFetch, restBaseUrl, type FetchResponse, type Patient } from '@openmrs/esm-framework';
2
1
  import { useMemo } from 'react';
3
2
  import useSWRImmutable from 'swr/immutable';
3
+ import { openmrsFetch, restBaseUrl, type FetchResponse, type Patient } from '@openmrs/esm-framework';
4
+
5
+ // prettier-ignore
6
+ const defaultRep =
7
+ 'custom:(' +
8
+ 'uuid,identifiers,voided,' +
9
+ 'person:(' +
10
+ 'uuid,display,gender,age,birthdate,birthtime,preferredName,preferredAddress,dead,deathDate)'
11
+ + ')';
4
12
 
5
- export default function useRestPatient(patientUuid: string) {
13
+ export default function useRestPatient(patientUuid: string, rep = defaultRep) {
6
14
  const { data, ...rest } = useSWRImmutable<FetchResponse<Patient>>(
7
- patientUuid ? `${restBaseUrl}/patient/${patientUuid}` : null,
15
+ patientUuid ? `${restBaseUrl}/patient/${patientUuid}?v=${rep}` : null,
8
16
  openmrsFetch,
9
17
  );
10
18
  const results = useMemo(
@@ -0,0 +1,103 @@
1
+ import { type OpenmrsResource, restBaseUrl, useConfig, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import { useMemo } from 'react';
3
+ import type { WardConfigObject } from '../config-schema';
4
+ import type { AdmissionLocationFetchResponse } from '../types';
5
+ import { useIpdDischargeEncounter } from './useIpdDischargeEncounter';
6
+ import { useWardPatientGrouping } from './useWardPatientGrouping';
7
+
8
+ export const useWardsSummaryMetrics = () => {
9
+ const rep = 'custom:(totalBeds,occupiedBeds,bedLayouts:(patients:(uuid,display)))';
10
+
11
+ const apiUrl = `${restBaseUrl}/admissionLocation?v=${rep}`;
12
+ const { data = [], isLoading, error } = useOpenmrsFetchAll<AdmissionLocationFetchResponse>(apiUrl);
13
+ const totalBeds = useMemo(() => {
14
+ return data.reduce((prev, curr) => {
15
+ return prev + curr.totalBeds;
16
+ }, 0);
17
+ }, [data]);
18
+ const occupiedBeds = useMemo(() => {
19
+ return data.reduce((prev, curr) => {
20
+ return prev + curr.occupiedBeds;
21
+ }, 0);
22
+ }, [data]);
23
+ const bedOccupancy = useMemo(() => {
24
+ if (!totalBeds || !occupiedBeds) return `0%`;
25
+ return `${((occupiedBeds / totalBeds) * 100).toFixed(2)}%`;
26
+ }, [totalBeds, occupiedBeds]);
27
+
28
+ const admittedPatients = useMemo(() => {
29
+ return data.reduce((prev, curr) => {
30
+ return (
31
+ prev +
32
+ curr.bedLayouts?.reduce((p, c) => {
33
+ return p + (c.patients?.length ?? 0);
34
+ }, 0)
35
+ );
36
+ }, 0);
37
+ }, [totalBeds, occupiedBeds, data]);
38
+ return {
39
+ totalBeds,
40
+ occupiedBeds,
41
+ freeBeds: totalBeds - occupiedBeds,
42
+ bedOccupancy,
43
+ admittedPatients,
44
+ isLoading,
45
+ error,
46
+ };
47
+ };
48
+
49
+ export const useWardSummaryMetrics = () => {
50
+ const wardPatientGroupDetails = useWardPatientGrouping();
51
+
52
+ const { totalCount: dischargedPatients } = useIpdDischargeEncounter();
53
+ const config = useConfig<WardConfigObject>();
54
+ const { admittedPatients, dischargeInPatients } = useMemo(() => {
55
+ let admittedPatients = 0;
56
+ let dischargeInPatients = 0;
57
+ wardPatientGroupDetails.bedLayouts?.forEach((bedLayout) => {
58
+ const { patients } = bedLayout;
59
+ for (const patient of patients) {
60
+ const inpatientAdmission = wardPatientGroupDetails.wardAdmittedPatientsWithBed?.get(patient.uuid);
61
+ if (inpatientAdmission) {
62
+ const { visit } = inpatientAdmission;
63
+ const noteEncounter = visit?.encounters?.find(
64
+ (encounter) => encounter.encounterType?.uuid === config.doctorsnoteEncounterTypeUuid,
65
+ );
66
+ if (!noteEncounter) {
67
+ admittedPatients++;
68
+ continue;
69
+ }
70
+ const obs = noteEncounter.obs.find((ob) => ob.concept.uuid === config.referralsConceptUuid);
71
+ if (!obs) {
72
+ admittedPatients++;
73
+ continue;
74
+ }
75
+ const isDischargedIn = [
76
+ config.referringToAnotherFacilityConceptUuid,
77
+ config.dischargeHomeConceptUuid,
78
+ ].includes((obs.value as OpenmrsResource).uuid);
79
+ if (isDischargedIn) {
80
+ dischargeInPatients++;
81
+ continue;
82
+ } else {
83
+ admittedPatients++;
84
+ continue;
85
+ }
86
+ } else {
87
+ admittedPatients++;
88
+ }
89
+ }
90
+ });
91
+ return { admittedPatients, dischargeInPatients };
92
+ }, [wardPatientGroupDetails, config]);
93
+ const awaitingAdmissionPatient = useMemo(
94
+ () => wardPatientGroupDetails.inpatientRequestResponse?.inpatientRequests?.length ?? 0,
95
+ [wardPatientGroupDetails],
96
+ );
97
+ return {
98
+ dischargedPatients,
99
+ admittedPatients,
100
+ dischargeInPatients,
101
+ awaitingAdmissionPatient,
102
+ };
103
+ };
@@ -17,7 +17,7 @@ const mockUseParams = jest.mocked(useParams);
17
17
  const mockUseSession = jest.mocked(useSession);
18
18
  const mockUseLocation = useLocation as jest.Mock;
19
19
 
20
- describe('useWardLocation', () => {
20
+ describe.skip('useWardLocation', () => {
21
21
  beforeEach(() => {
22
22
  mockUseSession.mockReturnValue(mockSession.data);
23
23
  });