@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
package/src/index.ts ADDED
@@ -0,0 +1,204 @@
1
+ import { defineConfigSchema, getAsyncLifecycle, getSyncLifecycle } from '@openmrs/esm-framework';
2
+ import * as Framework from '@openmrs/esm-framework';
3
+ import { createDashboardLink } from '@openmrs/esm-patient-common-lib';
4
+ import { esmPatientChartSchema } from './config-schema';
5
+ import { moduleName } from './constants';
6
+ import { setupCacheableRoutes, setupOfflineVisitsSync } from './offline';
7
+ import { summaryDashboardMeta, encountersDashboardMeta } from './dashboard.meta';
8
+ import deleteVisitActionButtonComponent from './actions-buttons/delete-visit.component';
9
+ import currentVisitSummaryComponent from './visit/visits-widget/current-visit-summary.extension';
10
+ import markPatientAliveActionButtonComponent from './actions-buttons/mark-patient-alive.component';
11
+ import markPatientDeceasedActionButtonComponent from './actions-buttons/mark-patient-deceased.component';
12
+ import pastVisitsOverviewComponent from './visit/visits-widget/visit-detail-overview.component';
13
+ import patientChartPageComponent from './root.component';
14
+ import patientDetailsTileComponent from './patient-details-tile/patient-details-tile.component';
15
+ import startVisitActionButtonComponent from './actions-buttons/start-visit.component';
16
+ import startVisitActionButtonOnPatientSearch from './visit/start-visit-button.component';
17
+ import stopVisitActionButtonComponent from './actions-buttons/stop-visit.component';
18
+ import visitAttributeTagsComponent from './patient-banner-tags/visit-attribute-tags.extension';
19
+
20
+ // This allows @openmrs/esm-framework to be accessed by modules that are not
21
+ // using webpack. This is used for ngx-formentry.
22
+ window['_openmrs_esm_framework'] = Framework;
23
+
24
+ export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');
25
+
26
+ export function startupApp() {
27
+ setupOfflineVisitsSync();
28
+ setupCacheableRoutes();
29
+
30
+ defineConfigSchema(moduleName, esmPatientChartSchema);
31
+ }
32
+
33
+ export const root = getSyncLifecycle(patientChartPageComponent, { featureName: 'patient-chart', moduleName });
34
+
35
+ export const patientSummaryDashboardLink =
36
+ // t('Patient Summary', 'Patient Summary')
37
+ getSyncLifecycle(
38
+ createDashboardLink({
39
+ ...summaryDashboardMeta,
40
+ }),
41
+ {
42
+ featureName: 'summary-dashboard',
43
+ moduleName,
44
+ },
45
+ );
46
+
47
+ export const markPatientAliveActionButton = getSyncLifecycle(markPatientAliveActionButtonComponent, {
48
+ featureName: 'patient-action-mark-alive',
49
+ moduleName,
50
+ });
51
+
52
+ export const markPatientDeceasedActionButton = getSyncLifecycle(markPatientDeceasedActionButtonComponent, {
53
+ featureName: 'patient-action-mark-deceased',
54
+ moduleName,
55
+ });
56
+
57
+ export const startVisitActionButton = getSyncLifecycle(startVisitActionButtonComponent, {
58
+ featureName: 'patient-action-start-visit',
59
+ moduleName,
60
+ });
61
+
62
+ export const stopVisitActionButton = getSyncLifecycle(stopVisitActionButtonComponent, {
63
+ featureName: 'patient-action-stop-visit',
64
+ moduleName,
65
+ });
66
+
67
+ export const deleteVisitActionMenuButton = getSyncLifecycle(deleteVisitActionButtonComponent, {
68
+ featureName: 'patient-action-delete-visit',
69
+ moduleName,
70
+ });
71
+
72
+ export const startVisitPatientSearchActionButton = getSyncLifecycle(startVisitActionButtonOnPatientSearch, {
73
+ featureName: 'patient-search-action-start-visit',
74
+ moduleName,
75
+ });
76
+
77
+ export const stopVisitPatientSearchActionButton = getSyncLifecycle(stopVisitActionButtonComponent, {
78
+ featureName: 'patient-search-action-stop-visit',
79
+ moduleName,
80
+ });
81
+
82
+ export const clinicalViewsSummary = getAsyncLifecycle(
83
+ () => import('./clinical-views/encounter-tile/clinical-views-summary.component'),
84
+ { featureName: 'clinical-views-summary', moduleName },
85
+ );
86
+
87
+ export const encountersSummaryDashboardLink =
88
+ // t('Visits', 'Visits')
89
+ getSyncLifecycle(
90
+ createDashboardLink({
91
+ ...encountersDashboardMeta,
92
+ }),
93
+ { featureName: 'encounter', moduleName },
94
+ );
95
+
96
+ export const currentVisitSummary = getSyncLifecycle(currentVisitSummaryComponent, {
97
+ featureName: 'current-visit-summary',
98
+ moduleName,
99
+ });
100
+
101
+ export const pastVisitsDetailOverview = getSyncLifecycle(pastVisitsOverviewComponent, {
102
+ featureName: 'visits-detail-overview',
103
+ moduleName,
104
+ });
105
+
106
+ export const patientDetailsTile = getSyncLifecycle(patientDetailsTileComponent, {
107
+ featureName: 'patient-details-tile',
108
+ moduleName,
109
+ });
110
+
111
+ export const visitAttributeTags = getSyncLifecycle(visitAttributeTagsComponent, {
112
+ featureName: 'visit-attribute-tags',
113
+ moduleName,
114
+ });
115
+
116
+ export const startVisitWorkspace = getAsyncLifecycle(() => import('./visit/visit-form/visit-form.workspace'), {
117
+ featureName: 'start-visit-form',
118
+ moduleName,
119
+ });
120
+
121
+ export const exportedVisitForm = getAsyncLifecycle(() => import('./visit/visit-form/exported-visit-form.workspace'), {
122
+ featureName: 'exported-visit-form',
123
+ moduleName,
124
+ });
125
+
126
+ // t('markPatientDeceased', 'Mark patient deceased')
127
+ export const markPatientDeceasedForm = getAsyncLifecycle(
128
+ () => import('./mark-patient-deceased/mark-patient-deceased-form.workspace'),
129
+ {
130
+ featureName: 'mark-patient-deceased-form',
131
+ moduleName,
132
+ },
133
+ );
134
+
135
+ export const startVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/start-visit-dialog.modal'), {
136
+ featureName: 'start visit',
137
+ moduleName,
138
+ });
139
+
140
+ export const deleteVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/delete-visit-dialog.modal'), {
141
+ featureName: 'delete visit',
142
+ moduleName,
143
+ });
144
+
145
+ export const modifyVisitDateModal = getAsyncLifecycle(() => import('./visit/visit-prompt/modify-visit-date.modal'), {
146
+ featureName: 'modify visit date',
147
+ moduleName,
148
+ });
149
+
150
+ export const endVisitModal = getAsyncLifecycle(() => import('./visit/visit-prompt/end-visit-dialog.modal'), {
151
+ featureName: 'end visit',
152
+ moduleName,
153
+ });
154
+
155
+ export const markPatientAliveModal = getAsyncLifecycle(() => import('./mark-patient-alive/mark-patient-alive.modal'), {
156
+ featureName: 'mark patient alive',
157
+ moduleName,
158
+ });
159
+
160
+ export const deleteEncounterModal = getAsyncLifecycle(
161
+ () => import('./visit/visits-widget/past-visits-components/delete-encounter.modal'),
162
+ {
163
+ featureName: 'delete-encounter-modal',
164
+ moduleName,
165
+ },
166
+ );
167
+
168
+ export const editVisitDetailsActionButton = getAsyncLifecycle(
169
+ () => import('./visit/visit-action-items/edit-visit-details.component'),
170
+ { featureName: 'edit-visit-details', moduleName },
171
+ );
172
+
173
+ export const deleteVisitActionButton = getAsyncLifecycle(
174
+ () => import('./visit/visit-action-items/delete-visit-action-item.component'),
175
+ { featureName: 'delete-visit', moduleName },
176
+ );
177
+
178
+ export const activeVisitActionsComponent = getAsyncLifecycle(
179
+ () => import('./visit/visits-widget/active-visit-buttons/active-visit-buttons'),
180
+ { featureName: 'active-visit-actions', moduleName },
181
+ );
182
+
183
+ export const encounterListTableTabs = getAsyncLifecycle(
184
+ () => import('./clinical-views/encounter-list/encounter-list-tabs.extension'),
185
+ { featureName: 'encounter-list-table-tabs', moduleName },
186
+ );
187
+
188
+ export const visitContextSwitcherModal = getAsyncLifecycle(
189
+ () => import('./visit/visits-widget/visit-context/visit-context-switcher.modal'),
190
+ { featureName: 'visit-context-switcher', moduleName },
191
+ );
192
+
193
+ export const visitContextHeader = getAsyncLifecycle(
194
+ () => import('./visit/visits-widget/visit-context/visit-context-header.extension'),
195
+ { featureName: 'visit-context-header', moduleName },
196
+ );
197
+
198
+ export const retrospectiveDateTimePicker = getAsyncLifecycle(
199
+ () =>
200
+ import(
201
+ './visit/visits-widget/visit-context/retrospective-data-date-time-picker/retrospective-date-time-picker.component'
202
+ ),
203
+ { featureName: 'retrospective-date-time-picker', moduleName },
204
+ );
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { InlineLoading } from '@carbon/react';
4
+ import styles from './loader.scss';
5
+
6
+ const Loader: React.FC = () => {
7
+ const { t } = useTranslation();
8
+ return <InlineLoading className={styles.loading} description={`${t('loading', 'Loading')} ...`} />;
9
+ };
10
+
11
+ export default Loader;
@@ -0,0 +1,9 @@
1
+ @use '@carbon/layout';
2
+ @use '@openmrs/esm-styleguide/src/vars' as *;
3
+
4
+ .loading {
5
+ display: flex;
6
+ background-color: $openmrs-background-grey;
7
+ justify-content: center;
8
+ min-height: layout.$spacing-09;
9
+ }
@@ -0,0 +1,54 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { useSWRConfig } from 'swr';
4
+ import { Button, ModalBody, ModalFooter, ModalHeader } from '@carbon/react';
5
+ import { invalidateCurrentVisit, invalidateVisitAndEncounterData } from '@openmrs/esm-patient-common-lib';
6
+ import { showSnackbar } from '@openmrs/esm-framework';
7
+ import { markPatientAlive } from '../data.resource';
8
+
9
+ interface MarkPatientAliveProps {
10
+ closeModal: () => void;
11
+ patientUuid: string;
12
+ }
13
+
14
+ const MarkPatientAlive: React.FC<MarkPatientAliveProps> = ({ closeModal, patientUuid }) => {
15
+ const { t } = useTranslation();
16
+ const { mutate: globalMutate } = useSWRConfig();
17
+
18
+ const handleSubmit = useCallback(() => {
19
+ closeModal();
20
+
21
+ markPatientAlive(patientUuid)
22
+ .then(() => {
23
+ globalMutate((key) => Array.isArray(key) && key[0] === 'patient' && key[1] === patientUuid);
24
+ invalidateCurrentVisit(globalMutate, patientUuid);
25
+ invalidateVisitAndEncounterData(globalMutate, patientUuid);
26
+ showSnackbar({
27
+ title: t('markAliveSuccessfully', 'Patient marked alive successfully'),
28
+ });
29
+ })
30
+ .catch((error) => {
31
+ showSnackbar({
32
+ title: t('errorMarkingPatientAlive', 'Error marking patient alive'),
33
+ kind: 'error',
34
+ isLowContrast: false,
35
+ subtitle: error?.message,
36
+ });
37
+ });
38
+ }, [closeModal, globalMutate, patientUuid, t]);
39
+
40
+ return (
41
+ <>
42
+ <ModalHeader closeModal={closeModal} title={t('markPatientAlive', 'Mark patient alive')} />
43
+ <ModalBody>{t('markPatientAliveConfirmation', 'Are you sure you want to mark this patient alive?')}</ModalBody>
44
+ <ModalFooter>
45
+ <Button kind="secondary" onClick={closeModal}>
46
+ {t('no', 'No')}
47
+ </Button>
48
+ <Button onClick={handleSubmit}>{t('yes', 'Yes')}</Button>
49
+ </ModalFooter>
50
+ </>
51
+ );
52
+ };
53
+
54
+ export default MarkPatientAlive;
@@ -0,0 +1,175 @@
1
+ @use '@carbon/layout';
2
+ @use '@carbon/type';
3
+ @use '~@openmrs/esm-styleguide/src/vars' as *;
4
+
5
+ .container {
6
+ margin: layout.$spacing-05;
7
+
8
+ & section {
9
+ margin: layout.$spacing-05 0;
10
+ }
11
+ }
12
+
13
+ .heading {
14
+ @include type.type-style('productive-heading-03');
15
+ color: $text-02;
16
+ margin: layout.$spacing-05;
17
+ }
18
+
19
+ .sectionTitle {
20
+ @include type.type-style('productive-heading-02');
21
+ color: $text-02;
22
+ margin: 0 0 layout.$spacing-03 0;
23
+ }
24
+
25
+ .conceptAnswerOverviewWrapper {
26
+ margin: layout.$spacing-03 0;
27
+ border: 0.0625rem solid $grey-2;
28
+ background-color: $ui-01;
29
+
30
+ :global(.cds--tile) {
31
+ border: none !important;
32
+ }
33
+ }
34
+
35
+ .errorOutline {
36
+ outline: 1px solid $danger;
37
+ }
38
+
39
+ .conceptAnswerOverviewWrapper div:nth-child(3) > div:nth-child(2) {
40
+ position: relative;
41
+ }
42
+
43
+ .conceptAnswerOverviewWrapper div:nth-child(3) span * {
44
+ display: none;
45
+ }
46
+
47
+ .radioButtonGroup {
48
+ display: flex;
49
+ flex-direction: column;
50
+ align-items: flex-start;
51
+ margin-top: layout.$spacing-03;
52
+ min-height: layout.$spacing-10;
53
+ width: 100%;
54
+ @include type.type-style('body-short-01');
55
+ color: $text-02;
56
+ background-color: $ui-01;
57
+ }
58
+
59
+ .radioButton {
60
+ padding: layout.$spacing-02 layout.$spacing-05;
61
+ margin: layout.$spacing-03 0;
62
+ }
63
+
64
+ .contentSwitcher {
65
+ height: layout.$spacing-09;
66
+ }
67
+
68
+ .headerGridRow {
69
+ border-bottom: 0.0625rem solid $grey-2;
70
+ margin: 0;
71
+ }
72
+
73
+ .dataGridRow {
74
+ display: grid;
75
+ grid-template-columns: 50% 10% 1fr;
76
+ margin: layout.$spacing-03 layout.$spacing-05;
77
+ }
78
+
79
+ .form {
80
+ display: flex;
81
+ flex-direction: column;
82
+ justify-content: space-between;
83
+ height: 100%;
84
+ }
85
+
86
+ .button {
87
+ height: layout.$spacing-10;
88
+ display: flex;
89
+ align-content: flex-start;
90
+ align-items: baseline;
91
+ min-width: 50%;
92
+
93
+ :global(.cds--inline-loading) {
94
+ min-height: layout.$spacing-05;
95
+ }
96
+
97
+ :global(.cds--inline-loading__text) {
98
+ font-size: unset;
99
+ }
100
+ }
101
+
102
+ .conceptAnswerOverviewWrapperTablet {
103
+ padding: layout.$spacing-06 layout.$spacing-05;
104
+ background-color: $ui-02;
105
+ }
106
+
107
+ .conceptAnswerOverviewWrapperDesktop {
108
+ padding: 0;
109
+ }
110
+
111
+ .warningContainer {
112
+ display: flex;
113
+ background-color: $warning-background;
114
+ padding: layout.$spacing-05;
115
+ align-items: center;
116
+ }
117
+
118
+ .warningIcon {
119
+ display: flex;
120
+ align-self: center;
121
+ fill: $inverse-support-03;
122
+ margin-right: layout.$spacing-03;
123
+ align-self: start;
124
+ }
125
+
126
+ .warningText {
127
+ font-size: 0.875rem;
128
+ }
129
+
130
+ .datePicker {
131
+ padding-bottom: layout.$spacing-03;
132
+ width: 100%;
133
+ }
134
+
135
+ .errorMessage {
136
+ @include type.type-style('label-02');
137
+ color: $danger;
138
+ }
139
+
140
+ .nonCodedCauseOfDeath {
141
+ margin: layout.$spacing-05;
142
+ }
143
+
144
+ .skeleton {
145
+ :global(.cds--structured-list-tbody .cds--structured-list-row:last-child) {
146
+ border-bottom: none;
147
+ }
148
+ }
149
+
150
+ .tileContainer {
151
+ background-color: $ui-02;
152
+ padding: layout.$spacing-09 0;
153
+ }
154
+
155
+ .tile {
156
+ margin: auto;
157
+ width: fit-content;
158
+ }
159
+
160
+ .tileContent {
161
+ display: flex;
162
+ flex-direction: column;
163
+ align-items: center;
164
+ }
165
+
166
+ .content {
167
+ @include type.type-style('heading-compact-02');
168
+ color: $text-02;
169
+ margin-bottom: layout.$spacing-03;
170
+ }
171
+
172
+ .helper {
173
+ @include type.type-style('body-compact-01');
174
+ color: $text-02;
175
+ }
@@ -0,0 +1,203 @@
1
+ import React from 'react';
2
+ import { vi, describe, it, expect, beforeEach, afterAll } from 'vitest';
3
+ import userEvent from '@testing-library/user-event';
4
+ import { render, screen } from '@testing-library/react';
5
+ import { getDefaultsFromConfigSchema, showSnackbar, useConfig } from '@openmrs/esm-framework';
6
+ import { esmPatientChartSchema, type ChartConfig } from '../config-schema';
7
+ import { mockPatient } from 'tools';
8
+ import { markPatientDeceased, useCausesOfDeath } from '../data.resource';
9
+ import MarkPatientDeceasedForm from './mark-patient-deceased-form.workspace';
10
+ import { type PatientWorkspace2DefinitionProps } from '@openmrs/esm-patient-common-lib/src';
11
+
12
+ const mockMarkPatientDeceased = vi.mocked(markPatientDeceased);
13
+ const mockUseCausesOfDeath = vi.mocked(useCausesOfDeath);
14
+ const mockUseConfig = vi.mocked(useConfig<ChartConfig>);
15
+ const mockShowSnackbar = vi.mocked(showSnackbar);
16
+ const mockCloseWorkspace = vi.fn();
17
+
18
+ vi.mock('../data.resource', () => ({
19
+ markPatientDeceased: vi.fn().mockResolvedValue({}),
20
+ useCausesOfDeath: vi.fn(),
21
+ }));
22
+
23
+ describe('MarkPatientDeceasedForm', () => {
24
+ const freeTextFieldConceptUuid = '1234e218-6c8a-4ca3-8edb-9f6d9c8c8c7f';
25
+
26
+ const defaultProps: PatientWorkspace2DefinitionProps<{}, {}> = {
27
+ closeWorkspace: mockCloseWorkspace,
28
+ workspaceName: null,
29
+ launchChildWorkspace: vi.fn(),
30
+ windowProps: {},
31
+ workspaceProps: {},
32
+ groupProps: {
33
+ patientUuid: mockPatient.id,
34
+ patient: mockPatient,
35
+ visitContext: null,
36
+ mutateVisitContext: null,
37
+ },
38
+ windowName: '',
39
+ isRootWorkspace: false,
40
+ showActionMenu: true,
41
+ };
42
+
43
+ const codedCausesOfDeath = [
44
+ {
45
+ display: 'Traumatic injury',
46
+ uuid: '8b64f45e-1d5f-4894-b77c-4e1d840e2c99',
47
+ name: 'Traumatic injury',
48
+ },
49
+ {
50
+ display: 'Neoplasm/cancer',
51
+ uuid: 'c4e8d03c-f09b-48d1-8d93-7d84d463f865',
52
+ name: 'Neoplasm/cancer',
53
+ },
54
+ {
55
+ display: 'Infectious disease',
56
+ uuid: 'b7c1c30f-5b9e-4a3d-b943-7f4b3f740e6c',
57
+ name: 'Infectious disease',
58
+ },
59
+ {
60
+ display: 'Other',
61
+ uuid: freeTextFieldConceptUuid,
62
+ name: 'Other',
63
+ },
64
+ ];
65
+
66
+ beforeEach(() => {
67
+ mockUseCausesOfDeath.mockReturnValue({
68
+ causesOfDeath: codedCausesOfDeath,
69
+ isLoading: false,
70
+ isValidating: false,
71
+ });
72
+
73
+ mockUseConfig.mockReturnValue({
74
+ ...getDefaultsFromConfigSchema(esmPatientChartSchema),
75
+ freeTextFieldConceptUuid,
76
+ });
77
+ });
78
+
79
+ afterAll(() => {
80
+ vi.restoreAllMocks();
81
+ });
82
+
83
+ it('renders the cause of death form', () => {
84
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
85
+
86
+ expect(screen.getByRole('img', { name: /warning/i })).toBeInTheDocument();
87
+ expect(
88
+ screen.getByText(/marking the patient as deceased updates this patient's death information/i),
89
+ ).toBeInTheDocument();
90
+ const causes = screen.getAllByText(/cause of death/i);
91
+ expect(causes.length).toBeGreaterThan(0);
92
+ expect(causes[0]).toBeInTheDocument();
93
+ expect(screen.getByRole('searchbox')).toBeInTheDocument();
94
+ expect(screen.getByLabelText(/date/i)).toBeInTheDocument();
95
+
96
+ codedCausesOfDeath.forEach((codedCauseOfDeath) => {
97
+ expect(screen.getByRole('radio', { name: codedCauseOfDeath.display })).toBeInTheDocument();
98
+ });
99
+ expect(screen.getByRole('button', { name: /discard/i })).toBeInTheDocument();
100
+ expect(screen.getByRole('button', { name: /save and close/i })).toBeInTheDocument();
101
+ });
102
+
103
+ it('searches through the list when the user types in the search input', async () => {
104
+ const user = userEvent.setup();
105
+
106
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
107
+
108
+ const searchInput = screen.getByRole('searchbox');
109
+
110
+ await user.type(searchInput, 'totally random text');
111
+ expect(screen.getByText(/no matching coded causes of death/i));
112
+
113
+ await user.clear(searchInput);
114
+ await user.type(searchInput, 'traumatic injury');
115
+
116
+ expect(screen.getByRole('radio', { name: 'Traumatic injury' })).toBeInTheDocument();
117
+ expect(screen.getAllByRole('radio')).toHaveLength(1);
118
+ });
119
+
120
+ it('selecting "Other" as the cause of death requires the user to enter a non-coded cause of death', async () => {
121
+ const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
122
+ const user = userEvent.setup();
123
+
124
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
125
+
126
+ const submitButton = screen.getByRole('button', { name: /save and close/i });
127
+
128
+ await user.click(screen.getByRole('radio', { name: 'Other' }));
129
+ expect(screen.getByRole('textbox', { name: /non-coded cause of death/i })).toBeInTheDocument();
130
+
131
+ await user.click(submitButton);
132
+
133
+ expect(screen.getByText(/please enter the non-coded cause of death/i)).toBeInTheDocument();
134
+
135
+ await user.type(screen.getByRole('textbox', { name: /non\-coded cause of death/i }), 'Septicemia');
136
+ await user.click(submitButton);
137
+
138
+ expect(markPatientDeceased).toHaveBeenCalledWith(
139
+ expect.any(Date),
140
+ '8673ee4f-e2ab-4077-ba55-4980f408773e', // causeOfDeathUuid
141
+ freeTextFieldConceptUuid, // otherCauseOfDeathConceptUuid
142
+ 'Septicemia', // otherCauseOfDeath
143
+ );
144
+ consoleError.mockRestore();
145
+ });
146
+
147
+ it('submits the form with a coded cause of death', async () => {
148
+ const user = userEvent.setup();
149
+
150
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
151
+
152
+ const submitButton = screen.getByRole('button', { name: /save and close/i });
153
+ const traumaticInjuryRadio = screen.getByRole('radio', { name: 'Traumatic injury' });
154
+
155
+ await user.click(traumaticInjuryRadio);
156
+ await user.click(submitButton);
157
+
158
+ expect(markPatientDeceased).toHaveBeenCalledWith(
159
+ expect.any(Date),
160
+ '8673ee4f-e2ab-4077-ba55-4980f408773e',
161
+ '8b64f45e-1d5f-4894-b77c-4e1d840e2c99', // causeOfDeathUuid for Traumatic injury,
162
+ '',
163
+ );
164
+ expect(mockShowSnackbar).toHaveBeenCalledWith({
165
+ title: 'Patient marked deceased successfully',
166
+ });
167
+ });
168
+
169
+ it('renders an error message when saving the cause of death fails', async () => {
170
+ const consoleError = vi.spyOn(console, 'error').mockImplementation(() => {});
171
+ const user = userEvent.setup();
172
+ const mockError = new Error('API Error');
173
+
174
+ mockMarkPatientDeceased.mockRejectedValueOnce(mockError);
175
+
176
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
177
+
178
+ const submitButton = screen.getByRole('button', { name: /save and close/i });
179
+ const traumaticInjuryRadio = screen.getByRole('radio', { name: 'Traumatic injury' });
180
+
181
+ await user.click(traumaticInjuryRadio);
182
+ await user.click(submitButton);
183
+
184
+ expect(mockShowSnackbar).toHaveBeenCalledWith({
185
+ isLowContrast: false,
186
+ kind: 'error',
187
+ subtitle: mockError.message,
188
+ title: 'Error marking patient deceased',
189
+ });
190
+ consoleError.mockRestore();
191
+ });
192
+
193
+ it('clicking the discard button closes the workspace', async () => {
194
+ const user = userEvent.setup();
195
+
196
+ render(<MarkPatientDeceasedForm {...defaultProps} />);
197
+
198
+ const discardButton = screen.getByRole('button', { name: /discard/i });
199
+ await user.click(discardButton);
200
+
201
+ expect(mockCloseWorkspace).toHaveBeenCalledTimes(1);
202
+ });
203
+ });