@kenyaemr/esm-service-queues-app 8.1.1-pre.114 → 8.1.1-pre.118
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 +19 -19
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/199.js +1 -1
- package/dist/199.js.map +1 -1
- package/dist/271.js +1 -1
- package/dist/319.js +1 -1
- package/dist/460.js +1 -1
- package/dist/574.js +1 -1
- package/dist/60.js +1 -0
- package/dist/60.js.map +1 -0
- package/dist/644.js +1 -1
- package/dist/665.js +2 -0
- package/dist/665.js.map +1 -0
- package/dist/670.js +1 -1
- package/dist/670.js.map +1 -1
- package/dist/748.js +1 -0
- package/dist/748.js.map +1 -0
- package/dist/757.js +1 -1
- package/dist/788.js +1 -1
- package/dist/807.js +1 -1
- package/dist/833.js +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +99 -75
- package/dist/kenyaemr-esm-service-queues-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/active-visits/change-status-dialog.component.tsx +141 -138
- package/src/active-visits/change-status-dialog.test.tsx +5 -5
- package/src/config-schema.ts +4 -10
- package/src/index.ts +7 -0
- package/src/patient-queue-header/patient-queue-header.component.tsx +25 -38
- package/src/patient-queue-header/patient-queue-header.scss +3 -41
- package/src/queue-screen/queue-screen.component.tsx +67 -11
- package/src/queue-screen/queue-screen.test.tsx +1 -1
- package/src/queue-screen/useActiveTickets.tsx +1 -1
- package/src/queue-table/cells/columns.resource.ts +2 -2
- package/src/queue-table/queue-entry-actions/transition-queue-entry.modal.tsx +7 -2
- package/src/routes.json +4 -0
- package/src/transition-latest-queue-entry/transition-latest-queue-entry.component.tsx +33 -0
- package/src/transition-latest-queue-entry/transition-latest-queue-entry.resource.ts +30 -0
- package/translations/am.json +4 -3
- package/translations/ar.json +5 -4
- package/translations/en.json +7 -4
- package/translations/es.json +81 -80
- package/translations/fr.json +255 -254
- package/translations/he.json +5 -4
- package/translations/km.json +5 -4
- package/translations/zh.json +5 -4
- package/translations/zh_CN.json +5 -4
- package/dist/265.js +0 -1
- package/dist/265.js.map +0 -1
- package/dist/62.js +0 -2
- package/dist/62.js.map +0 -1
- package/src/patient-queue-header/patient-queue-illustration.component.tsx +0 -22
- /package/dist/{62.js.LICENSE.txt → 665.js.LICENSE.txt} +0 -0
package/dist/routes.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0","queue":"^2.4.0-0"},"extensions":[{"name":"outpatient-side-nav-ext","component":"outpatientSideNav","slot":"outpatient-sidebar-slot","online":true,"offline":true},{"name":"service-queues-dashboard-link","component":"serviceQueuesDashboardLink","slot":"homepage-dashboard-slot","meta":{"name":"service-queues","slot":"service-queues-dashboard-slot","title":"Service queues"},"online":true,"offline":true},{"name":"queue-table-by-status-menu-dashboard-link","component":"queueTableByStatusMenu","meta":{"name":"service-queues","slot":"service-queues-dashboard-slot","title":"Service queues"},"online":true,"offline":true},{"component":"root","name":"service-queues-dashboard","slot":"service-queues-dashboard-slot"},{"name":"edit-queue-entry-status-modal","component":"editQueueEntryStatusModal"},{"name":"patient-info-banner-slot","component":"patientInfoBannerSlot"},{"name":"remove-queue-entry","component":"removeQueueEntry"},{"name":"clear-all-queue-entries","component":"clearAllQueueEntries"},{"name":"add-visit-to-queue-modal","component":"addVisitToQueueModal"},{"name":"transition-queue-entry-status-modal","component":"transitionQueueEntryStatusModal"},{"name":"previous-visit-summary-widget","component":"pastVisitSummary","slot":"previous-visit-summary-slot"},{"name":"add-provider-to-room-modal","component":"addProviderToRoomModal"},{"name":"transition-queue-entry-modal","component":"transitionQueueEntryModal"},{"name":"edit-queue-entry-modal","component":"editQueueEntryModal"},{"name":"undo-transition-queue-entry-modal","component":"undoTransitionQueueEntryModal"},{"name":"void-queue-entry-modal","component":"voidQueueEntryModal"},{"name":"end-queue-entry-modal","component":"endQueueEntryModal"},{"name":"active-visits-row-actions","component":"activeVisitsRowActions","slot":"queue-table-serve-patient-slot"},{"name":"visit-form-queue-fields","component":"visitFormQueueFields","slot":"visit-form-queue-slot"}],"workspaces":[{"name":"service-queues-service-form","title":"addNewQueueService","component":"addNewQueueServiceWorkspace","type":"service-queues"},{"name":"service-queues-room-form","title":"addNewQueueServiceRoom","component":"addNewQueueServiceRoomWorkspace","type":"service-queues"},{"name":"service-queues-linelist-filter","title":"filter","component":"queueLinelistFilterWorkspace","type":"service-queues"},{"name":"service-queues-patient-search","title":"searchPatient","component":"patientSearchWorkspace","type":"service-queues"}],"version":"8.1.1-pre.
|
|
1
|
+
{"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":"^2.2.0","queue":"^2.4.0-0"},"extensions":[{"name":"outpatient-side-nav-ext","component":"outpatientSideNav","slot":"outpatient-sidebar-slot","online":true,"offline":true},{"name":"service-queues-dashboard-link","component":"serviceQueuesDashboardLink","slot":"homepage-dashboard-slot","meta":{"name":"service-queues","slot":"service-queues-dashboard-slot","title":"Service queues"},"online":true,"offline":true},{"name":"queue-table-by-status-menu-dashboard-link","component":"queueTableByStatusMenu","meta":{"name":"service-queues","slot":"service-queues-dashboard-slot","title":"Service queues"},"online":true,"offline":true},{"component":"root","name":"service-queues-dashboard","slot":"service-queues-dashboard-slot"},{"name":"edit-queue-entry-status-modal","component":"editQueueEntryStatusModal"},{"name":"patient-info-banner-slot","component":"patientInfoBannerSlot"},{"name":"remove-queue-entry","component":"removeQueueEntry"},{"name":"clear-all-queue-entries","component":"clearAllQueueEntries"},{"name":"add-visit-to-queue-modal","component":"addVisitToQueueModal"},{"name":"transition-queue-entry-status-modal","component":"transitionQueueEntryStatusModal"},{"name":"previous-visit-summary-widget","component":"pastVisitSummary","slot":"previous-visit-summary-slot"},{"name":"add-provider-to-room-modal","component":"addProviderToRoomModal"},{"name":"transition-queue-entry-modal","component":"transitionQueueEntryModal"},{"name":"transition-patient-to-latest-queue-modal","component":"transitionPatientToLatestQueue"},{"name":"edit-queue-entry-modal","component":"editQueueEntryModal"},{"name":"undo-transition-queue-entry-modal","component":"undoTransitionQueueEntryModal"},{"name":"void-queue-entry-modal","component":"voidQueueEntryModal"},{"name":"end-queue-entry-modal","component":"endQueueEntryModal"},{"name":"active-visits-row-actions","component":"activeVisitsRowActions","slot":"queue-table-serve-patient-slot"},{"name":"visit-form-queue-fields","component":"visitFormQueueFields","slot":"visit-form-queue-slot"}],"workspaces":[{"name":"service-queues-service-form","title":"addNewQueueService","component":"addNewQueueServiceWorkspace","type":"service-queues"},{"name":"service-queues-room-form","title":"addNewQueueServiceRoom","component":"addNewQueueServiceRoomWorkspace","type":"service-queues"},{"name":"service-queues-linelist-filter","title":"filter","component":"queueLinelistFilterWorkspace","type":"service-queues"},{"name":"service-queues-patient-search","title":"searchPatient","component":"patientSearchWorkspace","type":"service-queues"}],"version":"8.1.1-pre.118"}
|
package/package.json
CHANGED
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Button,
|
|
4
|
+
ContentSwitcher,
|
|
5
|
+
Form,
|
|
6
|
+
InlineLoading,
|
|
7
|
+
InlineNotification,
|
|
4
8
|
ModalBody,
|
|
5
9
|
ModalFooter,
|
|
6
10
|
ModalHeader,
|
|
7
|
-
Form,
|
|
8
|
-
ContentSwitcher,
|
|
9
|
-
Switch,
|
|
10
|
-
Select,
|
|
11
|
-
SelectItem,
|
|
12
|
-
InlineNotification,
|
|
13
11
|
RadioButton,
|
|
14
12
|
RadioButtonGroup,
|
|
15
|
-
|
|
13
|
+
Select,
|
|
14
|
+
SelectItem,
|
|
15
|
+
Stack,
|
|
16
|
+
Switch,
|
|
16
17
|
} from '@carbon/react';
|
|
17
18
|
import { useTranslation } from 'react-i18next';
|
|
18
|
-
import { navigate, showSnackbar, useConfig } from '@openmrs/esm-framework';
|
|
19
|
-
import { type MappedQueueEntry } from '../types';
|
|
20
|
-
import { updateQueueEntry } from './active-visits-table.resource';
|
|
21
|
-
import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
|
|
22
|
-
import styles from './change-status-dialog.scss';
|
|
23
|
-
import { useQueues } from '../hooks/useQueues';
|
|
24
19
|
import { useForm, Controller } from 'react-hook-form';
|
|
25
20
|
import { z } from 'zod';
|
|
26
21
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
22
|
+
import { navigate, showSnackbar, useConfig } from '@openmrs/esm-framework';
|
|
23
|
+
import { type MappedQueueEntry } from '../types';
|
|
27
24
|
import { type ConfigObject } from '../config-schema';
|
|
25
|
+
import { useQueues } from '../hooks/useQueues';
|
|
26
|
+
import { updateQueueEntry } from './active-visits-table.resource';
|
|
28
27
|
import { useMutateQueueEntries } from '../hooks/useQueueEntries';
|
|
28
|
+
import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
|
|
29
|
+
import styles from './change-status-dialog.scss';
|
|
29
30
|
|
|
30
31
|
interface ChangeStatusDialogProps {
|
|
31
32
|
queueEntry: MappedQueueEntry;
|
|
@@ -41,9 +42,9 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
|
|
|
41
42
|
() =>
|
|
42
43
|
z.object({
|
|
43
44
|
location: z.string({ required_error: t('queueLocationRequired', 'Queue location is required') }),
|
|
45
|
+
priority: z.string({ required_error: t('priorityIsRequired', 'Priority is required') }),
|
|
44
46
|
service: z.string({ required_error: t('serviceIsRequired', 'Service is required') }),
|
|
45
47
|
status: z.string({ required_error: t('statusIsRequired', 'Status is required') }),
|
|
46
|
-
priority: z.string({ required_error: t('priorityIsRequired', 'Priority is required') }),
|
|
47
48
|
}),
|
|
48
49
|
[],
|
|
49
50
|
);
|
|
@@ -82,18 +83,16 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
|
|
|
82
83
|
endDate,
|
|
83
84
|
sortWeight,
|
|
84
85
|
).then(
|
|
85
|
-
(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
navigate({ to: `${window.spaBase}/home/service-queues` });
|
|
96
|
-
}
|
|
86
|
+
() => {
|
|
87
|
+
showSnackbar({
|
|
88
|
+
isLowContrast: true,
|
|
89
|
+
title: t('updateEntry', 'Update entry'),
|
|
90
|
+
kind: 'success',
|
|
91
|
+
subtitle: t('queueEntryUpdateSuccessfully', 'Queue Entry Updated Successfully'),
|
|
92
|
+
});
|
|
93
|
+
closeModal();
|
|
94
|
+
mutateQueueEntries();
|
|
95
|
+
navigate({ to: `${window.spaBase}/home/service-queues` });
|
|
97
96
|
},
|
|
98
97
|
(error) => {
|
|
99
98
|
showSnackbar({
|
|
@@ -121,127 +120,131 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
|
|
|
121
120
|
<ModalBody>
|
|
122
121
|
<div className={styles.modalBody}>
|
|
123
122
|
<h5>
|
|
124
|
-
{
|
|
125
|
-
|
|
123
|
+
{t('patientInfo', '{{name}}{{sexInfo}}{{ageInfo}}', {
|
|
124
|
+
name: queueEntry.name,
|
|
125
|
+
sexInfo: queueEntry.patientSex ? ` · ${queueEntry.patientSex} · ` : '',
|
|
126
|
+
ageInfo: queueEntry.patientAge ? `${queueEntry.patientAge} ${t('years', 'Years')}` : '',
|
|
127
|
+
})}
|
|
126
128
|
</h5>
|
|
127
129
|
</div>
|
|
128
|
-
<
|
|
129
|
-
<
|
|
130
|
-
|
|
131
|
-
control={control}
|
|
132
|
-
render={({ field: { onChange, value } }) => (
|
|
133
|
-
<Select
|
|
134
|
-
labelText={t('selectQueueLocation', 'Select a queue location')}
|
|
135
|
-
id="location"
|
|
136
|
-
invalid={!!errors.location}
|
|
137
|
-
invalidText={errors.location?.message}
|
|
138
|
-
value={value}
|
|
139
|
-
onChange={(event) => {
|
|
140
|
-
onChange(event.target.value);
|
|
141
|
-
}}>
|
|
142
|
-
{!getValues()?.location && (
|
|
143
|
-
<SelectItem text={t('selectQueueLocation', 'Select a queue location')} value="" />
|
|
144
|
-
)}
|
|
145
|
-
{queueLocations?.length > 0 &&
|
|
146
|
-
queueLocations.map((location) => (
|
|
147
|
-
<SelectItem key={location.id} text={location.name} value={location.id}>
|
|
148
|
-
{location.name}
|
|
149
|
-
</SelectItem>
|
|
150
|
-
))}
|
|
151
|
-
</Select>
|
|
152
|
-
)}
|
|
153
|
-
/>
|
|
154
|
-
</section>
|
|
155
|
-
|
|
156
|
-
<section className={styles.section}>
|
|
157
|
-
<div className={styles.sectionTitle}>{t('queueService', 'Queue service')}</div>
|
|
158
|
-
<Controller
|
|
159
|
-
name="service"
|
|
160
|
-
control={control}
|
|
161
|
-
render={({ field: { onChange, value } }) => (
|
|
162
|
-
<Select
|
|
163
|
-
labelText={t('selectService', 'Select a service')}
|
|
164
|
-
id="service"
|
|
165
|
-
invalid={!!errors.service}
|
|
166
|
-
invalidText={errors.service?.message}
|
|
167
|
-
value={value}
|
|
168
|
-
onChange={(event) => onChange(event.target.value)}>
|
|
169
|
-
{!getValues()?.service && <SelectItem text={t('selectService', 'Select a service')} value="" />}
|
|
170
|
-
{queues?.length > 0 &&
|
|
171
|
-
queues.map((service) => (
|
|
172
|
-
<SelectItem key={service.uuid} text={service.display} value={service.uuid}>
|
|
173
|
-
{service.display}
|
|
174
|
-
</SelectItem>
|
|
175
|
-
))}
|
|
176
|
-
</Select>
|
|
177
|
-
)}
|
|
178
|
-
/>
|
|
179
|
-
</section>
|
|
180
|
-
|
|
181
|
-
<section className={styles.section}>
|
|
182
|
-
<div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
|
|
183
|
-
{!allowedStatuses?.length ? (
|
|
184
|
-
<InlineNotification
|
|
185
|
-
className={styles.inlineNotification}
|
|
186
|
-
kind={'error'}
|
|
187
|
-
lowContrast
|
|
188
|
-
subtitle={t('configureStatus', 'Please configure status to continue.')}
|
|
189
|
-
title={t('noStatusConfigured', 'No status configured')}
|
|
190
|
-
/>
|
|
191
|
-
) : (
|
|
130
|
+
<Stack gap={4}>
|
|
131
|
+
<section>
|
|
132
|
+
<div className={styles.sectionTitle}>{t('queueLocation', 'Queue location')}</div>
|
|
192
133
|
<Controller
|
|
193
|
-
name="
|
|
134
|
+
name="location"
|
|
194
135
|
control={control}
|
|
195
|
-
render={({ field: {
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
invalid={!!errors.
|
|
200
|
-
invalidText={errors.
|
|
201
|
-
|
|
202
|
-
onChange={(
|
|
203
|
-
onChange(
|
|
136
|
+
render={({ field: { onChange, value } }) => (
|
|
137
|
+
<Select
|
|
138
|
+
labelText={t('selectQueueLocation', 'Select a queue location')}
|
|
139
|
+
id="location"
|
|
140
|
+
invalid={!!errors.location}
|
|
141
|
+
invalidText={errors.location?.message}
|
|
142
|
+
value={value}
|
|
143
|
+
onChange={(event) => {
|
|
144
|
+
onChange(event.target.value);
|
|
204
145
|
}}>
|
|
205
|
-
{
|
|
206
|
-
|
|
207
|
-
|
|
146
|
+
{!getValues()?.location && (
|
|
147
|
+
<SelectItem text={t('selectQueueLocation', 'Select a queue location')} value="" />
|
|
148
|
+
)}
|
|
149
|
+
{queueLocations?.length > 0 &&
|
|
150
|
+
queueLocations.map((location) => (
|
|
151
|
+
<SelectItem key={location.id} text={location.name} value={location.id}>
|
|
152
|
+
{location.name}
|
|
153
|
+
</SelectItem>
|
|
208
154
|
))}
|
|
209
|
-
</
|
|
155
|
+
</Select>
|
|
210
156
|
)}
|
|
211
157
|
/>
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
onChange={(event) =>
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
158
|
+
</section>
|
|
159
|
+
<section className={styles.section}>
|
|
160
|
+
<div className={styles.sectionTitle}>{t('queueService', 'Queue service')}</div>
|
|
161
|
+
<Controller
|
|
162
|
+
name="service"
|
|
163
|
+
control={control}
|
|
164
|
+
render={({ field: { onChange, value } }) => (
|
|
165
|
+
<Select
|
|
166
|
+
labelText={t('selectService', 'Select a service')}
|
|
167
|
+
id="service"
|
|
168
|
+
invalid={!!errors.service}
|
|
169
|
+
invalidText={errors.service?.message}
|
|
170
|
+
value={value}
|
|
171
|
+
onChange={(event) => onChange(event.target.value)}>
|
|
172
|
+
{!getValues()?.service && <SelectItem text={t('selectService', 'Select a service')} value="" />}
|
|
173
|
+
{queues?.length > 0 &&
|
|
174
|
+
queues.map((service) => (
|
|
175
|
+
<SelectItem key={service.uuid} text={service.display} value={service.uuid}>
|
|
176
|
+
{service.display}
|
|
177
|
+
</SelectItem>
|
|
178
|
+
))}
|
|
179
|
+
</Select>
|
|
180
|
+
)}
|
|
181
|
+
/>
|
|
182
|
+
</section>
|
|
183
|
+
<section className={styles.section}>
|
|
184
|
+
<div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
|
|
185
|
+
{!allowedStatuses?.length ? (
|
|
186
|
+
<InlineNotification
|
|
187
|
+
className={styles.inlineNotification}
|
|
188
|
+
kind={'error'}
|
|
189
|
+
lowContrast
|
|
190
|
+
subtitle={t('configureStatus', 'Please configure status to continue.')}
|
|
191
|
+
title={t('noStatusConfigured', 'No status configured')}
|
|
192
|
+
/>
|
|
193
|
+
) : (
|
|
194
|
+
<Controller
|
|
195
|
+
name="status"
|
|
196
|
+
control={control}
|
|
197
|
+
render={({ field: { value, onChange } }) => (
|
|
198
|
+
<RadioButtonGroup
|
|
199
|
+
className={styles.radioButtonWrapper}
|
|
200
|
+
id="status"
|
|
201
|
+
name="status"
|
|
202
|
+
invalid={!!errors.status}
|
|
203
|
+
invalidText={errors.status?.message}
|
|
204
|
+
defaultSelected={value}
|
|
205
|
+
onChange={(uuid) => {
|
|
206
|
+
onChange(uuid);
|
|
207
|
+
}}>
|
|
208
|
+
{allowedStatuses?.length > 0 &&
|
|
209
|
+
allowedStatuses.map(({ uuid, display }) => (
|
|
210
|
+
<RadioButton key={uuid} labelText={display} value={uuid} />
|
|
211
|
+
))}
|
|
212
|
+
</RadioButtonGroup>
|
|
213
|
+
)}
|
|
214
|
+
/>
|
|
242
215
|
)}
|
|
243
|
-
|
|
244
|
-
|
|
216
|
+
</section>
|
|
217
|
+
<section className={styles.section}>
|
|
218
|
+
<div className={styles.sectionTitle}>{t('queuePriority', 'Queue priority')}</div>
|
|
219
|
+
<Controller
|
|
220
|
+
control={control}
|
|
221
|
+
name="priority"
|
|
222
|
+
render={({ field: { onChange } }) => (
|
|
223
|
+
<>
|
|
224
|
+
<ContentSwitcher
|
|
225
|
+
size="sm"
|
|
226
|
+
selectedIndex={1}
|
|
227
|
+
onChange={(event) => {
|
|
228
|
+
onChange(event.name as any);
|
|
229
|
+
}}>
|
|
230
|
+
{allowedPriorities?.length > 0 ? (
|
|
231
|
+
allowedPriorities.map(({ uuid, display }) => {
|
|
232
|
+
return <Switch name={uuid} text={display} key={uuid} value={uuid} />;
|
|
233
|
+
})
|
|
234
|
+
) : (
|
|
235
|
+
<Switch
|
|
236
|
+
name={t('noPriorityFound', 'No priority found')}
|
|
237
|
+
text={t('noPriorityFound', 'No priority found')}
|
|
238
|
+
value={null}
|
|
239
|
+
/>
|
|
240
|
+
)}
|
|
241
|
+
</ContentSwitcher>
|
|
242
|
+
{errors.priority && <div className={styles.error}>{errors.priority.message}</div>}
|
|
243
|
+
</>
|
|
244
|
+
)}
|
|
245
|
+
/>
|
|
246
|
+
</section>
|
|
247
|
+
</Stack>
|
|
245
248
|
</ModalBody>
|
|
246
249
|
<ModalFooter>
|
|
247
250
|
<Button kind="secondary" onClick={closeModal}>
|
|
@@ -39,7 +39,7 @@ jest.mock('../hooks/useQueues', () => {
|
|
|
39
39
|
};
|
|
40
40
|
});
|
|
41
41
|
|
|
42
|
-
describe('
|
|
42
|
+
describe('ChangeStatusDialog', () => {
|
|
43
43
|
beforeEach(() => {
|
|
44
44
|
mockUseConfig.mockReturnValue({
|
|
45
45
|
...getDefaultsFromConfigSchema(configSchema),
|
|
@@ -62,14 +62,14 @@ describe('Queue entry details', () => {
|
|
|
62
62
|
expect(screen.getByText(/queue service/i)).toBeInTheDocument();
|
|
63
63
|
expect(screen.getByText(/queue priority/i)).toBeInTheDocument();
|
|
64
64
|
|
|
65
|
-
// user selects a service
|
|
66
|
-
const queueServiceTypes = screen.getByRole('combobox', { name: /select a service/i });
|
|
67
|
-
await user.selectOptions(queueServiceTypes, '176052c7-5fd4-4b33-89cc-7bae6848c65a');
|
|
68
|
-
|
|
69
65
|
// user selects queue location
|
|
70
66
|
const queueLocation = screen.getByRole('combobox', { name: /Select a queue location/i });
|
|
71
67
|
await user.selectOptions(queueLocation, 'some-uuid1');
|
|
72
68
|
|
|
69
|
+
// user selects a service
|
|
70
|
+
const queueServiceTypes = screen.getByRole('combobox', { name: /select a service/i });
|
|
71
|
+
await user.selectOptions(queueServiceTypes, '176052c7-5fd4-4b33-89cc-7bae6848c65a');
|
|
72
|
+
|
|
73
73
|
// user selects queue status
|
|
74
74
|
const queueStatus = screen.getByRole('radio', { name: /Waiting/i });
|
|
75
75
|
await user.click(queueStatus);
|
package/src/config-schema.ts
CHANGED
|
@@ -82,6 +82,10 @@ export const configSchema = {
|
|
|
82
82
|
_description: 'The UUID of the default status for attending a service in the queues eg In Service.',
|
|
83
83
|
_default: 'ca7494ae-437f-4fd0-8aae-b88b9a2ba47d',
|
|
84
84
|
},
|
|
85
|
+
systolicBloodPressureUuid: {
|
|
86
|
+
_type: Type.ConceptUuid,
|
|
87
|
+
_default: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
88
|
+
},
|
|
85
89
|
diastolicBloodPressureUuid: {
|
|
86
90
|
_type: Type.ConceptUuid,
|
|
87
91
|
_default: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
@@ -112,10 +116,6 @@ export const configSchema = {
|
|
|
112
116
|
_type: Type.ConceptUuid,
|
|
113
117
|
_default: '5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
114
118
|
},
|
|
115
|
-
systolicBloodPressureUuid: {
|
|
116
|
-
_type: Type.ConceptUuid,
|
|
117
|
-
_default: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
118
|
-
},
|
|
119
119
|
temperatureUuid: {
|
|
120
120
|
_type: Type.ConceptUuid,
|
|
121
121
|
_default: '5088AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
|
|
@@ -242,11 +242,6 @@ export const configSchema = {
|
|
|
242
242
|
'The header text for the column. Will be translated if it is a valid translation key. If not provided, the header will be based on the columnType.',
|
|
243
243
|
_default: null,
|
|
244
244
|
},
|
|
245
|
-
headerI18nModule: {
|
|
246
|
-
_type: Type.String,
|
|
247
|
-
_description: 'The module to use for translation of the header.',
|
|
248
|
-
_default: '@openmrs/esm-service-queues-app',
|
|
249
|
-
},
|
|
250
245
|
config: {
|
|
251
246
|
identifierTypeUuid: {
|
|
252
247
|
_type: Type.UUID,
|
|
@@ -440,7 +435,6 @@ export type ColumnDefinition = {
|
|
|
440
435
|
id: string;
|
|
441
436
|
columnType?: ColumnType;
|
|
442
437
|
header?: string;
|
|
443
|
-
headerI18nModule?: string;
|
|
444
438
|
config: ColumnConfig;
|
|
445
439
|
};
|
|
446
440
|
|
package/src/index.ts
CHANGED
|
@@ -138,6 +138,13 @@ export const addNewQueueServiceWorkspace = getAsyncLifecycle(
|
|
|
138
138
|
moduleName,
|
|
139
139
|
},
|
|
140
140
|
);
|
|
141
|
+
export const transitionPatientToLatestQueue = getAsyncLifecycle(
|
|
142
|
+
() => import('./transition-latest-queue-entry/transition-latest-queue-entry.component'),
|
|
143
|
+
{
|
|
144
|
+
featureName: 'transition patient to new queue',
|
|
145
|
+
moduleName,
|
|
146
|
+
},
|
|
147
|
+
);
|
|
141
148
|
|
|
142
149
|
// t('addNewQueueServiceRoom', 'Add new queue service room')
|
|
143
150
|
export const addNewQueueServiceRoomWorkspace = getAsyncLifecycle(
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import React, { useCallback, useEffect } from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import { Location } from '@carbon/react/icons';
|
|
4
3
|
import { Dropdown } from '@carbon/react';
|
|
5
|
-
import { useConfig, useSession } from '@openmrs/esm-framework';
|
|
6
|
-
import PatientQueueIllustration from './patient-queue-illustration.component';
|
|
4
|
+
import { useConfig, useSession, PageHeader, PageHeaderContent, ServiceQueuesPictogram } from '@openmrs/esm-framework';
|
|
7
5
|
import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
|
|
8
|
-
|
|
9
6
|
import {
|
|
10
7
|
updateSelectedQueueLocationUuid,
|
|
11
8
|
updateSelectedQueueLocationName,
|
|
@@ -13,8 +10,8 @@ import {
|
|
|
13
10
|
useSelectedQueueLocationName,
|
|
14
11
|
useSelectedQueueLocationUuid,
|
|
15
12
|
} from '../helpers/helpers';
|
|
16
|
-
import styles from './patient-queue-header.scss';
|
|
17
13
|
import type { ConfigObject } from '../config-schema';
|
|
14
|
+
import styles from './patient-queue-header.scss';
|
|
18
15
|
|
|
19
16
|
interface PatientQueueHeaderProps {
|
|
20
17
|
title?: string | JSX.Element;
|
|
@@ -27,7 +24,6 @@ const PatientQueueHeader: React.FC<PatientQueueHeaderProps> = ({ title, showLoca
|
|
|
27
24
|
const { queueLocations, isLoading, error } = useQueueLocations();
|
|
28
25
|
const { dashboardTitle } = useConfig<ConfigObject>();
|
|
29
26
|
const userSession = useSession();
|
|
30
|
-
const userLocation = userSession?.sessionLocation?.display;
|
|
31
27
|
const currentQueueLocationName = useSelectedQueueLocationName();
|
|
32
28
|
const currentQueueLocationUuid = useSelectedQueueLocationUuid();
|
|
33
29
|
|
|
@@ -69,39 +65,30 @@ const PatientQueueHeader: React.FC<PatientQueueHeaderProps> = ({ title, showLoca
|
|
|
69
65
|
]);
|
|
70
66
|
|
|
71
67
|
return (
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
itemToString={(item) => (item ? item.name : '')}
|
|
96
|
-
titleText={t('location', 'Location')}
|
|
97
|
-
type="inline"
|
|
98
|
-
onChange={handleQueueLocationChange}
|
|
99
|
-
/>
|
|
100
|
-
)}
|
|
101
|
-
{actions}
|
|
102
|
-
</div>
|
|
68
|
+
<PageHeader className={styles.header} data-testid="patient-queue-header">
|
|
69
|
+
<PageHeaderContent
|
|
70
|
+
title={title ? title : t(dashboardTitle.key, dashboardTitle.value)}
|
|
71
|
+
illustration={<ServiceQueuesPictogram />}
|
|
72
|
+
/>
|
|
73
|
+
<div className={styles.dropdownContainer}>
|
|
74
|
+
{showLocationDropdown && (
|
|
75
|
+
<Dropdown
|
|
76
|
+
aria-label={t('selectQueueLocation', 'Select queue location')}
|
|
77
|
+
className={styles.dropdown}
|
|
78
|
+
id="queueLocationDropdown"
|
|
79
|
+
label={currentQueueLocationName ?? t('all', 'All')}
|
|
80
|
+
items={
|
|
81
|
+
queueLocations.length !== 1 ? [{ id: 'all', name: t('all', 'All') }, ...queueLocations] : queueLocations
|
|
82
|
+
}
|
|
83
|
+
itemToString={(item) => (item ? item.name : '')}
|
|
84
|
+
titleText={t('location', 'Location')}
|
|
85
|
+
type="inline"
|
|
86
|
+
onChange={handleQueueLocationChange}
|
|
87
|
+
/>
|
|
88
|
+
)}
|
|
89
|
+
{actions}
|
|
103
90
|
</div>
|
|
104
|
-
</
|
|
91
|
+
</PageHeader>
|
|
105
92
|
);
|
|
106
93
|
};
|
|
107
94
|
|
|
@@ -3,63 +3,25 @@
|
|
|
3
3
|
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
4
|
|
|
5
5
|
.header {
|
|
6
|
-
@include type.type-style('body-compact-02');
|
|
7
|
-
color: $text-02;
|
|
8
6
|
background-color: $ui-02;
|
|
9
7
|
border: 1px solid $ui-03;
|
|
10
8
|
border-left: 0px;
|
|
11
9
|
display: flex;
|
|
12
10
|
justify-content: space-between;
|
|
13
|
-
padding-right: layout.$spacing-
|
|
11
|
+
padding-right: layout.$spacing-03;
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
.
|
|
14
|
+
.dropdownContainer {
|
|
17
15
|
display: flex;
|
|
18
|
-
flex-direction: row;
|
|
19
16
|
align-items: center;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.right-justified-items {
|
|
23
|
-
@include type.type-style('body-compact-02');
|
|
24
|
-
color: $text-02;
|
|
25
|
-
padding-top: layout.$spacing-05;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.page-name {
|
|
29
|
-
@include type.type-style('heading-04');
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
.page-labels {
|
|
33
|
-
p:first-of-type {
|
|
34
|
-
margin-bottom: layout.$spacing-02;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.date-and-location {
|
|
39
|
-
display: flex;
|
|
40
17
|
justify-content: flex-end;
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.value {
|
|
45
|
-
margin-left: layout.$spacing-02;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.middot {
|
|
49
|
-
margin: 0 layout.$spacing-03;
|
|
18
|
+
margin-top: layout.$spacing-03;
|
|
50
19
|
}
|
|
51
20
|
|
|
52
21
|
.view {
|
|
53
22
|
@include type.type-style('label-01');
|
|
54
23
|
}
|
|
55
24
|
|
|
56
|
-
.dropdownContainer {
|
|
57
|
-
display: flex;
|
|
58
|
-
align-items: center;
|
|
59
|
-
justify-content: flex-end;
|
|
60
|
-
margin-top: layout.$spacing-03;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
25
|
.dropdown {
|
|
64
26
|
:global(.cds--list-box__field) {
|
|
65
27
|
width: 14rem;
|