@kenyaemr/esm-service-queues-app 7.0.2-pre.65
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 +40 -0
- package/README.md +20 -0
- package/dist/130.js +2 -0
- package/dist/130.js.LICENSE.txt +3 -0
- package/dist/130.js.map +1 -0
- package/dist/152.js +1 -0
- package/dist/152.js.map +1 -0
- package/dist/169.js +1 -0
- package/dist/169.js.map +1 -0
- package/dist/185.js +1 -0
- package/dist/185.js.map +1 -0
- package/dist/233.js +1 -0
- package/dist/233.js.map +1 -0
- package/dist/237.js +1 -0
- package/dist/237.js.map +1 -0
- package/dist/255.js +2 -0
- package/dist/255.js.LICENSE.txt +9 -0
- package/dist/255.js.map +1 -0
- package/dist/271.js +1 -0
- package/dist/276.js +1 -0
- package/dist/276.js.map +1 -0
- package/dist/303.js +1 -0
- package/dist/303.js.map +1 -0
- package/dist/319.js +1 -0
- package/dist/401.js +1 -0
- package/dist/401.js.map +1 -0
- package/dist/430.js +2 -0
- package/dist/430.js.LICENSE.txt +50 -0
- package/dist/430.js.map +1 -0
- package/dist/460.js +1 -0
- package/dist/501.js +1 -0
- package/dist/501.js.map +1 -0
- package/dist/574.js +1 -0
- package/dist/591.js +2 -0
- package/dist/591.js.LICENSE.txt +32 -0
- package/dist/591.js.map +1 -0
- package/dist/644.js +1 -0
- package/dist/647.js +1 -0
- package/dist/647.js.map +1 -0
- package/dist/650.js +1 -0
- package/dist/650.js.map +1 -0
- package/dist/669.js +1 -0
- package/dist/669.js.map +1 -0
- package/dist/696.js +1 -0
- package/dist/696.js.map +1 -0
- package/dist/703.js +1 -0
- package/dist/703.js.map +1 -0
- package/dist/729.js +1 -0
- package/dist/729.js.map +1 -0
- package/dist/738.js +1 -0
- package/dist/738.js.map +1 -0
- package/dist/757.js +1 -0
- package/dist/764.js +1 -0
- package/dist/764.js.map +1 -0
- package/dist/784.js +2 -0
- package/dist/784.js.LICENSE.txt +9 -0
- package/dist/784.js.map +1 -0
- package/dist/788.js +1 -0
- package/dist/806.js +1 -0
- package/dist/806.js.map +1 -0
- package/dist/807.js +1 -0
- package/dist/833.js +1 -0
- package/dist/877.js +1 -0
- package/dist/877.js.map +1 -0
- package/dist/917.js +1 -0
- package/dist/917.js.map +1 -0
- package/dist/940.js +1 -0
- package/dist/940.js.map +1 -0
- package/dist/981.js +1 -0
- package/dist/981.js.map +1 -0
- package/dist/kenyaemr-esm-service-queues-app.js +1 -0
- package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +965 -0
- package/dist/kenyaemr-esm-service-queues-app.js.map +1 -0
- package/dist/main.js +2 -0
- package/dist/main.js.LICENSE.txt +60 -0
- package/dist/main.js.map +1 -0
- package/dist/routes.json +1 -0
- package/jest.config.js +3 -0
- package/package.json +54 -0
- package/src/active-visits/active-visits-row-actions.component.tsx +25 -0
- package/src/active-visits/active-visits-row-actions.scss +4 -0
- package/src/active-visits/active-visits-table.resource.ts +273 -0
- package/src/active-visits/change-status-dialog.component.tsx +272 -0
- package/src/active-visits/change-status-dialog.scss +47 -0
- package/src/active-visits/change-status-dialog.test.tsx +154 -0
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +228 -0
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +32 -0
- package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +238 -0
- package/src/add-provider-queue-room/add-provider-queue-room.resource.ts +76 -0
- package/src/add-provider-queue-room/add-provider-queue-room.scss +17 -0
- package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +105 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +76 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.resource.ts +7 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +8 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +43 -0
- package/src/clear-queue-entries-dialog/clear-queue-entries.component.tsx +43 -0
- package/src/config-schema.ts +465 -0
- package/src/constants.ts +10 -0
- package/src/createDashboardLink.component.tsx +39 -0
- package/src/current-visit/current-visit-summary.component.tsx +38 -0
- package/src/current-visit/current-visit-summary.test.tsx +43 -0
- package/src/current-visit/current-visit.resource.ts +84 -0
- package/src/current-visit/current-visit.scss +34 -0
- package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +101 -0
- package/src/current-visit/visit-details/biometrics-config-schema.ts +14 -0
- package/src/current-visit/visit-details/current-visit-details.component.tsx +96 -0
- package/src/current-visit/visit-details/triage-note.component.tsx +53 -0
- package/src/current-visit/visit-details/triage-note.scss +89 -0
- package/src/current-visit/visit-details/vitals-config-schema.ts +17 -0
- package/src/current-visit/visit-details/vitals.component.tsx +165 -0
- package/src/dashboard.meta.ts +5 -0
- package/src/declarations.d.ts +4 -0
- package/src/helpers/functions.ts +28 -0
- package/src/helpers/helpers.ts +177 -0
- package/src/helpers/time-helpers.ts +15 -0
- package/src/home.component.tsx +16 -0
- package/src/home.test.tsx +48 -0
- package/src/hooks/useConcept.ts +13 -0
- package/src/hooks/useQueue.ts +10 -0
- package/src/hooks/useQueueEntries.ts +187 -0
- package/src/hooks/useQueues.ts +22 -0
- package/src/hooks/useSystemSetting.ts +18 -0
- package/src/index.ts +172 -0
- package/src/past-visit/past-visit-details/encounter-list.component.tsx +54 -0
- package/src/past-visit/past-visit-details/medications-list.component.tsx +98 -0
- package/src/past-visit/past-visit-details/notes-list.component.tsx +41 -0
- package/src/past-visit/past-visit-details/past-visit-summary.component.tsx +181 -0
- package/src/past-visit/past-visit-details/past-visit-summary.scss +58 -0
- package/src/past-visit/past-visit.component.tsx +37 -0
- package/src/past-visit/past-visit.resource.ts +83 -0
- package/src/past-visit/past-visit.scss +126 -0
- package/src/past-visit/past-visit.test.tsx +41 -0
- package/src/patient-info/appointment-details.component.tsx +98 -0
- package/src/patient-info/appointment-details.scss +34 -0
- package/src/patient-info/appointment-details.test.tsx +36 -0
- package/src/patient-info/appointments.resource.ts +43 -0
- package/src/patient-info/hooks/usePatientAttributes.tsx +42 -0
- package/src/patient-info/patient-info.component.tsx +82 -0
- package/src/patient-info/patient-info.scss +60 -0
- package/src/patient-info/patient-info.test.tsx +43 -0
- package/src/patient-queue-header/patient-queue-header.component.tsx +99 -0
- package/src/patient-queue-header/patient-queue-header.scss +90 -0
- package/src/patient-queue-header/patient-queue-illustration.component.tsx +22 -0
- package/src/patient-queue-metrics/clinic-metrics.component.tsx +98 -0
- package/src/patient-queue-metrics/clinic-metrics.resource.ts +58 -0
- package/src/patient-queue-metrics/clinic-metrics.scss +11 -0
- package/src/patient-queue-metrics/clinic-metrics.test.tsx +76 -0
- package/src/patient-queue-metrics/metrics-card.component.tsx +68 -0
- package/src/patient-queue-metrics/metrics-card.scss +80 -0
- package/src/patient-queue-metrics/metrics-header.component.tsx +61 -0
- package/src/patient-queue-metrics/metrics-header.scss +26 -0
- package/src/patient-queue-metrics/queue-metrics.resource.ts +42 -0
- package/src/patient-search/advanced-search.component.tsx +191 -0
- package/src/patient-search/advanced-search.scss +154 -0
- package/src/patient-search/advanced-search.test.tsx +29 -0
- package/src/patient-search/basic-search.component.tsx +112 -0
- package/src/patient-search/basic-search.scss +139 -0
- package/src/patient-search/basic-search.test.tsx +23 -0
- package/src/patient-search/empty-data-illustration.component.tsx +41 -0
- package/src/patient-search/hooks/useActivePatientEnrollment.tsx +29 -0
- package/src/patient-search/hooks/useDefaultLocation.ts +14 -0
- package/src/patient-search/hooks/usePatients.tsx +25 -0
- package/src/patient-search/hooks/useQueueLocations.tsx +23 -0
- package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +35 -0
- package/src/patient-search/hooks/useScheduledVisits.ts +52 -0
- package/src/patient-search/patient-scheduled-visits.component.tsx +324 -0
- package/src/patient-search/patient-scheduled-visits.scss +131 -0
- package/src/patient-search/patient-scheduled-visits.test.tsx +44 -0
- package/src/patient-search/patient-search.scss +43 -0
- package/src/patient-search/patient-search.workspace.tsx +135 -0
- package/src/patient-search/search-illustration.component.tsx +27 -0
- package/src/patient-search/search-results.component.tsx +75 -0
- package/src/patient-search/search-results.scss +80 -0
- package/src/patient-search/search-results.test.tsx +77 -0
- package/src/patient-search/search.resource.ts +10 -0
- package/src/patient-search/visit-form/existing-visit-form.component.tsx +112 -0
- package/src/patient-search/visit-form/queue.resource.ts +64 -0
- package/src/patient-search/visit-form/visit-form.component.tsx +344 -0
- package/src/patient-search/visit-form/visit-form.scss +73 -0
- package/src/patient-search/visit-form/visit-type-selector.component.tsx +155 -0
- package/src/patient-search/visit-form/visit-type-selector.scss +100 -0
- package/src/patient-search/visit-form/visit-type-selector.test.tsx +83 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +178 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +19 -0
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +63 -0
- package/src/queue-entry-table-components/edit-entry.scss +14 -0
- package/src/queue-entry-table-components/queue-duration.component.tsx +41 -0
- package/src/queue-entry-table-components/queue-priority.component.tsx +38 -0
- package/src/queue-entry-table-components/queue-priority.scss +12 -0
- package/src/queue-entry-table-components/queue-status.component.tsx +39 -0
- package/src/queue-entry-table-components/transition-entry.component.tsx +55 -0
- package/src/queue-entry-table-components/transition-entry.scss +22 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +241 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.scss +110 -0
- package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +93 -0
- package/src/queue-patient-linelists/queue-linelist-filter.scss +63 -0
- package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +94 -0
- package/src/queue-patient-linelists/queue-linelist-filter.workspace.tsx +185 -0
- package/src/queue-patient-linelists/queue-linelist.resource.ts +84 -0
- package/src/queue-patient-linelists/queue-services-table.component.tsx +63 -0
- package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +305 -0
- package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +41 -0
- package/src/queue-rooms/queue-room-form.scss +56 -0
- package/src/queue-rooms/queue-room-form.test.tsx +80 -0
- package/src/queue-rooms/queue-room-form.workspace.tsx +169 -0
- package/src/queue-rooms/queue-room.resource.ts +20 -0
- package/src/queue-screen/queue-screen.component.tsx +47 -0
- package/src/queue-screen/queue-screen.scss +39 -0
- package/src/queue-screen/queue-screen.test.tsx +51 -0
- package/src/queue-screen/useActiveTickets.tsx +13 -0
- package/src/queue-services/queue-service-form.scss +61 -0
- package/src/queue-services/queue-service-form.test.tsx +60 -0
- package/src/queue-services/queue-service-form.workspace.tsx +179 -0
- package/src/queue-services/queue-service.resource.ts +33 -0
- package/src/queue-table/cells/columns.resource.ts +135 -0
- package/src/queue-table/cells/queue-table-action-cell.component.tsx +88 -0
- package/src/queue-table/cells/queue-table-action-cell.scss +7 -0
- package/src/queue-table/cells/queue-table-coming-from-cell.component.tsx +13 -0
- package/src/queue-table/cells/queue-table-extension-cell.component.tsx +16 -0
- package/src/queue-table/cells/queue-table-name-cell.component.tsx +20 -0
- package/src/queue-table/cells/queue-table-patient-age-cell.component.tsx +18 -0
- package/src/queue-table/cells/queue-table-patient-identifier-cell.component.tsx +25 -0
- package/src/queue-table/cells/queue-table-priority-cell.component.tsx +23 -0
- package/src/queue-table/cells/queue-table-queue-name-cell.component.tsx +14 -0
- package/src/queue-table/cells/queue-table-status-cell.component.tsx +18 -0
- package/src/queue-table/cells/queue-table-visit-attribute-queue-number-cell.component.tsx +37 -0
- package/src/queue-table/cells/queue-table-visit-start-time-cell.component.tsx +20 -0
- package/src/queue-table/cells/queue-table-wait-time-cell.component.tsx +17 -0
- package/src/queue-table/default-queue-table.component.tsx +174 -0
- package/src/queue-table/default-queue-table.test.tsx +131 -0
- package/src/queue-table/queue-entry-actions/edit-queue-entry-modal.component.tsx +52 -0
- package/src/queue-table/queue-entry-actions/end-queue-entry-modal.component.tsx +39 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.component.tsx +362 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.test.tsx +152 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actions.resource.ts +83 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actons-modal.scss +36 -0
- package/src/queue-table/queue-entry-actions/queue-entry-confirm-action-modal.component.tsx +97 -0
- package/src/queue-table/queue-entry-actions/queue-entry-confirm-action-modal.test.tsx +106 -0
- package/src/queue-table/queue-entry-actions/queue-entry-undo-actions-modal.test.tsx +76 -0
- package/src/queue-table/queue-entry-actions/transition-queue-entry-modal.component.tsx +51 -0
- package/src/queue-table/queue-entry-actions/undo-transition-queue-entry-modal.component.tsx +58 -0
- package/src/queue-table/queue-entry-actions/void-queue-entry-modal.component.tsx +34 -0
- package/src/queue-table/queue-table-by-status-menu.component.tsx +42 -0
- package/src/queue-table/queue-table-by-status-menu.scss +11 -0
- package/src/queue-table/queue-table-by-status-skeleton.component.tsx +32 -0
- package/src/queue-table/queue-table-by-status.component.tsx +96 -0
- package/src/queue-table/queue-table-expanded-row.component.tsx +29 -0
- package/src/queue-table/queue-table-metrics-card.component.tsx +50 -0
- package/src/queue-table/queue-table-metrics-card.scss +48 -0
- package/src/queue-table/queue-table-metrics.component.tsx +30 -0
- package/src/queue-table/queue-table-metrics.scss +11 -0
- package/src/queue-table/queue-table.component.tsx +179 -0
- package/src/queue-table/queue-table.scss +192 -0
- package/src/queue-table/queue-table.test.tsx +210 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +87 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.resource.ts +93 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.scss +7 -0
- package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +45 -0
- package/src/root.component.tsx +28 -0
- package/src/root.scss +15 -0
- package/src/root.test.tsx +24 -0
- package/src/routes.json +133 -0
- package/src/side-menu/nav-group/createNavGroup.tsx +17 -0
- package/src/side-menu/nav-group/nav-group.component.tsx +24 -0
- package/src/side-menu/nav-group/nav-group.test.tsx +32 -0
- package/src/side-menu/nav-group/nav-group.ts +10 -0
- package/src/side-menu/side-menu.component.tsx +6 -0
- package/src/side-menu/side-menu.test.tsx +17 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +134 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.scss +12 -0
- package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +102 -0
- package/src/transition-queue-entry/transition-queue-entry.resource.ts +16 -0
- package/src/types/index.ts +494 -0
- package/src/views/queue-table-by-status-view.component.tsx +25 -0
- package/src/views/queue-tables-for-all-statuses.component.tsx +150 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +277 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +93 -0
- package/src/visits-missing-inqueue/visits-missing-inqueue.scss +108 -0
- package/translations/am.json +295 -0
- package/translations/ar.json +295 -0
- package/translations/en.json +305 -0
- package/translations/es.json +295 -0
- package/translations/fr.json +295 -0
- package/translations/he.json +295 -0
- package/translations/km.json +295 -0
- package/translations/zh.json +295 -0
- package/translations/zh_CN.json +295 -0
- package/tsconfig.json +5 -0
- package/webpack.config.js +1 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
Checkbox,
|
|
4
|
+
ContentSwitcher,
|
|
5
|
+
DatePicker,
|
|
6
|
+
DatePickerInput,
|
|
7
|
+
InlineNotification,
|
|
8
|
+
ModalBody,
|
|
9
|
+
ModalFooter,
|
|
10
|
+
ModalHeader,
|
|
11
|
+
RadioButton,
|
|
12
|
+
RadioButtonGroup,
|
|
13
|
+
Select,
|
|
14
|
+
SelectItem,
|
|
15
|
+
Stack,
|
|
16
|
+
Switch,
|
|
17
|
+
TextArea,
|
|
18
|
+
TimePicker,
|
|
19
|
+
TimePickerSelect,
|
|
20
|
+
} from '@carbon/react';
|
|
21
|
+
import { showSnackbar, type FetchResponse } from '@openmrs/esm-framework';
|
|
22
|
+
import dayjs from 'dayjs';
|
|
23
|
+
import React, { useMemo, useState } from 'react';
|
|
24
|
+
import { useTranslation } from 'react-i18next';
|
|
25
|
+
import { datePickerFormat, datePickerPlaceHolder, time12HourFormatRegexPattern } from '../../constants';
|
|
26
|
+
import { convertTime12to24, type amPm } from '../../helpers/time-helpers';
|
|
27
|
+
import { useMutateQueueEntries } from '../../hooks/useQueueEntries';
|
|
28
|
+
import { useQueues } from '../../hooks/useQueues';
|
|
29
|
+
import { type QueueEntry } from '../../types';
|
|
30
|
+
import styles from './queue-entry-actons-modal.scss';
|
|
31
|
+
|
|
32
|
+
interface QueueEntryActionModalProps {
|
|
33
|
+
queueEntry: QueueEntry;
|
|
34
|
+
closeModal: () => void;
|
|
35
|
+
modalParams: ModalParams;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface FormState {
|
|
39
|
+
selectedQueue: string;
|
|
40
|
+
selectedPriority: string;
|
|
41
|
+
selectedStatus: string;
|
|
42
|
+
prioritycomment: string;
|
|
43
|
+
modifyDefaultTransitionDateTime: boolean;
|
|
44
|
+
transitionDate: Date;
|
|
45
|
+
transitionTime: string;
|
|
46
|
+
transitionTimeFormat: amPm;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface ModalParams {
|
|
50
|
+
modalTitle: string;
|
|
51
|
+
modalInstruction: string;
|
|
52
|
+
submitButtonText: string;
|
|
53
|
+
submitSuccessTitle: string;
|
|
54
|
+
submitSuccessText: string;
|
|
55
|
+
submitFailureTitle: string;
|
|
56
|
+
submitAction: (queueEntry: QueueEntry, formState: FormState) => Promise<FetchResponse<any>>;
|
|
57
|
+
disableSubmit: (queueEntry, formState) => boolean;
|
|
58
|
+
isTransition: boolean; // is transition or edit?
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Modal for performing a queue entry action that requires additional form fields / inputs from user
|
|
62
|
+
// Used by EditQueueEntryModal and TransitionQueueEntryModal
|
|
63
|
+
export const QueueEntryActionModal: React.FC<QueueEntryActionModalProps> = ({
|
|
64
|
+
queueEntry,
|
|
65
|
+
closeModal,
|
|
66
|
+
modalParams,
|
|
67
|
+
}) => {
|
|
68
|
+
const { t } = useTranslation();
|
|
69
|
+
const { mutateQueueEntries } = useMutateQueueEntries();
|
|
70
|
+
const {
|
|
71
|
+
modalTitle,
|
|
72
|
+
modalInstruction,
|
|
73
|
+
submitButtonText,
|
|
74
|
+
submitSuccessTitle,
|
|
75
|
+
submitSuccessText,
|
|
76
|
+
submitFailureTitle,
|
|
77
|
+
submitAction,
|
|
78
|
+
disableSubmit,
|
|
79
|
+
isTransition,
|
|
80
|
+
} = modalParams;
|
|
81
|
+
|
|
82
|
+
const initialTransitionDate = isTransition ? new Date() : new Date(queueEntry.startedAt);
|
|
83
|
+
const [formState, setFormState] = useState<FormState>({
|
|
84
|
+
selectedQueue: queueEntry.queue.uuid,
|
|
85
|
+
selectedPriority: queueEntry.priority.uuid,
|
|
86
|
+
selectedStatus: queueEntry.status.uuid,
|
|
87
|
+
prioritycomment: queueEntry.priorityComment ?? '',
|
|
88
|
+
modifyDefaultTransitionDateTime: false,
|
|
89
|
+
transitionDate: initialTransitionDate,
|
|
90
|
+
transitionTime: dayjs(initialTransitionDate).format('hh:mm'),
|
|
91
|
+
transitionTimeFormat: dayjs(initialTransitionDate).hour() < 12 ? 'AM' : 'PM',
|
|
92
|
+
});
|
|
93
|
+
const { queues } = useQueues();
|
|
94
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
95
|
+
|
|
96
|
+
const selectedQueue = queues.find((q) => q.uuid == formState.selectedQueue);
|
|
97
|
+
|
|
98
|
+
const statuses = selectedQueue?.allowedStatuses;
|
|
99
|
+
const hasNoStatusesConfigured = selectedQueue && statuses.length == 0;
|
|
100
|
+
const priorities = selectedQueue?.allowedPriorities;
|
|
101
|
+
const hasNoPrioritiesConfigured = selectedQueue && priorities.length == 0;
|
|
102
|
+
|
|
103
|
+
const setSelectedQueueUuid = (selectedQueueUuid: string) => {
|
|
104
|
+
const newSelectedQueue = queues.find((q) => q.uuid == selectedQueueUuid);
|
|
105
|
+
const { allowedStatuses, allowedPriorities } = newSelectedQueue;
|
|
106
|
+
const newQueueHasCurrentStatus = allowedStatuses.find((s) => s.uuid == formState.selectedStatus);
|
|
107
|
+
const newQueueHasCurrentPriority = allowedPriorities.find((s) => s.uuid == formState.selectedPriority);
|
|
108
|
+
setFormState({
|
|
109
|
+
...formState,
|
|
110
|
+
selectedQueue: selectedQueueUuid,
|
|
111
|
+
selectedStatus: newQueueHasCurrentStatus ? formState.selectedStatus : allowedStatuses[0]?.uuid,
|
|
112
|
+
selectedPriority: newQueueHasCurrentPriority ? formState.selectedPriority : allowedPriorities[0]?.uuid,
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const setSelectedPriorityUuid = (selectedPriorityUuid: string) => {
|
|
117
|
+
setFormState({ ...formState, selectedPriority: selectedPriorityUuid });
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const setSelectedStatusUuid = (selectedStatusUuid: string) => {
|
|
121
|
+
setFormState({ ...formState, selectedStatus: selectedStatusUuid });
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const setPriorityComment = (prioritycomment: string) => {
|
|
125
|
+
setFormState({ ...formState, prioritycomment });
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const setTransitionDate = (transitionDate: Date) => {
|
|
129
|
+
setFormState({ ...formState, transitionDate });
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const setTransitionTime = (transitionTime: string) => {
|
|
133
|
+
setFormState({ ...formState, transitionTime });
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const setTransitionTimeFormat = (transitionTimeFormat: amPm) => {
|
|
137
|
+
setFormState({ ...formState, transitionTimeFormat });
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const setModifyDefaultTransitionDateTime = (modifyDefaultTransitionDateTime) => {
|
|
141
|
+
setFormState({ ...formState, modifyDefaultTransitionDateTime });
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const submitForm = (e) => {
|
|
145
|
+
e.preventDefault();
|
|
146
|
+
setIsSubmitting(true);
|
|
147
|
+
|
|
148
|
+
submitAction(queueEntry, formState)
|
|
149
|
+
.then(({ status }) => {
|
|
150
|
+
if (status === 200) {
|
|
151
|
+
showSnackbar({
|
|
152
|
+
isLowContrast: true,
|
|
153
|
+
title: submitSuccessTitle,
|
|
154
|
+
kind: 'success',
|
|
155
|
+
subtitle: submitSuccessText,
|
|
156
|
+
});
|
|
157
|
+
mutateQueueEntries();
|
|
158
|
+
closeModal();
|
|
159
|
+
} else {
|
|
160
|
+
throw { message: t('unexpectedServerResponse', 'Unexpected Server Response') };
|
|
161
|
+
}
|
|
162
|
+
})
|
|
163
|
+
.catch((error) => {
|
|
164
|
+
showSnackbar({
|
|
165
|
+
title: submitFailureTitle,
|
|
166
|
+
kind: 'error',
|
|
167
|
+
subtitle: error?.message,
|
|
168
|
+
});
|
|
169
|
+
})
|
|
170
|
+
.finally(() => {
|
|
171
|
+
setIsSubmitting(false);
|
|
172
|
+
});
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
const isTimeInvalid = useMemo(() => {
|
|
176
|
+
const now = new Date();
|
|
177
|
+
const startAtDate = new Date(formState.transitionDate);
|
|
178
|
+
const [hour, minute] = convertTime12to24(formState.transitionTime, formState.transitionTimeFormat);
|
|
179
|
+
startAtDate.setHours(hour, minute, 0, 0);
|
|
180
|
+
return startAtDate > now;
|
|
181
|
+
}, [formState.transitionDate, formState.transitionTime, formState.transitionTimeFormat]);
|
|
182
|
+
|
|
183
|
+
const selectedPriorityIndex = priorities.findIndex((p) => p.uuid == formState.selectedPriority);
|
|
184
|
+
|
|
185
|
+
return (
|
|
186
|
+
<>
|
|
187
|
+
<ModalHeader closeModal={closeModal} title={modalTitle} />
|
|
188
|
+
<ModalBody>
|
|
189
|
+
<div className={styles.queueEntryActionModalBody}>
|
|
190
|
+
<Stack gap={4}>
|
|
191
|
+
<h5>{queueEntry.display}</h5>
|
|
192
|
+
<p>{modalInstruction}</p>
|
|
193
|
+
<section className={styles.section}>
|
|
194
|
+
<div className={styles.sectionTitle}>{t('serviceQueue', 'Service queue')}</div>
|
|
195
|
+
<Select
|
|
196
|
+
labelText={t('selectQueue', 'Select a queue')}
|
|
197
|
+
id="queue"
|
|
198
|
+
invalidText="Required"
|
|
199
|
+
value={formState.selectedQueue}
|
|
200
|
+
onChange={(event) => setSelectedQueueUuid(event.target.value)}>
|
|
201
|
+
{queues?.map(({ uuid, display, location }) => (
|
|
202
|
+
<SelectItem
|
|
203
|
+
key={uuid}
|
|
204
|
+
text={
|
|
205
|
+
uuid == queueEntry.queue.uuid
|
|
206
|
+
? t('currentValueFormatted', '{{value}} (Current)', {
|
|
207
|
+
value: `${display} - ${location?.display}`,
|
|
208
|
+
interpolation: { escapeValue: false },
|
|
209
|
+
})
|
|
210
|
+
: `${display} - ${location?.display}`
|
|
211
|
+
}
|
|
212
|
+
value={uuid}
|
|
213
|
+
/>
|
|
214
|
+
))}
|
|
215
|
+
</Select>
|
|
216
|
+
</section>
|
|
217
|
+
|
|
218
|
+
<section>
|
|
219
|
+
<div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
|
|
220
|
+
{hasNoStatusesConfigured ? (
|
|
221
|
+
<InlineNotification
|
|
222
|
+
kind={'error'}
|
|
223
|
+
lowContrast
|
|
224
|
+
subtitle={t('configureStatus', 'Please configure status to continue.')}
|
|
225
|
+
title={t('noStatusConfigured', 'No status configured')}
|
|
226
|
+
/>
|
|
227
|
+
) : (
|
|
228
|
+
<RadioButtonGroup
|
|
229
|
+
name="status"
|
|
230
|
+
valueSelected={formState.selectedStatus}
|
|
231
|
+
onChange={(uuid) => {
|
|
232
|
+
setSelectedStatusUuid(uuid);
|
|
233
|
+
}}>
|
|
234
|
+
{statuses?.map(({ uuid, display }) => (
|
|
235
|
+
<RadioButton
|
|
236
|
+
key={uuid}
|
|
237
|
+
name={display}
|
|
238
|
+
labelText={
|
|
239
|
+
uuid == queueEntry.status.uuid
|
|
240
|
+
? t('currentValueFormatted', '{{value}} (Current)', {
|
|
241
|
+
value: display,
|
|
242
|
+
interpolation: { escapeValue: false },
|
|
243
|
+
})
|
|
244
|
+
: display
|
|
245
|
+
}
|
|
246
|
+
value={uuid}
|
|
247
|
+
/>
|
|
248
|
+
))}
|
|
249
|
+
</RadioButtonGroup>
|
|
250
|
+
)}
|
|
251
|
+
</section>
|
|
252
|
+
|
|
253
|
+
<section className={styles.section}>
|
|
254
|
+
<div className={styles.sectionTitle}>{t('queuePriority', 'Queue priority')}</div>
|
|
255
|
+
{hasNoPrioritiesConfigured ? (
|
|
256
|
+
<InlineNotification
|
|
257
|
+
className={styles.inlineNotification}
|
|
258
|
+
kind={'error'}
|
|
259
|
+
lowContrast
|
|
260
|
+
subtitle={t('configurePriorities', 'Please configure priorities to continue.')}
|
|
261
|
+
title={t('noPrioritiesConfigured', 'No priorities configured')}
|
|
262
|
+
/>
|
|
263
|
+
) : (
|
|
264
|
+
<ContentSwitcher
|
|
265
|
+
size="sm"
|
|
266
|
+
selectedIndex={selectedPriorityIndex}
|
|
267
|
+
onChange={(event) => {
|
|
268
|
+
setSelectedPriorityUuid(event.name as string);
|
|
269
|
+
}}>
|
|
270
|
+
{priorities?.map(({ uuid, display }) => (
|
|
271
|
+
<Switch
|
|
272
|
+
role="radio"
|
|
273
|
+
name={uuid}
|
|
274
|
+
text={
|
|
275
|
+
uuid == queueEntry.priority.uuid
|
|
276
|
+
? t('currentValueFormatted', '{{value}} (Current)', {
|
|
277
|
+
value: display,
|
|
278
|
+
interpolation: { escapeValue: false },
|
|
279
|
+
})
|
|
280
|
+
: display
|
|
281
|
+
}
|
|
282
|
+
key={uuid}
|
|
283
|
+
value={uuid}
|
|
284
|
+
/>
|
|
285
|
+
))}
|
|
286
|
+
</ContentSwitcher>
|
|
287
|
+
)}
|
|
288
|
+
</section>
|
|
289
|
+
|
|
290
|
+
<section className={styles.section}>
|
|
291
|
+
<div className={styles.sectionTitle}>{t('priorityComment', 'Priority comment')}</div>
|
|
292
|
+
<TextArea
|
|
293
|
+
labelText=""
|
|
294
|
+
value={formState.prioritycomment}
|
|
295
|
+
onChange={(e) => setPriorityComment(e.target.value)}
|
|
296
|
+
placeholder={t('enterCommentHere', 'Enter comment here')}
|
|
297
|
+
/>
|
|
298
|
+
</section>
|
|
299
|
+
|
|
300
|
+
<section className={styles.section}>
|
|
301
|
+
<div className={styles.sectionTitle}>{t('timeOfTransition', 'Time of transition')}</div>
|
|
302
|
+
<Checkbox
|
|
303
|
+
labelText={t('modifyDefaultValue', 'Modify default value')}
|
|
304
|
+
id={'modifyTransitionTime'}
|
|
305
|
+
checked={formState.modifyDefaultTransitionDateTime}
|
|
306
|
+
onChange={(_, { checked }) => {
|
|
307
|
+
setModifyDefaultTransitionDateTime(checked);
|
|
308
|
+
}}
|
|
309
|
+
/>
|
|
310
|
+
<div className={styles.dateTimeFields}>
|
|
311
|
+
<DatePicker
|
|
312
|
+
datePickerType="single"
|
|
313
|
+
dateFormat={datePickerFormat}
|
|
314
|
+
value={formState.transitionDate}
|
|
315
|
+
maxDate={new Date().setHours(23, 59, 59, 59)}
|
|
316
|
+
onChange={([date]) => {
|
|
317
|
+
setTransitionDate(date);
|
|
318
|
+
}}>
|
|
319
|
+
<DatePickerInput
|
|
320
|
+
id="datePickerInput"
|
|
321
|
+
labelText={t('date', 'Date')}
|
|
322
|
+
placeholder={datePickerPlaceHolder}
|
|
323
|
+
disabled={!formState.modifyDefaultTransitionDateTime}
|
|
324
|
+
/>
|
|
325
|
+
</DatePicker>
|
|
326
|
+
|
|
327
|
+
<TimePicker
|
|
328
|
+
labelText={t('time', 'Time')}
|
|
329
|
+
onChange={(event) => setTransitionTime(event.target.value)}
|
|
330
|
+
pattern={time12HourFormatRegexPattern}
|
|
331
|
+
value={formState.transitionTime}
|
|
332
|
+
invalid={isTimeInvalid}
|
|
333
|
+
invalidText={t('timeCannotBeInFuture', 'Time cannot be in the future')}
|
|
334
|
+
disabled={!formState.modifyDefaultTransitionDateTime}>
|
|
335
|
+
<TimePickerSelect
|
|
336
|
+
id="visitStartTimeSelect"
|
|
337
|
+
onChange={(event) => setTransitionTimeFormat(event.target.value as amPm)}
|
|
338
|
+
value={formState.transitionTimeFormat}
|
|
339
|
+
labelText={t('time', 'Time')}
|
|
340
|
+
aria-label={t('time', 'Time')}>
|
|
341
|
+
<SelectItem value="AM" text="AM" />
|
|
342
|
+
<SelectItem value="PM" text="PM" />
|
|
343
|
+
</TimePickerSelect>
|
|
344
|
+
</TimePicker>
|
|
345
|
+
</div>
|
|
346
|
+
</section>
|
|
347
|
+
</Stack>
|
|
348
|
+
</div>
|
|
349
|
+
</ModalBody>
|
|
350
|
+
<ModalFooter>
|
|
351
|
+
<Button kind="secondary" onClick={closeModal}>
|
|
352
|
+
{t('cancel', 'Cancel')}
|
|
353
|
+
</Button>
|
|
354
|
+
<Button disabled={isSubmitting || disableSubmit(queueEntry, formState)} onClick={submitForm}>
|
|
355
|
+
{submitButtonText}
|
|
356
|
+
</Button>
|
|
357
|
+
</ModalFooter>
|
|
358
|
+
</>
|
|
359
|
+
);
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
export default QueueEntryActionModal;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
2
|
+
import { screen } from '@testing-library/react';
|
|
3
|
+
import { mockQueueEntryBrian, mockQueueSurgery, mockStatusInService, mockQueues } from '__mocks__';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { renderWithSwr } from 'tools';
|
|
6
|
+
import TransitionQueueEntryModal from './transition-queue-entry-modal.component';
|
|
7
|
+
import userEvent from '@testing-library/user-event';
|
|
8
|
+
import EditQueueEntryModal from './edit-queue-entry-modal.component';
|
|
9
|
+
|
|
10
|
+
const mockedOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
11
|
+
|
|
12
|
+
jest.mock('../../hooks/useQueues', () => {
|
|
13
|
+
return {
|
|
14
|
+
useQueues: jest.fn().mockReturnValue({
|
|
15
|
+
queues: mockQueues,
|
|
16
|
+
}),
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe('TransitionQueueEntryModal: ', () => {
|
|
21
|
+
const queueEntry = mockQueueEntryBrian;
|
|
22
|
+
const { queue } = queueEntry;
|
|
23
|
+
const { allowedStatuses, allowedPriorities } = queue;
|
|
24
|
+
|
|
25
|
+
const nextQueue = mockQueueSurgery;
|
|
26
|
+
|
|
27
|
+
it('renders the dialog with the right status and priority options', () => {
|
|
28
|
+
renderWithSwr(<TransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
29
|
+
expect(screen.getByText(queueEntry.patient.display)).toBeInTheDocument();
|
|
30
|
+
|
|
31
|
+
for (const status of allowedStatuses) {
|
|
32
|
+
const expectedStatusDisplay =
|
|
33
|
+
queueEntry.status.uuid == status.uuid ? `${status.display} (Current)` : status.display;
|
|
34
|
+
expect(screen.getByRole('radio', { name: expectedStatusDisplay })).toBeInTheDocument();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const pri of allowedPriorities) {
|
|
38
|
+
const expectedPriorityDisplay = queueEntry.priority.uuid == pri.uuid ? `${pri.display} (Current)` : pri.display;
|
|
39
|
+
expect(screen.getByRole('radio', { name: expectedPriorityDisplay })).toBeInTheDocument();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('has a cancel button that closes the modal', async () => {
|
|
44
|
+
const closeModal = jest.fn();
|
|
45
|
+
const user = userEvent.setup();
|
|
46
|
+
|
|
47
|
+
renderWithSwr(<TransitionQueueEntryModal queueEntry={queueEntry} closeModal={closeModal} />);
|
|
48
|
+
const cancelButton = screen.getByText('Cancel');
|
|
49
|
+
await user.click(cancelButton);
|
|
50
|
+
expect(closeModal).toHaveBeenCalled();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('has a disabled submit button when selected queue and status is same as before', () => {
|
|
54
|
+
renderWithSwr(<TransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
55
|
+
const submitButton = screen.getByRole('button', { name: /Transition patient/ });
|
|
56
|
+
expect(submitButton).toBeDisabled();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('has an working submit button when selected queue and status is different from before', async () => {
|
|
60
|
+
mockedOpenmrsFetch.mockResolvedValue({
|
|
61
|
+
status: 200,
|
|
62
|
+
});
|
|
63
|
+
const user = userEvent.setup();
|
|
64
|
+
renderWithSwr(<TransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
65
|
+
|
|
66
|
+
// change queue
|
|
67
|
+
const queueDropdown = screen.getByRole('combobox', { name: /Select a queue/ });
|
|
68
|
+
await queueDropdown.click();
|
|
69
|
+
const queueSelection = screen.getByRole('option', {
|
|
70
|
+
name: `${nextQueue.display} - ${nextQueue.location?.display}`,
|
|
71
|
+
});
|
|
72
|
+
await user.selectOptions(queueDropdown, queueSelection);
|
|
73
|
+
|
|
74
|
+
// change status
|
|
75
|
+
const inServiceRadioButton = screen.getByText(mockStatusInService.display);
|
|
76
|
+
await inServiceRadioButton.click();
|
|
77
|
+
|
|
78
|
+
const submitButton = screen.getByRole('button', { name: /Transition patient/ });
|
|
79
|
+
expect(submitButton).not.toBeDisabled();
|
|
80
|
+
await submitButton.click();
|
|
81
|
+
|
|
82
|
+
expect(mockedOpenmrsFetch).toHaveBeenCalled();
|
|
83
|
+
expect(showSnackbar).toHaveBeenCalled();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
describe('EditQueueEntryModal: ', () => {
|
|
88
|
+
const queueEntry = mockQueueEntryBrian;
|
|
89
|
+
const { queue } = queueEntry;
|
|
90
|
+
const { allowedStatuses, allowedPriorities } = queue;
|
|
91
|
+
|
|
92
|
+
const nextQueue = mockQueueSurgery;
|
|
93
|
+
|
|
94
|
+
it('renders the dialog with the right status and priority options', () => {
|
|
95
|
+
renderWithSwr(<EditQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
96
|
+
expect(screen.getByText(queueEntry.patient.display)).toBeInTheDocument();
|
|
97
|
+
|
|
98
|
+
for (const status of allowedStatuses) {
|
|
99
|
+
const expectedStatusDisplay =
|
|
100
|
+
queueEntry.status.uuid == status.uuid ? `${status.display} (Current)` : status.display;
|
|
101
|
+
expect(screen.getByRole('radio', { name: expectedStatusDisplay })).toBeInTheDocument();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
for (const pri of allowedPriorities) {
|
|
105
|
+
const expectedPriorityDisplay = queueEntry.priority.uuid == pri.uuid ? `${pri.display} (Current)` : pri.display;
|
|
106
|
+
expect(screen.getByRole('radio', { name: expectedPriorityDisplay })).toBeInTheDocument();
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('has a cancel button that closes the modal', async () => {
|
|
111
|
+
const closeModal = jest.fn();
|
|
112
|
+
const user = userEvent.setup();
|
|
113
|
+
|
|
114
|
+
renderWithSwr(<EditQueueEntryModal queueEntry={queueEntry} closeModal={closeModal} />);
|
|
115
|
+
const cancelButton = screen.getByText('Cancel');
|
|
116
|
+
await user.click(cancelButton);
|
|
117
|
+
expect(closeModal).toHaveBeenCalled();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('has a enabled submit button when selected queue and status is same as before', () => {
|
|
121
|
+
renderWithSwr(<EditQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
122
|
+
const submitButton = screen.getByRole('button', { name: /Edit queue entry/ });
|
|
123
|
+
expect(submitButton).toBeEnabled();
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('has an working submit button when selected queue and status is different from before', async () => {
|
|
127
|
+
mockedOpenmrsFetch.mockResolvedValue({
|
|
128
|
+
status: 200,
|
|
129
|
+
});
|
|
130
|
+
const user = userEvent.setup();
|
|
131
|
+
renderWithSwr(<EditQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
132
|
+
|
|
133
|
+
// change queue
|
|
134
|
+
const queueDropdown = screen.getByRole('combobox', { name: /Select a queue/ });
|
|
135
|
+
await queueDropdown.click();
|
|
136
|
+
const queueSelection = screen.getByRole('option', {
|
|
137
|
+
name: `${nextQueue.display} - ${nextQueue.location?.display}`,
|
|
138
|
+
});
|
|
139
|
+
await user.selectOptions(queueDropdown, queueSelection);
|
|
140
|
+
|
|
141
|
+
// change status
|
|
142
|
+
const inServiceRadioButton = screen.getByText(mockStatusInService.display);
|
|
143
|
+
await inServiceRadioButton.click();
|
|
144
|
+
|
|
145
|
+
const submitButton = screen.getByRole('button', { name: /Edit queue entry/ });
|
|
146
|
+
expect(submitButton).not.toBeDisabled();
|
|
147
|
+
await submitButton.click();
|
|
148
|
+
|
|
149
|
+
expect(mockedOpenmrsFetch).toHaveBeenCalled();
|
|
150
|
+
expect(showSnackbar).toHaveBeenCalled();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { openmrsFetch, restBaseUrl, type Location } from '@openmrs/esm-framework';
|
|
2
|
+
import { type Concept, type QueueEntry } from '../../types';
|
|
3
|
+
|
|
4
|
+
// see QueueEntryTransition.java in openmrs-module-queue
|
|
5
|
+
interface TransitionQueueEntryParams {
|
|
6
|
+
queueEntryToTransition: string;
|
|
7
|
+
transitionDate?: string;
|
|
8
|
+
newQueue?: string;
|
|
9
|
+
newStatus?: string;
|
|
10
|
+
newPriority?: string;
|
|
11
|
+
newPriorityComment?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A transition is defined as an action that ends a current queue entry and immediately starts a new one
|
|
16
|
+
* with (slightly) different values. For now, this could be used to transition the queue entry's status,
|
|
17
|
+
* priority or queue. This allows us to keep a history of queue entries through a patient's visit.
|
|
18
|
+
* Note that there are some use cases (like RDE or data correction) where a transition is NOT appropriate.
|
|
19
|
+
* @param params
|
|
20
|
+
* @param abortController
|
|
21
|
+
* @returns
|
|
22
|
+
*/
|
|
23
|
+
export function transitionQueueEntry(params: TransitionQueueEntryParams, abortController?: AbortController) {
|
|
24
|
+
return openmrsFetch(`${restBaseUrl}/queue-entry/transition`, {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
signal: abortController?.signal,
|
|
30
|
+
body: params,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// see QueueEntryResource.java#getUpdatableProperties() in openmrs-module-queue
|
|
35
|
+
interface UpdateQueueEntryParams {
|
|
36
|
+
status?: Concept;
|
|
37
|
+
priority?: Concept;
|
|
38
|
+
priorityComment?: string;
|
|
39
|
+
sortWeight?: number;
|
|
40
|
+
startedAt?: string;
|
|
41
|
+
endedAt?: string;
|
|
42
|
+
loationWaitingFor?: Location;
|
|
43
|
+
providerWaitingFor?: Location;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function updateQueueEntry(
|
|
47
|
+
queueEntryUuid: string,
|
|
48
|
+
params: UpdateQueueEntryParams,
|
|
49
|
+
abortController?: AbortController,
|
|
50
|
+
) {
|
|
51
|
+
return openmrsFetch(`${restBaseUrl}/queue-entry/${queueEntryUuid}`, {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
headers: {
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
},
|
|
56
|
+
signal: abortController?.signal,
|
|
57
|
+
body: params,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
interface UndoTransitionParams {
|
|
61
|
+
queueEntry: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function undoTransition(params: UndoTransitionParams, abortController?: AbortController) {
|
|
65
|
+
return openmrsFetch(`${restBaseUrl}/queue-entry/transition`, {
|
|
66
|
+
method: 'DELETE',
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
},
|
|
70
|
+
signal: abortController?.signal,
|
|
71
|
+
body: params,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function voidQueueEntry(queueEntryUuid: string, abortController?: AbortController) {
|
|
76
|
+
return openmrsFetch(`${restBaseUrl}/queue-entry/${queueEntryUuid}`, {
|
|
77
|
+
method: 'DELETE',
|
|
78
|
+
headers: {
|
|
79
|
+
'Content-Type': 'application/json',
|
|
80
|
+
},
|
|
81
|
+
signal: abortController?.signal,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
@use '@carbon/styles/scss/spacing';
|
|
2
|
+
@use '@carbon/styles/scss/type';
|
|
3
|
+
@import '~@openmrs/esm-styleguide/src/vars';
|
|
4
|
+
|
|
5
|
+
.radioButtonGroup {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
align-items: flex-start;
|
|
9
|
+
margin-top: spacing.$spacing-03;
|
|
10
|
+
min-height: spacing.$spacing-10;
|
|
11
|
+
width: 100%;
|
|
12
|
+
@include type.type-style('body-compact-01');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.radioButton {
|
|
16
|
+
padding: spacing.$spacing-02 spacing.$spacing-02;
|
|
17
|
+
margin: spacing.$spacing-03 0;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
section {
|
|
21
|
+
margin: spacing.$spacing-03;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.sectionTitle {
|
|
25
|
+
@include type.type-style('heading-compact-02');
|
|
26
|
+
color: $text-02;
|
|
27
|
+
margin-bottom: spacing.$spacing-04;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.queueEntryActionModalBody {
|
|
31
|
+
padding-bottom: spacing.$spacing-05;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.dateTimeFields {
|
|
35
|
+
display: flex;
|
|
36
|
+
}
|