@bathiran212/esm-patient-chart-app 7.0.0

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 (382) hide show
  1. package/README.md +3 -0
  2. package/dist/108.js +1 -0
  3. package/dist/108.js.map +1 -0
  4. package/dist/1339.js +1 -0
  5. package/dist/1339.js.map +1 -0
  6. package/dist/1480.js +1 -0
  7. package/dist/1480.js.map +1 -0
  8. package/dist/1543.js +1 -0
  9. package/dist/1543.js.map +1 -0
  10. package/dist/1582.js +1 -0
  11. package/dist/1582.js.map +1 -0
  12. package/dist/1646.js +1 -0
  13. package/dist/1646.js.map +1 -0
  14. package/dist/1797.js +1 -0
  15. package/dist/1797.js.map +1 -0
  16. package/dist/1869.js +1 -0
  17. package/dist/1869.js.map +1 -0
  18. package/dist/1877.js +1 -0
  19. package/dist/1877.js.map +1 -0
  20. package/dist/2020.js +1 -0
  21. package/dist/2020.js.map +1 -0
  22. package/dist/2246.js +1 -0
  23. package/dist/2246.js.map +1 -0
  24. package/dist/2317.js +1 -0
  25. package/dist/2317.js.map +1 -0
  26. package/dist/2416.js +1 -0
  27. package/dist/2416.js.map +1 -0
  28. package/dist/2790.js +1 -0
  29. package/dist/2790.js.map +1 -0
  30. package/dist/282.js +1 -0
  31. package/dist/282.js.map +1 -0
  32. package/dist/2881.js +1 -0
  33. package/dist/2881.js.map +1 -0
  34. package/dist/3137.js +1 -0
  35. package/dist/3137.js.map +1 -0
  36. package/dist/3378.js +1 -0
  37. package/dist/3378.js.map +1 -0
  38. package/dist/3390.js +1 -0
  39. package/dist/3390.js.map +1 -0
  40. package/dist/3536.js +1 -0
  41. package/dist/3536.js.map +1 -0
  42. package/dist/3720.js +1 -0
  43. package/dist/3720.js.map +1 -0
  44. package/dist/3857.js +1 -0
  45. package/dist/3857.js.map +1 -0
  46. package/dist/3925.js +1 -0
  47. package/dist/3925.js.map +1 -0
  48. package/dist/3963.js +1 -0
  49. package/dist/3963.js.map +1 -0
  50. package/dist/3989.js +1 -0
  51. package/dist/3989.js.map +1 -0
  52. package/dist/4092.js +1 -0
  53. package/dist/4092.js.map +1 -0
  54. package/dist/4106.js +1 -0
  55. package/dist/4106.js.map +1 -0
  56. package/dist/4111.js +1 -0
  57. package/dist/4111.js.map +1 -0
  58. package/dist/4145.js +1 -0
  59. package/dist/4145.js.map +1 -0
  60. package/dist/434.js +1 -0
  61. package/dist/434.js.map +1 -0
  62. package/dist/4348.js +1 -0
  63. package/dist/4348.js.map +1 -0
  64. package/dist/4383.js +1 -0
  65. package/dist/4383.js.map +1 -0
  66. package/dist/4540.js +1 -0
  67. package/dist/4540.js.map +1 -0
  68. package/dist/4658.js +1 -0
  69. package/dist/4658.js.map +1 -0
  70. package/dist/466.js +1 -0
  71. package/dist/466.js.map +1 -0
  72. package/dist/4913.js +1 -0
  73. package/dist/4913.js.map +1 -0
  74. package/dist/4928.js +1 -0
  75. package/dist/4928.js.map +1 -0
  76. package/dist/5069.js +1 -0
  77. package/dist/5069.js.map +1 -0
  78. package/dist/5117.js +1 -0
  79. package/dist/5117.js.map +1 -0
  80. package/dist/5132.js +1 -0
  81. package/dist/5132.js.map +1 -0
  82. package/dist/5145.js +1 -0
  83. package/dist/5145.js.map +1 -0
  84. package/dist/52.js +1 -0
  85. package/dist/52.js.map +1 -0
  86. package/dist/5422.js +1 -0
  87. package/dist/5422.js.map +1 -0
  88. package/dist/5503.js +1 -0
  89. package/dist/5503.js.map +1 -0
  90. package/dist/5549.js +1 -0
  91. package/dist/5549.js.map +1 -0
  92. package/dist/556.js +1 -0
  93. package/dist/556.js.map +1 -0
  94. package/dist/5644.js +1 -0
  95. package/dist/5644.js.map +1 -0
  96. package/dist/5697.js +1 -0
  97. package/dist/5697.js.map +1 -0
  98. package/dist/5793.js +1 -0
  99. package/dist/5793.js.map +1 -0
  100. package/dist/5940.js +1 -0
  101. package/dist/5940.js.map +1 -0
  102. package/dist/5952.js +1 -0
  103. package/dist/5952.js.map +1 -0
  104. package/dist/6047.js +1 -0
  105. package/dist/6047.js.map +1 -0
  106. package/dist/6371.js +1 -0
  107. package/dist/6371.js.map +1 -0
  108. package/dist/6377.js +1 -0
  109. package/dist/6377.js.map +1 -0
  110. package/dist/6444.js +1 -0
  111. package/dist/6444.js.map +1 -0
  112. package/dist/6479.js +1 -0
  113. package/dist/6479.js.map +1 -0
  114. package/dist/6508.js +1 -0
  115. package/dist/6508.js.map +1 -0
  116. package/dist/6724.js +1 -0
  117. package/dist/6724.js.map +1 -0
  118. package/dist/6759.js +27 -0
  119. package/dist/6759.js.map +1 -0
  120. package/dist/689.js +1 -0
  121. package/dist/689.js.map +1 -0
  122. package/dist/6904.js +1 -0
  123. package/dist/6904.js.map +1 -0
  124. package/dist/7045.js +1 -0
  125. package/dist/7045.js.map +1 -0
  126. package/dist/7175.js +1 -0
  127. package/dist/7175.js.map +1 -0
  128. package/dist/7182.js +1 -0
  129. package/dist/7182.js.map +1 -0
  130. package/dist/7302.js +1 -0
  131. package/dist/7302.js.map +1 -0
  132. package/dist/7646.js +17 -0
  133. package/dist/7646.js.map +1 -0
  134. package/dist/7742.js +1 -0
  135. package/dist/7742.js.map +1 -0
  136. package/dist/7912.js +1 -0
  137. package/dist/7912.js.map +1 -0
  138. package/dist/8105.js +21 -0
  139. package/dist/8105.js.map +1 -0
  140. package/dist/8202.js +1 -0
  141. package/dist/8202.js.map +1 -0
  142. package/dist/8349.js +1 -0
  143. package/dist/8349.js.map +1 -0
  144. package/dist/8358.js +1 -0
  145. package/dist/8358.js.map +1 -0
  146. package/dist/8359.js +1 -0
  147. package/dist/8359.js.map +1 -0
  148. package/dist/8695.js +1 -0
  149. package/dist/8695.js.map +1 -0
  150. package/dist/8702.js +1 -0
  151. package/dist/8702.js.map +1 -0
  152. package/dist/8894.js +1 -0
  153. package/dist/8894.js.map +1 -0
  154. package/dist/8958.js +1 -0
  155. package/dist/8958.js.map +1 -0
  156. package/dist/903.js +1 -0
  157. package/dist/903.js.map +1 -0
  158. package/dist/9061.js +1 -0
  159. package/dist/9061.js.map +1 -0
  160. package/dist/9072.js +1 -0
  161. package/dist/9072.js.map +1 -0
  162. package/dist/9105.js +1 -0
  163. package/dist/9105.js.map +1 -0
  164. package/dist/9107.js +1 -0
  165. package/dist/9107.js.map +1 -0
  166. package/dist/9456.js +1 -0
  167. package/dist/9456.js.map +1 -0
  168. package/dist/9586.js +1 -0
  169. package/dist/9586.js.map +1 -0
  170. package/dist/9712.js +1 -0
  171. package/dist/9712.js.map +1 -0
  172. package/dist/9771.js +1 -0
  173. package/dist/9771.js.map +1 -0
  174. package/dist/9806.js +1 -0
  175. package/dist/9806.js.map +1 -0
  176. package/dist/9873.js +1 -0
  177. package/dist/9873.js.map +1 -0
  178. package/dist/9927.js +1 -0
  179. package/dist/9927.js.map +1 -0
  180. package/dist/main.js +6 -0
  181. package/dist/main.js.map +1 -0
  182. package/dist/openmrs-esm-patient-chart-app.js +6 -0
  183. package/dist/openmrs-esm-patient-chart-app.js.buildmanifest.json +2386 -0
  184. package/dist/openmrs-esm-patient-chart-app.js.map +1 -0
  185. package/dist/routes.json +1 -0
  186. package/package.json +63 -0
  187. package/rspack.config.js +1 -0
  188. package/src/actions-buttons/action-button.scss +3 -0
  189. package/src/actions-buttons/delete-visit.component.tsx +41 -0
  190. package/src/actions-buttons/delete-visit.test.tsx +26 -0
  191. package/src/actions-buttons/mark-patient-alive.component.tsx +42 -0
  192. package/src/actions-buttons/mark-patient-deceased.component.tsx +35 -0
  193. package/src/actions-buttons/start-visit.component.tsx +41 -0
  194. package/src/actions-buttons/start-visit.test.tsx +44 -0
  195. package/src/actions-buttons/stop-visit.component.tsx +39 -0
  196. package/src/actions-buttons/stop-visit.test.tsx +27 -0
  197. package/src/clinical-views/encounter-list/encounter-list-tabs.extension.tsx +78 -0
  198. package/src/clinical-views/encounter-list/encounter-list-tabs.scss +7 -0
  199. package/src/clinical-views/encounter-list/encounter-list.component.tsx +306 -0
  200. package/src/clinical-views/encounter-list/encounter-list.scss +36 -0
  201. package/src/clinical-views/encounter-list/table.component.tsx +63 -0
  202. package/src/clinical-views/encounter-list/table.scss +11 -0
  203. package/src/clinical-views/encounter-list/tag.component.test.tsx +307 -0
  204. package/src/clinical-views/encounter-list/tag.component.tsx +43 -0
  205. package/src/clinical-views/encounter-tile/clinical-views-summary.component.tsx +40 -0
  206. package/src/clinical-views/encounter-tile/encounter-tile.component.tsx +94 -0
  207. package/src/clinical-views/encounter-tile/tile.scss +82 -0
  208. package/src/clinical-views/hooks/index.ts +3 -0
  209. package/src/clinical-views/hooks/useEncounterRows.ts +60 -0
  210. package/src/clinical-views/hooks/useEncountersByVisit.ts +13 -0
  211. package/src/clinical-views/hooks/useFormsJson.ts +15 -0
  212. package/src/clinical-views/hooks/useLastEncounter.ts +29 -0
  213. package/src/clinical-views/types.ts +305 -0
  214. package/src/clinical-views/utils/concept-utils.ts +24 -0
  215. package/src/clinical-views/utils/encounter-list-config-builder.ts +160 -0
  216. package/src/clinical-views/utils/encounter-list.resource.ts +26 -0
  217. package/src/clinical-views/utils/helpers.ts +226 -0
  218. package/src/clinical-views/utils/index.ts +90 -0
  219. package/src/config-schema.ts +235 -0
  220. package/src/constants.ts +11 -0
  221. package/src/dashboard.meta.ts +15 -0
  222. package/src/data.resource.ts +117 -0
  223. package/src/declarations.d.ts +4 -0
  224. package/src/index.ts +204 -0
  225. package/src/loader/loader.component.tsx +11 -0
  226. package/src/loader/loader.scss +9 -0
  227. package/src/mark-patient-alive/mark-patient-alive.modal.tsx +54 -0
  228. package/src/mark-patient-deceased/mark-patient-deceased-form.scss +175 -0
  229. package/src/mark-patient-deceased/mark-patient-deceased-form.test.tsx +203 -0
  230. package/src/mark-patient-deceased/mark-patient-deceased-form.workspace.tsx +295 -0
  231. package/src/offline.ts +41 -0
  232. package/src/patient-banner-tags/visit-attribute-tags.extension.tsx +62 -0
  233. package/src/patient-banner-tags/visit-attribute-tags.scss +8 -0
  234. package/src/patient-chart/chart-review/chart-review.component.tsx +138 -0
  235. package/src/patient-chart/chart-review/chart-review.test.tsx +77 -0
  236. package/src/patient-chart/chart-review/dashboard-view.component.tsx +85 -0
  237. package/src/patient-chart/chart-review/dashboard-view.scss +84 -0
  238. package/src/patient-chart/patient-chart.component.tsx +71 -0
  239. package/src/patient-chart/patient-chart.resources.test.ts +238 -0
  240. package/src/patient-chart/patient-chart.resources.ts +231 -0
  241. package/src/patient-chart/patient-chart.scss +65 -0
  242. package/src/patient-details-tile/patient-details-tile.component.tsx +25 -0
  243. package/src/patient-details-tile/patient-details-tile.scss +24 -0
  244. package/src/root.component.tsx +35 -0
  245. package/src/root.scss +54 -0
  246. package/src/routes.json +267 -0
  247. package/src/side-nav/side-menu.component.tsx +10 -0
  248. package/src/side-nav/side-menu.scss +38 -0
  249. package/src/side-nav/side-menu.test.tsx +27 -0
  250. package/src/utils.test.ts +17 -0
  251. package/src/utils.ts +5 -0
  252. package/src/visit/hooks/useDefaultFacilityLocation.tsx +15 -0
  253. package/src/visit/hooks/useDefaultVisitLocation.tsx +24 -0
  254. package/src/visit/hooks/useDeleteVisit.test.tsx +267 -0
  255. package/src/visit/hooks/useDeleteVisit.tsx +103 -0
  256. package/src/visit/hooks/useOfflineVisitType.tsx +18 -0
  257. package/src/visit/hooks/useRecommendedVisitTypes.tsx +34 -0
  258. package/src/visit/hooks/useVisitAttributeType.tsx +102 -0
  259. package/src/visit/start-visit-button.component.tsx +47 -0
  260. package/src/visit/start-visit-button.test.tsx +32 -0
  261. package/src/visit/visit-action-items/delete-visit-action-item.component.tsx +60 -0
  262. package/src/visit/visit-action-items/delete-visit-action-item.test.tsx +48 -0
  263. package/src/visit/visit-action-items/edit-visit-details.component.tsx +79 -0
  264. package/src/visit/visit-form/base-visit-type.component.tsx +121 -0
  265. package/src/visit/visit-form/base-visit-type.scss +75 -0
  266. package/src/visit/visit-form/base-visit-type.test.tsx +153 -0
  267. package/src/visit/visit-form/exported-visit-form.workspace.tsx +755 -0
  268. package/src/visit/visit-form/location-selector.component.tsx +86 -0
  269. package/src/visit/visit-form/location-selector.test.tsx +146 -0
  270. package/src/visit/visit-form/recommended-visit-type.component.tsx +32 -0
  271. package/src/visit/visit-form/visit-attribute-type.component.tsx +258 -0
  272. package/src/visit/visit-form/visit-attribute-type.scss +5 -0
  273. package/src/visit/visit-form/visit-date-time.component.tsx +206 -0
  274. package/src/visit/visit-form/visit-form.resource.ts +401 -0
  275. package/src/visit/visit-form/visit-form.scss +167 -0
  276. package/src/visit/visit-form/visit-form.test.tsx +1233 -0
  277. package/src/visit/visit-form/visit-form.workspace.tsx +61 -0
  278. package/src/visit/visit-form/visit-type.test.tsx +88 -0
  279. package/src/visit/visit-history-table/visit-actions-cell.component.tsx +20 -0
  280. package/src/visit/visit-history-table/visit-actions-cell.scss +4 -0
  281. package/src/visit/visit-history-table/visit-date-cell.component.tsx +19 -0
  282. package/src/visit/visit-history-table/visit-diagnoses-cell.component.tsx +18 -0
  283. package/src/visit/visit-history-table/visit-history-table.component.tsx +145 -0
  284. package/src/visit/visit-history-table/visit-history-table.scss +25 -0
  285. package/src/visit/visit-history-table/visit-type-cell.component.tsx +15 -0
  286. package/src/visit/visit-prompt/delete-visit-dialog.modal.tsx +46 -0
  287. package/src/visit/visit-prompt/delete-visit-dialog.test.tsx +79 -0
  288. package/src/visit/visit-prompt/end-visit-dialog.modal.tsx +82 -0
  289. package/src/visit/visit-prompt/end-visit-dialog.scss +7 -0
  290. package/src/visit/visit-prompt/end-visit-dialog.test.tsx +131 -0
  291. package/src/visit/visit-prompt/modify-visit-date.modal.tsx +40 -0
  292. package/src/visit/visit-prompt/start-visit-dialog.modal.tsx +64 -0
  293. package/src/visit/visit-prompt/start-visit-dialog.scss +10 -0
  294. package/src/visit/visit-prompt/start-visit-dialog.test.tsx +40 -0
  295. package/src/visit/visits-widget/active-visit-buttons/active-visit-buttons.scss +7 -0
  296. package/src/visit/visits-widget/active-visit-buttons/active-visit-buttons.tsx +178 -0
  297. package/src/visit/visits-widget/current-visit-summary.extension.tsx +48 -0
  298. package/src/visit/visits-widget/current-visit-summary.scss +10 -0
  299. package/src/visit/visits-widget/current-visit-summary.test.tsx +85 -0
  300. package/src/visit/visits-widget/encounter-observations/encounter-observations.component.tsx +67 -0
  301. package/src/visit/visits-widget/encounter-observations/index.ts +3 -0
  302. package/src/visit/visits-widget/encounter-observations/styles.scss +22 -0
  303. package/src/visit/visits-widget/past-visits-components/delete-encounter.modal.tsx +47 -0
  304. package/src/visit/visits-widget/past-visits-components/delete-encounter.scss +9 -0
  305. package/src/visit/visits-widget/past-visits-components/encounters-table/all-encounters-table.component.tsx +49 -0
  306. package/src/visit/visits-widget/past-visits-components/encounters-table/completed-forms-table.component.tsx +67 -0
  307. package/src/visit/visits-widget/past-visits-components/encounters-table/completed-forms-table.test.tsx +146 -0
  308. package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.component.tsx +452 -0
  309. package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.resource.test.ts +156 -0
  310. package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.resource.ts +215 -0
  311. package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.scss +113 -0
  312. package/src/visit/visits-widget/past-visits-components/encounters-table/encounters-table.test.tsx +432 -0
  313. package/src/visit/visits-widget/past-visits-components/encounters-table/visit-completed-forms-table.component.tsx +61 -0
  314. package/src/visit/visits-widget/past-visits-components/encounters-table/visit-completed-forms-table.test.tsx +125 -0
  315. package/src/visit/visits-widget/past-visits-components/encounters-table/visit-encounters-table.component.tsx +47 -0
  316. package/src/visit/visits-widget/past-visits-components/medications-summary.component.tsx +163 -0
  317. package/src/visit/visits-widget/past-visits-components/notes-summary.component.tsx +66 -0
  318. package/src/visit/visits-widget/past-visits-components/patient-notes-summary.component.tsx +318 -0
  319. package/src/visit/visits-widget/past-visits-components/tests-summary.component.tsx +16 -0
  320. package/src/visit/visits-widget/past-visits-components/visit-summary.component.tsx +192 -0
  321. package/src/visit/visits-widget/past-visits-components/visit-summary.scss +72 -0
  322. package/src/visit/visits-widget/past-visits-components/visit-summary.test.tsx +105 -0
  323. package/src/visit/visits-widget/single-visit-details/visit-timeline/visit-timeline.component.tsx +94 -0
  324. package/src/visit/visits-widget/single-visit-details/visit-timeline/visit-timeline.scss +60 -0
  325. package/src/visit/visits-widget/visit-context/retrospective-data-date-time-picker/restrospective-date-time-picker.scss +35 -0
  326. package/src/visit/visits-widget/visit-context/retrospective-data-date-time-picker/retrospective-date-time-picker.component.tsx +140 -0
  327. package/src/visit/visits-widget/visit-context/visit-context-header.extension.tsx +61 -0
  328. package/src/visit/visits-widget/visit-context/visit-context-header.scss +45 -0
  329. package/src/visit/visits-widget/visit-context/visit-context-header.test.tsx +59 -0
  330. package/src/visit/visits-widget/visit-context/visit-context-info.component.tsx +37 -0
  331. package/src/visit/visits-widget/visit-context/visit-context-info.scss +12 -0
  332. package/src/visit/visits-widget/visit-context/visit-context-switcher.modal.tsx +166 -0
  333. package/src/visit/visits-widget/visit-context/visit-context-switcher.scss +83 -0
  334. package/src/visit/visits-widget/visit-context/visit-context-switcher.test.tsx +79 -0
  335. package/src/visit/visits-widget/visit-detail-overview.component.tsx +67 -0
  336. package/src/visit/visits-widget/visit-detail-overview.scss +301 -0
  337. package/src/visit/visits-widget/visit-detail-overview.test.tsx +205 -0
  338. package/src/visit/visits-widget/visit.resource.tsx +146 -0
  339. package/translations/am.json +209 -0
  340. package/translations/ar.json +209 -0
  341. package/translations/ar_SY.json +209 -0
  342. package/translations/bn.json +209 -0
  343. package/translations/cs.json +209 -0
  344. package/translations/de.json +209 -0
  345. package/translations/en.json +209 -0
  346. package/translations/en_US.json +209 -0
  347. package/translations/es.json +209 -0
  348. package/translations/es_MX.json +209 -0
  349. package/translations/fr.json +209 -0
  350. package/translations/he.json +209 -0
  351. package/translations/hi.json +209 -0
  352. package/translations/hi_IN.json +209 -0
  353. package/translations/id.json +209 -0
  354. package/translations/it.json +209 -0
  355. package/translations/ka.json +209 -0
  356. package/translations/km.json +209 -0
  357. package/translations/ku.json +209 -0
  358. package/translations/ky.json +209 -0
  359. package/translations/lg.json +209 -0
  360. package/translations/ne.json +209 -0
  361. package/translations/pl.json +209 -0
  362. package/translations/pt.json +209 -0
  363. package/translations/pt_BR.json +209 -0
  364. package/translations/qu.json +209 -0
  365. package/translations/ro_RO.json +209 -0
  366. package/translations/ru_RU.json +209 -0
  367. package/translations/si.json +209 -0
  368. package/translations/sq.json +209 -0
  369. package/translations/sw.json +209 -0
  370. package/translations/sw_KE.json +209 -0
  371. package/translations/tr.json +209 -0
  372. package/translations/tr_TR.json +209 -0
  373. package/translations/uk.json +209 -0
  374. package/translations/uz.json +209 -0
  375. package/translations/uz@Latn.json +209 -0
  376. package/translations/uz_UZ.json +209 -0
  377. package/translations/vi.json +209 -0
  378. package/translations/zh.json +209 -0
  379. package/translations/zh_CN.json +209 -0
  380. package/translations/zh_TW.json +209 -0
  381. package/tsconfig.json +4 -0
  382. package/vitest.config.ts +4 -0
