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

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 (116) hide show
  1. package/.turbo/turbo-build.log +20 -25
  2. package/dist/1.js +2 -0
  3. package/dist/1.js.map +1 -0
  4. package/dist/197.js +2 -1
  5. package/dist/197.js.map +1 -0
  6. package/dist/221.js +1 -1
  7. package/dist/221.js.map +1 -1
  8. package/dist/293.js +1 -1
  9. package/dist/294.js +1 -1
  10. package/dist/300.js +1 -1
  11. package/dist/340.js +2 -0
  12. package/dist/340.js.map +1 -0
  13. package/dist/351.js +1 -0
  14. package/dist/351.js.map +1 -0
  15. package/dist/404.js +1 -0
  16. package/dist/404.js.map +1 -0
  17. package/dist/441.js +1 -0
  18. package/dist/441.js.map +1 -0
  19. package/dist/578.js +1 -0
  20. package/dist/608.js +1 -0
  21. package/dist/608.js.map +1 -0
  22. package/dist/611.js +2 -0
  23. package/dist/611.js.map +1 -0
  24. package/dist/632.js +1 -1
  25. package/dist/632.js.map +1 -1
  26. package/dist/653.js +1 -1
  27. package/dist/653.js.map +1 -1
  28. package/dist/758.js +1 -0
  29. package/dist/758.js.map +1 -0
  30. package/dist/805.js +1 -1
  31. package/dist/805.js.map +1 -1
  32. package/dist/814.js +2 -0
  33. package/dist/814.js.LICENSE.txt +5 -0
  34. package/dist/814.js.map +1 -0
  35. package/dist/824.js +1 -1
  36. package/dist/824.js.map +1 -1
  37. package/dist/845.js +1 -0
  38. package/dist/845.js.map +1 -0
  39. package/dist/888.js +1 -0
  40. package/dist/888.js.map +1 -0
  41. package/dist/918.js +1 -1
  42. package/dist/918.js.map +1 -1
  43. package/dist/990.js +1 -0
  44. package/dist/990.js.map +1 -0
  45. package/dist/kenyaemr-esm-morgue-app.js +1 -1
  46. package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +250 -203
  47. package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
  48. package/dist/main.js +1 -1
  49. package/dist/main.js.LICENSE.txt +0 -6
  50. package/dist/main.js.map +1 -1
  51. package/dist/routes.json +1 -1
  52. package/package.json +1 -1
  53. package/src/bed/bed.component.tsx +63 -134
  54. package/src/bed/components/deceased-patient-card-header.component.tsx +73 -0
  55. package/src/bed/components/deceased-patient-info.component.tsx +47 -0
  56. package/src/bed/components/deceased-patient-status-footer.component.tsx +43 -0
  57. package/src/bed-layout/admitted/admitted-bed-layout.component.tsx +175 -96
  58. package/src/bed-layout/awaiting/awaiting-bed-layout.component.tsx +103 -36
  59. package/src/bed-layout/bed-layout.scss +4 -0
  60. package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +131 -73
  61. package/src/bed-linelist-view/admitted/admitted-bed-linelist-view.component.tsx +182 -134
  62. package/src/bed-linelist-view/awaiting/awaiting-bed-linelist-view.component.tsx +115 -71
  63. package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +181 -109
  64. package/src/config-schema.ts +140 -4
  65. package/src/context/deceased-person-context.tsx +33 -0
  66. package/src/extension/actionButton.component.tsx +1 -1
  67. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.resource.ts +84 -166
  68. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.scss +14 -0
  69. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.workspace.tsx +504 -334
  70. package/src/forms/discharge-deceased-person-workspace/discharge-body.resource.ts +0 -1
  71. package/src/forms/discharge-deceased-person-workspace/discharge-body.scss +15 -0
  72. package/src/forms/discharge-deceased-person-workspace/discharge-body.workspace.tsx +303 -244
  73. package/src/helpers/expression-helper.ts +122 -0
  74. package/src/home/home.component.tsx +23 -4
  75. package/src/index.ts +0 -2
  76. package/src/metrics/metrics-card.component.tsx +2 -2
  77. package/src/routes.json +0 -6
  78. package/src/schemas/index.ts +243 -51
  79. package/src/summary/summary.component.tsx +16 -9
  80. package/src/switcher/content-switcher.component.tsx +61 -35
  81. package/src/switcher/content-switcher.scss +13 -0
  82. package/src/types/index.ts +43 -1
  83. package/translations/am.json +16 -6
  84. package/translations/en.json +16 -6
  85. package/translations/sw.json +16 -6
  86. package/dist/373.js +0 -2
  87. package/dist/373.js.map +0 -1
  88. package/dist/398.js +0 -1
  89. package/dist/398.js.map +0 -1
  90. package/dist/410.js +0 -1
  91. package/dist/410.js.map +0 -1
  92. package/dist/429.js +0 -2
  93. package/dist/429.js.map +0 -1
  94. package/dist/467.js +0 -1
  95. package/dist/467.js.map +0 -1
  96. package/dist/579.js +0 -2
  97. package/dist/579.js.map +0 -1
  98. package/dist/619.js +0 -1
  99. package/dist/619.js.map +0 -1
  100. package/dist/633.js +0 -1
  101. package/dist/633.js.map +0 -1
  102. package/dist/712.js +0 -1
  103. package/dist/712.js.map +0 -1
  104. package/dist/713.js +0 -1
  105. package/dist/713.js.map +0 -1
  106. package/dist/723.js +0 -1
  107. package/dist/723.js.map +0 -1
  108. package/dist/989.js +0 -2
  109. package/dist/989.js.map +0 -1
  110. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.resource.ts +0 -18
  111. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.scss +0 -84
  112. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.workspace.tsx +0 -505
  113. /package/dist/{373.js.LICENSE.txt → 1.js.LICENSE.txt} +0 -0
  114. /package/dist/{989.js.LICENSE.txt → 197.js.LICENSE.txt} +0 -0
  115. /package/dist/{579.js.LICENSE.txt → 340.js.LICENSE.txt} +0 -0
  116. /package/dist/{429.js.LICENSE.txt → 611.js.LICENSE.txt} +0 -0
