@kenyaemr/esm-morgue-app 5.4.2-pre.2330 → 5.4.2-pre.2344

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 (62) hide show
  1. package/.turbo/turbo-build.log +20 -20
  2. package/dist/197.js +1 -1
  3. package/dist/221.js +1 -0
  4. package/dist/221.js.map +1 -0
  5. package/dist/294.js +1 -1
  6. package/dist/300.js +1 -1
  7. package/dist/347.js +1 -1
  8. package/dist/347.js.map +1 -1
  9. package/dist/429.js +2 -0
  10. package/dist/429.js.map +1 -0
  11. package/dist/529.js +1 -0
  12. package/dist/529.js.map +1 -0
  13. package/dist/619.js +1 -0
  14. package/dist/619.js.map +1 -0
  15. package/dist/633.js +1 -1
  16. package/dist/633.js.map +1 -1
  17. package/dist/653.js +1 -0
  18. package/dist/653.js.map +1 -0
  19. package/dist/712.js +1 -0
  20. package/dist/712.js.map +1 -0
  21. package/dist/723.js +1 -0
  22. package/dist/723.js.map +1 -0
  23. package/dist/805.js +1 -0
  24. package/dist/805.js.map +1 -0
  25. package/dist/989.js +1 -1
  26. package/dist/989.js.map +1 -1
  27. package/dist/kenyaemr-esm-morgue-app.js +1 -1
  28. package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +182 -80
  29. package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
  30. package/dist/main.js +1 -1
  31. package/dist/main.js.map +1 -1
  32. package/dist/routes.json +1 -1
  33. package/package.json +1 -1
  34. package/src/bed/bed.component.tsx +10 -11
  35. package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +24 -7
  36. package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +35 -20
  37. package/src/config-schema.ts +1 -1
  38. package/src/extension/overflow-menu-item-postmortem/print-postmorterm-report.component.tsx +39 -0
  39. package/src/index.ts +11 -0
  40. package/src/modals/autopsy-report/autopsy-print-preview-confirmation.modal.tsx +569 -0
  41. package/src/modals/autopsy-report/autopsy-print-preview-confirmation.scss +715 -0
  42. package/src/modals/mortuary-gate-pass/print-preview-confirmation.modal.tsx +257 -0
  43. package/src/modals/mortuary-gate-pass/print-preview-confirmation.resource.ts +0 -0
  44. package/src/modals/mortuary-gate-pass/print-preview-confirmation.scss +333 -0
  45. package/src/routes.json +15 -0
  46. package/src/utils/utils.ts +6 -0
  47. package/src/view-details/panels/attachement.component.tsx +17 -3
  48. package/src/view-details/panels/autopsy.component.tsx +89 -75
  49. package/src/view-details/panels/billing-history.component.tsx +8 -1
  50. package/src/view-details/view-details.component.tsx +6 -2
  51. package/translations/am.json +8 -3
  52. package/translations/en.json +8 -3
  53. package/translations/sw.json +8 -3
  54. package/dist/201.js +0 -1
  55. package/dist/201.js.map +0 -1
  56. package/dist/389.js +0 -1
  57. package/dist/389.js.map +0 -1
  58. package/dist/420.js +0 -2
  59. package/dist/420.js.map +0 -1
  60. package/dist/798.js +0 -1
  61. package/dist/798.js.map +0 -1
  62. /package/dist/{420.js.LICENSE.txt → 429.js.LICENSE.txt} +0 -0
