@kenyaemr/esm-ward-app 8.1.1-pre.121 → 8.1.1-pre.124
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.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,12 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button,
|
|
3
|
-
ButtonSet,
|
|
4
|
-
Form,
|
|
5
|
-
InlineNotification,
|
|
6
|
-
RadioButton,
|
|
7
|
-
RadioButtonGroup,
|
|
8
|
-
RadioButtonSkeleton,
|
|
9
|
-
} from '@carbon/react';
|
|
1
|
+
import { Button, ButtonSet, Form, InlineNotification } from '@carbon/react';
|
|
10
2
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
11
3
|
import { showSnackbar, useAppContext, useSession } from '@openmrs/esm-framework';
|
|
12
4
|
import classNames from 'classnames';
|
|
@@ -16,8 +8,9 @@ import { useTranslation } from 'react-i18next';
|
|
|
16
8
|
import { z } from 'zod';
|
|
17
9
|
import useEmrConfiguration from '../../hooks/useEmrConfiguration';
|
|
18
10
|
import useWardLocation from '../../hooks/useWardLocation';
|
|
19
|
-
import type { BedLayout,
|
|
20
|
-
import { assignPatientToBed, createEncounter } from '../../ward.resource';
|
|
11
|
+
import type { BedLayout, WardPatientWorkspaceProps, WardViewContext } from '../../types';
|
|
12
|
+
import { assignPatientToBed, createEncounter, removePatientFromBed } from '../../ward.resource';
|
|
13
|
+
import BedSelector from '../bed-selector.component';
|
|
21
14
|
import styles from './patient-transfer-swap.scss';
|
|
22
15
|
|
|
23
16
|
export default function PatientBedSwapForm({
|
|
@@ -32,10 +25,8 @@ export default function PatientBedSwapForm({
|
|
|
32
25
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
33
26
|
const { currentProvider } = useSession();
|
|
34
27
|
const { location } = useWardLocation();
|
|
35
|
-
const {wardPatientGroupDetails} = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
36
|
-
const { isLoading
|
|
37
|
-
const { mutate: mutateInpatientRequest } = wardPatientGroupDetails?.inpatientRequestResponse ?? {};
|
|
38
|
-
const { mutate: mutateInpatientAdmission } = wardPatientGroupDetails?.inpatientAdmissionResponse ?? {};
|
|
28
|
+
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
29
|
+
const { isLoading } = wardPatientGroupDetails?.admissionLocationResponse ?? {};
|
|
39
30
|
|
|
40
31
|
const zodSchema = useMemo(
|
|
41
32
|
() =>
|
|
@@ -71,14 +62,6 @@ export default function PatientBedSwapForm({
|
|
|
71
62
|
);
|
|
72
63
|
|
|
73
64
|
const beds = wardPatientGroupDetails?.bedLayouts ?? [];
|
|
74
|
-
const bedDetails = useMemo(
|
|
75
|
-
() =>
|
|
76
|
-
beds.map((bed) => {
|
|
77
|
-
const isPatientAssignedToBed = bed.patients.find((bedPatient) => bedPatient.uuid === patient.uuid);
|
|
78
|
-
return { id: bed.bedId, label: getBedInformation(bed), isPatientAssignedToBed };
|
|
79
|
-
}),
|
|
80
|
-
[beds, getBedInformation],
|
|
81
|
-
);
|
|
82
65
|
|
|
83
66
|
const onSubmit = useCallback(
|
|
84
67
|
(values: FormValues) => {
|
|
@@ -98,47 +81,58 @@ export default function PatientBedSwapForm({
|
|
|
98
81
|
})
|
|
99
82
|
.then(async (response) => {
|
|
100
83
|
if (response.ok) {
|
|
101
|
-
|
|
84
|
+
if (bedSelected) {
|
|
85
|
+
return assignPatientToBed(values.bedId, patient.uuid, response.data.uuid);
|
|
86
|
+
} else {
|
|
87
|
+
// get the bed that the patient is currently assigned to
|
|
88
|
+
const bedAssignedToPatient = beds.find((bed) =>
|
|
89
|
+
bed.patients.some((bedPatient) => bedPatient.uuid == patient.uuid),
|
|
90
|
+
);
|
|
91
|
+
if (bedAssignedToPatient) {
|
|
92
|
+
return removePatientFromBed(bedAssignedToPatient.bedId, patient.uuid);
|
|
93
|
+
} else {
|
|
94
|
+
// no-op
|
|
95
|
+
return Promise.resolve({ ok: true });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
102
98
|
}
|
|
103
99
|
})
|
|
104
100
|
.then((response) => {
|
|
105
101
|
if (response && response?.ok) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
102
|
+
if (bedSelected) {
|
|
103
|
+
showSnackbar({
|
|
104
|
+
kind: 'success',
|
|
105
|
+
title: t('patientAssignedNewBed', 'Patient assigned to new bed'),
|
|
106
|
+
subtitle: t('patientAssignedNewBedDetail', '{{patientName}} assigned to bed {{bedNumber}}', {
|
|
107
|
+
patientName: patient.person.preferredName.display,
|
|
108
|
+
bedNumber: bedSelected.bedNumber,
|
|
109
|
+
}),
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
showSnackbar({
|
|
113
|
+
kind: 'success',
|
|
114
|
+
title: t('patientUnassignedFromBed', 'Patient unassigned from bed'),
|
|
115
|
+
subtitle: t('patientUnassignedFromBedDetail', '{{patientName}} is now unassigned from bed', {
|
|
116
|
+
patientName: patient.person.preferredName.display,
|
|
117
|
+
}),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
114
120
|
}
|
|
115
121
|
})
|
|
116
122
|
.catch((error: Error) => {
|
|
117
123
|
showSnackbar({
|
|
118
124
|
kind: 'error',
|
|
119
|
-
title: t('
|
|
125
|
+
title: t('errorChangingPatientBedAssignment', 'Error changing patient bed assignment'),
|
|
120
126
|
subtitle: error?.message,
|
|
121
127
|
});
|
|
122
128
|
})
|
|
123
129
|
.finally(() => {
|
|
124
130
|
setIsSubmitting(false);
|
|
125
|
-
|
|
126
|
-
mutateInpatientRequest();
|
|
127
|
-
mutateInpatientAdmission();
|
|
131
|
+
wardPatientGroupDetails.mutate();
|
|
128
132
|
closeWorkspaceWithSavedChanges();
|
|
129
133
|
});
|
|
130
134
|
},
|
|
131
|
-
[
|
|
132
|
-
setShowErrorNotifications,
|
|
133
|
-
patient,
|
|
134
|
-
emrConfiguration,
|
|
135
|
-
currentProvider,
|
|
136
|
-
location,
|
|
137
|
-
beds,
|
|
138
|
-
mutateAdmissionLocation,
|
|
139
|
-
mutateInpatientRequest,
|
|
140
|
-
mutateInpatientAdmission,
|
|
141
|
-
],
|
|
135
|
+
[setShowErrorNotifications, patient, emrConfiguration, currentProvider, location, beds, wardPatientGroupDetails],
|
|
142
136
|
);
|
|
143
137
|
|
|
144
138
|
const onError = useCallback(() => {
|
|
@@ -166,36 +160,21 @@ export default function PatientBedSwapForm({
|
|
|
166
160
|
</div>
|
|
167
161
|
)}
|
|
168
162
|
<h2 className={styles.productiveHeading02}>{t('selectABed', 'Select a bed')}</h2>
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
invalidText={errors?.bedId?.message}>
|
|
185
|
-
{bedDetails.map(({ id, label, isPatientAssignedToBed }) => (
|
|
186
|
-
<RadioButton
|
|
187
|
-
key={id}
|
|
188
|
-
labelText={label}
|
|
189
|
-
control={control}
|
|
190
|
-
value={id}
|
|
191
|
-
checked={id === value}
|
|
192
|
-
disabled={isPatientAssignedToBed}
|
|
193
|
-
/>
|
|
194
|
-
))}
|
|
195
|
-
</RadioButtonGroup>
|
|
196
|
-
)}
|
|
197
|
-
/>
|
|
198
|
-
)}
|
|
163
|
+
<Controller
|
|
164
|
+
name="bedId"
|
|
165
|
+
control={control}
|
|
166
|
+
render={({ field: { onChange, value }, fieldState: { error } }) => (
|
|
167
|
+
<BedSelector
|
|
168
|
+
beds={beds}
|
|
169
|
+
isLoadingBeds={isLoading}
|
|
170
|
+
currentPatient={patient}
|
|
171
|
+
selectedBedId={value}
|
|
172
|
+
error={error}
|
|
173
|
+
control={control}
|
|
174
|
+
onChange={onChange}
|
|
175
|
+
/>
|
|
176
|
+
)}
|
|
177
|
+
/>
|
|
199
178
|
{showErrorNotifications && (
|
|
200
179
|
<div className={styles.notifications}>
|
|
201
180
|
{Object.values(errors).map((error) => (
|
package/src/ward-workspace/patient-transfer-bed-swap/patient-transfer-request-form.component.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import { z } from 'zod';
|
|
|
9
9
|
import useEmrConfiguration from '../../hooks/useEmrConfiguration';
|
|
10
10
|
import useWardLocation from '../../hooks/useWardLocation';
|
|
11
11
|
import LocationSelector from '../../location-selector/location-selector.component';
|
|
12
|
-
import type { ObsPayload,
|
|
12
|
+
import type { ObsPayload, WardPatientWorkspaceProps, WardViewContext } from '../../types';
|
|
13
13
|
import { createEncounter } from '../../ward.resource';
|
|
14
14
|
import styles from './patient-transfer-swap.scss';
|
|
15
15
|
|
|
@@ -30,9 +30,6 @@ export default function PatientTransferForm({
|
|
|
30
30
|
[emrConfiguration],
|
|
31
31
|
);
|
|
32
32
|
const { wardPatientGroupDetails } = useAppContext<WardViewContext>('ward-view-context') ?? {};
|
|
33
|
-
const { mutate: mutateAdmissionLocation } = wardPatientGroupDetails?.admissionLocationResponse ?? {};
|
|
34
|
-
const { mutate: mutateInpatientAdmission } = wardPatientGroupDetails?.inpatientAdmissionResponse ?? {};
|
|
35
|
-
const { mutate: mutateInpatientRequest } = wardPatientGroupDetails?.inpatientRequestResponse ?? {};
|
|
36
33
|
|
|
37
34
|
const zodSchema = useMemo(
|
|
38
35
|
() =>
|
|
@@ -134,9 +131,7 @@ export default function PatientTransferForm({
|
|
|
134
131
|
.finally(() => {
|
|
135
132
|
setIsSubmitting(false);
|
|
136
133
|
closeWorkspaceWithSavedChanges();
|
|
137
|
-
|
|
138
|
-
mutateInpatientAdmission();
|
|
139
|
-
mutateInpatientRequest();
|
|
134
|
+
wardPatientGroupDetails.mutate();
|
|
140
135
|
});
|
|
141
136
|
},
|
|
142
137
|
[
|
|
@@ -146,9 +141,7 @@ export default function PatientTransferForm({
|
|
|
146
141
|
emrConfiguration,
|
|
147
142
|
patient?.uuid,
|
|
148
143
|
dispositionsWithTypeTransfer,
|
|
149
|
-
|
|
150
|
-
mutateInpatientAdmission,
|
|
151
|
-
mutateInpatientRequest,
|
|
144
|
+
wardPatientGroupDetails,
|
|
152
145
|
],
|
|
153
146
|
);
|
|
154
147
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { useFeatureFlag } from '@openmrs/esm-framework';
|
|
3
1
|
import { ContentSwitcher, Switch } from '@carbon/react';
|
|
2
|
+
import { useFeatureFlag } from '@openmrs/esm-framework';
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
|
-
import
|
|
5
|
+
import type { WardPatientWorkspaceProps } from '../../types';
|
|
6
|
+
import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
|
|
6
7
|
import PatientBedSwapForm from './patient-bed-swap-form.component';
|
|
8
|
+
import PatientTransferForm from './patient-transfer-request-form.component';
|
|
7
9
|
import styles from './patient-transfer-swap.scss';
|
|
8
|
-
import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
|
|
9
|
-
import type { WardPatientWorkspaceProps } from '../../types';
|
|
10
10
|
|
|
11
11
|
const TransferSection = {
|
|
12
12
|
TRANSFER: 'transfer',
|
|
@@ -37,7 +37,11 @@ export default function PatientTransferAndSwapWorkspace(props: WardPatientWorksp
|
|
|
37
37
|
</div>
|
|
38
38
|
)}
|
|
39
39
|
<div className={styles.workspaceForm}>
|
|
40
|
-
{selectedSection ===
|
|
40
|
+
{selectedSection === TransferSection.TRANSFER ? (
|
|
41
|
+
<PatientTransferForm {...props} />
|
|
42
|
+
) : (
|
|
43
|
+
<PatientBedSwapForm {...props} />
|
|
44
|
+
)}
|
|
41
45
|
</div>
|
|
42
46
|
</div>
|
|
43
47
|
);
|
package/src/ward.resource.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
2
|
-
import type { Encounter, EncounterPayload } from './types';
|
|
1
|
+
import { openmrsFetch, type Patient, restBaseUrl, useSession } from '@openmrs/esm-framework';
|
|
2
|
+
import type { DispositionType, Encounter, EncounterPayload } from './types';
|
|
3
|
+
import useEmrConfiguration from './hooks/useEmrConfiguration';
|
|
4
|
+
import useWardLocation from './hooks/useWardLocation';
|
|
3
5
|
|
|
4
6
|
export function createEncounter(encounterPayload: EncounterPayload) {
|
|
5
7
|
return openmrsFetch<Encounter>(`${restBaseUrl}/encounter`, {
|
|
@@ -11,6 +13,34 @@ export function createEncounter(encounterPayload: EncounterPayload) {
|
|
|
11
13
|
});
|
|
12
14
|
}
|
|
13
15
|
|
|
16
|
+
export function useAdmitPatient() {
|
|
17
|
+
const { location } = useWardLocation();
|
|
18
|
+
const { currentProvider } = useSession();
|
|
19
|
+
const { emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useEmrConfiguration();
|
|
20
|
+
|
|
21
|
+
const admitPatient = (patient: Patient, dispositionType: DispositionType) => {
|
|
22
|
+
return createEncounter({
|
|
23
|
+
patient: patient.uuid,
|
|
24
|
+
encounterType:
|
|
25
|
+
dispositionType === 'ADMIT'
|
|
26
|
+
? emrConfiguration.admissionEncounterType.uuid
|
|
27
|
+
: dispositionType === 'TRANSFER'
|
|
28
|
+
? emrConfiguration.transferWithinHospitalEncounterType.uuid
|
|
29
|
+
: null,
|
|
30
|
+
location: location?.uuid,
|
|
31
|
+
encounterProviders: [
|
|
32
|
+
{
|
|
33
|
+
provider: currentProvider?.uuid,
|
|
34
|
+
encounterRole: emrConfiguration.clinicianEncounterRole.uuid,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
obs: [],
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return { admitPatient, isLoadingEmrConfiguration, errorFetchingEmrConfiguration };
|
|
42
|
+
}
|
|
43
|
+
|
|
14
44
|
export function assignPatientToBed(bedUuid: number, patientUuid: string, encounterUuid: string) {
|
|
15
45
|
return openmrsFetch(`${restBaseUrl}/beds/${bedUuid}`, {
|
|
16
46
|
method: 'POST',
|
package/translations/en.json
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"admit": "Admit",
|
|
6
6
|
"admitPatient": "Admit patient",
|
|
7
7
|
"admitting": "Admitting...",
|
|
8
|
-
"bedManagementModuleNotInstalled": "Bed management module is not present to allow bed selection",
|
|
9
8
|
"bedShare": "Bed share",
|
|
10
9
|
"bedSwap": "Bed swap",
|
|
11
10
|
"cancel": "Cancel",
|
|
@@ -21,7 +20,7 @@
|
|
|
21
20
|
"emptyBed": "Empty bed",
|
|
22
21
|
"emptyText": "Empty",
|
|
23
22
|
"encounterDisplay": "{{encounterType}} {{encounterDate}}",
|
|
24
|
-
"
|
|
23
|
+
"errorChangingPatientBedAssignment": "Error changing patient bed assignment",
|
|
25
24
|
"errorConfiguringPatientCard": "Error configuring patient card",
|
|
26
25
|
"errorConfiguringPatientCardMessage": "Unable to find configuration for {{elementType}}, id: {{id}}",
|
|
27
26
|
"errorCreatingEncounter": "Failed to admit patient",
|
|
@@ -45,6 +44,7 @@
|
|
|
45
44
|
"manage": "Manage",
|
|
46
45
|
"motherChildBedShare": "Mother / Child",
|
|
47
46
|
"nextPage": "Next page",
|
|
47
|
+
"noBed": "No bed",
|
|
48
48
|
"noBedsConfigured": "No beds configured for this location",
|
|
49
49
|
"noBedsConfiguredForLocation": "No beds configured for {{location}} location",
|
|
50
50
|
"noLocationsFound": "No locations found",
|
|
@@ -56,14 +56,16 @@
|
|
|
56
56
|
"patientAdmittedSuccessfully": "Patient admitted successfully",
|
|
57
57
|
"patientAdmittedSuccessfullySubtitle": "{{patientName}} has been successfully admitted and assigned to bed {{bedNumber}}",
|
|
58
58
|
"patientAdmittedWoBed": "Patient admitted successfully to {{location}}",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
59
|
+
"patientAssignedNewBed": "Patient assigned to new bed",
|
|
60
|
+
"patientAssignedNewBedDetail": "{{patientName}} assigned to bed {{bedNumber}}",
|
|
61
61
|
"patientNoteNowVisible": "It should be now visible in the notes history",
|
|
62
62
|
"patientNoteSaveError": "Error saving patient note",
|
|
63
63
|
"patientNotesDidntLoad": "Patient notes didn't load",
|
|
64
64
|
"patients": "Patients",
|
|
65
65
|
"patientsMetricValue": "{{ metricValue }}",
|
|
66
66
|
"patientTransferRequestCreated": "Patient transfer request created",
|
|
67
|
+
"patientUnassignedFromBed": "Patient unassigned from bed",
|
|
68
|
+
"patientUnassignedFromBedDetail": "{{patientName}} is now unassigned from bed",
|
|
67
69
|
"patientWasDischarged": "Patient was discharged",
|
|
68
70
|
"pendingOut": "Pending out",
|
|
69
71
|
"pendingOutMetricValue": "{{ metricValue }}",
|
|
@@ -87,7 +89,6 @@
|
|
|
87
89
|
"transfers": "Transfers",
|
|
88
90
|
"transferType": "Transfer type",
|
|
89
91
|
"typeOfTransfer": "Type of transfer",
|
|
90
|
-
"unableToSelectBeds": "Unable to select beds",
|
|
91
92
|
"unknown": "Unknown",
|
|
92
93
|
"visitNoteSaved": "Patient note saved",
|
|
93
94
|
"wardClinicalNotePlaceholder": "Write any notes here",
|