@kenyaemr/esm-service-queues-app 8.1.1-pre.129 → 8.1.2-pre.154
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 +26 -26
- package/dist/1006.js +1 -0
- package/dist/1006.js.map +1 -0
- package/dist/1060.js +1 -0
- package/dist/1060.js.map +1 -0
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/1325.js +1 -0
- package/dist/1325.js.map +1 -0
- package/dist/1644.js +1 -0
- package/dist/1727.js +1 -0
- package/dist/1727.js.map +1 -0
- package/dist/1800.js +1 -0
- package/dist/1800.js.map +1 -0
- package/dist/236.js +1 -1
- package/dist/2757.js +1 -0
- package/dist/{282.js → 2760.js} +1 -1
- package/dist/2760.js.map +1 -0
- package/dist/2784.js +2 -0
- package/dist/2784.js.map +1 -0
- package/dist/3199.js +1 -0
- package/dist/3199.js.map +1 -0
- package/dist/3372.js +2 -0
- package/dist/3372.js.map +1 -0
- package/dist/3574.js +1 -0
- package/dist/3604.js +1 -0
- package/dist/3604.js.map +1 -0
- package/dist/3652.js +1 -0
- package/dist/3760.js +1 -0
- package/dist/3760.js.map +1 -0
- package/dist/3818.js +1 -0
- package/dist/3818.js.map +1 -0
- package/dist/3828.js +1 -0
- package/dist/3828.js.map +1 -0
- package/dist/4272.js +1 -0
- package/dist/4378.js +1 -0
- package/dist/443.js +1 -0
- package/dist/443.js.map +1 -0
- package/dist/4460.js +1 -0
- package/dist/4705.js +1 -0
- package/dist/4911.js +1 -0
- package/dist/4911.js.map +1 -0
- package/dist/5236.js +1 -0
- package/dist/5236.js.map +1 -0
- package/dist/5240.js +1 -0
- package/dist/5282.js +1 -0
- package/dist/5282.js.map +1 -0
- package/dist/5336.js +1 -0
- package/dist/539.js +1 -0
- package/dist/5673.js +1 -0
- package/dist/5711.js +1 -0
- package/dist/5737.js +1 -0
- package/dist/5833.js +1 -0
- package/dist/6566.js +1 -0
- package/dist/6578.js +2 -0
- package/dist/{660.js.LICENSE.txt → 6578.js.LICENSE.txt} +5 -0
- package/dist/6578.js.map +1 -0
- package/dist/6591.js +2 -0
- package/dist/6591.js.map +1 -0
- package/dist/6670.js +1 -0
- package/dist/6670.js.map +1 -0
- package/dist/6727.js +1 -0
- package/dist/744.js +1 -0
- package/dist/752.js +1 -1
- package/dist/752.js.map +1 -1
- package/dist/7807.js +1 -0
- package/dist/8271.js +1 -0
- package/dist/8319.js +1 -0
- package/dist/8788.js +1 -0
- package/dist/899.js +1 -0
- package/dist/9261.js +1 -0
- package/dist/9392.js +1 -0
- package/dist/9392.js.map +1 -0
- package/dist/9993.js +1 -0
- package/dist/9993.js.map +1 -0
- package/dist/kenyaemr-esm-service-queues-app.js +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +541 -234
- package/dist/kenyaemr-esm-service-queues-app.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.LICENSE.txt +5 -0
- package/dist/main.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package-lock.json +2 -2
- package/package.json +8 -5
- package/src/active-visits/active-visits-table.resource.ts +0 -62
- package/src/active-visits/change-status-dialog.component.tsx +10 -3
- package/src/active-visits/change-status-dialog.scss +29 -1
- package/src/active-visits/change-status-dialog.test.tsx +11 -3
- package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +53 -54
- package/src/add-provider-queue-room/add-provider-queue-room.scss +28 -0
- package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +1 -1
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +1 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +29 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +4 -1
- package/src/config-schema.ts +28 -8
- package/src/create-queue-entry/create-queue-entry.workspace.tsx +99 -0
- package/src/create-queue-entry/existing-visit-form/existing-visit-form.component.tsx +73 -0
- package/src/{patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx → create-queue-entry/queue-fields/queue-fields.component.tsx} +76 -50
- package/src/create-queue-entry/queue-fields/queue-fields.resource.ts +63 -0
- package/src/{patient-search/visit-form-queue-fields/visit-form-queue-fields.scss → create-queue-entry/queue-fields/queue-fields.scss} +0 -4
- package/src/{patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx → create-queue-entry/queue-fields/queue-fields.test.tsx} +37 -17
- package/src/create-queue-entry/queue-fields/visit-form-queue-fields.extension.tsx +31 -0
- package/src/hooks/useQueueEntries.ts +13 -12
- package/src/index.ts +8 -14
- package/src/patient-info/patient-info.component.tsx +10 -8
- package/src/patient-queue-header/patient-queue-header.component.tsx +18 -13
- package/src/patient-queue-metrics/metrics-header.component.tsx +4 -4
- package/src/queue-entry-table-components/queue-priority.component.tsx +16 -11
- package/src/queue-entry-table-components/queue-priority.scss +5 -0
- package/src/queue-entry-table-components/transition-entry.component.tsx +1 -1
- package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +1 -1
- package/src/queue-patient-linelists/queue-linelist-filter.workspace.tsx +13 -12
- package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +1 -1
- package/src/queue-rooms/queue-room-form.test.tsx +2 -2
- package/src/queue-rooms/queue-room-form.workspace.tsx +1 -1
- package/src/queue-screen/queue-screen.test.tsx +11 -4
- package/src/queue-services/queue-service-form.test.tsx +76 -16
- package/src/queue-services/queue-service-form.workspace.tsx +131 -131
- package/src/queue-services/queue-service.resource.ts +7 -2
- package/src/queue-table/cells/columns.resource.ts +10 -7
- package/src/queue-table/cells/queue-table-visit-attribute-queue-number-cell.component.tsx +1 -0
- package/src/queue-table/default-queue-table.component.tsx +12 -13
- package/src/queue-table/default-queue-table.test.tsx +3 -3
- package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.scss +28 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actions.modal.tsx +8 -2
- package/src/queue-table/queue-entry-actions/queue-entry-confirm-action.modal.tsx +2 -1
- package/src/queue-table/queue-entry-actions/queue-entry-confirm-action.scss +29 -0
- package/src/queue-table/queue-table.component.tsx +1 -1
- package/src/queue-table/queue-table.scss +12 -2
- package/src/queue-table/queue-table.test.tsx +10 -1
- package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +16 -4
- package/src/remove-queue-entry-dialog/remove-queue-entry.scss +29 -0
- package/src/routes.json +4 -8
- package/src/transition-latest-queue-entry/transition-latest-queue-entry.resource.ts +2 -10
- package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +41 -32
- package/src/transition-queue-entry/transition-queue-entry-dialog.scss +28 -0
- package/src/types/index.ts +0 -8
- package/src/views/queue-tables-for-all-statuses.component.tsx +12 -15
- package/translations/am.json +5 -78
- package/translations/ar.json +5 -78
- package/translations/de.json +235 -0
- package/translations/en.json +9 -86
- package/translations/es.json +3 -76
- package/translations/fr.json +5 -78
- package/translations/he.json +5 -78
- package/translations/hi.json +235 -0
- package/translations/hi_IN.json +235 -0
- package/translations/id.json +235 -0
- package/translations/it.json +235 -0
- package/translations/km.json +5 -78
- package/translations/ne.json +235 -0
- package/translations/pt.json +235 -0
- package/translations/pt_BR.json +235 -0
- package/translations/qu.json +235 -0
- package/translations/si.json +235 -0
- package/translations/sw.json +235 -0
- package/translations/sw_KE.json +235 -0
- package/translations/tr.json +235 -0
- package/translations/tr_TR.json +235 -0
- package/translations/uk.json +235 -0
- package/translations/vi.json +235 -0
- package/translations/zh.json +6 -79
- package/translations/zh_CN.json +5 -78
- package/dist/169.js +0 -1
- package/dist/169.js.map +0 -1
- package/dist/199.js +0 -1
- package/dist/199.js.map +0 -1
- package/dist/236.js.map +0 -1
- package/dist/271.js +0 -1
- package/dist/282.js.map +0 -1
- package/dist/319.js +0 -1
- package/dist/325.js +0 -1
- package/dist/325.js.map +0 -1
- package/dist/366.js +0 -1
- package/dist/366.js.map +0 -1
- package/dist/372.js +0 -2
- package/dist/372.js.map +0 -1
- package/dist/392.js +0 -1
- package/dist/392.js.map +0 -1
- package/dist/460.js +0 -1
- package/dist/501.js +0 -1
- package/dist/501.js.map +0 -1
- package/dist/574.js +0 -1
- package/dist/591.js +0 -2
- package/dist/591.js.map +0 -1
- package/dist/6.js +0 -1
- package/dist/6.js.map +0 -1
- package/dist/60.js +0 -1
- package/dist/60.js.map +0 -1
- package/dist/604.js +0 -1
- package/dist/604.js.map +0 -1
- package/dist/644.js +0 -1
- package/dist/660.js +0 -2
- package/dist/660.js.map +0 -1
- package/dist/670.js +0 -1
- package/dist/670.js.map +0 -1
- package/dist/727.js +0 -1
- package/dist/727.js.map +0 -1
- package/dist/748.js +0 -1
- package/dist/748.js.map +0 -1
- package/dist/757.js +0 -1
- package/dist/760.js +0 -1
- package/dist/760.js.map +0 -1
- package/dist/784.js +0 -2
- package/dist/784.js.map +0 -1
- package/dist/788.js +0 -1
- package/dist/800.js +0 -1
- package/dist/800.js.map +0 -1
- package/dist/807.js +0 -1
- package/dist/818.js +0 -1
- package/dist/818.js.map +0 -1
- package/dist/828.js +0 -1
- package/dist/828.js.map +0 -1
- package/dist/833.js +0 -1
- package/dist/911.js +0 -1
- package/dist/911.js.map +0 -1
- package/dist/940.js +0 -1
- package/dist/940.js.map +0 -1
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +0 -228
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +0 -32
- package/src/patient-search/advanced-search.component.tsx +0 -191
- package/src/patient-search/advanced-search.scss +0 -154
- package/src/patient-search/advanced-search.test.tsx +0 -26
- package/src/patient-search/basic-search.component.tsx +0 -112
- package/src/patient-search/basic-search.scss +0 -139
- package/src/patient-search/basic-search.test.tsx +0 -18
- package/src/patient-search/empty-data-illustration.component.tsx +0 -41
- package/src/patient-search/hooks/useActivePatientEnrollment.tsx +0 -29
- package/src/patient-search/hooks/useDefaultLocation.ts +0 -14
- package/src/patient-search/hooks/usePatients.tsx +0 -25
- package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +0 -35
- package/src/patient-search/hooks/useScheduledVisits.ts +0 -52
- package/src/patient-search/patient-scheduled-visits.component.tsx +0 -315
- package/src/patient-search/patient-scheduled-visits.scss +0 -131
- package/src/patient-search/patient-scheduled-visits.test.tsx +0 -39
- package/src/patient-search/patient-search.workspace.tsx +0 -135
- package/src/patient-search/search-illustration.component.tsx +0 -27
- package/src/patient-search/search-results.component.tsx +0 -75
- package/src/patient-search/search-results.scss +0 -80
- package/src/patient-search/search-results.test.tsx +0 -69
- package/src/patient-search/search.resource.ts +0 -10
- package/src/patient-search/visit-form/existing-visit-form.component.tsx +0 -112
- package/src/patient-search/visit-form/queue.resource.ts +0 -64
- package/src/patient-search/visit-form/visit-form.component.tsx +0 -337
- package/src/patient-search/visit-form/visit-type-selector.component.tsx +0 -153
- package/src/patient-search/visit-form/visit-type-selector.scss +0 -100
- package/src/patient-search/visit-form/visit-type-selector.test.tsx +0 -84
- package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +0 -277
- package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +0 -93
- package/src/visits-missing-inqueue/visits-missing-inqueue.scss +0 -111
- /package/dist/{784.js.LICENSE.txt → 2784.js.LICENSE.txt} +0 -0
- /package/dist/{372.js.LICENSE.txt → 3372.js.LICENSE.txt} +0 -0
- /package/dist/{591.js.LICENSE.txt → 6591.js.LICENSE.txt} +0 -0
- /package/src/{patient-search/patient-search.scss → create-queue-entry/create-queue-entry.scss} +0 -0
- /package/src/{patient-search/visit-form/visit-form.scss → create-queue-entry/existing-visit-form/existing-visit-form.scss} +0 -0
- /package/src/{patient-search → create-queue-entry}/hooks/useQueueLocations.tsx +0 -0
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import React, { useCallback, useState } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import {
|
|
4
|
-
Button,
|
|
5
|
-
Form,
|
|
6
|
-
InlineNotification,
|
|
7
|
-
ModalBody,
|
|
8
|
-
ModalFooter,
|
|
9
|
-
ModalHeader,
|
|
10
|
-
Select,
|
|
11
|
-
SelectItem,
|
|
12
|
-
RadioButtonGroup,
|
|
13
|
-
RadioButton,
|
|
14
|
-
RadioButtonSkeleton,
|
|
15
|
-
SelectSkeleton,
|
|
16
|
-
} from '@carbon/react';
|
|
17
|
-
import { showSnackbar, useConfig } from '@openmrs/esm-framework';
|
|
18
|
-
import { postQueueEntry } from '../active-visits/active-visits-table.resource';
|
|
19
|
-
import { type ActiveVisit } from '../visits-missing-inqueue/visits-missing-inqueue.resource';
|
|
20
|
-
import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
|
|
21
|
-
import { useQueues } from '../hooks/useQueues';
|
|
22
|
-
import { useMutateQueueEntries } from '../hooks/useQueueEntries';
|
|
23
|
-
import { type ConfigObject } from '../config-schema';
|
|
24
|
-
import styles from './add-patient-toqueue-dialog.scss';
|
|
25
|
-
|
|
26
|
-
interface AddVisitToQueueDialogProps {
|
|
27
|
-
visitDetails: ActiveVisit;
|
|
28
|
-
closeModal: () => void;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const AddVisitToQueue: React.FC<AddVisitToQueueDialogProps> = ({ visitDetails, closeModal }) => {
|
|
32
|
-
const { t } = useTranslation();
|
|
33
|
-
|
|
34
|
-
const visitUuid = visitDetails?.visitUuid;
|
|
35
|
-
const [queueUuid, setQueueUuid] = useState('');
|
|
36
|
-
const patientUuid = visitDetails?.patientUuid;
|
|
37
|
-
const patientName = visitDetails?.name;
|
|
38
|
-
const patientAge = visitDetails?.age;
|
|
39
|
-
const patientSex = visitDetails?.gender;
|
|
40
|
-
const [selectedQueueLocation, setSelectedQueueLocation] = useState('');
|
|
41
|
-
const { queues, isLoading: isLoadingQueues } = useQueues(selectedQueueLocation);
|
|
42
|
-
const { queueLocations, isLoading: isLoadingQueueLocations } = useQueueLocations();
|
|
43
|
-
const [isMissingPriority, setIsMissingPriority] = useState(false);
|
|
44
|
-
const [isMissingService, setIsMissingService] = useState(false);
|
|
45
|
-
const config = useConfig<ConfigObject>();
|
|
46
|
-
const { mutateQueueEntries } = useMutateQueueEntries();
|
|
47
|
-
const [priority, setPriority] = useState(config.concepts.defaultPriorityConceptUuid);
|
|
48
|
-
const priorities = queues.find((q) => q.uuid === queueUuid)?.allowedPriorities ?? [];
|
|
49
|
-
|
|
50
|
-
const addVisitToQueue = useCallback(() => {
|
|
51
|
-
if (!queueUuid) {
|
|
52
|
-
setIsMissingService(true);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
setIsMissingService(false);
|
|
56
|
-
|
|
57
|
-
if (!priority) {
|
|
58
|
-
setIsMissingPriority(true);
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
setIsMissingPriority(false);
|
|
62
|
-
const emergencyPriorityConceptUuid = config.concepts.emergencyPriorityConceptUuid;
|
|
63
|
-
const sortWeight = priority === emergencyPriorityConceptUuid ? 1.0 : 0.0;
|
|
64
|
-
const status = config.concepts.defaultStatusConceptUuid;
|
|
65
|
-
const visitQueueNumberAttributeUuid = config.visitQueueNumberAttributeUuid;
|
|
66
|
-
|
|
67
|
-
postQueueEntry(
|
|
68
|
-
visitUuid,
|
|
69
|
-
queueUuid,
|
|
70
|
-
patientUuid,
|
|
71
|
-
priority,
|
|
72
|
-
status,
|
|
73
|
-
sortWeight,
|
|
74
|
-
selectedQueueLocation,
|
|
75
|
-
visitQueueNumberAttributeUuid,
|
|
76
|
-
).then(
|
|
77
|
-
({ status }) => {
|
|
78
|
-
if (status === 201) {
|
|
79
|
-
showSnackbar({
|
|
80
|
-
isLowContrast: true,
|
|
81
|
-
title: t('addEntry', 'Add entry'),
|
|
82
|
-
kind: 'success',
|
|
83
|
-
subtitle: t('queueEntryAddedSuccessfully', 'Queue entry added successfully'),
|
|
84
|
-
});
|
|
85
|
-
closeModal();
|
|
86
|
-
mutateQueueEntries();
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
(error) => {
|
|
90
|
-
showSnackbar({
|
|
91
|
-
title: t('queueEntryAddFailed', 'Error adding queue entry status'),
|
|
92
|
-
kind: 'error',
|
|
93
|
-
isLowContrast: false,
|
|
94
|
-
subtitle: error?.message,
|
|
95
|
-
});
|
|
96
|
-
},
|
|
97
|
-
);
|
|
98
|
-
}, [
|
|
99
|
-
queueUuid,
|
|
100
|
-
priority,
|
|
101
|
-
config.concepts.emergencyPriorityConceptUuid,
|
|
102
|
-
config.concepts.defaultStatusConceptUuid,
|
|
103
|
-
config.visitQueueNumberAttributeUuid,
|
|
104
|
-
visitUuid,
|
|
105
|
-
patientUuid,
|
|
106
|
-
selectedQueueLocation,
|
|
107
|
-
t,
|
|
108
|
-
closeModal,
|
|
109
|
-
mutateQueueEntries,
|
|
110
|
-
]);
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<div>
|
|
114
|
-
<ModalHeader closeModal={closeModal} title={t('addVisitToQueue', 'Add Visit To Queue?')} />
|
|
115
|
-
<ModalBody>
|
|
116
|
-
<Form onSubmit={addVisitToQueue}>
|
|
117
|
-
<div className={styles.modalBody}>
|
|
118
|
-
<h5>
|
|
119
|
-
{patientName} · {patientSex} · {patientAge} {t('years', 'Years')}
|
|
120
|
-
</h5>
|
|
121
|
-
</div>
|
|
122
|
-
<section>
|
|
123
|
-
{isLoadingQueueLocations ? (
|
|
124
|
-
<SelectSkeleton />
|
|
125
|
-
) : (
|
|
126
|
-
<Select
|
|
127
|
-
labelText={t('selectQueueLocation', 'Select a queue location')}
|
|
128
|
-
id="location"
|
|
129
|
-
invalidText="Required"
|
|
130
|
-
value={selectedQueueLocation}
|
|
131
|
-
onChange={(event) => setSelectedQueueLocation(event.target.value)}>
|
|
132
|
-
{!selectedQueueLocation ? (
|
|
133
|
-
<SelectItem text={t('selectQueueLocation', 'Select a queue location')} value="" />
|
|
134
|
-
) : null}
|
|
135
|
-
{queueLocations?.length > 0 &&
|
|
136
|
-
queueLocations.map((location) => (
|
|
137
|
-
<SelectItem key={location.id} text={location.name} value={location.id}>
|
|
138
|
-
{location.name}
|
|
139
|
-
</SelectItem>
|
|
140
|
-
))}
|
|
141
|
-
</Select>
|
|
142
|
-
)}
|
|
143
|
-
</section>
|
|
144
|
-
|
|
145
|
-
<section className={styles.section}>
|
|
146
|
-
<div className={styles.sectionTitle}>{t('queueService', 'Queue service')}</div>
|
|
147
|
-
{isLoadingQueues ? (
|
|
148
|
-
<SelectSkeleton />
|
|
149
|
-
) : (
|
|
150
|
-
<Select
|
|
151
|
-
labelText={t('selectService', 'Select a service')}
|
|
152
|
-
id="service"
|
|
153
|
-
invalidText="Required"
|
|
154
|
-
value={queueUuid}
|
|
155
|
-
onChange={(event) => setQueueUuid(event.target.value)}>
|
|
156
|
-
{!queueUuid ? <SelectItem text={t('chooseService', 'Select a service')} value="" /> : null}
|
|
157
|
-
{queues?.length > 0 &&
|
|
158
|
-
queues.map((service) => (
|
|
159
|
-
<SelectItem key={service.uuid} text={service.display} value={service.uuid}>
|
|
160
|
-
{service.display}
|
|
161
|
-
</SelectItem>
|
|
162
|
-
))}
|
|
163
|
-
</Select>
|
|
164
|
-
)}
|
|
165
|
-
</section>
|
|
166
|
-
{isMissingService && (
|
|
167
|
-
<section>
|
|
168
|
-
<InlineNotification
|
|
169
|
-
style={{ margin: '0', minWidth: '100%' }}
|
|
170
|
-
kind="error"
|
|
171
|
-
lowContrast={true}
|
|
172
|
-
title={t('pleaseSelectService', 'Please select a service')}
|
|
173
|
-
/>
|
|
174
|
-
</section>
|
|
175
|
-
)}
|
|
176
|
-
|
|
177
|
-
<section className={styles.section}>
|
|
178
|
-
<div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
|
|
179
|
-
{isLoadingQueues ? (
|
|
180
|
-
<RadioButtonGroup>
|
|
181
|
-
<RadioButtonSkeleton />
|
|
182
|
-
<RadioButtonSkeleton />
|
|
183
|
-
<RadioButtonSkeleton />
|
|
184
|
-
</RadioButtonGroup>
|
|
185
|
-
) : !priorities?.length ? (
|
|
186
|
-
<InlineNotification
|
|
187
|
-
className={styles.inlineNotification}
|
|
188
|
-
kind={'error'}
|
|
189
|
-
lowContrast
|
|
190
|
-
subtitle={t('configurePriorities', 'Please configure priorities to continue.')}
|
|
191
|
-
title={t('noPriorityFound', 'No priority found')}
|
|
192
|
-
/>
|
|
193
|
-
) : (
|
|
194
|
-
<RadioButtonGroup
|
|
195
|
-
className={styles.radioButtonWrapper}
|
|
196
|
-
name="priority"
|
|
197
|
-
defaultSelected={priority}
|
|
198
|
-
onChange={(uuid) => {
|
|
199
|
-
setPriority(uuid);
|
|
200
|
-
}}>
|
|
201
|
-
{priorities?.length > 0 &&
|
|
202
|
-
priorities.map(({ uuid, display }) => <RadioButton key={uuid} labelText={display} value={uuid} />)}
|
|
203
|
-
</RadioButtonGroup>
|
|
204
|
-
)}
|
|
205
|
-
</section>
|
|
206
|
-
{isMissingPriority && (
|
|
207
|
-
<section>
|
|
208
|
-
<InlineNotification
|
|
209
|
-
style={{ margin: '0', minWidth: '100%' }}
|
|
210
|
-
kind="error"
|
|
211
|
-
lowContrast={true}
|
|
212
|
-
title={t('missingPriority', 'Please select a priority')}
|
|
213
|
-
/>
|
|
214
|
-
</section>
|
|
215
|
-
)}
|
|
216
|
-
</Form>
|
|
217
|
-
</ModalBody>
|
|
218
|
-
<ModalFooter>
|
|
219
|
-
<Button kind="secondary" onClick={closeModal}>
|
|
220
|
-
{t('cancel', 'Cancel')}
|
|
221
|
-
</Button>
|
|
222
|
-
<Button onClick={addVisitToQueue}>{t('save', 'Save')}</Button>
|
|
223
|
-
</ModalFooter>
|
|
224
|
-
</div>
|
|
225
|
-
);
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
export default AddVisitToQueue;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
@use '@carbon/layout';
|
|
2
|
-
@use '@carbon/type';
|
|
3
|
-
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
|
-
|
|
5
|
-
.radioButtonGroup {
|
|
6
|
-
display: flex;
|
|
7
|
-
flex-direction: column;
|
|
8
|
-
align-items: flex-start;
|
|
9
|
-
margin-top: layout.$spacing-03;
|
|
10
|
-
min-height: layout.$spacing-10;
|
|
11
|
-
width: 100%;
|
|
12
|
-
@include type.type-style('body-compact-01');
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.radioButton {
|
|
16
|
-
padding: layout.$spacing-02 layout.$spacing-02;
|
|
17
|
-
margin: layout.$spacing-03 0;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
section {
|
|
21
|
-
margin: layout.$spacing-03;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.sectionTitle {
|
|
25
|
-
@include type.type-style('heading-compact-02');
|
|
26
|
-
color: $text-02;
|
|
27
|
-
margin-bottom: layout.$spacing-04;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.modalBody {
|
|
31
|
-
padding-bottom: layout.$spacing-05;
|
|
32
|
-
}
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
-
import {
|
|
4
|
-
Button,
|
|
5
|
-
ButtonSet,
|
|
6
|
-
Column,
|
|
7
|
-
ContentSwitcher,
|
|
8
|
-
DatePicker,
|
|
9
|
-
DatePickerInput,
|
|
10
|
-
Form,
|
|
11
|
-
FormGroup,
|
|
12
|
-
Layer,
|
|
13
|
-
Stack,
|
|
14
|
-
Switch,
|
|
15
|
-
TextInput,
|
|
16
|
-
} from '@carbon/react';
|
|
17
|
-
import { ArrowLeft } from '@carbon/react/icons';
|
|
18
|
-
import { useLayoutType } from '@openmrs/esm-framework';
|
|
19
|
-
import { SearchTypes } from '../types';
|
|
20
|
-
import styles from './advanced-search.scss';
|
|
21
|
-
import { datePickerFormat, datePickerPlaceHolder } from '../constants';
|
|
22
|
-
|
|
23
|
-
interface PatientSearchProps {
|
|
24
|
-
toggleSearchType: (searchMode: SearchTypes) => void;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
enum fieldMatcherRange {
|
|
28
|
-
ANY = 'any',
|
|
29
|
-
ALL = 'all',
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
enum genders {
|
|
33
|
-
ANY = 'any',
|
|
34
|
-
MALE = 'male',
|
|
35
|
-
FEMALE = 'female',
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const AdvancedSearch: React.FC<PatientSearchProps> = ({ toggleSearchType }) => {
|
|
39
|
-
const { t } = useTranslation();
|
|
40
|
-
const isTablet = useLayoutType() === 'tablet';
|
|
41
|
-
const [firstName, setFirstName] = useState('');
|
|
42
|
-
const [middleName, setMiddleName] = useState('');
|
|
43
|
-
const [lastName, setLastName] = useState('');
|
|
44
|
-
const [gender, setGender] = useState('');
|
|
45
|
-
const [dateOfBirth, setDateOfBirth] = useState('');
|
|
46
|
-
const [phoneNumber, setPhoneNumber] = useState('');
|
|
47
|
-
const [postCode, setPostCode] = useState('');
|
|
48
|
-
const [lastVisitDate, setLastVisitDate] = useState('');
|
|
49
|
-
const [fieldMatcherRangeSwitcherValue, setFieldMatcherRangeSwitcherValue] = useState(0);
|
|
50
|
-
const [genderSwitcherValue, setGenderSwitcherValue] = useState(0);
|
|
51
|
-
const [searchParams, setSearchParams] = useState([]);
|
|
52
|
-
const [open, setOpen] = useState(false);
|
|
53
|
-
|
|
54
|
-
const handleSearch = () => {
|
|
55
|
-
setSearchParams([firstName, middleName, lastName, gender, dateOfBirth, phoneNumber, postCode, lastVisitDate]);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
<Form onSubmit={handleSearch} className={styles.form}>
|
|
60
|
-
<div>
|
|
61
|
-
<div className={styles.backButton}>
|
|
62
|
-
<Button
|
|
63
|
-
kind="ghost"
|
|
64
|
-
renderIcon={(props) => <ArrowLeft size={24} {...props} />}
|
|
65
|
-
iconDescription="Back to simple search"
|
|
66
|
-
size="sm"
|
|
67
|
-
onClick={() => toggleSearchType(SearchTypes.BASIC)}>
|
|
68
|
-
<span>{t('backToSimpleSearch', 'Back to simple search')}</span>
|
|
69
|
-
</Button>
|
|
70
|
-
</div>
|
|
71
|
-
<Stack gap={4} className={styles.grid}>
|
|
72
|
-
<Column>
|
|
73
|
-
<div className={styles.contentSwitcherContainer}>
|
|
74
|
-
<span>{t('match', 'Match')}</span>
|
|
75
|
-
<ContentSwitcher
|
|
76
|
-
size="sm"
|
|
77
|
-
className={styles.fieldRangeSwitcher}
|
|
78
|
-
onChange={({ index }) => setFieldMatcherRangeSwitcherValue(index)}>
|
|
79
|
-
<Switch name={fieldMatcherRange.ANY} text={t('any', 'Any')} />
|
|
80
|
-
<Switch name={fieldMatcherRange.ALL} text={t('all', 'All')} />
|
|
81
|
-
</ContentSwitcher>
|
|
82
|
-
<span>{t('fields', 'of the following fields')}:</span>
|
|
83
|
-
</div>
|
|
84
|
-
</Column>
|
|
85
|
-
|
|
86
|
-
<Column>
|
|
87
|
-
<h3 className={styles.heading}>{t('name', 'Name')}</h3>
|
|
88
|
-
<Layer>
|
|
89
|
-
<TextInput
|
|
90
|
-
className={styles.input}
|
|
91
|
-
id="firstName"
|
|
92
|
-
labelText={t('firstName', 'First name')}
|
|
93
|
-
onChange={(event) => setFirstName(event.target.value)}
|
|
94
|
-
value={firstName}
|
|
95
|
-
/>
|
|
96
|
-
</Layer>
|
|
97
|
-
<Layer>
|
|
98
|
-
<TextInput
|
|
99
|
-
className={styles.input}
|
|
100
|
-
id="middleName"
|
|
101
|
-
labelText={t('middleName', 'Middle name')}
|
|
102
|
-
onChange={(event) => setMiddleName(event.target.value)}
|
|
103
|
-
value={middleName}
|
|
104
|
-
/>
|
|
105
|
-
</Layer>
|
|
106
|
-
<Layer>
|
|
107
|
-
<TextInput
|
|
108
|
-
className={styles.input}
|
|
109
|
-
id="lastName"
|
|
110
|
-
labelText={t('lastName', 'Last name')}
|
|
111
|
-
onChange={(event) => setLastName(event.target.value)}
|
|
112
|
-
value={lastName}
|
|
113
|
-
/>
|
|
114
|
-
</Layer>
|
|
115
|
-
</Column>
|
|
116
|
-
<span className={styles.spacer} />
|
|
117
|
-
|
|
118
|
-
<Column>
|
|
119
|
-
<h3 className={styles.heading}>{t('personalDetails', 'Personal details')}</h3>
|
|
120
|
-
<FormGroup legendText={t('sex', 'Sex')}>
|
|
121
|
-
<ContentSwitcher
|
|
122
|
-
size="sm"
|
|
123
|
-
className={styles.genderSwitcher}
|
|
124
|
-
onChange={({ index }) => setGenderSwitcherValue(index)}>
|
|
125
|
-
<Switch name={genders.ANY} text={t('any', 'Any')} />
|
|
126
|
-
<Switch name={genders.MALE} text={t('male', 'Male')} />
|
|
127
|
-
<Switch name={genders.FEMALE} text={t('female', 'Female')} />
|
|
128
|
-
</ContentSwitcher>
|
|
129
|
-
</FormGroup>
|
|
130
|
-
<Layer>
|
|
131
|
-
<DatePicker datePickerType="single" dateFormat={datePickerFormat}>
|
|
132
|
-
<DatePickerInput
|
|
133
|
-
id="dateOfBirth"
|
|
134
|
-
placeholder={datePickerPlaceHolder}
|
|
135
|
-
labelText={t('dateOfBirth', 'Date of birth')}
|
|
136
|
-
onChange={(event) => setDateOfBirth(event.target.value)}
|
|
137
|
-
type="date"
|
|
138
|
-
/>
|
|
139
|
-
</DatePicker>
|
|
140
|
-
</Layer>
|
|
141
|
-
<Layer>
|
|
142
|
-
<TextInput
|
|
143
|
-
className={styles.input}
|
|
144
|
-
id="phoneNumber"
|
|
145
|
-
labelText={t('phoneNumber', 'Phone number')}
|
|
146
|
-
onChange={(event) => setPhoneNumber(event.target.value)}
|
|
147
|
-
value={phoneNumber}
|
|
148
|
-
/>
|
|
149
|
-
</Layer>
|
|
150
|
-
<Layer>
|
|
151
|
-
<TextInput
|
|
152
|
-
className={styles.input}
|
|
153
|
-
id="postCode"
|
|
154
|
-
labelText={t('postCode', 'Post code')}
|
|
155
|
-
onChange={(event) => setPostCode(event.target.value)}
|
|
156
|
-
value={postCode}
|
|
157
|
-
/>
|
|
158
|
-
</Layer>
|
|
159
|
-
</Column>
|
|
160
|
-
<span className={styles.spacer} />
|
|
161
|
-
|
|
162
|
-
<Column>
|
|
163
|
-
<h3 className={styles.heading}>{t('lastVisit', 'Last visit')}</h3>
|
|
164
|
-
<Layer>
|
|
165
|
-
<DatePicker datePickerType="single" dateFormat={datePickerFormat}>
|
|
166
|
-
<DatePickerInput
|
|
167
|
-
id="lastVisitDate"
|
|
168
|
-
placeholder={datePickerPlaceHolder}
|
|
169
|
-
labelText={t('lastVisitDate', 'Date')}
|
|
170
|
-
onChange={(event) => setLastVisitDate(event.target.value)}
|
|
171
|
-
type="date"
|
|
172
|
-
width={'120px'}
|
|
173
|
-
/>
|
|
174
|
-
</DatePicker>
|
|
175
|
-
</Layer>
|
|
176
|
-
</Column>
|
|
177
|
-
</Stack>
|
|
178
|
-
</div>
|
|
179
|
-
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
180
|
-
<Button className={styles.button} kind="secondary" onClick={() => toggleSearchType(SearchTypes.BASIC)}>
|
|
181
|
-
{t('cancel', 'Cancel')}
|
|
182
|
-
</Button>
|
|
183
|
-
<Button className={styles.button} kind="primary" type="submit">
|
|
184
|
-
{t('search', 'Search')}
|
|
185
|
-
</Button>
|
|
186
|
-
</ButtonSet>
|
|
187
|
-
</Form>
|
|
188
|
-
);
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
export default AdvancedSearch;
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
@use '@carbon/layout';
|
|
2
|
-
@use '@carbon/type';
|
|
3
|
-
@use '@openmrs/esm-styleguide/src/vars' as *;
|
|
4
|
-
|
|
5
|
-
.form {
|
|
6
|
-
display: flex;
|
|
7
|
-
flex-direction: column;
|
|
8
|
-
justify-content: space-between;
|
|
9
|
-
height: calc(100vh - layout.$spacing-11);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
.grid {
|
|
13
|
-
margin: 0 layout.$spacing-05;
|
|
14
|
-
padding: 0;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
.row {
|
|
18
|
-
margin: 0;
|
|
19
|
-
|
|
20
|
-
:global(.cds--col) {
|
|
21
|
-
:global(.cds--form-item) {
|
|
22
|
-
&:not(:first-of-type):not(:last-of-type) {
|
|
23
|
-
margin: layout.$spacing-05 0;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
:global(.cds--fieldset) {
|
|
28
|
-
margin: 0;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
:global(.cds--date-picker.cds--date-picker--single .cds--date-picker__input) {
|
|
32
|
-
width: layout.$spacing-13;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.heading {
|
|
38
|
-
@include type.type-style('heading-compact-02');
|
|
39
|
-
margin-bottom: layout.$spacing-03;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
.spacer {
|
|
43
|
-
margin-top: layout.$spacing-07;
|
|
44
|
-
display: inline-block;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.backButton {
|
|
48
|
-
align-items: center;
|
|
49
|
-
display: flex;
|
|
50
|
-
justify-content: flex-start;
|
|
51
|
-
margin: layout.$spacing-03 0;
|
|
52
|
-
padding: 0;
|
|
53
|
-
@include type.type-style('body-compact-01');
|
|
54
|
-
|
|
55
|
-
button {
|
|
56
|
-
display: flex;
|
|
57
|
-
|
|
58
|
-
svg {
|
|
59
|
-
order: 1;
|
|
60
|
-
margin-right: layout.$spacing-03;
|
|
61
|
-
margin-left: 0 !important;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
span {
|
|
65
|
-
order: 2;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.advancePatientSearchContainer {
|
|
71
|
-
margin: 0 layout.$spacing-05;
|
|
72
|
-
|
|
73
|
-
& .backButton {
|
|
74
|
-
margin: 0;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
& > button {
|
|
78
|
-
padding-left: 0;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
.label01 {
|
|
83
|
-
@include type.type-style('label-01');
|
|
84
|
-
color: $text-02;
|
|
85
|
-
margin: layout.$spacing-03 0;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
.formTextInput {
|
|
89
|
-
margin-bottom: layout.$spacing-04;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
.contentSwitcherContainer {
|
|
93
|
-
display: flex;
|
|
94
|
-
align-items: center;
|
|
95
|
-
height: layout.$spacing-09;
|
|
96
|
-
margin-bottom: layout.$spacing-05;
|
|
97
|
-
|
|
98
|
-
& > span {
|
|
99
|
-
@include type.type-style('heading-compact-01');
|
|
100
|
-
color: $text-02;
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
.formTitle {
|
|
105
|
-
font-weight: bold;
|
|
106
|
-
@include type.type-style('heading-compact-02');
|
|
107
|
-
margin-bottom: layout.$spacing-02;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
.fieldRangeSwitcher {
|
|
111
|
-
width: 8rem;
|
|
112
|
-
margin: 0 layout.$spacing-03 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.genderSwitcher {
|
|
116
|
-
width: 18rem;
|
|
117
|
-
margin: layout.$spacing-02 0 layout.$spacing-05;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
.button {
|
|
121
|
-
height: layout.$spacing-10;
|
|
122
|
-
display: flex;
|
|
123
|
-
align-content: flex-start;
|
|
124
|
-
align-items: baseline;
|
|
125
|
-
min-width: 50%;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
.tablet {
|
|
129
|
-
padding: layout.$spacing-06 layout.$spacing-05;
|
|
130
|
-
background-color: $ui-02;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
.desktop {
|
|
134
|
-
padding: 0;
|
|
135
|
-
margin-top: layout.$spacing-05;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/* Desktop */
|
|
139
|
-
:global(.omrs-breakpoint-gt-tablet) {
|
|
140
|
-
.form {
|
|
141
|
-
height: calc(100vh - layout.$spacing-11);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/* Tablet */
|
|
146
|
-
:global(.omrs-breakpoint-lt-desktop) {
|
|
147
|
-
.form {
|
|
148
|
-
height: calc(100vh - layout.$spacing-09);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
.input {
|
|
153
|
-
width: 13.5rem;
|
|
154
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
3
|
-
import AdvancedSearch from './advanced-search.component';
|
|
4
|
-
|
|
5
|
-
describe('AdvancedSearch', () => {
|
|
6
|
-
test('renders the advanced patient search in an overlay', async () => {
|
|
7
|
-
render(<AdvancedSearch toggleSearchType={jest.fn()} />);
|
|
8
|
-
|
|
9
|
-
expect(screen.getByRole('button', { name: /back to simple search/i })).toBeInTheDocument();
|
|
10
|
-
expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
|
|
11
|
-
expect(screen.getByRole('button', { name: /^search$/i })).toBeInTheDocument();
|
|
12
|
-
|
|
13
|
-
await screen.findAllByText(/any/i);
|
|
14
|
-
|
|
15
|
-
expect(screen.getByRole('tab', { name: /^male$/i })).toBeInTheDocument();
|
|
16
|
-
expect(screen.getByRole('tab', { name: /^female$/i })).toBeInTheDocument();
|
|
17
|
-
expect(screen.getByRole('heading', { name: /name/i })).toBeInTheDocument();
|
|
18
|
-
expect(screen.getByRole('heading', { name: /personal details/i })).toBeInTheDocument();
|
|
19
|
-
expect(screen.getByRole('heading', { name: /last visit/i })).toBeInTheDocument();
|
|
20
|
-
expect(screen.getByRole('textbox', { name: /first name/i })).toBeInTheDocument();
|
|
21
|
-
expect(screen.getByRole('textbox', { name: /middle name/i })).toBeInTheDocument();
|
|
22
|
-
expect(screen.getByRole('textbox', { name: /last name/i })).toBeInTheDocument();
|
|
23
|
-
expect(screen.getByRole('textbox', { name: /phone number/i })).toBeInTheDocument();
|
|
24
|
-
expect(screen.getByRole('textbox', { name: /post code/i })).toBeInTheDocument();
|
|
25
|
-
});
|
|
26
|
-
});
|