@@ -0,0 +1,257 @@
1
+ import React, { useRef, useState, useMemo } from 'react';
2
+ import { Button, ButtonSet, ModalBody, ModalFooter, InlineNotification } from '@carbon/react';
3
+ import { useReactToPrint } from 'react-to-print';
4
+ import { formatDate, formatDatetime, parseDate, useSession } from '@openmrs/esm-framework';
5
+ import styles from './print-preview-confirmation.scss';
6
+ import { type Patient } from '../../types';
7
+ import { formatDateTime, documentId } from '../../utils/utils';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ type PrintPreviewModalProps = {
11
+ onClose: () => void;
12
+ patient: Patient;
13
+ encounterDate?: string;
14
+ };
15
+
16
+ const PrintPreviewModal: React.FC<PrintPreviewModalProps> = ({ onClose, patient, encounterDate }) => {
17
+ const { t } = useTranslation();
18
+ const [printError, setPrintError] = useState<string | null>(null);
19
+ const printRef = useRef<HTMLDivElement>(null);
20
+ const { sessionLocation, user } = useSession();
21
+ const userDisplay = user ? user.display : '';
22
+ const generationTimestamp = useMemo(() => new Date(), []);
23
+
24
+ const handlePrint = useReactToPrint({
25
+ content: () => printRef.current,
26
+ documentTitle: 'Mortuary Gate Pass',
27
+ onAfterPrint: () => {
28
+ setPrintError(null);
29
+ },
30
+ onPrintError: (_, error) => {
31
+ setPrintError(error?.message || 'An error occurred while printing');
32
+ },
33
+ pageStyle: `
34
+ @page {
35
+ size: A4;
36
+ margin: 15mm;
37
+ }
38
+ `,
39
+ });
40
+
41
+ const getPatientNumber = () => {
42
+ const openMRSId =
43
+ patient.identifiers
44
+ ?.find((id) => id.display?.includes('OpenMRS ID'))
45
+ ?.display?.split('=')?.[1]
46
+ ?.trim() || '';
47
+ return openMRSId;
48
+ };
49
+
50
+ const getCurrentDateTime = () => {
51
+ const now = new Date();
52
+ return {
53
+ date: formatDate(now, { mode: 'standard' }),
54
+ time: now.toLocaleTimeString('en-US', {
55
+ hour12: false,
56
+ hour: '2-digit',
57
+ minute: '2-digit',
58
+ }),
59
+ };
60
+ };
61
+
62
+ const currentDateTime = getCurrentDateTime();
63
+
64
+ return (
65
+ <>
66
+ <ModalBody>
67
+ <div className={styles.container}>
68
+ <div ref={printRef} className={styles.printableContent}>
69
+ <div className={styles.printableHeader}>
70
+ <div className={styles.facilityDetails}>
71
+ <div className={styles.facilityName}>{sessionLocation?.display}</div>
72
+ <div className={styles.heading}>{t('mortuaryGatePass', 'Mortuary Gate Pass')}</div>
73
+ </div>
74
+ </div>
75
+
76
+ <div className={styles.printableBody}>
77
+ <div className={styles.gatePassForm}>
78
+ <div className={styles.topInfoRow}>
79
+ <div className={styles.infoItem}>
80
+ <span className={styles.label}>{t('paperNo', 'Paper No' + ':')}</span>
81
+ <span className={styles.value}>{getPatientNumber()}</span>
82
+ </div>
83
+ <div className={styles.infoItem}>
84
+ <span className={styles.label}>{t('patientNo', 'Patient No' + ':')}</span>
85
+ <span className={styles.value}>{getPatientNumber()}</span>
86
+ </div>
87
+ <div className={styles.infoItem}>
88
+ <span className={styles.label}>{t('date', 'Date' + ':')}</span>
89
+ <span className={styles.value}>{currentDateTime.date}</span>
90
+ </div>
91
+ <div className={styles.infoItem}>
92
+ <span className={styles.label}>{t('time', 'Time' + ':')}</span>
93
+ <span className={styles.value}>{currentDateTime.time}</span>
94
+ </div>
95
+ </div>
96
+ <div className={styles.secondInfoRow}>
97
+ <div className={styles.patientField}>
98
+ <span className={styles.label}>{t('patientName', 'Patient Name' + ':')}</span>
99
+ <span className={styles.valueWide}>{patient.person?.display || ''}</span>
100
+ </div>
101
+ <div className={styles.ageField}>
102
+ <span className={styles.label}>{t('age', 'Age' + ':')}</span>
103
+ <span className={styles.value}>{patient.person?.age || ''}</span>
104
+ </div>
105
+ </div>
106
+ <div className={styles.secondInfoRow}>
107
+ <div className={styles.patientField}>
108
+ <span className={styles.label}>{t('dateOfAdmission', 'Date of Admission' + ':')}</span>
109
+ <span className={styles.valueWide}>{formatDateTime(patient.person?.deathDate)}</span>
110
+ </div>
111
+ <div className={styles.ageField}>
112
+ <span className={styles.label}>{t('dateOfDischarge', 'Date of Discharge' + ':')}</span>
113
+ <span className={styles.value}>{formatDateTime(encounterDate)}</span>
114
+ </div>
115
+ </div>
116
+ </div>
117
+
118
+ <div className={styles.paymentSection}>
119
+ <div className={styles.sectionTitle}>
120
+ {t('methodOfPayment', 'Method of payment (tick as appropriate)')}
121
+ </div>
122
+ <div className={styles.paymentGrid}>
123
+ <div className={styles.paymentOption}>
124
+ <span className={styles.checkbox}></span>
125
+ <span className={styles.optionLabel}>{t('cash', 'Cash')}</span>
126
+ </div>
127
+ <div className={styles.paymentOption}>
128
+ <span className={styles.checkbox}></span>
129
+ <span className={styles.optionLabel}>{t('cheque', 'Cheque')}</span>
130
+ </div>
131
+ <div className={styles.paymentOption}>
132
+ <span className={styles.checkbox}></span>
133
+ <span className={styles.optionLabel}>{t('sha', 'SHA')}</span>
134
+ </div>
135
+ <div className={styles.paymentOption}>
136
+ <span className={styles.checkbox}></span>
137
+ <span className={styles.optionLabel}>{t('scheme', 'Scheme')}</span>
138
+ </div>
139
+ <div className={styles.paymentOption}>
140
+ <span className={styles.checkbox}></span>
141
+ <span className={styles.optionLabel}>{t('mrM', 'M.R.M')}</span>
142
+ </div>
143
+ <div className={styles.paymentOption}>
144
+ <span className={styles.checkbox}></span>
145
+ <span className={styles.optionLabel}>
146
+ {t('others', 'Others:')} {'...........................'}
147
+ </span>
148
+ </div>
149
+ </div>
150
+ </div>
151
+
152
+ <div className={styles.signaturesSection}>
153
+ <div className={styles.signatureBlock}>
154
+ <div className={styles.signatureRow}>
155
+ <div className={styles.nameField}>
156
+ <span className={styles.label}>{t('accountOfficer', 'Account Officer:')}</span>
157
+ <span className={styles.nameValue}>{''}</span>
158
+ </div>
159
+ <div className={styles.signField}>
160
+ <span className={styles.label}>{t('sign', 'Sign:')}</span>
161
+ <div className={styles.signatureLine}></div>
162
+ </div>
163
+ <div className={styles.dateField}>
164
+ <span className={styles.label}>{t('date', 'Date:')}</span>
165
+ <div className={styles.signatureLine}></div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ <div className={styles.signatureBlock}>
171
+ <div className={styles.signatureRow}>
172
+ <div className={styles.nameField}>
173
+ <span className={styles.label}>{t('nurseOfficerIncharge', 'Nurse Officer Incharge:')}</span>
174
+ <span className={styles.nameValue}>{''}</span>
175
+ </div>
176
+ <div className={styles.signField}>
177
+ <span className={styles.label}>{t('sign', 'Sign:')}</span>
178
+ <div className={styles.signatureLine}></div>
179
+ </div>
180
+ <div className={styles.dateField}>
181
+ <span className={styles.label}>{t('date', 'Date:')}</span>
182
+ <div className={styles.signatureLine}></div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+
187
+ <div className={styles.signatureBlock}>
188
+ <div className={styles.signatureRow}>
189
+ <div className={styles.nameField}>
190
+ <span className={styles.label}>{t('securityGuardName', 'S. Guard Name:')}</span>
191
+ <span className={styles.nameValue}>{''}</span>
192
+ </div>
193
+ <div className={styles.signField}>
194
+ <span className={styles.label}>{t('sign', 'Sign:')}</span>
195
+ <div className={styles.signatureLine}></div>
196
+ </div>
197
+ <div className={styles.dateField}>
198
+ <span className={styles.label}>{t('date', 'Date:')}</span>
199
+ <div className={styles.signatureLine}></div>
200
+ </div>
201
+ </div>
202
+ </div>
203
+
204
+ <div className={styles.signatureBlock}>
205
+ <div className={styles.signatureRow}>
206
+ <div className={styles.nameField}>
207
+ <span className={styles.label}>{t('printedBy', 'Printed by:')}</span>
208
+ <span className={styles.nameValue}>{userDisplay}</span>
209
+ </div>
210
+ </div>
211
+ </div>
212
+ </div>
213
+
214
+ <div className={styles.footerNote}>
215
+ <div className={styles.noteText}>
216
+ <strong>{t('nb', 'N/B:')}</strong>{' '}
217
+ {t(
218
+ 'formDuplicateNote',
219
+ 'This form should be filled in duplicate, one copy to be retained in the ward and the other to be left at the main gate',
220
+ )}
221
+ </div>
222
+ </div>
223
+
224
+ <div className={styles.footer}>
225
+ <div className={styles.footerDetails}>
226
+ <div>
227
+ {documentId()} | {t('generatedBy', 'Generated By')}: {userDisplay}
228
+ </div>
229
+ <div>
230
+ {t('generationTimestamp', 'Generated')}: {formatDatetime(generationTimestamp)} |{' '}
231
+ {t('facility', 'Facility')}: {sessionLocation?.display}
232
+ </div>
233
+ </div>
234
+ </div>
235
+ </div>
236
+ </div>
237
+ </div>
238
+ </ModalBody>
239
+ <ModalFooter>
240
+ <ButtonSet className={styles.btnSet}>
241
+ <Button kind="secondary" onClick={onClose} type="button">
242
+ {t('cancel', 'Cancel')}
243
+ </Button>
244
+ <Button kind="primary" type="button" onClick={handlePrint}>
245
+ {t('print', 'Print')}
246
+ </Button>
247
+ </ButtonSet>
248
+ </ModalFooter>
249
+
250
+ {printError && (
251
+ <InlineNotification kind="error" title={t('printError', 'Error')} subtitle={printError} hideCloseButton />
252
+ )}
253
+ </>
254
+ );
255
+ };
256
+
257
+ export default PrintPreviewModal;
@@ -0,0 +1,333 @@
1
+ @use '@carbon/colors';
2
+ @use '@carbon/layout';
3
+ @use '@carbon/type';
4
+
5
+ .container {
6
+ padding: layout.$spacing-06;
7
+ margin-bottom: layout.$spacing-05;
8
+ background-color: colors.$white;
9
+
10
+ @media print {
11
+ padding: 0;
12
+ margin: 0;
13
+ background-color: colors.$white;
14
+ }
15
+ }
16
+
17
+ .noPrint {
18
+ @media print {
19
+ display: none !important;
20
+ }
21
+ }
22
+
23
+ .printableContent {
24
+ background-color: colors.$white;
25
+ width: 210mm;
26
+ min-height: 297mm;
27
+ margin: 0 auto;
28
+ padding: layout.$spacing-07;
29
+ box-sizing: border-box;
30
+ font-size: 11px;
31
+ line-height: 1.3;
32
+ color: colors.$black;
33
+
34
+ @media print {
35
+ width: 100%;
36
+ height: 100%;
37
+ padding: layout.$spacing-07;
38
+ margin: 0;
39
+ box-shadow: none;
40
+ border: none;
41
+ page-break-after: avoid;
42
+ page-break-before: avoid;
43
+ }
44
+ }
45
+
46
+ .printableHeader {
47
+ text-align: center;
48
+ margin-bottom: layout.$spacing-05;
49
+ padding-bottom: layout.$spacing-03;
50
+ border-bottom: 1px solid colors.$black;
51
+
52
+ @media print {
53
+ border-bottom: 1px solid colors.$black;
54
+ }
55
+ }
56
+
57
+ .facilityDetails {
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: center;
61
+ }
62
+
63
+ .facilityName {
64
+ font-weight: 700;
65
+ color: colors.$black;
66
+ text-transform: uppercase;
67
+ letter-spacing: 2px;
68
+ margin-bottom: layout.$spacing-03;
69
+ font-size: 14px;
70
+
71
+ @media print {
72
+ color: colors.$black;
73
+ }
74
+ }
75
+
76
+ .heading {
77
+ font-weight: 600;
78
+ color: colors.$black;
79
+ text-transform: uppercase;
80
+ letter-spacing: 1px;
81
+ font-size: 12px;
82
+
83
+ @media print {
84
+ color: colors.$black;
85
+ }
86
+ }
87
+
88
+ .printableBody {
89
+ display: flex;
90
+ flex-direction: column;
91
+ gap: layout.$spacing-05;
92
+ }
93
+
94
+ .gatePassForm {
95
+ display: flex;
96
+ flex-direction: column;
97
+ gap: layout.$spacing-05;
98
+ }
99
+
100
+ .topInfoRow {
101
+ display: grid;
102
+ grid-template-columns: repeat(4, 1fr);
103
+ gap: layout.$spacing-03;
104
+ padding: layout.$spacing-03;
105
+ border: 1px solid colors.$black;
106
+ border-radius: 2px;
107
+
108
+ @media print {
109
+ border: 1px solid colors.$black;
110
+ }
111
+ }
112
+
113
+ .secondInfoRow {
114
+ display: grid;
115
+ grid-template-columns: 1fr 1fr;
116
+ gap: layout.$spacing-03;
117
+ padding: layout.$spacing-03;
118
+ border: 1px solid colors.$black;
119
+ border-radius: 2px;
120
+
121
+ @media print {
122
+ border: 1px solid colors.$black;
123
+ }
124
+ }
125
+
126
+ .infoItem,
127
+ .patientField,
128
+ .ageField {
129
+ display: flex;
130
+ flex-direction: column;
131
+ gap: layout.$spacing-02;
132
+ }
133
+
134
+ .paymentSection {
135
+ padding: layout.$spacing-03;
136
+ border: 1px solid colors.$black;
137
+ border-radius: 2px;
138
+ margin: layout.$spacing-03 0;
139
+
140
+ @media print {
141
+ border: 1px solid colors.$black;
142
+ }
143
+ }
144
+
145
+ .sectionTitle {
146
+ font-weight: 600;
147
+ color: colors.$black;
148
+ margin-bottom: layout.$spacing-03;
149
+ font-size: 11px;
150
+
151
+ @media print {
152
+ color: colors.$black;
153
+ }
154
+ }
155
+
156
+ .paymentGrid {
157
+ display: grid;
158
+ grid-template-columns: repeat(3, 1fr);
159
+ gap: layout.$spacing-03;
160
+ }
161
+
162
+ .paymentOption {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: layout.$spacing-02;
166
+ }
167
+
168
+ .checkbox {
169
+ width: 12px;
170
+ height: 12px;
171
+ border: 1px solid colors.$black;
172
+ background-color: colors.$white;
173
+ flex-shrink: 0;
174
+ }
175
+
176
+ .optionLabel {
177
+ color: colors.$black;
178
+ font-size: 10px;
179
+ }
180
+
181
+ .signaturesSection {
182
+ margin-top: layout.$spacing-05;
183
+ padding-top: layout.$spacing-03;
184
+ border-top: 1px solid colors.$black;
185
+ }
186
+
187
+ .signatureBlock {
188
+ margin-bottom: layout.$spacing-03;
189
+ }
190
+
191
+ .signatureRow {
192
+ display: grid;
193
+ grid-template-columns: 2fr 1fr 1fr;
194
+ gap: layout.$spacing-03;
195
+ align-items: center;
196
+ padding: layout.$spacing-02;
197
+ }
198
+
199
+ .nameField,
200
+ .signField {
201
+ display: flex;
202
+ flex-direction: column;
203
+ gap: layout.$spacing-02;
204
+ }
205
+
206
+ .signatureLine {
207
+ border-bottom: 1px solid colors.$black;
208
+ height: layout.$spacing-04;
209
+ width: 100%;
210
+ }
211
+
212
+ .nameValue {
213
+ color: colors.$black;
214
+ border-bottom: 1px solid colors.$black;
215
+ padding: layout.$spacing-01;
216
+ min-height: layout.$spacing-04;
217
+ display: flex;
218
+ align-items: center;
219
+ font-size: 10px;
220
+ }
221
+
222
+ .footerNote {
223
+ margin-top: layout.$spacing-05;
224
+ padding: layout.$spacing-03;
225
+ border: 1px solid colors.$black;
226
+ border-radius: 2px;
227
+ }
228
+
229
+ .noteText {
230
+ color: colors.$black;
231
+ line-height: 1.4;
232
+ font-size: 10px;
233
+ }
234
+
235
+ .label {
236
+ font-weight: 600;
237
+ color: colors.$black;
238
+ font-size: 10px;
239
+ white-space: nowrap;
240
+ }
241
+
242
+ .value,
243
+ .valueWide {
244
+ color: colors.$black;
245
+ border-bottom: 1px solid colors.$black;
246
+ padding: layout.$spacing-01;
247
+ min-height: layout.$spacing-04;
248
+ display: flex;
249
+ align-items: center;
250
+ font-size: 10px;
251
+ }
252
+
253
+ .btnSet {
254
+ width: 100%;
255
+ margin-top: layout.$spacing-05;
256
+ }
257
+
258
+ @media print {
259
+ body * {
260
+ visibility: hidden;
261
+ }
262
+ .printableContent,
263
+ .printableContent * {
264
+ visibility: visible;
265
+ }
266
+ .printableContent {
267
+ position: absolute;
268
+ left: 0;
269
+ top: 0;
270
+ width: 100%;
271
+ height: 100%;
272
+ margin: 0;
273
+ padding: layout.$spacing-07;
274
+ }
275
+ }
276
+
277
+ .footer {
278
+ margin-top: layout.$spacing-06;
279
+ padding-top: layout.$spacing-04;
280
+ border-top: 1px solid colors.$black;
281
+ text-align: center;
282
+ page-break-inside: avoid;
283
+
284
+ @media print {
285
+ position: fixed !important;
286
+ bottom: layout.$spacing-05 !important;
287
+ left: 0 !important;
288
+ right: 0 !important;
289
+ width: 100% !important;
290
+ margin: 0 !important;
291
+ padding: layout.$spacing-03 0 !important;
292
+ background: colors.$white !important;
293
+ border-top: 0.5pt solid colors.$gray-50 !important;
294
+ z-index: 1000 !important;
295
+ box-sizing: border-box !important;
296
+ }
297
+ }
298
+
299
+ .footerDetails {
300
+ margin-top: layout.$spacing-03;
301
+ padding-top: layout.$spacing-03;
302
+ border-top: 1px solid colors.$gray-30;
303
+ font-size: layout.$spacing-02;
304
+ color: colors.$gray-70;
305
+ text-align: center;
306
+ line-height: 1.3;
307
+
308
+ div {
309
+ margin-bottom: layout.$spacing-02;
310
+
311
+ &:last-child {
312
+ margin-bottom: 0;
313
+ }
314
+ }
315
+
316
+ @media print {
317
+ margin: 0 !important;
318
+ padding: layout.$spacing-02 0 !important;
319
+ border-top: none !important;
320
+ font-size: 7pt !important;
321
+ color: colors.$gray-50 !important;
322
+ line-height: 1.1 !important;
323
+
324
+ div {
325
+ margin-bottom: layout.$spacing-01 !important;
326
+ display: inline-block !important;
327
+
328
+ &:last-child {
329
+ margin-bottom: 0 !important;
330
+ }
331
+ }
332
+ }
333
+ }
package/src/routes.json CHANGED
@@ -33,6 +33,11 @@
33
33
  "fullWidth": false
