@kenyaemr/esm-ward-app 8.1.1-pre.123 → 8.1.1-pre.129
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.
- package/.turbo/turbo-build.log +8 -8
- package/dist/124.js +1 -1
- package/dist/124.js.map +1 -1
- package/dist/125.js +1 -1
- package/dist/125.js.map +1 -1
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/153.js +1 -1
- package/dist/153.js.map +1 -1
- package/dist/303.js +2 -0
- package/dist/303.js.map +1 -0
- package/dist/471.js +1 -1
- package/dist/471.js.map +1 -1
- package/dist/53.js +1 -1
- package/dist/53.js.map +1 -1
- package/dist/574.js +1 -1
- package/dist/577.js +1 -1
- package/dist/577.js.map +1 -1
- package/dist/662.js +1 -1
- package/dist/662.js.map +1 -1
- package/dist/921.js +1 -1
- package/dist/921.js.map +1 -1
- package/dist/922.js +1 -1
- package/dist/922.js.map +1 -1
- package/dist/kenyaemr-esm-ward-app.js +1 -1
- package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +60 -60
- package/dist/kenyaemr-esm-ward-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/beds/ward-bed.test.tsx +16 -5
- package/src/hooks/useWardPatientGrouping.ts +5 -0
- package/src/ward-view/materal-ward/maternal-ward-patient-card.test.tsx +11 -0
- package/src/ward-view/ward-view.scss +1 -1
- package/src/ward-view/ward-view.test.tsx +8 -0
- package/src/ward-view-header/ward-metric.scss +5 -5
- package/src/ward-view-header/ward-metrics.scss +1 -2
- package/src/ward-workspace/admission-request-card/admission-request-card-actions.component.tsx +59 -6
- package/src/ward-workspace/admission-request-workspace/admission-requests-workspace.test.tsx +45 -1
- package/src/ward-workspace/admission-request-workspace/admission-requests.workspace.tsx +26 -5
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.test.tsx +30 -94
- package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +101 -189
- package/src/ward-workspace/bed-selector.component.tsx +119 -0
- package/src/ward-workspace/bed-selector.scss +15 -0
- package/src/ward-workspace/patient-discharge/patient-discharge.workspace.tsx +4 -11
- package/src/ward-workspace/patient-transfer-bed-swap/patient-bed-swap-form.component.tsx +56 -77
- package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-request-form.component.tsx +3 -10
- package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-swap.workspace.tsx +10 -6
- package/src/ward.resource.ts +32 -2
- package/translations/en.json +6 -5
- package/dist/67.js +0 -2
- package/dist/67.js.map +0 -1
- /package/dist/{67.js.LICENSE.txt → 303.js.LICENSE.txt} +0 -0
|
@@ -1,18 +1,24 @@
|
|
|
1
|
-
import { Button, ButtonSet, Column,
|
|
1
|
+
import { Button, ButtonSet, Column, Form, InlineNotification, Row } from '@carbon/react';
|
|
2
2
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
3
|
-
import { showSnackbar, useAppContext
|
|
3
|
+
import { showSnackbar, useAppContext } from '@openmrs/esm-framework';
|
|
4
4
|
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import { Controller, useForm } from 'react-hook-form';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { z } from 'zod';
|
|
8
|
-
import
|
|
8
|
+
import { useAssignedBedByPatient } from '../../hooks/useAssignedBedByPatient';
|
|
9
9
|
import useWardLocation from '../../hooks/useWardLocation';
|
|
10
|
-
import type {
|
|
11
|
-
import { assignPatientToBed,
|
|
10
|
+
import type { WardViewContext } from '../../types';
|
|
11
|
+
import { assignPatientToBed, removePatientFromBed, useAdmitPatient } from '../../ward.resource';
|
|
12
|
+
import BedSelector from '../bed-selector.component';
|
|
12
13
|
import styles from './admit-patient-form.scss';
|
|
13
14
|
import type { AdmitPatientFormWorkspaceProps } from './types';
|
|
14
|
-
import { useAssignedBedByPatient } from '../../hooks/useAssignedBedByPatient';
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* This form gets rendered when the user clicks "admit patient" in
|
|
18
|
+
* the patient card in the admission requests workspace, but only when
|
|
19
|
+
* the bed management module is installed. It asks to (optionally) select
|
|
20
|
+
* a bed to assign to patient
|
|
21
|
+
*/
|
|
16
22
|
const AdmitPatientFormWorkspace: React.FC<AdmitPatientFormWorkspaceProps> = ({
|
|
17
23
|
patient,
|
|
18
24
|
dispositionType,
|
|
@@ -22,34 +28,23 @@ const AdmitPatientFormWorkspace: React.FC<AdmitPatientFormWorkspaceProps> = ({
|
|
|
22
28
|
}) => {
|
|
23
29
|
const { t } = useTranslation();
|
|
24
30
|
const { location } = useWardLocation();
|
|
25
|
-
const { currentProvider } = useSession();
|
|
26
31
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
27
|
-
const {
|
|
32
|
+
const { admitPatient, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useAdmitPatient();
|
|
28
33
|
const [showErrorNotifications, setShowErrorNotifications] = useState(false);
|
|
29
34
|
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
30
|
-
const { isLoading
|
|
31
|
-
|
|
32
|
-
const { mutate: mutateInpatientAdmission } = wardPatientGroupDetails?.inpatientAdmissionResponse ?? {};
|
|
35
|
+
const { isLoading } = wardPatientGroupDetails?.admissionLocationResponse ?? {};
|
|
36
|
+
|
|
33
37
|
const { data: bedsAssignedToPatient, isLoading: isLoadingBedsAssignedToPatient } = useAssignedBedByPatient(
|
|
34
38
|
patient.uuid,
|
|
35
39
|
);
|
|
36
40
|
const beds = isLoading ? [] : wardPatientGroupDetails?.bedLayouts ?? [];
|
|
37
|
-
const isBedManagementModuleInstalled = useFeatureFlag('bedmanagement-module');
|
|
38
|
-
const getBedRepresentation = useCallback((bedLayout: BedLayout) => {
|
|
39
|
-
const bedNumber = bedLayout.bedNumber;
|
|
40
|
-
const patients =
|
|
41
|
-
bedLayout.patients.length === 0
|
|
42
|
-
? [t('emptyText', 'Empty')]
|
|
43
|
-
: bedLayout.patients.map((patient) => patient?.person?.preferredName?.display);
|
|
44
|
-
return [bedNumber, ...patients].join(' · ');
|
|
45
|
-
}, []);
|
|
46
41
|
|
|
47
42
|
const zodSchema = useMemo(
|
|
48
43
|
() =>
|
|
49
44
|
z.object({
|
|
50
45
|
bedId: z.number().optional(),
|
|
51
46
|
}),
|
|
52
|
-
[
|
|
47
|
+
[beds],
|
|
53
48
|
);
|
|
54
49
|
|
|
55
50
|
type FormValues = z.infer<typeof zodSchema>;
|
|
@@ -58,8 +53,6 @@ const AdmitPatientFormWorkspace: React.FC<AdmitPatientFormWorkspaceProps> = ({
|
|
|
58
53
|
control,
|
|
59
54
|
formState: { errors, isDirty },
|
|
60
55
|
handleSubmit,
|
|
61
|
-
getValues,
|
|
62
|
-
watch,
|
|
63
56
|
} = useForm<FormValues>({
|
|
64
57
|
resolver: zodResolver(zodSchema),
|
|
65
58
|
});
|
|
@@ -68,114 +61,77 @@ const AdmitPatientFormWorkspace: React.FC<AdmitPatientFormWorkspaceProps> = ({
|
|
|
68
61
|
promptBeforeClosing(() => isDirty);
|
|
69
62
|
}, [isDirty]);
|
|
70
63
|
|
|
71
|
-
const onSubmit =
|
|
72
|
-
(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
encounterProviders: [
|
|
86
|
-
{
|
|
87
|
-
provider: currentProvider?.uuid,
|
|
88
|
-
encounterRole: emrConfiguration.clinicianEncounterRole.uuid,
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
obs: [],
|
|
92
|
-
})
|
|
93
|
-
.then(
|
|
94
|
-
async (response) => {
|
|
95
|
-
if (response.ok) {
|
|
96
|
-
if (bedSelected) {
|
|
97
|
-
return assignPatientToBed(values.bedId, patient.uuid, response.data.uuid);
|
|
98
|
-
} else {
|
|
99
|
-
const assignedBedId = bedsAssignedToPatient?.data?.results?.[0]?.bedId;
|
|
100
|
-
if (assignedBedId) {
|
|
101
|
-
return removePatientFromBed(assignedBedId, patient.uuid);
|
|
102
|
-
}
|
|
103
|
-
return response;
|
|
64
|
+
const onSubmit = (values: FormValues) => {
|
|
65
|
+
setShowErrorNotifications(false);
|
|
66
|
+
setIsSubmitting(true);
|
|
67
|
+
const bedSelected = beds.find((bed) => bed.bedId === values.bedId);
|
|
68
|
+
admitPatient(patient, dispositionType)
|
|
69
|
+
.then(
|
|
70
|
+
async (response) => {
|
|
71
|
+
if (response.ok) {
|
|
72
|
+
if (bedSelected) {
|
|
73
|
+
return assignPatientToBed(values.bedId, patient.uuid, response.data.uuid);
|
|
74
|
+
} else {
|
|
75
|
+
const assignedBedId = bedsAssignedToPatient?.data?.results?.[0]?.bedId;
|
|
76
|
+
if (assignedBedId) {
|
|
77
|
+
return removePatientFromBed(assignedBedId, patient.uuid);
|
|
104
78
|
}
|
|
79
|
+
return response;
|
|
105
80
|
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
subtitle: t('patientAdmittedWoBed', 'Patient admitted successfully to {{location}}', {
|
|
141
|
-
location: location?.display,
|
|
142
|
-
}),
|
|
143
|
-
});
|
|
144
|
-
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
(err: Error) => {
|
|
84
|
+
showSnackbar({
|
|
85
|
+
kind: 'error',
|
|
86
|
+
title: t('errorCreatingEncounter', 'Failed to admit patient'),
|
|
87
|
+
subtitle: err.message,
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
)
|
|
91
|
+
.then(
|
|
92
|
+
(response) => {
|
|
93
|
+
if (response && response?.ok) {
|
|
94
|
+
if (bedSelected) {
|
|
95
|
+
showSnackbar({
|
|
96
|
+
kind: 'success',
|
|
97
|
+
title: t('patientAdmittedSuccessfully', 'Patient admitted successfully'),
|
|
98
|
+
subtitle: t(
|
|
99
|
+
'patientAdmittedSuccessfullySubtitle',
|
|
100
|
+
'{{patientName}} has been successfully admitted and assigned to bed {{bedNumber}}',
|
|
101
|
+
{
|
|
102
|
+
patientName: patient.person.preferredName.display,
|
|
103
|
+
bedNumber: bedSelected.bedNumber,
|
|
104
|
+
},
|
|
105
|
+
),
|
|
106
|
+
});
|
|
107
|
+
} else {
|
|
108
|
+
showSnackbar({
|
|
109
|
+
kind: 'success',
|
|
110
|
+
title: t('patientAdmittedSuccessfully', 'Patient admitted successfully'),
|
|
111
|
+
subtitle: t('patientAdmittedWoBed', 'Patient admitted successfully to {{location}}', {
|
|
112
|
+
location: location?.display,
|
|
113
|
+
}),
|
|
114
|
+
});
|
|
145
115
|
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
},
|
|
166
|
-
[
|
|
167
|
-
beds,
|
|
168
|
-
patient,
|
|
169
|
-
emrConfiguration,
|
|
170
|
-
location,
|
|
171
|
-
closeWorkspaceWithSavedChanges,
|
|
172
|
-
dispositionType,
|
|
173
|
-
currentProvider,
|
|
174
|
-
mutateAdmissionLocation,
|
|
175
|
-
mutateInpatientRequest,
|
|
176
|
-
mutateInpatientAdmission,
|
|
177
|
-
],
|
|
178
|
-
);
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
() => {
|
|
119
|
+
showSnackbar({
|
|
120
|
+
kind: 'warning',
|
|
121
|
+
title: t('patientAdmittedSuccessfully', 'Patient admitted successfully'),
|
|
122
|
+
subtitle: t(
|
|
123
|
+
'patientAdmittedButBedNotAssigned',
|
|
124
|
+
'Patient admitted successfully but fail to assign bed to patient',
|
|
125
|
+
),
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
)
|
|
129
|
+
.finally(() => {
|
|
130
|
+
setIsSubmitting(false);
|
|
131
|
+
wardPatientGroupDetails?.mutate?.();
|
|
132
|
+
closeWorkspaceWithSavedChanges();
|
|
133
|
+
});
|
|
134
|
+
};
|
|
179
135
|
|
|
180
136
|
const onError = useCallback((values) => {
|
|
181
137
|
setShowErrorNotifications(true);
|
|
@@ -186,71 +142,27 @@ const AdmitPatientFormWorkspace: React.FC<AdmitPatientFormWorkspaceProps> = ({
|
|
|
186
142
|
return (
|
|
187
143
|
<Form control={control} className={styles.form} onSubmit={handleSubmit(onSubmit, onError)}>
|
|
188
144
|
<div className={styles.formContent}>
|
|
189
|
-
{errorFetchingEmrConfiguration && (
|
|
190
|
-
<div className={styles.formError}>
|
|
191
|
-
<InlineNotification
|
|
192
|
-
kind="error"
|
|
193
|
-
title={t('somePartsOfTheFormDidntLoad', "Some parts of the form didn't load")}
|
|
194
|
-
subtitle={t(
|
|
195
|
-
'fetchingEmrConfigurationFailed',
|
|
196
|
-
'Fetching EMR configuration failed. Try refreshing the page or contact your system administrator.',
|
|
197
|
-
)}
|
|
198
|
-
lowContrast
|
|
199
|
-
hideCloseButton
|
|
200
|
-
/>
|
|
201
|
-
</div>
|
|
202
|
-
)}
|
|
203
145
|
<Row>
|
|
204
146
|
<Column>
|
|
205
147
|
<h2 className={styles.productiveHeading02}>{t('selectABed', 'Select a bed')}</h2>
|
|
206
148
|
<div className={styles.bedSelectionDropdown}>
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
selectedItem={selectedItem}
|
|
225
|
-
onChange={({ selectedItem }: { selectedItem: BedLayout }) => onChange(selectedItem.bedId)}
|
|
226
|
-
invalid={!!error}
|
|
227
|
-
invalidText={error?.message}
|
|
228
|
-
/>
|
|
229
|
-
);
|
|
230
|
-
}}
|
|
231
|
-
/>
|
|
232
|
-
) : (
|
|
233
|
-
<InlineNotification
|
|
234
|
-
kind="error"
|
|
235
|
-
title={t('noBedsConfiguredForLocation', 'No beds configured for {{location}} location', {
|
|
236
|
-
location: location?.display,
|
|
237
|
-
})}
|
|
238
|
-
lowContrast
|
|
239
|
-
hideCloseButton
|
|
240
|
-
/>
|
|
241
|
-
)
|
|
242
|
-
) : (
|
|
243
|
-
<InlineNotification
|
|
244
|
-
kind="info"
|
|
245
|
-
title={t('unableToSelectBeds', 'Unable to select beds')}
|
|
246
|
-
subtitle={t(
|
|
247
|
-
'bedManagementModuleNotInstalled',
|
|
248
|
-
'Bed management module is not present to allow bed selection',
|
|
249
|
-
)}
|
|
250
|
-
lowContrast
|
|
251
|
-
hideCloseButton
|
|
252
|
-
/>
|
|
253
|
-
)}
|
|
149
|
+
<Controller
|
|
150
|
+
control={control}
|
|
151
|
+
name="bedId"
|
|
152
|
+
render={({ field: { onChange, value }, fieldState: { error } }) => {
|
|
153
|
+
return (
|
|
154
|
+
<BedSelector
|
|
155
|
+
beds={beds}
|
|
156
|
+
isLoadingBeds={isLoading}
|
|
157
|
+
currentPatient={patient}
|
|
158
|
+
selectedBedId={value}
|
|
159
|
+
error={error}
|
|
160
|
+
control={control}
|
|
161
|
+
onChange={onChange}
|
|
162
|
+
/>
|
|
163
|
+
);
|
|
164
|
+
}}
|
|
165
|
+
/>
|
|
254
166
|
</div>
|
|
255
167
|
</Column>
|
|
256
168
|
</Row>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { Dropdown, InlineNotification, RadioButton, RadioButtonGroup, RadioButtonSkeleton } from '@carbon/react';
|
|
2
|
+
import { type Patient } from '@openmrs/esm-framework';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { type Control, type FieldError } from 'react-hook-form';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import useWardLocation from '../hooks/useWardLocation';
|
|
7
|
+
import { type BedLayout } from '../types';
|
|
8
|
+
import styles from './bed-selector.scss';
|
|
9
|
+
|
|
10
|
+
interface BedSelectorProps {
|
|
11
|
+
beds: BedLayout[];
|
|
12
|
+
isLoadingBeds: boolean;
|
|
13
|
+
currentPatient: Patient;
|
|
14
|
+
selectedBedId: number;
|
|
15
|
+
error: FieldError;
|
|
16
|
+
onChange(bedId: number);
|
|
17
|
+
control: Control<{ bedId?: number }, any, { bedId?: number }>;
|
|
18
|
+
minBedCountToUseDropdown?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface BedDropdownItem {
|
|
22
|
+
bedId: number;
|
|
23
|
+
label: string;
|
|
24
|
+
disabled: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const BedSelector: React.FC<BedSelectorProps> = ({
|
|
28
|
+
selectedBedId,
|
|
29
|
+
beds,
|
|
30
|
+
isLoadingBeds,
|
|
31
|
+
error,
|
|
32
|
+
onChange,
|
|
33
|
+
currentPatient,
|
|
34
|
+
control,
|
|
35
|
+
minBedCountToUseDropdown = 16,
|
|
36
|
+
}) => {
|
|
37
|
+
const { location } = useWardLocation();
|
|
38
|
+
const { t } = useTranslation();
|
|
39
|
+
|
|
40
|
+
const getBedRepresentation = (bedLayout: BedLayout) => {
|
|
41
|
+
const bedNumber = bedLayout.bedNumber;
|
|
42
|
+
const patients =
|
|
43
|
+
bedLayout.patients.length === 0
|
|
44
|
+
? [t('emptyText', 'Empty')]
|
|
45
|
+
: bedLayout.patients.map((patient) => patient?.person?.preferredName?.display);
|
|
46
|
+
return [bedNumber, ...patients].join(' · ');
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const bedDropdownItems: BedDropdownItem[] = [
|
|
50
|
+
{ bedId: 0, label: t('noBed', 'No bed'), disabled: false },
|
|
51
|
+
...beds.map((bed) => {
|
|
52
|
+
const isPatientAssignedToBed = bed.patients.some((bedPatient) => bedPatient.uuid === currentPatient.uuid);
|
|
53
|
+
return { bedId: bed.bedId, label: getBedRepresentation(bed), disabled: isPatientAssignedToBed };
|
|
54
|
+
}),
|
|
55
|
+
];
|
|
56
|
+
const selectedItem = bedDropdownItems.find((bed) => bed.bedId === selectedBedId);
|
|
57
|
+
|
|
58
|
+
const useDropdown = beds.length >= minBedCountToUseDropdown;
|
|
59
|
+
|
|
60
|
+
if (isLoadingBeds) {
|
|
61
|
+
return (
|
|
62
|
+
<RadioButtonGroup className={styles.radioButtonGroup} name="bedId">
|
|
63
|
+
<RadioButtonSkeleton />
|
|
64
|
+
<RadioButtonSkeleton />
|
|
65
|
+
<RadioButtonSkeleton />
|
|
66
|
+
</RadioButtonGroup>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
if (!beds.length) {
|
|
70
|
+
return (
|
|
71
|
+
<InlineNotification
|
|
72
|
+
kind="error"
|
|
73
|
+
title={t('noBedsConfiguredForLocation', 'No beds configured for {{location}} location', {
|
|
74
|
+
location: location?.display,
|
|
75
|
+
})}
|
|
76
|
+
lowContrast
|
|
77
|
+
hideCloseButton
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
if (useDropdown) {
|
|
82
|
+
return (
|
|
83
|
+
<Dropdown
|
|
84
|
+
id="default"
|
|
85
|
+
titleText=""
|
|
86
|
+
helperText=""
|
|
87
|
+
label={!selectedItem && t('chooseAnOption', 'Choose an option')}
|
|
88
|
+
items={bedDropdownItems}
|
|
89
|
+
itemToString={(bedDropdownItem: BedDropdownItem) => bedDropdownItem.label}
|
|
90
|
+
selectedItem={selectedItem}
|
|
91
|
+
onChange={({ selectedItem }: { selectedItem: BedLayout }) => onChange(selectedItem.bedId)}
|
|
92
|
+
invalid={!!error}
|
|
93
|
+
invalidText={error?.message}
|
|
94
|
+
/>
|
|
95
|
+
);
|
|
96
|
+
} else {
|
|
97
|
+
return (
|
|
98
|
+
<RadioButtonGroup
|
|
99
|
+
name="bedId"
|
|
100
|
+
className={styles.radioButtonGroup}
|
|
101
|
+
onChange={onChange}
|
|
102
|
+
invalid={!!error}
|
|
103
|
+
invalidText={error?.message}>
|
|
104
|
+
{bedDropdownItems.map(({ bedId, label, disabled }) => (
|
|
105
|
+
<RadioButton
|
|
106
|
+
key={bedId}
|
|
107
|
+
labelText={label}
|
|
108
|
+
control={control}
|
|
109
|
+
value={bedId}
|
|
110
|
+
checked={bedId === selectedBedId}
|
|
111
|
+
disabled={disabled}
|
|
112
|
+
/>
|
|
113
|
+
))}
|
|
114
|
+
</RadioButtonGroup>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default BedSelector;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
@use '@carbon/type';
|
|
2
|
+
@use '@carbon/layout';
|
|
3
|
+
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
|
+
|
|
5
|
+
.radioButtonGroup {
|
|
6
|
+
margin-top: layout.$spacing-03;
|
|
7
|
+
fieldset {
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
|
|
11
|
+
:global(.cds--radio-button-wrapper) {
|
|
12
|
+
margin-bottom: layout.$spacing-04;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -5,7 +5,7 @@ import React, { useCallback, useState } from 'react';
|
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import useEmrConfiguration from '../../hooks/useEmrConfiguration';
|
|
7
7
|
import useWardLocation from '../../hooks/useWardLocation';
|
|
8
|
-
import { type
|
|
8
|
+
import { type WardPatientWorkspaceProps, type WardViewContext } from '../../types';
|
|
9
9
|
import { createEncounter, removePatientFromBed } from '../../ward.resource';
|
|
10
10
|
import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
|
|
11
11
|
import styles from './patient-discharge.scss';
|
|
@@ -17,10 +17,7 @@ export default function PatientDischargeWorkspace(props: WardPatientWorkspacePro
|
|
|
17
17
|
const { currentProvider } = useSession();
|
|
18
18
|
const { location } = useWardLocation();
|
|
19
19
|
const { emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useEmrConfiguration();
|
|
20
|
-
const {wardPatientGroupDetails} = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
21
|
-
const { mutate: mutateAdmissionLocation } = wardPatientGroupDetails?.admissionLocationResponse ?? {};
|
|
22
|
-
const { mutate: mutateInpatientRequest } = wardPatientGroupDetails?.inpatientRequestResponse ?? {};
|
|
23
|
-
const { mutate: mutateInpatientAdmission } = wardPatientGroupDetails?.inpatientAdmissionResponse ?? {};
|
|
20
|
+
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
24
21
|
|
|
25
22
|
const submitDischarge = useCallback(() => {
|
|
26
23
|
setIsSubmitting(true);
|
|
@@ -63,9 +60,7 @@ export default function PatientDischargeWorkspace(props: WardPatientWorkspacePro
|
|
|
63
60
|
.finally(() => {
|
|
64
61
|
setIsSubmitting(false);
|
|
65
62
|
closeWorkspaceWithSavedChanges();
|
|
66
|
-
|
|
67
|
-
mutateInpatientRequest();
|
|
68
|
-
mutateInpatientAdmission();
|
|
63
|
+
wardPatientGroupDetails.mutate();
|
|
69
64
|
});
|
|
70
65
|
}, [
|
|
71
66
|
currentProvider,
|
|
@@ -73,9 +68,7 @@ export default function PatientDischargeWorkspace(props: WardPatientWorkspacePro
|
|
|
73
68
|
emrConfiguration,
|
|
74
69
|
wardPatient?.patient?.uuid,
|
|
75
70
|
wardPatient?.bed?.uuid,
|
|
76
|
-
|
|
77
|
-
mutateInpatientRequest,
|
|
78
|
-
mutateInpatientAdmission,
|
|
71
|
+
wardPatientGroupDetails,
|
|
79
72
|
]);
|
|
80
73
|
|
|
81
74
|
if (!wardPatientGroupDetails) return <></>;
|