@@ -1,18 +0,0 @@
1
- import useSWR from 'swr';
2
- import { type ConceptResponse } from '../../types';
3
- import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
4
-
5
- export const useConcept = (conceptUuid: string) => {
6
- const apiUrl = `${restBaseUrl}/concept/${conceptUuid}`;
7
-
8
- const { data, error, isLoading } = useSWR<{ data: ConceptResponse }, Error>(
9
- conceptUuid ? apiUrl : null,
10
- openmrsFetch,
11
- );
12
-
13
- return {
14
- concept: data?.data || null,
15
- error: error,
16
- isLoading: isLoading,
17
- };
18
- };
@@ -1,84 +0,0 @@
1
- @use '@carbon/colors';
2
- @use '@carbon/layout';
3
- @use '@carbon/type';
4
-
5
- .form {
6
- display: flex;
7
- flex-direction: column;
8
- justify-content: space-between;
9
- height: 100%;
10
- }
11
-
12
- .formContainer {
13
- margin: layout.$spacing-05;
14
- display: flex;
15
- flex-direction: column;
16
- gap: layout.$spacing-05;
17
- }
18
-
19
- .tablet {
20
- padding: layout.$spacing-06 layout.$spacing-05;
21
- background-color: colors.$white;
22
- }
23
-
24
- .desktop {
25
- padding: 0;
26
- padding: layout.$spacing-01 layout.$spacing-04;
27
- }
28
- .buttonContainer {
29
- max-width: 50%;
30
- }
31
- .inlineLoading {
32
- display: flex;
33
- align-items: center;
34
- gap: layout.$spacing-03;
35
- }
36
- .formDeathTimepickerSelector {
37
- min-width: layout.$spacing-05;
38
- margin-top: layout.$spacing-06;
39
- }
40
- .formAdmissionTimepicker input {
41
- min-width: 11rem;
42
- }
43
- .formAdmissionDatepicker input {
44
- min-width: 24rem;
45
- }
46
- .dateTimeSection {
47
- display: flex;
48
- flex-direction: row;
49
- gap: layout.$spacing-02;
50
- align-items: center;
51
- margin-top: layout.$spacing-02;
52
- }
53
-
54
- .radioButtonGroup {
55
- display: flex;
56
- flex-direction: column;
57
- align-items: flex-start;
58
- margin-top: layout.$spacing-03;
59
- min-height: layout.$spacing-10;
60
- width: 100%;
61
- @include type.type-style('body-compact-01');
62
- }
63
-
64
- .radioButton {
65
- padding: layout.$spacing-02 layout.$spacing-05;
66
- margin: layout.$spacing-03 0;
67
- }
68
-
69
- .visitTypeOverviewWrapper {
70
- margin: layout.$spacing-05 0;
71
- border: 0.0625rem solid colors.$gray-30;
72
- }
73
-
74
- .visitTypeOverviewWrapper div:nth-child(3) > div:nth-child(2) {
75
- position: relative;
76
- }
77
-
78
- .visitTypeOverviewWrapper div:nth-child(3) span * {
79
- display: none;
80
- }
81
-
82
- .sectionField {
83
- padding-top: layout.$spacing-03;
84
- }
@@ -1,505 +0,0 @@
1
- import {
2
- Button,
3
- ButtonSet,
4
- Column,
5
- DatePicker,
6
- DatePickerInput,
7
- Form,
8
- InlineLoading,
9
- InlineNotification,
10
- SelectItem,
11
- Stack,
12
- TextInput,
13
- TimePicker,
14
- TimePickerSelect,
15
- } from '@carbon/react';
16
- import { zodResolver } from '@hookform/resolvers/zod';
17
- import {
18
- ExtensionSlot,
19
- fhirBaseUrl,
20
- ResponsiveWrapper,
21
- restBaseUrl,
22
- setCurrentVisit,
23
- showSnackbar,
24
- useConfig,
25
- useLayoutType,
26
- useVisit,
27
- } from '@openmrs/esm-framework';
28
- import React, { useCallback, useEffect, useState } from 'react';
29
- import { Controller, useForm } from 'react-hook-form';
30
- import { useTranslation } from 'react-i18next';
31
- import { mutate as mutateSWR } from 'swr';
32
- import { z } from 'zod';
33
- import styles from './dispose-deceased-person.scss';
34
- import DeceasedInfo from '../../deceased-patient-header/deceasedInfo/deceased-info.component';
35
- import { PatientInfo } from '../../types';
36
- import {
37
- useBlockDischargeWithPendingBills,
38
- usePersonAttributes,
39
- } from '../discharge-deceased-person-workspace/discharge-body.resource';
40
- import { ConfigObject } from '../../config-schema';
41
- import { getCurrentTime } from '../../utils/utils';
42
- import { disposeSchema } from '../../schemas';
43
- import { useAwaitingQueuePatients, useVisitQueueEntry } from '../../home/home.resource';
44
- import classNames from 'classnames';
45
- import { useMortuaryOperation } from '../admit-deceased-person-workspace/admit-deceased-person.resource';
46
-
47
- interface DisposeFormProps {
48
- closeWorkspace: () => void;
49
- patientUuid: string;
50
- bedId: number;
51
- mutate: () => void;
52
- }
53
-
54
- type DisposeFormValues = z.infer<typeof disposeSchema>;
55
-
56
- const DisposeForm: React.FC<DisposeFormProps> = ({ closeWorkspace, patientUuid, bedId, mutate }) => {
57
- const { t } = useTranslation();
58
- const isTablet = useLayoutType() === 'tablet';
59
- const [submissionError, setSubmissionError] = useState<string | null>(null);
60
-
61
- const { activeVisit, currentVisitIsRetrospective } = useVisit(patientUuid);
62
- const { queueEntry } = useVisitQueueEntry(patientUuid, activeVisit?.uuid);
63
-
64
- const { disposeBody, isLoadingEmrConfiguration } = useMortuaryOperation();
65
-
66
- const {
67
- createOrUpdatePersonAttribute,
68
- personAttributes,
69
- isLoading: isLoadingAttributes,
70
- } = usePersonAttributes(patientUuid);
71
-
72
- const { isDischargeBlocked, blockingMessage, isLoadingBills } = useBlockDischargeWithPendingBills({
73
- patientUuid,
74
- actionType: 'dispose',
75
- });
76
-
77
- const { nextOfKinNameUuid, nextOfKinRelationshipUuid, nextOfKinPhoneUuid, nextOfKinAddressUuid } =
78
- useConfig<ConfigObject>();
79
-
80
- const { time: defaultTime, period: defaultPeriod } = getCurrentTime();
81
-
82
- const getAttributeValue = useCallback(
83
- (attributeTypeUuid: string) => {
84
- if (!personAttributes || !Array.isArray(personAttributes)) {
85
- return '';
86
- }
87
- const attribute = personAttributes.find((attr) => attr.attributeType.uuid === attributeTypeUuid);
88
- return attribute ? attribute.value : '';
89
- },
90
- [personAttributes],
91
- );
92
-
93
- const getExistingAttributeUuid = useCallback(
94
- (attributeTypeUuid: string) => {
95
- if (!personAttributes || !Array.isArray(personAttributes)) {
96
- return null;
97
- }
98
- const attribute = personAttributes.find((attr) => attr.attributeType.uuid === attributeTypeUuid);
99
- return attribute ? attribute.uuid : null;
100
- },
101
- [personAttributes],
102
- );
103
-
104
- const {
105
- control,
106
- setValue,
107
- handleSubmit,
108
- formState: { errors, isDirty, isSubmitting },
109
- watch,
110
- } = useForm<DisposeFormValues>({
111
- resolver: zodResolver(disposeSchema),
112
- defaultValues: {
113
- dateOfDischarge: new Date(),
114
- timeOfDischarge: defaultTime,
115
- period: defaultPeriod,
116
- serialNumber: '',
117
- courtOrderCaseNumber: '',
118
- nextOfKinNames: '',
119
- relationshipType: '',
120
- nextOfKinContact: '',
121
- nextOfKinAddress: '',
122
- },
123
- });
124
-
125
- useEffect(() => {
126
- if (Array.isArray(personAttributes) && personAttributes.length > 0) {
127
- const initialValues = {
128
- nextOfKinNames: getAttributeValue(nextOfKinNameUuid),
129
- relationshipType: getAttributeValue(nextOfKinRelationshipUuid),
130
- nextOfKinContact: getAttributeValue(nextOfKinPhoneUuid),
131
- nextOfKinAddress: getAttributeValue(nextOfKinAddressUuid),
132
- };
133
-
134
- Object.entries(initialValues).forEach(([field, value]) => {
135
- if (value !== undefined && value !== null && value !== '') {
136
- setValue(field as keyof DisposeFormValues, value);
137
- }
138
- });
139
- }
140
- }, [
141
- personAttributes,
142
- setValue,
143
- getAttributeValue,
144
- nextOfKinNameUuid,
145
- nextOfKinRelationshipUuid,
146
- nextOfKinPhoneUuid,
147
- nextOfKinAddressUuid,
148
- ]);
149
-
150
- const onSubmit = async (data: DisposeFormValues) => {
151
- setSubmissionError(null);
152
-
153
- if (currentVisitIsRetrospective) {
154
- setCurrentVisit(null, null);
155
- closeWorkspace();
156
- return;
157
- }
158
-
159
- try {
160
- await disposeBody(activeVisit, queueEntry, bedId, data);
161
-
162
- const attributeUpdates = [
163
- {
164
- uuid: nextOfKinNameUuid,
165
- value: data.nextOfKinNames,
166
- existingUuid: getExistingAttributeUuid(nextOfKinNameUuid),
167
- },
168
- {
169
- uuid: nextOfKinRelationshipUuid,
170
- value: data.relationshipType,
171
- existingUuid: getExistingAttributeUuid(nextOfKinRelationshipUuid),
172
- },
173
- {
174
- uuid: nextOfKinPhoneUuid,
175
- value: data.nextOfKinContact,
176
- existingUuid: getExistingAttributeUuid(nextOfKinPhoneUuid),
177
- },
178
- {
179
- uuid: nextOfKinAddressUuid,
180
- value: data.nextOfKinAddress,
181
- existingUuid: getExistingAttributeUuid(nextOfKinAddressUuid),
182
- },
183
- ].filter((attr) => attr.value !== undefined && attr.value !== null && attr.value !== '');
184
-
185
- const patientInfo: PatientInfo = {
186
- uuid: activeVisit.patient.uuid,
187
- attributes: personAttributes || [],
188
- };
189
-
190
- for (const attr of attributeUpdates) {
191
- try {
192
- const attributeData: any = {
193
- attributeType: attr.uuid,
194
- value: attr.value,
195
- };
196
-
197
- if (attr.existingUuid) {
198
- attributeData.uuid = attr.existingUuid;
199
- }
200
-
201
- await createOrUpdatePersonAttribute(patientUuid, attributeData, patientInfo);
202
- } catch (error) {
203
- showSnackbar({
204
- title: t('errorUpdatingAttribute', 'Error Updating Attribute'),
205
- subtitle: t('errorUpdatingAttributeDescription', 'An error occurred while updating the attribute'),
206
- kind: 'error',
207
- isLowContrast: true,
208
- });
209
- }
210
- }
211
-
212
- await Promise.all([
213
- mutateSWR((key) => typeof key === 'string' && key.startsWith(`${restBaseUrl}/visit`)),
214
- mutateSWR((key) => typeof key === 'string' && key.startsWith(`${restBaseUrl}/patient`)),
215
- mutateSWR((key) => typeof key === 'string' && key.startsWith(`${fhirBaseUrl}/Encounter`)),
216
- ]);
217
-
218
- showSnackbar({
219
- title: t('disposedDeceasedPatient', 'Deceased patient disposed'),
220
- subtitle: t('deceasedPatientDisposedSuccessfully', 'Deceased patient has been disposed successfully'),
221
- kind: 'success',
222
- isLowContrast: true,
223
- });
224
-
225
- mutate();
226
- closeWorkspace();
227
- } catch (error) {
228
- let errorMessage = t('disposeUnknownError', 'An unknown error occurred');
229
- if (error?.message) {
230
- errorMessage = error.message;
231
- } else if (error?.responseBody?.error?.message) {
232
- errorMessage = error.responseBody.error.message.replace(/\[|\]/g, '');
233
- } else if (error?.responseBody?.error?.globalErrors) {
234
- errorMessage = error.responseBody.error.globalErrors[0]?.message || errorMessage;
235
- }
236
-
237
- setSubmissionError(errorMessage);
238
- showSnackbar({
239
- title: t('disposedError', 'Dispose Error'),
240
- subtitle: errorMessage,
241
- kind: 'error',
242
- isLowContrast: true,
243
- });
244
- }
245
- };
246
-
247
- if (isLoadingEmrConfiguration || isLoadingAttributes || !activeVisit) {
248
- return <InlineLoading status="active" iconDescription="Loading" description={t('loading', 'Loading...')} />;
249
- }
250
-
251
- return (
252
- <Form onSubmit={handleSubmit(onSubmit)} className={styles.form}>
253
- <div className={styles.formContainer}>
254
- {isLoadingBills && (
255
- <InlineLoading
256
- status="active"
257
- iconDescription="Loading"
258
- description={t('loadingBills', 'Loading bills...')}
259
- />
260
- )}
261
-
262
- {isDischargeBlocked && (
263
- <InlineNotification
264
- kind="warning"
265
- title={t('warningMsg', 'Warning')}
266
- subtitle={blockingMessage}
267
- lowContrast={true}
268
- className={styles.blockingNotification}
269
- />
270
- )}
271
-
272
- {submissionError && (
273
- <InlineNotification
274
- kind="error"
275
- title={t('error', 'Error')}
276
- subtitle={submissionError}
277
- lowContrast={true}
278
- className={styles.errorNotification}
279
- />
280
- )}
281
-
282
- <Stack gap={3}>
283
- <DeceasedInfo patientUuid={patientUuid} />
284
-
285
- <ResponsiveWrapper>
286
- <div className={styles.dateTimePickerContainer}>
287
- <Column>
288
- <Controller
289
- name="dateOfDischarge"
290
- control={control}
291
- render={({ field }) => (
292
- <DatePicker
293
- datePickerType="single"
294
- className={styles.formAdmissionDatepicker}
295
- onChange={(event) => {
296
- if (event.length) {
297
- field.onChange(event[0]);
298
- }
299
- }}
300
- value={field.value ? new Date(field.value) : null}>
301
- <DatePickerInput
302
- {...field}
303
- id="date-of-discharge"
304
- placeholder="yyyy-mm-dd"
305
- labelText={t('dateOfDischarge', 'Date of discharge*')}
306
- invalid={!!errors.dateOfDischarge}
307
- invalidText={errors.dateOfDischarge?.message}
308
- />
309
- </DatePicker>
310
- )}
311
- />
312
- </Column>
313
-
314
- <Column>
315
- <div className={styles.dateTimeSection}>
316
- <ResponsiveWrapper>
317
- <Controller
318
- name="timeOfDischarge"
319
- control={control}
320
- render={({ field }) => (
321
- <TimePicker
322
- {...field}
323
- id="time-of-discharge-picker"
324
- labelText={t('timeOfDischarge', 'Time of discharge*')}
325
- className={styles.formAdmissionTimepicker}
326
- invalid={!!errors.timeOfDischarge}
327
- invalidText={errors.timeOfDischarge?.message}
328
- />
329
- )}
330
- />
331
- <Controller
332
- name="period"
333
- control={control}
334
- render={({ field }) => (
335
- <TimePickerSelect
336
- {...field}
337
- className={styles.formDeathTimepickerSelector}
338
- id="time-picker-select">
339
- <SelectItem value="AM" text="AM" />
340
- <SelectItem value="PM" text="PM" />
341
- </TimePickerSelect>
342
- )}
343
- />
344
- </ResponsiveWrapper>
345
- </div>
346
- </Column>
347
- </div>
348
-
349
- <Column className={styles.fieldColumn}>
350
- <Controller
351
- name="serialNumber"
352
- control={control}
353
- render={({ field }) => (
354
- <TextInput
355
- {...field}
356
- id="serialNumber"
357
- type="text"
358
- className={styles.sectionField}
359
- placeholder={t('serialNumber', 'Serial number')}
360
- labelText={t('serialNumber', 'Serial number*')}
361
- invalid={!!errors.serialNumber}
362
- invalidText={errors.serialNumber?.message}
363
- />
364
- )}
365
- />
366
- </Column>
367
-
368
- <Column className={styles.fieldColumn}>
369
- <Controller
370
- name="courtOrderCaseNumber"
371
- control={control}
372
- render={({ field }) => (
373
- <TextInput
374
- {...field}
375
- id="courtOrderCaseNumber"
376
- type="text"
377
- className={styles.sectionField}
378
- placeholder={t('courtOrderCaseNumber', 'Court order case number')}
379
- labelText={t('courtOrderCaseNumber', 'Court order case number')}
380
- invalid={!!errors.courtOrderCaseNumber}
381
- invalidText={errors.courtOrderCaseNumber?.message}
382
- />
383
- )}
384
- />
385
- </Column>
386
-
387
- <Column className={styles.fieldColumn}>
388
- <Controller
389
- name="nextOfKinNames"
390
- control={control}
391
- render={({ field }) => (
392
- <TextInput
393
- {...field}
394
- id="nextOfKinNames"
395
- type="text"
396
- className={styles.sectionField}
397
- placeholder={t('nextOfKinNames', 'Next of kin names')}
398
- labelText={t('nextOfKinNames', 'Next of kin names')}
399
- invalid={!!errors.nextOfKinNames}
400
- invalidText={errors.nextOfKinNames?.message}
401
- />
402
- )}
403
- />
404
- </Column>
405
-
406
- <Column className={styles.fieldColumn}>
407
- <Controller
408
- name="relationshipType"
409
- control={control}
410
- render={({ field }) => (
411
- <TextInput
412
- {...field}
413
- id="relationshipType"
414
- type="text"
415
- className={styles.sectionField}
416
- placeholder={t('relationshipType', 'Relationship')}
417
- labelText={t('relationshipType', 'Relationship')}
418
- invalid={!!errors.relationshipType}
419
- invalidText={errors.relationshipType?.message}
420
- />
421
- )}
422
- />
423
- </Column>
424
-
425
- <Column className={styles.fieldColumn}>
426
- <Controller
427
- name="nextOfKinContact"
428
- control={control}
429
- render={({ field }) => (
430
- <TextInput
431
- {...field}
432
- id="nextOfKinContact"
433
- type="text"
434
- className={styles.sectionField}
435
- placeholder={t('nextOfKinContact', 'Next of kin contact')}
436
- labelText={t('nextOfKinContact', 'Next of kin contact')}
437
- invalid={!!errors.nextOfKinContact}
438
- invalidText={errors.nextOfKinContact?.message}
439
- />
440
- )}
441
- />
442
- </Column>
443
-
444
- <Column className={styles.fieldColumn}>
445
- <Controller
446
- name="nextOfKinAddress"
447
- control={control}
448
- render={({ field }) => (
449
- <TextInput
450
- {...field}
451
- id="nextOfKinAddress"
452
- type="text"
453
- className={styles.sectionField}
454
- placeholder={t('nextOfKinAddress', 'Next of kin address')}
455
- labelText={t('nextOfKinAddress', 'Next of kin address')}
456
- invalid={!!errors.nextOfKinAddress}
457
- invalidText={errors.nextOfKinAddress?.message}
458
- />
459
- )}
460
- />
461
- </Column>
462
- </ResponsiveWrapper>
463
-
464
- <ResponsiveWrapper>
465
- <Column>
466
- <ExtensionSlot
467
- name="patient-chart-attachments-dashboard-slot"
468
- className={styles.sectionField}
469
- state={{
470
- patientUuid,
471
- }}
472
- />
473
- </Column>
474
- </ResponsiveWrapper>
475
- </Stack>
476
- </div>
477
-
478
- <ButtonSet
479
- className={classNames({
480
- [styles.tablet]: isTablet,
481
- [styles.desktop]: !isTablet,
482
- })}>
483
- <Button className={styles.buttonContainer} kind="secondary" onClick={() => closeWorkspace()}>
484
- {t('cancel', 'Cancel')}
485
- </Button>
486
- <Button
487
- className={styles.buttonContainer}
488
- disabled={isSubmitting || !isDirty || isDischargeBlocked || isLoadingBills}
489
- kind="primary"
490
- type="submit">
491
- {isSubmitting ? (
492
- <span className={styles.inlineLoading}>
493
- {t('submitting', 'Submitting...')}
494
- <InlineLoading status="active" iconDescription="Loading" />
495
- </span>
496
- ) : (
497
- t('saveAndClose', 'Save & close')
498
- )}
499
- </Button>
500
- </ButtonSet>
501
- </Form>
502
- );
503
- };
504
-
505
- export default DisposeForm;
File without changes
File without changes
File without changes
File without changes