@kenyaemr/esm-service-queues-app 7.0.3-pre.88 → 7.0.3-pre.94
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 +18 -17
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/199.js +1 -1
- package/dist/236.js +1 -0
- package/dist/236.js.map +1 -0
- package/dist/265.js +1 -0
- package/dist/265.js.map +1 -0
- package/dist/271.js +1 -1
- package/dist/282.js +1 -0
- package/dist/282.js.map +1 -0
- package/dist/319.js +1 -1
- package/dist/366.js +1 -0
- package/dist/366.js.map +1 -0
- package/dist/392.js +1 -0
- package/dist/392.js.map +1 -0
- package/dist/460.js +1 -1
- package/dist/484.js +2 -0
- package/dist/484.js.map +1 -0
- package/dist/574.js +1 -1
- package/dist/6.js +1 -1
- package/dist/604.js +1 -0
- package/dist/604.js.map +1 -0
- package/dist/644.js +1 -1
- package/dist/670.js +1 -0
- package/dist/670.js.map +1 -0
- package/dist/727.js +1 -0
- package/dist/727.js.map +1 -0
- package/dist/752.js +1 -1
- package/dist/757.js +1 -1
- package/dist/760.js +1 -0
- package/dist/760.js.map +1 -0
- package/dist/788.js +1 -1
- package/dist/800.js +1 -1
- package/dist/807.js +1 -1
- package/dist/818.js +1 -0
- package/dist/818.js.map +1 -0
- package/dist/828.js +1 -1
- package/dist/833.js +1 -1
- package/dist/911.js +1 -0
- package/dist/911.js.map +1 -0
- package/dist/kenyaemr-esm-service-queues-app.js +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +160 -160
- 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/active-visits-table.resource.ts +1 -1
- package/src/active-visits/change-status-dialog.scss +11 -11
- package/src/active-visits/change-status-dialog.test.tsx +36 -31
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +10 -10
- package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +4 -4
- package/src/add-provider-queue-room/add-provider-queue-room.resource.ts +2 -2
- package/src/add-provider-queue-room/add-provider-queue-room.scss +6 -6
- package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +44 -38
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +1 -1
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +2 -3
- package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +15 -15
- package/src/config-schema.ts +84 -84
- package/src/current-visit/current-visit-summary.component.tsx +1 -1
- package/src/current-visit/current-visit-summary.test.tsx +12 -11
- package/src/current-visit/current-visit.resource.ts +1 -1
- package/src/current-visit/current-visit.scss +4 -4
- package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +1 -1
- package/src/current-visit/visit-details/triage-note.scss +11 -11
- package/src/helpers/helpers.test.ts +24 -0
- package/src/helpers/helpers.ts +41 -14
- package/src/home.test.tsx +10 -12
- package/src/hooks/useQueueService.ts +16 -10
- package/src/past-visit/past-visit-details/past-visit-summary.scss +8 -8
- package/src/past-visit/past-visit.component.tsx +1 -1
- package/src/past-visit/past-visit.resource.ts +1 -1
- package/src/past-visit/past-visit.scss +17 -17
- package/src/past-visit/past-visit.test.tsx +8 -13
- package/src/patient-info/appointment-details.scss +7 -7
- package/src/patient-info/appointment-details.test.tsx +11 -6
- package/src/patient-info/appointments.resource.ts +1 -1
- package/src/patient-info/patient-info.scss +9 -9
- package/src/patient-info/patient-info.test.tsx +3 -14
- package/src/patient-queue-header/patient-queue-header.component.tsx +4 -1
- package/src/patient-queue-header/patient-queue-header.scss +11 -11
- package/src/patient-queue-metrics/clinic-metrics.component.tsx +1 -1
- package/src/patient-queue-metrics/clinic-metrics.resource.ts +2 -2
- package/src/patient-queue-metrics/clinic-metrics.scss +4 -4
- package/src/patient-queue-metrics/clinic-metrics.test.tsx +40 -45
- package/src/patient-queue-metrics/metrics-card.scss +11 -11
- package/src/patient-queue-metrics/metrics-header.scss +2 -2
- package/src/patient-search/advanced-search.scss +27 -27
- package/src/patient-search/advanced-search.test.tsx +6 -9
- package/src/patient-search/basic-search.scss +14 -14
- package/src/patient-search/basic-search.test.tsx +2 -7
- package/src/patient-search/hooks/useDefaultLocation.ts +1 -1
- package/src/patient-search/hooks/useQueueLocations.tsx +1 -0
- package/src/patient-search/hooks/useScheduledVisits.ts +1 -1
- package/src/patient-search/patient-scheduled-visits.component.tsx +4 -4
- package/src/patient-search/patient-scheduled-visits.scss +17 -17
- package/src/patient-search/patient-scheduled-visits.test.tsx +18 -23
- package/src/patient-search/patient-search.scss +7 -7
- package/src/patient-search/patient-search.workspace.tsx +4 -4
- package/src/patient-search/search-results.scss +11 -11
- package/src/patient-search/search-results.test.tsx +2 -10
- package/src/patient-search/visit-form/visit-form.scss +12 -13
- package/src/patient-search/visit-form/visit-type-selector.component.tsx +9 -11
- package/src/patient-search/visit-form/visit-type-selector.scss +13 -13
- package/src/patient-search/visit-form/visit-type-selector.test.tsx +4 -3
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +1 -3
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +15 -9
- package/src/queue-entry-table-components/edit-entry.scss +1 -1
- package/src/queue-entry-table-components/queue-priority.scss +3 -4
- package/src/queue-entry-table-components/transition-entry.scss +1 -1
- package/src/queue-patient-linelists/queue-linelist-base-table.scss +16 -17
- package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +7 -8
- package/src/queue-patient-linelists/queue-linelist-filter.scss +13 -13
- package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +9 -6
- package/src/queue-patient-linelists/queue-linelist.resource.ts +4 -4
- package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +10 -7
- package/src/queue-rooms/queue-room-form.scss +13 -13
- package/src/queue-rooms/queue-room-form.test.tsx +10 -8
- package/src/queue-screen/queue-screen.scss +6 -4
- package/src/queue-screen/queue-screen.test.tsx +6 -6
- package/src/queue-services/queue-service-form.scss +13 -13
- package/src/queue-services/queue-service-form.test.tsx +15 -8
- package/src/queue-table/cells/queue-table-action-cell.component.tsx +2 -2
- package/src/queue-table/cells/queue-table-coming-from-cell.component.tsx +1 -1
- package/src/queue-table/default-queue-table.component.tsx +63 -61
- package/src/queue-table/default-queue-table.test.tsx +61 -61
- package/src/queue-table/queue-entry-actions/queue-entry-actions-modal.scss +36 -0
- package/src/queue-table/queue-entry-actions/queue-entry-actions.modal.tsx +30 -10
- package/src/queue-table/queue-entry-actions/queue-entry-actions.test.tsx +34 -103
- package/src/queue-table/queue-entry-actions/queue-entry-confirm-action.test.tsx +42 -25
- package/src/queue-table/queue-entry-actions/queue-entry-undo-actions.test.tsx +19 -14
- package/src/queue-table/queue-table-by-status-skeleton.component.tsx +1 -5
- package/src/queue-table/queue-table-expanded-row.component.tsx +1 -2
- package/src/queue-table/queue-table-metrics-card.scss +7 -7
- package/src/queue-table/queue-table-metrics.scss +3 -3
- package/src/queue-table/queue-table.component.tsx +8 -11
- package/src/queue-table/queue-table.scss +32 -26
- package/src/queue-table/queue-table.test.tsx +46 -21
- package/src/remove-queue-entry-dialog/remove-queue-entry.resource.ts +1 -1
- package/src/remove-queue-entry-dialog/remove-queue-entry.scss +2 -2
- package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +13 -12
- package/src/side-menu/side-menu.test.tsx +0 -1
- package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +1 -1
- package/src/transition-queue-entry/transition-queue-entry-dialog.scss +5 -5
- package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +33 -44
- package/src/views/queue-tables-for-all-statuses.component.tsx +14 -14
- package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +1 -1
- package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +1 -1
- package/src/visits-missing-inqueue/visits-missing-inqueue.scss +17 -14
- package/translations/am.json +4 -2
- package/translations/ar.json +4 -2
- package/translations/en.json +1 -0
- package/translations/es.json +4 -2
- package/translations/fr.json +39 -37
- package/translations/he.json +4 -2
- package/translations/km.json +4 -2
- package/translations/zh.json +4 -2
- package/translations/zh_CN.json +4 -2
- package/dist/276.js +0 -1
- package/dist/276.js.map +0 -1
- package/dist/384.js +0 -2
- package/dist/384.js.map +0 -1
- package/dist/401.js +0 -1
- package/dist/401.js.map +0 -1
- package/dist/430.js +0 -1
- package/dist/430.js.map +0 -1
- package/dist/60.js +0 -1
- package/dist/60.js.map +0 -1
- package/dist/600.js +0 -1
- package/dist/600.js.map +0 -1
- package/dist/647.js +0 -1
- package/dist/647.js.map +0 -1
- package/dist/650.js +0 -1
- package/dist/650.js.map +0 -1
- package/dist/669.js +0 -1
- package/dist/669.js.map +0 -1
- package/dist/764.js +0 -1
- package/dist/764.js.map +0 -1
- package/dist/877.js +0 -1
- package/dist/877.js.map +0 -1
- package/dist/917.js +0 -1
- package/dist/917.js.map +0 -1
- package/src/queue-table/queue-entry-actions/queue-entry-actons-modal.scss +0 -36
- package/src/root.scss +0 -15
- /package/dist/{384.js.LICENSE.txt → 484.js.LICENSE.txt} +0 -0
|
@@ -2,33 +2,26 @@ import React from 'react';
|
|
|
2
2
|
import { of } from 'rxjs';
|
|
3
3
|
import { screen } from '@testing-library/react';
|
|
4
4
|
import { useConfig, useSession, getDefaultsFromConfigSchema } from '@openmrs/esm-framework';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
mockServices,
|
|
7
|
+
mockSession,
|
|
8
|
+
mockQueueEntries,
|
|
9
|
+
mockQueueRooms,
|
|
10
|
+
mockLocationTriage,
|
|
11
|
+
mockLocationSurgery,
|
|
12
|
+
} from '__mocks__';
|
|
6
13
|
import { renderWithSwr } from 'tools';
|
|
7
14
|
import { useQueueEntries } from '../hooks/useQueueEntries';
|
|
8
15
|
import { useQueueRooms } from '../add-provider-queue-room/add-provider-queue-room.resource';
|
|
9
16
|
import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
|
|
17
|
+
import { type ConfigObject, configSchema } from '../config-schema';
|
|
10
18
|
import DefaultQueueTable from '../queue-table/default-queue-table.component';
|
|
11
|
-
import { configSchema } from '../config-schema';
|
|
12
|
-
|
|
13
|
-
const mockedUseConfig = useConfig as jest.Mock;
|
|
14
|
-
const mockUseQueueEntries = useQueueEntries as jest.Mock;
|
|
15
|
-
const mockQueueLocations = useQueueLocations as jest.Mock;
|
|
16
|
-
const mockUseQueueRooms = useQueueRooms as jest.Mock;
|
|
17
|
-
const mockUseSession = useSession as jest.Mock;
|
|
18
|
-
|
|
19
|
-
mockedUseConfig.mockReturnValue({
|
|
20
|
-
...getDefaultsFromConfigSchema(configSchema),
|
|
21
|
-
visitQueueNumberAttributeUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
|
|
22
|
-
customPatientChartUrl: 'someUrl',
|
|
23
|
-
});
|
|
24
19
|
|
|
25
|
-
jest.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
31
|
-
});
|
|
20
|
+
const mockUseConfig = jest.mocked(useConfig<ConfigObject>);
|
|
21
|
+
const mockUseQueueEntries = jest.mocked(useQueueEntries);
|
|
22
|
+
const mockQueueLocations = jest.mocked(useQueueLocations);
|
|
23
|
+
const mockUseQueueRooms = jest.mocked(useQueueRooms);
|
|
24
|
+
const mockUseSession = jest.mocked(useSession);
|
|
32
25
|
|
|
33
26
|
jest.mock('../hooks/useQueues', () => {
|
|
34
27
|
return {
|
|
@@ -36,51 +29,47 @@ jest.mock('../hooks/useQueues', () => {
|
|
|
36
29
|
};
|
|
37
30
|
});
|
|
38
31
|
|
|
39
|
-
jest.mock('../patient-search/hooks/useQueueLocations', () => {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
...originalModule,
|
|
44
|
-
useQueueLocations: jest.fn(),
|
|
45
|
-
};
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
jest.mock('../add-provider-queue-room/add-provider-queue-room.resource', () => {
|
|
49
|
-
const originalModule = jest.requireActual('../add-provider-queue-room/add-provider-queue-room.resource');
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
...originalModule,
|
|
53
|
-
useQueueRooms: jest.fn(),
|
|
54
|
-
};
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
jest.mock('../hooks/useQueueEntries', () => {
|
|
58
|
-
const originalModule = jest.requireActual('../hooks/useQueueEntries');
|
|
32
|
+
jest.mock('../patient-search/hooks/useQueueLocations', () => ({
|
|
33
|
+
...jest.requireActual('../patient-search/hooks/useQueueLocations'),
|
|
34
|
+
useQueueLocations: jest.fn(),
|
|
35
|
+
}));
|
|
59
36
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
});
|
|
37
|
+
jest.mock('../add-provider-queue-room/add-provider-queue-room.resource', () => ({
|
|
38
|
+
...jest.requireActual('../add-provider-queue-room/add-provider-queue-room.resource'),
|
|
39
|
+
useQueueRooms: jest.fn(),
|
|
40
|
+
}));
|
|
65
41
|
|
|
66
|
-
jest.mock('../
|
|
67
|
-
|
|
42
|
+
jest.mock('../hooks/useQueueEntries', () => ({
|
|
43
|
+
...jest.requireActual('../hooks/useQueueEntries'),
|
|
44
|
+
useQueueEntries: jest.fn(),
|
|
45
|
+
}));
|
|
68
46
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
47
|
+
jest.mock('../helpers/helpers', () => ({
|
|
48
|
+
...jest.requireActual('../helpers/helpers'),
|
|
49
|
+
getSelectedServiceName: jest.fn().mockReturnValue(of({ serviceName: 'All' })),
|
|
50
|
+
}));
|
|
74
51
|
|
|
75
|
-
describe('DefaultQueueTable
|
|
52
|
+
describe('DefaultQueueTable', () => {
|
|
76
53
|
beforeEach(() => {
|
|
77
|
-
|
|
54
|
+
mockUseConfig.mockReturnValue({
|
|
55
|
+
...getDefaultsFromConfigSchema(configSchema),
|
|
56
|
+
customPatientChartUrl: 'someUrl',
|
|
57
|
+
visitQueueNumberAttributeUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
|
|
58
|
+
});
|
|
59
|
+
mockUseSession.mockReturnValue(mockSession.data);
|
|
78
60
|
});
|
|
79
61
|
|
|
80
62
|
it('renders an empty state view if data is unavailable', async () => {
|
|
81
|
-
mockQueueLocations.mockReturnValue({ queueLocations: [] });
|
|
82
|
-
mockUseQueueRooms.mockReturnValue({ rooms: [] });
|
|
83
|
-
mockUseQueueEntries.mockReturnValue({
|
|
63
|
+
mockQueueLocations.mockReturnValue({ queueLocations: [], isLoading: false, error: null });
|
|
64
|
+
mockUseQueueRooms.mockReturnValue({ rooms: [], isLoading: false, error: undefined });
|
|
65
|
+
mockUseQueueEntries.mockReturnValue({
|
|
66
|
+
queueEntries: [],
|
|
67
|
+
isLoading: false,
|
|
68
|
+
error: undefined,
|
|
69
|
+
totalCount: 0,
|
|
70
|
+
isValidating: false,
|
|
71
|
+
mutate: jest.fn(),
|
|
72
|
+
});
|
|
84
73
|
|
|
85
74
|
rendeDefaultQueueTable();
|
|
86
75
|
|
|
@@ -92,9 +81,20 @@ describe('DefaultQueueTable: ', () => {
|
|
|
92
81
|
});
|
|
93
82
|
|
|
94
83
|
it('renders a tabular overview of visit queue entry data when available', async () => {
|
|
95
|
-
mockQueueLocations.mockReturnValue({
|
|
96
|
-
|
|
97
|
-
|
|
84
|
+
mockQueueLocations.mockReturnValue({
|
|
85
|
+
queueLocations: [mockLocationSurgery, mockLocationTriage],
|
|
86
|
+
isLoading: false,
|
|
87
|
+
error: null,
|
|
88
|
+
});
|
|
89
|
+
mockUseQueueRooms.mockReturnValue({ rooms: mockQueueRooms.data.results, isLoading: false, error: undefined });
|
|
90
|
+
mockUseQueueEntries.mockReturnValue({
|
|
91
|
+
queueEntries: mockQueueEntries,
|
|
92
|
+
error: undefined,
|
|
93
|
+
isLoading: false,
|
|
94
|
+
isValidating: false,
|
|
95
|
+
mutate: jest.fn(),
|
|
96
|
+
totalCount: 2,
|
|
97
|
+
});
|
|
98
98
|
|
|
99
99
|
rendeDefaultQueueTable();
|
|
100
100
|
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
.queueEntryActionModalBody {
|
|
31
|
+
padding-bottom: layout.$spacing-05;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.dateTimeFields {
|
|
35
|
+
display: flex;
|
|
36
|
+
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import React, { useMemo, useState } from 'react';
|
|
2
|
+
import dayjs from 'dayjs';
|
|
1
3
|
import {
|
|
2
4
|
Button,
|
|
3
5
|
Checkbox,
|
|
@@ -18,16 +20,14 @@ import {
|
|
|
18
20
|
TimePicker,
|
|
19
21
|
TimePickerSelect,
|
|
20
22
|
} 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
23
|
import { useTranslation } from 'react-i18next';
|
|
24
|
+
import { showSnackbar, type FetchResponse } from '@openmrs/esm-framework';
|
|
25
25
|
import { datePickerFormat, datePickerPlaceHolder, time12HourFormatRegexPattern } from '../../constants';
|
|
26
26
|
import { convertTime12to24, type amPm } from '../../helpers/time-helpers';
|
|
27
27
|
import { useMutateQueueEntries } from '../../hooks/useQueueEntries';
|
|
28
28
|
import { useQueues } from '../../hooks/useQueues';
|
|
29
29
|
import { type QueueEntry } from '../../types';
|
|
30
|
-
import styles from './queue-entry-
|
|
30
|
+
import styles from './queue-entry-actions-modal.scss';
|
|
31
31
|
|
|
32
32
|
interface QueueEntryActionModalProps {
|
|
33
33
|
queueEntry: QueueEntry;
|
|
@@ -172,15 +172,35 @@ export const QueueEntryActionModal: React.FC<QueueEntryActionModalProps> = ({
|
|
|
172
172
|
});
|
|
173
173
|
};
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
// non-null if the selected date+time is invalid
|
|
176
|
+
const timeInvalidMessage = useMemo(() => {
|
|
176
177
|
const now = new Date();
|
|
177
178
|
const startAtDate = new Date(formState.transitionDate);
|
|
178
179
|
const [hour, minute] = convertTime12to24(formState.transitionTime, formState.transitionTimeFormat);
|
|
179
180
|
startAtDate.setHours(hour, minute, 0, 0);
|
|
180
|
-
return startAtDate > now;
|
|
181
|
-
}, [formState.transitionDate, formState.transitionTime, formState.transitionTimeFormat]);
|
|
182
181
|
|
|
183
|
-
|
|
182
|
+
const previousQueueEntryStartTimeStr = queueEntry.previousQueueEntry?.startedAt;
|
|
183
|
+
const previousQueueEntryStartTime = previousQueueEntryStartTimeStr
|
|
184
|
+
? new Date(previousQueueEntryStartTimeStr)
|
|
185
|
+
: null;
|
|
186
|
+
|
|
187
|
+
if (startAtDate > now) {
|
|
188
|
+
return t('timeCannotBeInFuture', 'Time cannot be in the future');
|
|
189
|
+
}
|
|
190
|
+
if (startAtDate <= previousQueueEntryStartTime) {
|
|
191
|
+
return t(
|
|
192
|
+
'timeCannotBePriorToPreviousQueueEntry',
|
|
193
|
+
'Time cannot be before start of previous queue entry: {{time}}',
|
|
194
|
+
{
|
|
195
|
+
time: previousQueueEntryStartTime.toLocaleString(),
|
|
196
|
+
interpolation: { escapeValue: false },
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}, [formState.transitionDate, formState.transitionTime, formState.transitionTimeFormat, t]);
|
|
202
|
+
|
|
203
|
+
const selectedPriorityIndex = priorities?.findIndex((p) => p.uuid == formState.selectedPriority);
|
|
184
204
|
|
|
185
205
|
return (
|
|
186
206
|
<>
|
|
@@ -329,8 +349,8 @@ export const QueueEntryActionModal: React.FC<QueueEntryActionModalProps> = ({
|
|
|
329
349
|
onChange={(event) => setTransitionTime(event.target.value)}
|
|
330
350
|
pattern={time12HourFormatRegexPattern}
|
|
331
351
|
value={formState.transitionTime}
|
|
332
|
-
invalid={
|
|
333
|
-
invalidText={
|
|
352
|
+
invalid={timeInvalidMessage != null}
|
|
353
|
+
invalidText={timeInvalidMessage}
|
|
334
354
|
disabled={!formState.modifyDefaultTransitionDateTime}>
|
|
335
355
|
<TimePickerSelect
|
|
336
356
|
id="visitStartTimeSelect"
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
2
|
-
import { screen } from '@testing-library/react';
|
|
3
|
-
import { mockQueueEntryBrian, mockQueueSurgery, mockStatusInService, mockQueues } from '__mocks__';
|
|
4
1
|
import React from 'react';
|
|
5
|
-
import { renderWithSwr } from 'tools';
|
|
6
|
-
import TransitionQueueEntryModal from './transition-queue-entry.modal';
|
|
7
2
|
import userEvent from '@testing-library/user-event';
|
|
8
|
-
import
|
|
3
|
+
import { type FetchResponse, openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
4
|
+
import { screen } from '@testing-library/react';
|
|
5
|
+
import { mockQueues, mockQueueEntryAlice } from '__mocks__';
|
|
6
|
+
import { renderWithSwr } from 'tools';
|
|
7
|
+
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry.modal';
|
|
8
|
+
import VoidQueueEntryModal from './void-queue-entry.modal';
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const mockOpenmrsFetch = jest.mocked(openmrsFetch);
|
|
11
11
|
|
|
12
12
|
jest.mock('../../hooks/useQueues', () => {
|
|
13
13
|
return {
|
|
@@ -17,136 +17,67 @@ jest.mock('../../hooks/useQueues', () => {
|
|
|
17
17
|
};
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
describe('
|
|
21
|
-
const queueEntry =
|
|
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
|
-
});
|
|
20
|
+
describe('UndoTransitionQueueEntryModal', () => {
|
|
21
|
+
const queueEntry = mockQueueEntryAlice;
|
|
42
22
|
|
|
43
23
|
it('has a cancel button that closes the modal', async () => {
|
|
44
24
|
const closeModal = jest.fn();
|
|
45
25
|
const user = userEvent.setup();
|
|
46
26
|
|
|
47
|
-
renderWithSwr(<
|
|
27
|
+
renderWithSwr(<UndoTransitionQueueEntryModal queueEntry={queueEntry} closeModal={closeModal} />);
|
|
28
|
+
|
|
48
29
|
const cancelButton = screen.getByText('Cancel');
|
|
49
30
|
await user.click(cancelButton);
|
|
50
31
|
expect(closeModal).toHaveBeenCalled();
|
|
51
32
|
});
|
|
52
33
|
|
|
53
|
-
it('has
|
|
54
|
-
|
|
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({
|
|
34
|
+
it('has an working submit button', async () => {
|
|
35
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
61
36
|
status: 200,
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
renderWithSwr(<TransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
37
|
+
data: [],
|
|
38
|
+
} as unknown as FetchResponse);
|
|
65
39
|
|
|
66
|
-
|
|
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);
|
|
40
|
+
const user = userEvent.setup();
|
|
73
41
|
|
|
74
|
-
|
|
75
|
-
const inServiceRadioButton = screen.getByText(mockStatusInService.display);
|
|
76
|
-
await inServiceRadioButton.click();
|
|
42
|
+
renderWithSwr(<UndoTransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
77
43
|
|
|
78
|
-
const submitButton = screen.getByRole('button', { name: /
|
|
79
|
-
expect(submitButton).
|
|
80
|
-
await
|
|
44
|
+
const submitButton = screen.getByRole('button', { name: /Undo transition/ });
|
|
45
|
+
expect(submitButton).toBeEnabled();
|
|
46
|
+
await user.click(submitButton);
|
|
81
47
|
|
|
82
|
-
expect(
|
|
48
|
+
expect(mockOpenmrsFetch).toHaveBeenCalled();
|
|
83
49
|
expect(showSnackbar).toHaveBeenCalled();
|
|
84
50
|
});
|
|
85
51
|
});
|
|
86
52
|
|
|
87
|
-
describe('
|
|
88
|
-
const queueEntry =
|
|
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
|
-
});
|
|
53
|
+
describe('VoidQueueEntryModal', () => {
|
|
54
|
+
const queueEntry = mockQueueEntryAlice;
|
|
109
55
|
|
|
110
56
|
it('has a cancel button that closes the modal', async () => {
|
|
111
57
|
const closeModal = jest.fn();
|
|
112
58
|
const user = userEvent.setup();
|
|
113
59
|
|
|
114
|
-
renderWithSwr(<
|
|
60
|
+
renderWithSwr(<VoidQueueEntryModal queueEntry={queueEntry} closeModal={closeModal} />);
|
|
115
61
|
const cancelButton = screen.getByText('Cancel');
|
|
116
62
|
await user.click(cancelButton);
|
|
117
63
|
expect(closeModal).toHaveBeenCalled();
|
|
118
64
|
});
|
|
119
65
|
|
|
120
|
-
it('has
|
|
121
|
-
|
|
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({
|
|
66
|
+
it('has an working submit button', async () => {
|
|
67
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
128
68
|
status: 200,
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
renderWithSwr(<EditQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
69
|
+
data: [],
|
|
70
|
+
} as unknown as FetchResponse);
|
|
132
71
|
|
|
133
|
-
|
|
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);
|
|
72
|
+
const user = userEvent.setup();
|
|
140
73
|
|
|
141
|
-
|
|
142
|
-
const inServiceRadioButton = screen.getByText(mockStatusInService.display);
|
|
143
|
-
await inServiceRadioButton.click();
|
|
74
|
+
renderWithSwr(<VoidQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
144
75
|
|
|
145
|
-
const submitButton = screen.getByRole('button', { name: /
|
|
146
|
-
expect(submitButton).
|
|
147
|
-
await
|
|
76
|
+
const submitButton = screen.getByRole('button', { name: /Delete queue entry/ });
|
|
77
|
+
expect(submitButton).toBeEnabled();
|
|
78
|
+
await user.click(submitButton);
|
|
148
79
|
|
|
149
|
-
expect(
|
|
80
|
+
expect(mockOpenmrsFetch).toHaveBeenCalled();
|
|
150
81
|
expect(showSnackbar).toHaveBeenCalled();
|
|
151
82
|
});
|
|
152
83
|
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
2
3
|
import { screen } from '@testing-library/react';
|
|
4
|
+
import { type FetchResponse, openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
3
5
|
import { mockQueues, mockQueueEntryAlice } from '__mocks__';
|
|
4
|
-
import React from 'react';
|
|
5
6
|
import { renderWithSwr } from 'tools';
|
|
6
|
-
import
|
|
7
|
+
import EndQueueEntryModal from './end-queue-entry.modal';
|
|
7
8
|
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry.modal';
|
|
8
9
|
import VoidQueueEntryModal from './void-queue-entry.modal';
|
|
9
|
-
import EndQueueEntryModal from './end-queue-entry.modal';
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const mockOpenmrsFetch = jest.mocked(openmrsFetch);
|
|
12
12
|
|
|
13
13
|
jest.mock('../../hooks/useQueues', () => {
|
|
14
14
|
return {
|
|
@@ -18,7 +18,7 @@ jest.mock('../../hooks/useQueues', () => {
|
|
|
18
18
|
};
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
-
describe('UndoTransitionQueueEntryModal
|
|
21
|
+
describe('UndoTransitionQueueEntryModal', () => {
|
|
22
22
|
const queueEntry = mockQueueEntryAlice;
|
|
23
23
|
|
|
24
24
|
it('has a cancel button that closes the modal', async () => {
|
|
@@ -32,22 +32,28 @@ describe('UndoTransitionQueueEntryModal: ', () => {
|
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('has an working submit button', async () => {
|
|
35
|
-
|
|
35
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
36
36
|
status: 200,
|
|
37
|
-
});
|
|
37
|
+
} as unknown as FetchResponse);
|
|
38
|
+
|
|
38
39
|
const user = userEvent.setup();
|
|
40
|
+
|
|
39
41
|
renderWithSwr(<UndoTransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
40
42
|
|
|
41
|
-
const submitButton = screen.getByRole('button', { name: /
|
|
42
|
-
expect(submitButton).
|
|
43
|
-
await user.click(submitButton);
|
|
43
|
+
const submitButton = screen.getByRole('button', { name: /undo transition/i });
|
|
44
|
+
expect(submitButton).toBeEnabled();
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
expect(showSnackbar).
|
|
46
|
+
await user.click(submitButton);
|
|
47
|
+
expect(showSnackbar).toHaveBeenCalledWith({
|
|
48
|
+
isLowContrast: true,
|
|
49
|
+
kind: 'success',
|
|
50
|
+
subtitle: 'Queue entry transition undo success',
|
|
51
|
+
title: 'Undo transition success',
|
|
52
|
+
});
|
|
47
53
|
});
|
|
48
54
|
});
|
|
49
55
|
|
|
50
|
-
describe('VoidQueueEntryModal
|
|
56
|
+
describe('VoidQueueEntryModal', () => {
|
|
51
57
|
const queueEntry = mockQueueEntryAlice;
|
|
52
58
|
|
|
53
59
|
it('has a cancel button that closes the modal', async () => {
|
|
@@ -61,22 +67,27 @@ describe('VoidQueueEntryModal: ', () => {
|
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
it('has an working submit button', async () => {
|
|
64
|
-
|
|
70
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
65
71
|
status: 200,
|
|
66
|
-
});
|
|
72
|
+
} as unknown as FetchResponse);
|
|
73
|
+
|
|
67
74
|
const user = userEvent.setup();
|
|
68
75
|
renderWithSwr(<VoidQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
69
76
|
|
|
70
77
|
const submitButton = screen.getByRole('button', { name: /Delete queue entry/ });
|
|
71
|
-
expect(submitButton).
|
|
78
|
+
expect(submitButton).toBeEnabled();
|
|
72
79
|
await user.click(submitButton);
|
|
73
80
|
|
|
74
|
-
expect(
|
|
75
|
-
|
|
81
|
+
expect(showSnackbar).toHaveBeenCalledWith({
|
|
82
|
+
isLowContrast: true,
|
|
83
|
+
kind: 'success',
|
|
84
|
+
subtitle: 'Queue entry deleted successfully',
|
|
85
|
+
title: 'Queue entry deleted successfully',
|
|
86
|
+
});
|
|
76
87
|
});
|
|
77
88
|
});
|
|
78
89
|
|
|
79
|
-
describe('EndQueueEntryModal
|
|
90
|
+
describe('EndQueueEntryModal', () => {
|
|
80
91
|
const queueEntry = mockQueueEntryAlice;
|
|
81
92
|
|
|
82
93
|
it('has a cancel button that closes the modal', async () => {
|
|
@@ -90,17 +101,23 @@ describe('EndQueueEntryModal: ', () => {
|
|
|
90
101
|
});
|
|
91
102
|
|
|
92
103
|
it('has an working submit button', async () => {
|
|
93
|
-
|
|
104
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
94
105
|
status: 200,
|
|
95
|
-
});
|
|
106
|
+
} as unknown as FetchResponse);
|
|
107
|
+
|
|
96
108
|
const user = userEvent.setup();
|
|
109
|
+
|
|
97
110
|
renderWithSwr(<EndQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
98
111
|
|
|
99
112
|
const submitButton = screen.getByRole('button', { name: /Remove patient/ });
|
|
100
|
-
expect(submitButton).
|
|
113
|
+
expect(submitButton).toBeEnabled();
|
|
101
114
|
await user.click(submitButton);
|
|
102
115
|
|
|
103
|
-
expect(
|
|
104
|
-
|
|
116
|
+
expect(showSnackbar).toHaveBeenCalledWith({
|
|
117
|
+
isLowContrast: true,
|
|
118
|
+
kind: 'success',
|
|
119
|
+
subtitle: 'Paient removed from queue successfully',
|
|
120
|
+
title: 'Patient removed',
|
|
121
|
+
});
|
|
105
122
|
});
|
|
106
123
|
});
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import userEvent from '@testing-library/user-event';
|
|
3
|
+
import { type FetchResponse, openmrsFetch, showSnackbar } from '@openmrs/esm-framework';
|
|
2
4
|
import { screen } from '@testing-library/react';
|
|
3
5
|
import { mockQueues, mockQueueEntryAlice } from '__mocks__';
|
|
4
|
-
import React from 'react';
|
|
5
6
|
import { renderWithSwr } from 'tools';
|
|
6
|
-
import userEvent from '@testing-library/user-event';
|
|
7
7
|
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry.modal';
|
|
8
8
|
import VoidQueueEntryModal from './void-queue-entry.modal';
|
|
9
9
|
|
|
10
|
-
const
|
|
10
|
+
const mockOpenmrsFetch = jest.mocked(openmrsFetch);
|
|
11
11
|
|
|
12
12
|
jest.mock('../../hooks/useQueues', () => {
|
|
13
13
|
return {
|
|
@@ -17,7 +17,7 @@ jest.mock('../../hooks/useQueues', () => {
|
|
|
17
17
|
};
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
describe('UndoTransitionQueueEntryModal
|
|
20
|
+
describe('UndoTransitionQueueEntryModal', () => {
|
|
21
21
|
const queueEntry = mockQueueEntryAlice;
|
|
22
22
|
|
|
23
23
|
it('has a cancel button that closes the modal', async () => {
|
|
@@ -25,28 +25,31 @@ describe('UndoTransitionQueueEntryModal: ', () => {
|
|
|
25
25
|
const user = userEvent.setup();
|
|
26
26
|
|
|
27
27
|
renderWithSwr(<UndoTransitionQueueEntryModal queueEntry={queueEntry} closeModal={closeModal} />);
|
|
28
|
+
|
|
28
29
|
const cancelButton = screen.getByText('Cancel');
|
|
29
30
|
await user.click(cancelButton);
|
|
30
31
|
expect(closeModal).toHaveBeenCalled();
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
it('has an working submit button', async () => {
|
|
34
|
-
|
|
35
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
35
36
|
status: 200,
|
|
36
|
-
});
|
|
37
|
+
} as unknown as FetchResponse);
|
|
38
|
+
|
|
37
39
|
const user = userEvent.setup();
|
|
40
|
+
|
|
38
41
|
renderWithSwr(<UndoTransitionQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
39
42
|
|
|
40
43
|
const submitButton = screen.getByRole('button', { name: /Undo transition/ });
|
|
41
|
-
expect(submitButton).
|
|
44
|
+
expect(submitButton).toBeEnabled();
|
|
42
45
|
await user.click(submitButton);
|
|
43
46
|
|
|
44
|
-
expect(
|
|
47
|
+
expect(mockOpenmrsFetch).toHaveBeenCalled();
|
|
45
48
|
expect(showSnackbar).toHaveBeenCalled();
|
|
46
49
|
});
|
|
47
50
|
});
|
|
48
51
|
|
|
49
|
-
describe('VoidQueueEntryModal
|
|
52
|
+
describe('VoidQueueEntryModal', () => {
|
|
50
53
|
const queueEntry = mockQueueEntryAlice;
|
|
51
54
|
|
|
52
55
|
it('has a cancel button that closes the modal', async () => {
|
|
@@ -60,17 +63,19 @@ describe('VoidQueueEntryModal: ', () => {
|
|
|
60
63
|
});
|
|
61
64
|
|
|
62
65
|
it('has an working submit button', async () => {
|
|
63
|
-
|
|
66
|
+
mockOpenmrsFetch.mockResolvedValue({
|
|
64
67
|
status: 200,
|
|
65
|
-
});
|
|
68
|
+
} as unknown as FetchResponse);
|
|
69
|
+
|
|
66
70
|
const user = userEvent.setup();
|
|
71
|
+
|
|
67
72
|
renderWithSwr(<VoidQueueEntryModal queueEntry={queueEntry} closeModal={() => {}} />);
|
|
68
73
|
|
|
69
74
|
const submitButton = screen.getByRole('button', { name: /Delete queue entry/ });
|
|
70
|
-
expect(submitButton).
|
|
75
|
+
expect(submitButton).toBeEnabled();
|
|
71
76
|
await user.click(submitButton);
|
|
72
77
|
|
|
73
|
-
expect(
|
|
78
|
+
expect(mockOpenmrsFetch).toHaveBeenCalled();
|
|
74
79
|
expect(showSnackbar).toHaveBeenCalled();
|
|
75
80
|
});
|
|
76
81
|
});
|