34
34
  }
35
35
  },
36
+ {
37
+ "name": "print-post-mortem-overflow-menu-item",
38
+ "component": "printPostMortemOverflowMenuItem",
39
+ "slot": "print-post-mortem-overflow-menu-item-slot"
40
+ },
36
41
  {
37
42
  "component": "root",
38
43
  "name": "morgue-dashboard-root",
@@ -89,6 +94,16 @@
89
94
  "title": "Dispose Deceased Person",
90
95
  "type": "other-form"
91
96
  }
97
+ ],
98
+ "modals": [
99
+ {
100
+ "name": "print-confirmation-modal",
101
+ "component": "printConfirmationModal"
102
+ },
103
+ {
104
+ "name": "autopsy-report-modal",
105
+ "component": "autopsyReportModal"
106
+ }
92
107
  ],
93
108
  "pages": [
94
109
  {
@@ -110,3 +110,9 @@ export const parseDischargeDateTime = (data: {
110
110
 
111
111
  return dischargeDateTime;
112
112
  };
113
+
114
+ export const documentId = () => {
115
+ const timestamp = Date.now();
116
+ const random = Math.random().toString(36).substr(2, 9);
117
+ return `PM-${timestamp}-${random}`.toUpperCase();
118
+ };
@@ -1,12 +1,26 @@
1
1
  import React from 'react';
2
+ import { useParams } from 'react-router-dom';
2
3
  import { ExtensionSlot, navigate, usePatient } from '@openmrs/esm-framework';
3
4
  import { useTranslation } from 'react-i18next';
4
- import { EmptyState, getPatientUuidFromStore } from '@openmrs/esm-patient-common-lib';
5
- import styles from './panels.scss';
5
+ import { EmptyState } from '@openmrs/esm-patient-common-lib';
6
+
7
+ interface RouteParams {
8
+ patientUuid: string;
9
+ [key: string]: string | undefined;
10
+ }
6
11
 
7
12
  const AttachmentView: React.FC = () => {
8
13
  const { t } = useTranslation();
9
- const patientUuid = getPatientUuidFromStore();
14
+ const { patientUuid } = useParams<RouteParams>();
15
+
16
+ if (!patientUuid) {
17
+ return (
18
+ <EmptyState
19
+ displayText={t('noPatientSelected', 'No patient selected')}
20
+ headerTitle={t('attachments', 'Attachments')}
21
+ />
22
+ );
23
+ }
10
24
 
11
25
  return (
12
26
  <ExtensionSlot