@@ -0,0 +1,305 @@
1
+ import { type ReactElement } from 'react';
2
+ import { type OpenmrsResource } from '@openmrs/esm-framework';
3
+
4
+ export type TableHeaderType = {
5
+ key: string;
6
+ header: string;
7
+ };
8
+
9
+ export interface Encounter extends OpenmrsResource {
10
+ encounterDatetime: string;
11
+ encounterType: { uuid: string; name: string };
12
+ patient: {
13
+ uuid: string;
14
+ display: string;
15
+ age: number;
16
+ birthDate: string;
17
+ };
18
+ location: {
19
+ uuid: string;
20
+ display: string;
21
+ name: string;
22
+ };
23
+ encounterProviders?: Array<{ encounterRole: string; provider: { uuid: string; name: string } }>;
24
+ obs: Array<Observation>;
25
+ form?: {
26
+ uuid: string;
27
+ };
28
+ visit?: {
29
+ uuid: string;
30
+ startDatetime: string;
31
+ stopDatetime?: string;
32
+ visitType?: {
33
+ uuid: string;
34
+ display: string;
35
+ };
36
+ };
37
+ }
38
+
39
+ export interface Observation {
40
+ uuid: string;
41
+ concept: { uuid: string; name: string; units?: string };
42
+ value:
43
+ | {
44
+ uuid: string;
45
+ name: {
46
+ name: string;
47
+ display?: string;
48
+ };
49
+ names?: Array<{ uuid: string; name: string; conceptNameType: string }>;
50
+ }
51
+ | string;
52
+ groupMembers?: Array<Observation>;
53
+ obsDatetime: string;
54
+ }
55
+
56
+ export interface ListResponse<T> {
57
+ results: Array<T>;
58
+ }
59
+
60
+ export interface Privilege {
61
+ uuid: string;
62
+ name: string;
63
+ display?: string;
64
+ description?: string;
65
+ }
66
+
67
+ export interface EncounterType {
68
+ uuid: string;
69
+ name: string;
70
+ viewPrivilege: Privilege | null;
71
+ editPrivilege: Privilege | null;
72
+ }
73
+
74
+ export interface Form {
75
+ uuid: string;
76
+ encounterType?: EncounterType;
77
+ name: string;
78
+ display?: string;
79
+ version: string;
80
+ published: boolean;
81
+ retired: boolean;
82
+ resources: Array<FormEncounterResource>;
83
+ formCategory?: string;
84
+ }
85
+
86
+ export interface FormEncounterResource {
87
+ uuid: string;
88
+ name: string;
89
+ dataType: string;
90
+ valueReference: string;
91
+ }
92
+
93
+ export interface EncounterWithFormRef {
94
+ uuid: string;
95
+ encounterType?: EncounterType;
96
+ encounterDatetime: string;
97
+ form?: Form;
98
+ }
99
+
100
+ export interface CompletedFormInfo {
101
+ form: Form;
102
+ associatedEncounters: Array<EncounterWithFormRef>;
103
+ lastCompleted?: Date;
104
+ }
105
+
106
+ export interface HtmlFormEntryForm {
107
+ formUuid: string;
108
+ formName: string;
109
+ formUiResource: string;
110
+ formUiPage: 'enterHtmlFormWithSimpleUi' | 'enterHtmlFormWithStandardUi';
111
+ formEditUiPage: 'editHtmlFormWithSimpleUi' | 'editHtmlFormWithStandardUi';
112
+ }
113
+
114
+ export interface FormsSection {
115
+ name: string;
116
+ forms: Array<string>;
117
+ }
118
+
119
+ export interface ConfigObject {
120
+ htmlFormEntryForms: Array<HtmlFormEntryForm>;
121
+ formSections: Array<FormsSection>;
122
+ customFormsUrl: string;
123
+ orderBy: 'name' | 'most-recent';
124
+ showHtmlFormEntryForms: boolean;
125
+ }
126
+
127
+ // encounter list types
128
+
129
+ export interface ActionProps {
130
+ mode: string;
131
+ label: string;
132
+ formName: string;
133
+ intent?: string;
134
+ }
135
+
136
+ export interface ConditionalActionProps {
137
+ mode: string;
138
+ label: string;
139
+ formName: string;
140
+ dependsOn?: string;
141
+ dependantConcept?: string;
142
+ dependantEncounter?: string;
143
+ intent?: string;
144
+ }
145
+
146
+ export interface ColumnDefinition {
147
+ id: string;
148
+ title: string;
149
+ isComplex?: boolean;
150
+ concept?: string;
151
+ secondaryConcept?: string;
152
+ multipleConcepts?: Array<string>;
153
+ fallbackConcepts?: Array<string>;
154
+ actionOptions?: Array<ActionProps>;
155
+ conditionalActionOptions?: Array<ConditionalActionProps>;
156
+ isDate?: boolean;
157
+ isTrueFalseConcept?: boolean;
158
+ type?: EncounterPropertyType;
159
+ isLink?: boolean;
160
+ useMultipleObs?: boolean;
161
+ valueMappings?: Record<string, string>;
162
+ conceptMappings?: Array<string>;
163
+ statusColorMappings?: Record<string, string>;
164
+ isConditionalConcept?: boolean;
165
+ conditionalConceptMappings?: Record<string, string>;
166
+ conditionalEncounterMappings?: Record<string, ConditionalEncounterMapping>;
167
+ encounterType: string;
168
+ hasSummary?: boolean;
169
+ summaryConcept?: SummaryConcept;
170
+ }
171
+
172
+ export interface ConditionalEncounterMapping {
173
+ concept: string;
174
+ isDate?: boolean;
175
+ }
176
+
177
+ interface LaunchOptions {
178
+ displayText: string;
179
+ hideFormLauncher?: boolean;
180
+ }
181
+ export interface TabSchema {
182
+ tabName: string;
183
+ hasFilter?: boolean;
184
+ headerTitle: string;
185
+ displayText: string;
186
+ encounterType: string;
187
+ columns: Array<ColumnDefinition>;
188
+ formList: Array<{ name: string; uuid: string; fixedIntent?: string; excludedIntents?: Array<string> }>;
189
+ launchOptions: LaunchOptions;
190
+ }
191
+
192
+ export type Mode = 'edit' | 'view' | 'delete';
193
+
194
+ export interface Action {
195
+ label: string;
196
+ mode: Mode;
197
+ form?: { name: string };
198
+ intent?: string;
199
+ }
200
+
201
+ export interface TableRow {
202
+ id: string;
203
+ actions?: ReactElement;
204
+ }
205
+
206
+ export interface FormColumn {
207
+ form: { name: string };
208
+ encounterUuid: string;
209
+ intent: string;
210
+ label: string;
211
+ mode: string;
212
+ }
213
+
214
+ export type NamedColumn =
215
+ | string
216
+ | {
217
+ uuid: string;
218
+ name: { name: string };
219
+ names?: { uuid: string; name: string; conceptNameType: string }[];
220
+ };
221
+
222
+ export type ColumnValue = string | number | JSX.Element | NamedColumn | Array<NamedColumn> | Array<FormColumn> | null;
223
+
224
+ export interface ConfigConcepts {
225
+ trueConceptUuid: string;
226
+ falseConceptUuid: string;
227
+ otherConceptUuid: string;
228
+ }
229
+
230
+ export interface FormattedColumn {
231
+ key: string;
232
+ header: string;
233
+ getValue: (encounter: Encounter) => ColumnValue;
234
+ link?: { getUrl: (encounter: Encounter) => string; handleNavigate?: (encounter: Encounter) => void };
235
+ concept?: string;
236
+ }
237
+
238
+ export interface EncounterTileColumn {
239
+ key: string;
240
+ header: string;
241
+ encounterTypeUuid: string;
242
+ concept: string;
243
+ title?: string;
244
+ getObsValue: (encounter: Encounter) => string;
245
+ getSummaryObsValue?: (encounter: Encounter) => string;
246
+ encounter?: Encounter;
247
+ hasSummary?: boolean;
248
+ summaryConcept?: SummaryConcept;
249
+ }
250
+ export interface EncounterTileProps {
251
+ patientUuid: string;
252
+ columns: Array<EncounterTileColumn>;
253
+ headerTitle: string;
254
+ }
255
+
256
+ export interface MenuCardProps {
257
+ tileHeader: string;
258
+ columns: Array<ColumnDefinition>;
259
+ }
260
+
261
+ interface SummaryConcept {
262
+ primaryConcept: string;
263
+ secondaryConcept?: string;
264
+ isDate?: boolean;
265
+ hasCalculatedDate?: boolean;
266
+ type?: EncounterPropertyType;
267
+ }
268
+
269
+ export interface FormattedCardColumn {
270
+ key: string;
271
+ header: string;
272
+ concept: string;
273
+ encounterUuid: string;
274
+ title?: string;
275
+ getObsValue: (encounter: Encounter) => string;
276
+ getSummaryObsValue?: (encounter: Encounter) => string;
277
+ hasSummary: boolean;
278
+ }
279
+
280
+ export interface ConfigConcepts {
281
+ trueConceptUuid: string;
282
+ falseConceptUuid: string;
283
+ otherConceptUuid: string;
284
+ }
285
+
286
+ export enum EncounterPropertyType {
287
+ location = 'location',
288
+ provider = 'provider',
289
+ encounterType = 'encounterType',
290
+ visitType = 'visitType',
291
+ ageAtEncounter = 'ageAtEncounter',
292
+ visitDate = 'visitDate',
293
+ encounterDatetime = 'encounterDatetime',
294
+ }
295
+
296
+ export interface GetObsFromEncounterParams {
297
+ encounter: Encounter;
298
+ obsConcept: string;
299
+ isDate?: boolean;
300
+ isTrueFalseConcept?: boolean;
301
+ type?: EncounterPropertyType;
302
+ fallbackConcepts?: Array<string>;
303
+ secondaryConcept?: string;
304
+ config?: ConfigConcepts;
305
+ }
@@ -0,0 +1,24 @@
1
+ import type { Encounter } from '../types';
2
+
3
+ /**
4
+ * Helper function to extract units from an encounter for a specific concept
5
+ * @param encounter The encounter containing observations
6
+ * @param conceptUuid The concept UUID to find
7
+ * @returns The units string if found
8
+ */
9
+ export function getConceptUnitsFromEncounter(encounter: Encounter | null, conceptUuid: string): string {
10
+ if (!encounter || !encounter.obs || !conceptUuid) {
11
+ return '';
12
+ }
13
+
14
+ // Find the observation for this concept
15
+ const obs = encounter.obs.find((o) => o.concept?.uuid === conceptUuid);
16
+
17
+ // Return the units if found
18
+ return obs?.concept?.units || '';
19
+ }
20
+
21
+ export const withUnit = (value: string | number, unit: string | null | undefined) => {
22
+ if (!value || value === '--') return value;
23
+ return unit ? `${value} ${unit}` : value;
24
+ };
@@ -0,0 +1,160 @@
1
+ import {
2
+ getObsFromEncounter,
3
+ getMultipleObsFromEncounter,
4
+ resolveValueUsingMappings,
5
+ getConceptFromMappings,
6
+ getConditionalConceptValue,
7
+ } from './helpers';
8
+ import {
9
+ type Encounter,
10
+ type ColumnDefinition,
11
+ type TabSchema,
12
+ type ActionProps,
13
+ type ConditionalActionProps,
14
+ type ColumnValue,
15
+ type NamedColumn,
16
+ type ConfigConcepts,
17
+ } from '../types';
18
+ import { renderTag } from '../encounter-list/tag.component';
19
+ import type { TFunction } from 'i18next';
20
+
21
+ export interface FormattedColumn {
22
+ key: string;
23
+ header: string;
24
+ getValue: (encounter: Encounter) => ColumnValue;
25
+ link?: { getUrl: (encounter: Encounter) => string; handleNavigate?: (encounter: Encounter) => void };
26
+ concept?: string;
27
+ }
28
+
29
+ const getColumnValue = (
30
+ encounter: Encounter,
31
+ column: ColumnDefinition,
32
+ config: ConfigConcepts,
33
+ t: TFunction,
34
+ ): ColumnValue => {
35
+ if (column.id === 'actions') {
36
+ return getActions(encounter, column, config);
37
+ }
38
+ if (column.statusColorMappings) {
39
+ return renderTag(encounter, column.concept, column.statusColorMappings, config);
40
+ }
41
+
42
+ if (column.isConditionalConcept) {
43
+ return getConditionalConceptValue(encounter, column.conditionalConceptMappings, column.isDate, config);
44
+ }
45
+
46
+ if (column.useMultipleObs) {
47
+ return getMultipleObsFromEncounter(encounter, column.multipleConcepts, config);
48
+ }
49
+
50
+ if (column.valueMappings) {
51
+ const resolvedValue = resolveValueUsingMappings(encounter, column.concept, column.valueMappings, t);
52
+ if (resolvedValue !== null && resolvedValue !== undefined) {
53
+ return resolvedValue;
54
+ }
55
+ }
56
+
57
+ if (column.conceptMappings) {
58
+ return getMappedConceptValue(encounter, column, config);
59
+ }
60
+
61
+ return getObsFromEncounter({
62
+ encounter: encounter,
63
+ obsConcept: column.concept,
64
+ isDate: column.isDate,
65
+ isTrueFalseConcept: column.isTrueFalseConcept,
66
+ type: column.type,
67
+ fallbackConcepts: column.fallbackConcepts,
68
+ secondaryConcept: column.secondaryConcept,
69
+ config: config,
70
+ });
71
+ };
72
+
73
+ const createActionObject = (encounter: Encounter, action: ActionProps | ConditionalActionProps) => ({
74
+ form: { name: action.formName },
75
+ encounterUuid: encounter.uuid,
76
+ intent: action.intent || '*',
77
+ label: action.label,
78
+ mode: action.mode,
79
+ });
80
+
81
+ const getActions = (encounter: Encounter, column: ColumnDefinition, config: ConfigConcepts) => {
82
+ const baseActions = column.actionOptions?.map((action: ActionProps) => createActionObject(encounter, action)) || [];
83
+
84
+ const conditionalActions =
85
+ column.conditionalActionOptions
86
+ ?.map((action) => createConditionalAction(encounter, action, config))
87
+ .filter(Boolean) || [];
88
+
89
+ return [...baseActions, ...conditionalActions];
90
+ };
91
+
92
+ const createConditionalAction = (encounter: Encounter, action: ConditionalActionProps, config: ConfigConcepts) => {
93
+ const dependantObsValue = getObsFromEncounter({
94
+ encounter: encounter,
95
+ obsConcept: action.dependantConcept,
96
+ config: config,
97
+ });
98
+ if (dependantObsValue === action.dependsOn) {
99
+ return createActionObject(encounter, action);
100
+ }
101
+
102
+ const dependantEncounterValue = encounter.encounterType?.uuid;
103
+ if (dependantEncounterValue === action.dependantEncounter) {
104
+ return createActionObject(encounter, action);
105
+ }
106
+
107
+ return null;
108
+ };
109
+
110
+ const getMappedConceptValue = (encounter: Encounter, column: ColumnDefinition, config: ConfigConcepts): NamedColumn => {
111
+ const concept = getConceptFromMappings(encounter, column.conceptMappings);
112
+ return getObsFromEncounter({
113
+ encounter: encounter,
114
+ obsConcept: concept,
115
+ isDate: column.isDate,
116
+ isTrueFalseConcept: column.isTrueFalseConcept,
117
+ type: column.type,
118
+ fallbackConcepts: column.fallbackConcepts,
119
+ secondaryConcept: column.secondaryConcept,
120
+ config: config,
121
+ });
122
+ };
123
+
124
+ export const getTabColumns = (columnsDefinition: Array<ColumnDefinition>, config: ConfigConcepts, t: TFunction) => {
125
+ const columns: Array<FormattedColumn> = columnsDefinition.map((column: ColumnDefinition) => ({
126
+ key: column.id,
127
+ header: column.title,
128
+ concept: column.concept,
129
+ getValue: (encounter) => getColumnValue(encounter, column, config, t),
130
+ link: column.isLink
131
+ ? {
132
+ getUrl: (encounter) => encounter.url,
133
+ handleNavigate: (encounter) => encounter.launchFormActions?.viewEncounter(),
134
+ }
135
+ : null,
136
+ }));
137
+
138
+ return columns;
139
+ };
140
+
141
+ export const getMenuItemTabsConfiguration = (
142
+ tabDefinitions: Array<TabSchema>,
143
+ config: ConfigConcepts,
144
+ t: TFunction,
145
+ ) => {
146
+ const tabs = tabDefinitions.map((tab) => {
147
+ return {
148
+ name: tab.tabName,
149
+ hasFilter: tab.hasFilter || false,
150
+ encounterType: tab.encounterType,
151
+ headerTitle: tab.headerTitle,
152
+ description: tab.displayText,
153
+ formList: tab.formList,
154
+ columns: getTabColumns(tab.columns, config, t),
155
+ launchOptions: tab.launchOptions,
156
+ };
157
+ });
158
+
159
+ return tabs;
160
+ };
@@ -0,0 +1,26 @@
1
+ import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
2
+
3
+ export function fetchOpenMRSForms(formUuid: string) {
4
+ return openmrsFetch(`${restBaseUrl}/form/${formUuid}`).then(({ data }) => {
5
+ if (data.results.length) {
6
+ return data.results;
7
+ }
8
+ return null;
9
+ });
10
+ }
11
+
12
+ export function fetchPatientRelationships(patientUuid: string) {
13
+ return openmrsFetch(`${restBaseUrl}relationship?person=${patientUuid}&v=full`).then(({ data }) => {
14
+ if (data.results.length) {
15
+ return data.results;
16
+ }
17
+ return null;
18
+ });
19
+ }
20
+
21
+ export function deleteEncounter(encounterUuid: string, abortController: AbortController) {
22
+ return openmrsFetch(`${restBaseUrl}/encounter/${encounterUuid}`, {
23
+ method: 'DELETE',
24
+ signal: abortController.signal,
25
+ });
26
+ }