@kenyaemr/esm-morgue-app 5.4.2-pre.2283 → 5.4.2-pre.2291

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 (193) hide show
  1. package/.turbo/turbo-build.log +19 -19
  2. package/dist/109.js +2 -0
  3. package/dist/109.js.map +1 -0
  4. package/dist/201.js +1 -0
  5. package/dist/201.js.map +1 -0
  6. package/dist/293.js +1 -0
  7. package/dist/293.js.map +1 -0
  8. package/dist/300.js +1 -1
  9. package/dist/347.js +1 -2
  10. package/dist/347.js.map +1 -1
  11. package/dist/373.js +2 -0
  12. package/dist/373.js.map +1 -0
  13. package/dist/38.js +1 -0
  14. package/dist/38.js.map +1 -0
  15. package/dist/389.js +1 -0
  16. package/dist/389.js.map +1 -0
  17. package/dist/398.js +1 -0
  18. package/dist/398.js.map +1 -0
  19. package/dist/4.js +2 -0
  20. package/dist/4.js.map +1 -0
  21. package/dist/410.js +1 -0
  22. package/dist/410.js.map +1 -0
  23. package/dist/420.js +2 -0
  24. package/dist/420.js.map +1 -0
  25. package/dist/467.js +1 -0
  26. package/dist/467.js.map +1 -0
  27. package/dist/632.js +1 -0
  28. package/dist/632.js.map +1 -0
  29. package/dist/798.js +1 -0
  30. package/dist/798.js.map +1 -0
  31. package/dist/811.js +1 -0
  32. package/dist/811.js.map +1 -0
  33. package/dist/824.js +1 -0
  34. package/dist/824.js.map +1 -0
  35. package/dist/827.js +1 -0
  36. package/dist/827.js.map +1 -0
  37. package/dist/842.js +2 -0
  38. package/dist/842.js.LICENSE.txt +5 -0
  39. package/dist/842.js.map +1 -0
  40. package/dist/918.js +1 -1
  41. package/dist/918.js.map +1 -1
  42. package/dist/kenyaemr-esm-morgue-app.js +1 -1
  43. package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +218 -291
  44. package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
  45. package/dist/main.js +2 -1
  46. package/dist/main.js.LICENSE.txt +15 -0
  47. package/dist/main.js.map +1 -1
  48. package/dist/routes.json +1 -1
  49. package/package.json +1 -1
  50. package/src/bed/bed.component.tsx +164 -0
  51. package/src/bed/bed.scss +192 -0
  52. package/src/bed/divider/divider.component.tsx +18 -0
  53. package/src/bed/empty-bed.component.tsx +47 -0
  54. package/src/bed-layout/admitted/admitted-bed-layout.component.tsx +189 -0
  55. package/src/bed-layout/awaiting/awaiting-bed-layout.component.tsx +86 -0
  56. package/src/bed-layout/bed-layout.resource.ts +72 -0
  57. package/src/bed-layout/bed-layout.scss +55 -0
  58. package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +109 -0
  59. package/src/bed-layout/discharged/discharged-bed-layout.resource.ts +99 -0
  60. package/src/bed-linelist-view/admitted/admitted-bed-linelist-view.component.tsx +420 -0
  61. package/src/bed-linelist-view/awaiting/awaiting-bed-linelist-view.component.tsx +224 -0
  62. package/src/bed-linelist-view/bed-linelist-view.scss +5 -0
  63. package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +256 -0
  64. package/src/config-schema.ts +41 -9
  65. package/src/constants.ts +57 -0
  66. package/src/deceased-patient-header/deceased-patient-header.component.tsx +31 -0
  67. package/src/deceased-patient-header/deceased-patient-header.scss +50 -0
  68. package/src/{component → deceased-patient-header}/deceasedInfo/deceased-info.component.tsx +1 -1
  69. package/src/deceased-patient-header/deceasedInfo/deceased-info.resource.ts +11 -0
  70. package/src/extension/actionButton.component.tsx +5 -59
  71. package/src/extension/deceasedInfoBanner.component.tsx +5 -9
  72. package/src/{hook/useAdmitPatient.ts → forms/admit-deceased-person-workspace/admit-deceased-person.resource.ts} +177 -46
  73. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.scss +143 -0
  74. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.workspace.tsx +648 -0
  75. package/src/{hook/usePersonAttributes.ts → forms/discharge-deceased-person-workspace/discharge-body.resource.ts} +1 -1
  76. package/src/forms/discharge-deceased-person-workspace/discharge-body.scss +56 -0
  77. package/src/forms/discharge-deceased-person-workspace/discharge-body.workspace.tsx +362 -0
  78. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.resource.ts +18 -0
  79. package/src/{workspaces/patientAdditionalInfoForm.scss → forms/dispose-deceased-person-workspace/dispose-deceased-person.scss} +46 -66
  80. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.workspace.tsx +401 -0
  81. package/src/forms/form-entry-workspace/form-entry-workspace.workspace.tsx +62 -0
  82. package/src/forms/swap-compartment-workspace/swap-unit.scss +144 -0
  83. package/src/forms/swap-compartment-workspace/swap-unit.workspace.tsx +280 -0
  84. package/src/header/header.component.tsx +41 -0
  85. package/src/header/header.scss +58 -0
  86. package/src/home/home.component.tsx +87 -0
  87. package/src/home/home.resource.ts +261 -0
  88. package/src/home/home.scss +5 -0
  89. package/src/index.ts +18 -12
  90. package/src/metrics/metrics-card.component.tsx +31 -0
  91. package/src/metrics/metrics-card.scss +51 -0
  92. package/src/root.component.tsx +7 -3
  93. package/src/routes.json +25 -14
  94. package/src/schemas/index.ts +66 -0
  95. package/src/summary/summary.component.tsx +42 -0
  96. package/src/summary/summary.scss +10 -0
  97. package/src/switcher/content-switcher.component.tsx +220 -0
  98. package/src/switcher/content-switcher.scss +30 -0
  99. package/src/types/index.ts +336 -359
  100. package/src/utils/utils.ts +20 -2
  101. package/src/view-details/main/main.component.tsx +34 -0
  102. package/src/view-details/main/main.scss +45 -0
  103. package/src/view-details/panels/attachement.component.tsx +21 -0
  104. package/src/view-details/panels/autopsy.component.tsx +215 -0
  105. package/src/view-details/panels/billing-history.component.tsx +13 -0
  106. package/src/view-details/panels/observations/observation.component.tsx +57 -0
  107. package/src/view-details/panels/observations/observation.scss +24 -0
  108. package/src/view-details/panels/panels.scss +46 -0
  109. package/src/view-details/view-details.component.tsx +65 -0
  110. package/src/view-details/view-details.resource.ts +65 -0
  111. package/src/view-details/views-details.scss +82 -0
  112. package/translations/en.json +74 -21
  113. package/tsconfig.json +1 -1
  114. package/dist/113.js +0 -1
  115. package/dist/113.js.map +0 -1
  116. package/dist/160.js +0 -1
  117. package/dist/160.js.map +0 -1
  118. package/dist/299.js +0 -1
  119. package/dist/299.js.map +0 -1
  120. package/dist/433.js +0 -2
  121. package/dist/433.js.map +0 -1
  122. package/dist/441.js +0 -1
  123. package/dist/441.js.map +0 -1
  124. package/dist/496.js +0 -1
  125. package/dist/496.js.map +0 -1
  126. package/dist/511.js +0 -1
  127. package/dist/511.js.map +0 -1
  128. package/dist/603.js +0 -1
  129. package/dist/603.js.map +0 -1
  130. package/dist/610.js +0 -1
  131. package/dist/610.js.map +0 -1
  132. package/dist/612.js +0 -1
  133. package/dist/612.js.map +0 -1
  134. package/dist/656.js +0 -2
  135. package/dist/656.js.map +0 -1
  136. package/dist/752.js +0 -1
  137. package/dist/752.js.map +0 -1
  138. package/dist/754.js +0 -1
  139. package/dist/754.js.map +0 -1
  140. package/dist/781.js +0 -1
  141. package/dist/781.js.map +0 -1
  142. package/dist/801.js +0 -2
  143. package/dist/801.js.map +0 -1
  144. package/dist/817.js +0 -1
  145. package/dist/817.js.map +0 -1
  146. package/dist/877.js +0 -1
  147. package/dist/877.js.map +0 -1
  148. package/dist/924.js +0 -1
  149. package/dist/924.js.map +0 -1
  150. package/src/autosuggest/autosuggest.component.tsx +0 -162
  151. package/src/autosuggest/autosuggest.scss +0 -61
  152. package/src/autosuggest/patient-search-info.component.tsx +0 -75
  153. package/src/autosuggest/patient-search-info.scss +0 -62
  154. package/src/autosuggest/search-empty-state.component.tsx +0 -21
  155. package/src/autosuggest/search-empty-state.scss +0 -18
  156. package/src/card/avail-compartment.compartment.tsx +0 -94
  157. package/src/card/compartment-view.compartment.tsx +0 -62
  158. package/src/card/compartment.scss +0 -128
  159. package/src/card/compartmentSharing.component.tsx +0 -21
  160. package/src/card/compartmentSharing.scss +0 -24
  161. package/src/card/empty-compartment.component.tsx +0 -28
  162. package/src/card/empty-compartment.scss +0 -61
  163. package/src/component/main.component.tsx +0 -17
  164. package/src/component/next-of-kin-details/nextOfKinDetails.component.tsx +0 -50
  165. package/src/component/next-of-kin-details/nextOfKinDetails.scss +0 -37
  166. package/src/header/admitted-queue-header.component.tsx +0 -30
  167. package/src/header/admitted-queue-header.scss +0 -32
  168. package/src/header/morgue-header.component.tsx +0 -38
  169. package/src/header/morgue-header.scss +0 -95
  170. package/src/header/morgue-illustration.component.tsx +0 -13
  171. package/src/hook/useDeceasedPatients.ts +0 -12
  172. package/src/hook/useDischargedPatient.ts +0 -55
  173. package/src/hook/useMorgue.resource.ts +0 -163
  174. package/src/hook/useMortuaryAdmissionLocation.ts +0 -64
  175. package/src/tables/admitted-queue.component.tsx +0 -54
  176. package/src/tables/admitted-queue.scss +0 -62
  177. package/src/tables/discharge-queue.component.tsx +0 -87
  178. package/src/tables/generic-table.component.tsx +0 -140
  179. package/src/tables/generic-table.scss +0 -37
  180. package/src/tabs/tabs.component.tsx +0 -82
  181. package/src/tabs/tabs.scss +0 -15
  182. package/src/workspaces/admit-body.scss +0 -46
  183. package/src/workspaces/admit-body.workspace.tsx +0 -79
  184. package/src/workspaces/discharge-body.scss +0 -67
  185. package/src/workspaces/discharge-body.workspace.tsx +0 -329
  186. package/src/workspaces/patientAdditionalInfoForm.workspace.tsx +0 -562
  187. package/src/workspaces/swap-unit.scss +0 -46
  188. package/src/workspaces/swap-unit.workspace.tsx +0 -168
  189. /package/dist/{347.js.LICENSE.txt → 109.js.LICENSE.txt} +0 -0
  190. /package/dist/{656.js.LICENSE.txt → 373.js.LICENSE.txt} +0 -0
  191. /package/dist/{801.js.LICENSE.txt → 4.js.LICENSE.txt} +0 -0
  192. /package/dist/{433.js.LICENSE.txt → 420.js.LICENSE.txt} +0 -0
  193. /package/src/{component → deceased-patient-header}/deceasedInfo/deceased-info.scss +0 -0
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { InlineLoading, SkeletonText } from '@carbon/react';
4
+ import styles from '../bed-layout.scss';
5
+ import BedCard from '../../bed/bed.component';
6
+ import { MortuaryPatient, MortuaryLocationResponse } from '../../types';
7
+ import { useAwaitingPatients } from '../../home/home.resource';
8
+ import { launchWorkspace } from '@openmrs/esm-framework';
9
+ import { EmptyState } from '@openmrs/esm-patient-common-lib/src';
10
+
11
+ interface BedLayoutProps {
12
+ awaitingQueueDeceasedPatients: MortuaryPatient[];
13
+ mortuaryLocation: MortuaryLocationResponse;
14
+ isLoading: boolean;
15
+ mutated?: () => void;
16
+ }
17
+
18
+ const AwaitingBedLayout: React.FC<BedLayoutProps> = ({
19
+ awaitingQueueDeceasedPatients,
20
+ mortuaryLocation,
21
+ isLoading,
22
+ mutated,
23
+ }) => {
24
+ const { t } = useTranslation();
25
+
26
+ const trulyAwaitingPatients = useAwaitingPatients(awaitingQueueDeceasedPatients);
27
+
28
+ if (isLoading) {
29
+ return (
30
+ <div className={styles.emptyState}>
31
+ <SkeletonText />
32
+ <InlineLoading description={t('loadingPatients', 'Loading patients...')} />
33
+ </div>
34
+ );
35
+ }
36
+
37
+ if (trulyAwaitingPatients.length === 0) {
38
+ return (
39
+ <div className={styles.emptyState}>
40
+ <EmptyState
41
+ headerTitle={t('noAwaitingPatients', 'No awaiting patients found')}
42
+ displayText={t('noAwaitingPatientsDescription', 'There are currently no awaiting patients to display.')}
43
+ />
44
+ </div>
45
+ );
46
+ }
47
+
48
+ const handleAdmit = (patientData: MortuaryPatient) => {
49
+ launchWorkspace('admit-deceased-person-form', {
50
+ workspaceTitle: t('admissionForm', 'Admission form'),
51
+ patientData,
52
+ mortuaryLocation,
53
+ mutated,
54
+ });
55
+ };
56
+
57
+ return (
58
+ <div className={styles.bedLayoutWrapper}>
59
+ <div className={styles.bedLayoutContainer}>
60
+ {trulyAwaitingPatients.map((mortuaryPatient) => {
61
+ const patientUuid = mortuaryPatient?.person?.person?.uuid;
62
+ const patientName = mortuaryPatient?.person?.person?.display;
63
+ const gender = mortuaryPatient?.person?.person?.gender;
64
+ const age = mortuaryPatient?.person?.person?.age;
65
+ const causeOfDeath = mortuaryPatient?.person?.person?.causeOfDeath?.display;
66
+ const dateOfDeath = mortuaryPatient?.person?.person?.deathDate;
67
+
68
+ return (
69
+ <BedCard
70
+ key={patientUuid}
71
+ patientName={patientName}
72
+ gender={gender}
73
+ age={age}
74
+ causeOfDeath={causeOfDeath}
75
+ dateOfDeath={dateOfDeath}
76
+ patientUuid={patientUuid}
77
+ onAdmit={() => handleAdmit(mortuaryPatient)}
78
+ />
79
+ );
80
+ })}
81
+ </div>
82
+ </div>
83
+ );
84
+ };
85
+
86
+ export default AwaitingBedLayout;
@@ -0,0 +1,72 @@
1
+ import { FetchResponse, openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
2
+ import { useMemo } from 'react';
3
+ import useSWR from 'swr';
4
+ import { type MortuaryLocationResponse, type AdmissionLocationResponse, type Bed, type MappedBedData } from '../types';
5
+ import { ConfigObject } from '../config-schema';
6
+
7
+ export const useLocation = () => {
8
+ const { mortuaryLocationTagUuid } = useConfig<ConfigObject>();
9
+ const url = `${restBaseUrl}/admissionLocation?v=full`;
10
+ const { isLoading, error, data, mutate } = useSWR<FetchResponse<AdmissionLocationResponse>>(url, openmrsFetch);
11
+
12
+ const mortuaryLocations = useMemo(() => {
13
+ if (!data?.data?.results || !mortuaryLocationTagUuid) {
14
+ return [];
15
+ }
16
+
17
+ return data.data.results.filter((location) =>
18
+ location.ward.tags.some((tag) => tag.uuid === mortuaryLocationTagUuid),
19
+ );
20
+ }, [data?.data?.results, mortuaryLocationTagUuid]);
21
+
22
+ return {
23
+ locations: mortuaryLocations,
24
+ isLoading,
25
+ error,
26
+ mutate,
27
+ };
28
+ };
29
+
30
+ export const useBedsForLocation = (locationUuid: string) => {
31
+ const apiUrl = `${restBaseUrl}/bed?locationUuid=${locationUuid}&v=full`;
32
+
33
+ const { data, isLoading, error, mutate, isValidating } = useSWR<{ data: { results: Array<Bed> } }, Error>(
34
+ locationUuid ? apiUrl : null,
35
+ openmrsFetch,
36
+ );
37
+
38
+ const mappedBedData: MappedBedData = (data?.data?.results ?? []).map((bed) => ({
39
+ id: bed.id,
40
+ type: bed.bedType?.displayName,
41
+ number: bed.bedNumber,
42
+ status: bed.status,
43
+ uuid: bed.uuid,
44
+ }));
45
+
46
+ const results = useMemo(
47
+ () => ({
48
+ bedsData: mappedBedData,
49
+ errorLoadingBeds: error,
50
+ isLoadingBeds: isLoading,
51
+ mutate,
52
+ isValidating,
53
+ }),
54
+ [mappedBedData, isLoading, error, mutate, isValidating],
55
+ );
56
+
57
+ return results;
58
+ };
59
+
60
+ export function useMortuaryAdmissionLocation(locationUuid: string) {
61
+ const customRepresentation =
62
+ 'custom:(ward,totalBeds,occupiedBeds,bedLayouts:(rowNumber,columnNumber,bedNumber,bedType,bedId,bedUuid,status,location,patients:(person:full,identifiers,uuid)))';
63
+
64
+ const url = locationUuid ? `${restBaseUrl}/admissionLocation/${locationUuid}?v=${customRepresentation}` : null;
65
+
66
+ const { data, ...rest } = useSWR<FetchResponse<MortuaryLocationResponse>, Error>(url, openmrsFetch);
67
+
68
+ return {
69
+ admissionLocation: data?.data,
70
+ ...rest,
71
+ };
72
+ }
@@ -0,0 +1,55 @@
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+
4
+ .bedLayoutContainer {
5
+ background-color: colors.$white-0;
6
+ display: grid;
7
+ grid-template-columns: repeat(4, minmax(0, 1fr));
8
+ justify-content: space-between;
9
+ flex: 1;
10
+ overflow-y: auto;
11
+ overflow-x: hidden;
12
+ padding: layout.$spacing-02;
13
+ max-height: calc(100vh - 200px);
14
+ gap: 1rem;
15
+ &::-webkit-scrollbar {
16
+ width: 8px;
17
+ }
18
+
19
+ &::-webkit-scrollbar-track {
20
+ background: colors.$white-0;
21
+ border-radius: 4px;
22
+ }
23
+
24
+ &::-webkit-scrollbar-thumb {
25
+ background: colors.$gray-30;
26
+ border-radius: 4px;
27
+
28
+ &:hover {
29
+ background: colors.$gray-40;
30
+ }
31
+ }
32
+ }
33
+
34
+ .bedLayoutWrapper {
35
+ height: 100%;
36
+ overflow: hidden;
37
+ display: flex;
38
+ flex-direction: column;
39
+ }
40
+
41
+ .loadingContainer {
42
+ display: flex;
43
+ justify-content: center;
44
+ align-items: center;
45
+ height: 200px;
46
+ }
47
+
48
+ .emptyState {
49
+ display: flex;
50
+ justify-content: center;
51
+ align-items: center;
52
+ height: 200px;
53
+ color: colors.$gray-60;
54
+ font-style: italic;
55
+ }
@@ -0,0 +1,109 @@
1
+ import React from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { InlineLoading } from '@carbon/react';
4
+ import { launchWorkspace, useConfig } from '@openmrs/esm-framework';
5
+ import styles from '../bed-layout.scss';
6
+ import { type MortuaryLocationResponse } from '../../types';
7
+ import { ConfigObject } from '../../config-schema';
8
+ import { mutate as mutateSWR } from 'swr';
9
+ import usePatients, { useMortuaryDischargeEncounter } from './discharged-bed-layout.resource';
10
+ import BedCard from '../../bed/bed.component';
11
+
12
+ interface BedLayoutProps {
13
+ AdmittedDeceasedPatient: MortuaryLocationResponse | null;
14
+ isLoading: boolean;
15
+ onPrintGatePass?: (patientUuid: string) => void;
16
+ onPrintPostmortem?: (patientUuid: string) => void;
17
+ mutate?: () => void;
18
+ }
19
+
20
+ const DischargedBedLayout: React.FC<BedLayoutProps> = ({
21
+ AdmittedDeceasedPatient,
22
+ isLoading,
23
+ onPrintGatePass,
24
+ onPrintPostmortem,
25
+ mutate,
26
+ }) => {
27
+ const { t } = useTranslation();
28
+ const { morgueDischargeEncounterTypeUuid } = useConfig<ConfigObject>();
29
+
30
+ const {
31
+ dischargedPatientUuids,
32
+ isLoading: encountersLoading,
33
+ error: encountersError,
34
+ } = useMortuaryDischargeEncounter(morgueDischargeEncounterTypeUuid, AdmittedDeceasedPatient);
35
+
36
+ const {
37
+ patients: dischargedPatients,
38
+ isLoading: patientsLoading,
39
+ error: patientsError,
40
+ } = usePatients(dischargedPatientUuids || []);
41
+
42
+ const handlePrintGatePass = (patientUuid: string) => {
43
+ if (onPrintGatePass) {
44
+ onPrintGatePass(patientUuid);
45
+ }
46
+ };
47
+
48
+ const handlePrintPostmortem = (patientUuid: string) => {
49
+ if (onPrintPostmortem) {
50
+ onPrintPostmortem(patientUuid);
51
+ }
52
+ };
53
+
54
+ if (isLoading || encountersLoading || patientsLoading) {
55
+ return (
56
+ <div className={styles.loadingContainer}>
57
+ <InlineLoading description={t('loadingPatients', 'Loading patients...')} />
58
+ </div>
59
+ );
60
+ }
61
+
62
+ if (encountersError || patientsError) {
63
+ return (
64
+ <div className={styles.emptyState}>
65
+ <p>{t('errorLoadingPatients', 'Error loading discharged patients')}</p>
66
+ </div>
67
+ );
68
+ }
69
+
70
+ if (!dischargedPatients || dischargedPatients.length === 0) {
71
+ return (
72
+ <div className={styles.emptyState}>
73
+ <p>{t('noDischargedPatients', 'No discharged patients found')}</p>
74
+ </div>
75
+ );
76
+ }
77
+
78
+ return (
79
+ <div className={styles.bedLayoutWrapper}>
80
+ <div className={styles.bedLayoutContainer}>
81
+ {dischargedPatients.map((patient) => {
82
+ const patientUuid = patient?.uuid;
83
+ const patientName = patient?.person?.display;
84
+ const gender = patient?.person?.gender;
85
+ const age = patient?.person?.age;
86
+ const causeOfDeath = patient?.person?.causeOfDeath?.display;
87
+ const dateOfDeath = patient?.person?.deathDate;
88
+
89
+ return (
90
+ <BedCard
91
+ key={patientUuid}
92
+ patientName={patientName}
93
+ gender={gender}
94
+ age={age}
95
+ causeOfDeath={causeOfDeath}
96
+ dateOfDeath={dateOfDeath}
97
+ patientUuid={patientUuid}
98
+ onPrintGatePass={() => handlePrintGatePass(patientUuid)}
99
+ onPrintPostmortem={() => handlePrintPostmortem(patientUuid)}
100
+ isDischarged={true}
101
+ />
102
+ );
103
+ })}
104
+ </div>
105
+ </div>
106
+ );
107
+ };
108
+
109
+ export default DischargedBedLayout;
@@ -0,0 +1,99 @@
1
+ import {
2
+ FetchResponse,
3
+ fhirBaseUrl,
4
+ openmrsFetch,
5
+ restBaseUrl,
6
+ useFhirFetchAll,
7
+ useFhirPagination,
8
+ } from '@openmrs/esm-framework';
9
+ import useSWR from 'swr';
10
+ import { type Patient, type FHIREncounter, MortuaryLocationResponse, Entry } from '../../types';
11
+ import { useMemo, useState } from 'react';
12
+ import { parseDisplayText } from '../../utils/utils';
13
+
14
+ export const useMortuaryDischargeEncounter = (
15
+ dischargeEncounterTypeUuid: string,
16
+ admissionLocation: MortuaryLocationResponse,
17
+ ) => {
18
+ const pageSizes = [10, 20, 50, 100];
19
+ const locationUuid = admissionLocation?.ward?.uuid;
20
+ const [currPageSize, setCurrPageSize] = useState(10);
21
+ const urls = !admissionLocation
22
+ ? null
23
+ : `${fhirBaseUrl}/Encounter?_summary=data&type=${dischargeEncounterTypeUuid}&location=${locationUuid}`;
24
+ const { data, isLoading, error, paginated, currentPage, goTo, totalCount, currentPageSize, mutate } =
25
+ useFhirPagination<Entry>(urls, currPageSize);
26
+
27
+ const dischargedPatientUuids = useMemo(() => {
28
+ if (!data) {
29
+ return [];
30
+ }
31
+
32
+ const uuids = data
33
+ .map((entry) => {
34
+ const reference = entry?.subject?.reference;
35
+ if (reference && reference.startsWith('Patient/')) {
36
+ return reference.split('/')[1];
37
+ }
38
+ return undefined;
39
+ })
40
+ .filter((uuid) => uuid);
41
+
42
+ const admittedPatientUuids = admissionLocation?.bedLayouts
43
+ ?.flatMap((bed) => bed.patients?.map((patient) => patient.uuid))
44
+ .filter(Boolean);
45
+
46
+ const filteredDischargedPatientUuids = uuids?.filter((uuid) => !admittedPatientUuids?.includes(uuid));
47
+
48
+ return [...new Set(filteredDischargedPatientUuids)];
49
+ }, [data, admissionLocation]);
50
+
51
+ const encounters = useMemo(() => {
52
+ return (data ?? []).map((entry) => {
53
+ const { name, openmrsId } = parseDisplayText(entry.subject.display);
54
+ const patientUuid = entry.subject.reference.split('/').at(-1);
55
+ return {
56
+ uuid: entry?.id,
57
+ patient: { uuid: patientUuid, openmrsId, name },
58
+ encounterDateTime: entry.period?.start,
59
+ };
60
+ });
61
+ }, [data]);
62
+
63
+ return {
64
+ encounters,
65
+ dischargedPatientUuids,
66
+ isLoading: isLoading,
67
+ error: error,
68
+ paginated,
69
+ currentPage,
70
+ pageSizes,
71
+ goTo,
72
+ currPageSize,
73
+ setCurrPageSize,
74
+ totalCount,
75
+ currentPageSize,
76
+ mutate,
77
+ };
78
+ };
79
+
80
+ export const usePatients = (uuids: string[]) => {
81
+ const customRepresentation =
82
+ 'custom:(uuid,display,identifiers:(uuid,display),person:(uuid,display,gender,birthdate,dead,age,deathDate,causeOfDeath:(uuid,display),attributes:(uuid,display,value,attributeType:(uuid,))))';
83
+ const urls = uuids.map((uuid) => `${restBaseUrl}/patient/${uuid}?v=${customRepresentation}`);
84
+
85
+ const { data, error, isLoading, mutate } = useSWR<FetchResponse<Patient>[]>(urls, (urls) =>
86
+ Promise.all(urls.map((url) => openmrsFetch<Patient>(url))),
87
+ );
88
+
89
+ const deceasedPatients = data?.map((response) => response.data)?.filter((patient) => patient?.person?.dead === true);
90
+
91
+ return {
92
+ isLoading,
93
+ error,
94
+ patients: deceasedPatients,
95
+ mutate,
96
+ };
97
+ };
98
+
99
+ export default usePatients;