@kenyaemr/esm-service-queues-app 7.0.2-pre.67 → 7.0.3-pre.70
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 +14 -13
- package/dist/130.js +1 -1
- package/dist/130.js.map +1 -1
- package/dist/199.js +1 -0
- package/dist/{738.js.map → 199.js.map} +1 -1
- package/dist/271.js +1 -1
- package/dist/276.js +1 -1
- package/dist/319.js +1 -1
- package/dist/401.js +1 -1
- package/dist/430.js +1 -2
- package/dist/430.js.map +1 -1
- package/dist/460.js +1 -1
- package/dist/490.js +2 -0
- package/dist/490.js.map +1 -0
- package/dist/574.js +1 -1
- package/dist/6.js +1 -0
- package/dist/6.js.map +1 -0
- package/dist/60.js +1 -0
- package/dist/60.js.map +1 -0
- package/dist/600.js +1 -0
- package/dist/600.js.map +1 -0
- package/dist/644.js +1 -1
- package/dist/647.js +1 -1
- package/dist/647.js.map +1 -1
- package/dist/650.js +1 -1
- package/dist/650.js.map +1 -1
- package/dist/669.js +1 -1
- package/dist/669.js.map +1 -1
- package/dist/{806.js → 752.js} +1 -1
- package/dist/{806.js.map → 752.js.map} +1 -1
- package/dist/757.js +1 -1
- package/dist/764.js +1 -1
- package/dist/764.js.map +1 -1
- package/dist/788.js +1 -1
- package/dist/{981.js → 800.js} +1 -1
- package/dist/{981.js.map → 800.js.map} +1 -1
- package/dist/807.js +1 -1
- package/dist/{696.js → 828.js} +1 -1
- package/dist/{696.js.map → 828.js.map} +1 -1
- package/dist/833.js +1 -1
- package/dist/877.js +1 -1
- package/dist/877.js.map +1 -1
- package/dist/917.js +1 -1
- package/dist/917.js.map +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js +1 -1
- package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +193 -193
- 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 +3 -3
- package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +4 -4
- package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +12 -15
- package/src/config-schema.ts +20 -0
- package/src/helpers/helpers.ts +42 -32
- package/src/home.component.tsx +1 -1
- package/src/hooks/useQueueEntries.ts +1 -1
- package/src/hooks/useQueueService.ts +21 -0
- package/src/hooks/useQueueStatuses.ts +40 -0
- package/src/index.ts +5 -5
- package/src/patient-info/patient-info.component.tsx +9 -9
- package/src/patient-queue-header/patient-queue-header.component.tsx +30 -24
- package/src/patient-queue-header/patient-queue-header.scss +1 -2
- package/src/patient-queue-metrics/clinic-metrics.component.tsx +16 -27
- package/src/patient-queue-metrics/queue-metrics.resource.ts +1 -2
- package/src/patient-search/patient-scheduled-visits.scss +1 -1
- package/src/patient-search/patient-search.scss +6 -0
- package/src/patient-search/patient-search.workspace.tsx +30 -30
- package/src/patient-search/visit-form/visit-form.component.tsx +8 -8
- package/src/patient-search/visit-form/visit-form.scss +5 -3
- package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +14 -7
- package/src/queue-patient-linelists/queue-linelist-filter.scss +2 -12
- package/src/queue-rooms/queue-room-form.scss +1 -1
- package/src/queue-screen/queue-screen.component.tsx +1 -1
- package/src/queue-services/queue-service-form.scss +2 -2
- package/src/queue-table/cells/queue-table-action-cell.component.tsx +6 -4
- package/src/queue-table/cells/queue-table-action-cell.scss +7 -0
- package/src/queue-table/default-queue-table.component.tsx +69 -38
- package/src/queue-table/queue-entry-actions/{edit-queue-entry-modal.component.tsx → edit-queue-entry.modal.tsx} +1 -1
- package/src/queue-table/queue-entry-actions/{end-queue-entry-modal.component.tsx → end-queue-entry.modal.tsx} +1 -1
- package/src/queue-table/queue-entry-actions/{queue-entry-actions-modal.test.tsx → queue-entry-actions.test.tsx} +2 -2
- package/src/queue-table/queue-entry-actions/{queue-entry-confirm-action-modal.test.tsx → queue-entry-confirm-action.test.tsx} +3 -3
- package/src/queue-table/queue-entry-actions/{queue-entry-undo-actions-modal.test.tsx → queue-entry-undo-actions.test.tsx} +2 -2
- package/src/queue-table/queue-entry-actions/{transition-queue-entry-modal.component.tsx → transition-queue-entry.modal.tsx} +1 -1
- package/src/queue-table/queue-entry-actions/{undo-transition-queue-entry-modal.component.tsx → undo-transition-queue-entry.modal.tsx} +1 -1
- package/src/queue-table/queue-entry-actions/{void-queue-entry-modal.component.tsx → void-queue-entry.modal.tsx} +1 -1
- package/src/queue-table/queue-table-by-status-skeleton.component.tsx +18 -18
- package/src/queue-table/queue-table-metrics-card.scss +1 -1
- package/src/queue-table/queue-table-metrics.scss +1 -1
- package/src/queue-table/queue-table.component.tsx +35 -18
- package/src/queue-table/queue-table.scss +12 -4
- package/src/types/index.ts +3 -1
- package/src/views/queue-table-by-status-view.component.tsx +2 -14
- package/src/views/queue-tables-for-all-statuses.component.tsx +81 -43
- package/translations/am.json +29 -19
- package/translations/ar.json +33 -23
- package/translations/en.json +3 -2
- package/translations/es.json +29 -19
- package/translations/fr.json +29 -19
- package/translations/he.json +33 -23
- package/translations/km.json +31 -21
- package/translations/zh.json +39 -29
- package/translations/zh_CN.json +38 -28
- package/dist/185.js +0 -1
- package/dist/185.js.map +0 -1
- package/dist/233.js +0 -1
- package/dist/233.js.map +0 -1
- package/dist/237.js +0 -1
- package/dist/237.js.map +0 -1
- package/dist/703.js +0 -1
- package/dist/703.js.map +0 -1
- package/dist/738.js +0 -1
- /package/dist/{430.js.LICENSE.txt → 490.js.LICENSE.txt} +0 -0
- /package/src/queue-table/queue-entry-actions/{queue-entry-actions-modal.component.tsx → queue-entry-actions.modal.tsx} +0 -0
- /package/src/queue-table/queue-entry-actions/{queue-entry-confirm-action-modal.component.tsx → queue-entry-confirm-action.modal.tsx} +0 -0
|
@@ -3,18 +3,14 @@ import { useTranslation } from 'react-i18next';
|
|
|
3
3
|
import { Dropdown } from '@carbon/react';
|
|
4
4
|
import MetricsCard from './metrics-card.component';
|
|
5
5
|
import MetricsHeader from './metrics-header.component';
|
|
6
|
-
import {
|
|
7
|
-
updateSelectedServiceName,
|
|
8
|
-
updateSelectedServiceUuid,
|
|
9
|
-
useSelectedServiceName,
|
|
10
|
-
useSelectedServiceUuid,
|
|
11
|
-
useSelectedQueueLocationUuid,
|
|
12
|
-
} from '../helpers/helpers';
|
|
6
|
+
import { updateSelectedService, useSelectedService, useSelectedQueueLocationUuid } from '../helpers/helpers';
|
|
13
7
|
import { useActiveVisits, useAverageWaitTime } from './clinic-metrics.resource';
|
|
14
8
|
import { useServiceMetricsCount } from './queue-metrics.resource';
|
|
15
9
|
import styles from './clinic-metrics.scss';
|
|
16
10
|
import { useQueues } from '../hooks/useQueues';
|
|
17
11
|
import { useQueueEntries } from '../hooks/useQueueEntries';
|
|
12
|
+
import useQueueServices from '../hooks/useQueueService';
|
|
13
|
+
import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
|
|
18
14
|
|
|
19
15
|
export interface Service {
|
|
20
16
|
uuid: string;
|
|
@@ -23,32 +19,25 @@ export interface Service {
|
|
|
23
19
|
|
|
24
20
|
function ClinicMetrics() {
|
|
25
21
|
const { t } = useTranslation();
|
|
22
|
+
const layout = useLayoutType();
|
|
26
23
|
|
|
27
24
|
const currentQueueLocation = useSelectedQueueLocationUuid();
|
|
28
|
-
const {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const { serviceCount } = useServiceMetricsCount(currentServiceUuid, currentQueueLocation);
|
|
25
|
+
const { services } = useQueueServices();
|
|
26
|
+
const currentService = useSelectedService();
|
|
27
|
+
const { serviceCount } = useServiceMetricsCount(currentService?.serviceUuid, currentQueueLocation);
|
|
32
28
|
const [initialSelectedItem, setInitialSelectItem] = useState(() => {
|
|
33
|
-
|
|
34
|
-
return false;
|
|
35
|
-
} else if (currentServiceName === t('all', 'All')) {
|
|
36
|
-
return true;
|
|
37
|
-
} else {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
29
|
+
return !currentService?.serviceDisplay || !currentService?.serviceUuid;
|
|
40
30
|
});
|
|
41
|
-
const {
|
|
42
|
-
|
|
31
|
+
const { totalCount } = useQueueEntries({
|
|
32
|
+
service: currentService?.serviceUuid,
|
|
43
33
|
location: currentQueueLocation,
|
|
44
34
|
isEnded: false,
|
|
45
35
|
});
|
|
46
36
|
const { activeVisitsCount, isLoading: loading } = useActiveVisits();
|
|
47
|
-
const { waitTime } = useAverageWaitTime(
|
|
37
|
+
const { waitTime } = useAverageWaitTime(currentService?.serviceUuid, '');
|
|
48
38
|
|
|
49
39
|
const handleServiceChange = ({ selectedItem }) => {
|
|
50
|
-
|
|
51
|
-
updateSelectedServiceName(selectedItem.display);
|
|
40
|
+
updateSelectedService(selectedItem.uuid, selectedItem.display);
|
|
52
41
|
if (selectedItem.uuid == undefined) {
|
|
53
42
|
setInitialSelectItem(true);
|
|
54
43
|
} else {
|
|
@@ -70,18 +59,18 @@ function ClinicMetrics() {
|
|
|
70
59
|
label={t('patients', 'Patients')}
|
|
71
60
|
value={initialSelectedItem ? totalCount ?? '--' : serviceCount}
|
|
72
61
|
headerLabel={`${t('waitingFor', 'Waiting for')}:`}
|
|
73
|
-
service={
|
|
74
|
-
serviceUuid={
|
|
62
|
+
service={currentService?.serviceDisplay}
|
|
63
|
+
serviceUuid={currentService?.serviceUuid}
|
|
75
64
|
locationUuid={currentQueueLocation}>
|
|
76
65
|
<Dropdown
|
|
77
66
|
id="inline"
|
|
78
67
|
type="inline"
|
|
79
|
-
|
|
80
|
-
items={[{ display: `${t('all', 'All')}` }, ...queues]}
|
|
68
|
+
items={[{ display: `${t('all', 'All')}` }, ...(services ?? [])]}
|
|
81
69
|
itemToString={(item) =>
|
|
82
70
|
item ? `${item.display} ${item.location?.display ? `- ${item.location.display}` : ''}` : ''
|
|
83
71
|
}
|
|
84
72
|
onChange={handleServiceChange}
|
|
73
|
+
size={isDesktop(layout) ? 'sm' : 'lg'}
|
|
85
74
|
/>
|
|
86
75
|
</MetricsCard>
|
|
87
76
|
<MetricsCard
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import useSWR from 'swr';
|
|
2
|
-
import useSWRImmutable from 'swr/immutable';
|
|
3
2
|
import { openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
|
|
4
3
|
import { type Appointment, type QueueServiceInfo } from '../types';
|
|
5
4
|
import { startOfDay } from '../constants';
|
|
@@ -11,7 +10,7 @@ export function useServiceMetricsCount(service: string, location: string) {
|
|
|
11
10
|
(service ? `&service=${service}` : '') +
|
|
12
11
|
(location ? `&location=${location}` : '');
|
|
13
12
|
|
|
14
|
-
const { data } =
|
|
13
|
+
const { data } = useSWR<
|
|
15
14
|
{
|
|
16
15
|
data: {
|
|
17
16
|
count: number;
|
|
@@ -4,10 +4,10 @@ import { SearchTypes } from '../types';
|
|
|
4
4
|
import PatientScheduledVisits from './patient-scheduled-visits.component';
|
|
5
5
|
import VisitForm from './visit-form/visit-form.component';
|
|
6
6
|
import {
|
|
7
|
-
ArrowLeftIcon,
|
|
8
7
|
type DefaultWorkspaceProps,
|
|
9
|
-
|
|
8
|
+
ArrowLeftIcon,
|
|
10
9
|
ErrorState,
|
|
10
|
+
getPatientName,
|
|
11
11
|
PatientBannerContactDetails,
|
|
12
12
|
PatientBannerPatientInfo,
|
|
13
13
|
PatientBannerToggleContactDetailsButton,
|
|
@@ -76,35 +76,35 @@ const PatientSearch: React.FC<PatientSearchProps> = ({
|
|
|
76
76
|
}
|
|
77
77
|
}, [searchType, handleBackToSearchList]);
|
|
78
78
|
|
|
79
|
-
const patientName = patient &&
|
|
79
|
+
const patientName = patient && getPatientName(patient);
|
|
80
80
|
return patient ? (
|
|
81
|
-
<
|
|
82
|
-
<
|
|
83
|
-
<div className={styles.
|
|
84
|
-
<div className={styles.
|
|
85
|
-
<
|
|
81
|
+
<div className={styles.patientSearchContainer}>
|
|
82
|
+
<AddPatientToQueueContext.Provider value={{ currentServiceQueueUuid }}>
|
|
83
|
+
<div className={styles.patientBannerContainer}>
|
|
84
|
+
<div className={styles.patientBanner}>
|
|
85
|
+
<div className={styles.patientPhoto}>
|
|
86
|
+
<PatientPhoto patientUuid={patient.id} patientName={patientName} />
|
|
87
|
+
</div>
|
|
88
|
+
<PatientBannerPatientInfo patient={patient} />
|
|
89
|
+
<PatientBannerToggleContactDetailsButton
|
|
90
|
+
showContactDetails={showContactDetails}
|
|
91
|
+
toggleContactDetails={() => setContactDetails(!showContactDetails)}
|
|
92
|
+
/>
|
|
86
93
|
</div>
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
{showContactDetails ? (
|
|
95
|
+
<PatientBannerContactDetails patientId={patient.id} deceased={patient.deceasedBoolean} />
|
|
96
|
+
) : null}
|
|
97
|
+
</div>
|
|
98
|
+
<div className={styles.backButton}>
|
|
99
|
+
<Button
|
|
100
|
+
kind="ghost"
|
|
101
|
+
renderIcon={(props) => <ArrowLeftIcon size={24} {...props} />}
|
|
102
|
+
iconDescription={backButtonDescription}
|
|
103
|
+
size="sm"
|
|
104
|
+
onClick={handleBackToAction}>
|
|
105
|
+
<span>{backButtonDescription}</span>
|
|
106
|
+
</Button>
|
|
92
107
|
</div>
|
|
93
|
-
{showContactDetails ? (
|
|
94
|
-
<PatientBannerContactDetails patientId={patient.id} deceased={patient.deceasedBoolean} />
|
|
95
|
-
) : null}
|
|
96
|
-
</div>
|
|
97
|
-
<div className={styles.backButton}>
|
|
98
|
-
<Button
|
|
99
|
-
kind="ghost"
|
|
100
|
-
renderIcon={(props) => <ArrowLeftIcon size={24} {...props} />}
|
|
101
|
-
iconDescription={backButtonDescription}
|
|
102
|
-
size="sm"
|
|
103
|
-
onClick={() => handleBackToAction()}>
|
|
104
|
-
<span>{backButtonDescription}</span>
|
|
105
|
-
</Button>
|
|
106
|
-
</div>
|
|
107
|
-
<div>
|
|
108
108
|
{activeVisit ? (
|
|
109
109
|
<ExistingVisitFormComponent visit={activeVisit} closeWorkspace={closeWorkspace} />
|
|
110
110
|
) : (
|
|
@@ -127,8 +127,8 @@ const PatientSearch: React.FC<PatientSearchProps> = ({
|
|
|
127
127
|
) : null}
|
|
128
128
|
</>
|
|
129
129
|
)}
|
|
130
|
-
</
|
|
131
|
-
</
|
|
130
|
+
</AddPatientToQueueContext.Provider>
|
|
131
|
+
</div>
|
|
132
132
|
) : null;
|
|
133
133
|
};
|
|
134
134
|
|
|
@@ -327,16 +327,16 @@ const VisitForm: React.FC<VisitFormProps> = ({ patientUuid, closeWorkspace }) =>
|
|
|
327
327
|
)}
|
|
328
328
|
|
|
329
329
|
<VisitFormQueueFields setFormFields={setVisitFormFields} />
|
|
330
|
-
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
331
|
-
<Button className={styles.button} kind="secondary" onClick={closeWorkspace}>
|
|
332
|
-
{t('discard', 'Discard')}
|
|
333
|
-
</Button>
|
|
334
|
-
<Button className={styles.button} disabled={isSubmitting} kind="primary" type="submit">
|
|
335
|
-
{t('startVisit', 'Start visit')}
|
|
336
|
-
</Button>
|
|
337
|
-
</ButtonSet>
|
|
338
330
|
</Stack>
|
|
339
331
|
</div>
|
|
332
|
+
<ButtonSet className={isTablet ? styles.tabletButtons : styles.desktopButtons}>
|
|
333
|
+
<Button className={styles.button} kind="secondary" onClick={closeWorkspace}>
|
|
334
|
+
{t('discard', 'Discard')}
|
|
335
|
+
</Button>
|
|
336
|
+
<Button className={styles.button} disabled={isSubmitting} kind="primary" type="submit">
|
|
337
|
+
{t('startVisit', 'Start visit')}
|
|
338
|
+
</Button>
|
|
339
|
+
</ButtonSet>
|
|
340
340
|
</Form>
|
|
341
341
|
);
|
|
342
342
|
};
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
display: flex;
|
|
47
47
|
flex-direction: column;
|
|
48
48
|
justify-content: space-between;
|
|
49
|
-
height:
|
|
49
|
+
height: 100%;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
.button {
|
|
@@ -57,13 +57,15 @@
|
|
|
57
57
|
min-width: 50%;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
.
|
|
60
|
+
.tabletButtons {
|
|
61
61
|
padding: spacing.$spacing-06 spacing.$spacing-05;
|
|
62
|
+
margin-top: spacing.$spacing-10;
|
|
62
63
|
background-color: $ui-02;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
.
|
|
66
|
+
.desktopButtons {
|
|
66
67
|
padding: 0rem;
|
|
68
|
+
margin-top: spacing.$spacing-10;
|
|
67
69
|
}
|
|
68
70
|
|
|
69
71
|
@media screen and (max-width: 600px) {
|
|
@@ -1,15 +1,22 @@
|
|
|
1
|
-
import React, { useContext, useEffect,
|
|
1
|
+
import React, { useContext, useEffect, useState } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
2
3
|
import classNames from 'classnames';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
import {
|
|
5
|
+
InlineNotification,
|
|
6
|
+
RadioButton,
|
|
7
|
+
RadioButtonGroup,
|
|
8
|
+
RadioButtonSkeleton,
|
|
9
|
+
Select,
|
|
10
|
+
SelectItem,
|
|
11
|
+
SelectSkeleton,
|
|
12
|
+
TextInput,
|
|
13
|
+
} from '@carbon/react';
|
|
6
14
|
import { useConfig, ResponsiveWrapper, useSession } from '@openmrs/esm-framework';
|
|
7
|
-
import { useTranslation } from 'react-i18next';
|
|
8
15
|
import { useQueues } from '../../hooks/useQueues';
|
|
16
|
+
import { useQueueLocations } from '../hooks/useQueueLocations';
|
|
9
17
|
import { type ConfigObject } from '../../config-schema';
|
|
10
|
-
import { SelectSkeleton } from '@carbon/react';
|
|
11
|
-
import { RadioButtonSkeleton } from '@carbon/react';
|
|
12
18
|
import { AddPatientToQueueContext } from '../patient-search.workspace';
|
|
19
|
+
import styles from './visit-form-queue-fields.scss';
|
|
13
20
|
|
|
14
21
|
export interface VisitFormQueueFieldsProps {
|
|
15
22
|
setFormFields: (fields: {
|
|
@@ -48,16 +48,6 @@
|
|
|
48
48
|
margin-top: spacing.$spacing-05;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
:
|
|
53
|
-
.form {
|
|
54
|
-
height: calc(100vh - 6rem);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/* Tablet */
|
|
59
|
-
:global(.omrs-breakpoint-lt-desktop) {
|
|
60
|
-
.form {
|
|
61
|
-
height: calc(100vh - 3rem);
|
|
62
|
-
}
|
|
51
|
+
.form {
|
|
52
|
+
height: 100%;
|
|
63
53
|
}
|
|
@@ -28,7 +28,7 @@ const QueueScreen: React.FC<QueueScreenProps> = () => {
|
|
|
28
28
|
|
|
29
29
|
return (
|
|
30
30
|
<div>
|
|
31
|
-
<PatientQueueHeader title={t('queueScreen', 'Queue screen')} />
|
|
31
|
+
<PatientQueueHeader title={t('queueScreen', 'Queue screen')} showLocationDropdown />
|
|
32
32
|
<div className={styles.gridFlow}>
|
|
33
33
|
{rowData.map((row) => (
|
|
34
34
|
<div className={styles.card} key={row.id}>
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
display: flex;
|
|
24
24
|
flex-direction: column;
|
|
25
25
|
justify-content: space-between;
|
|
26
|
-
height:
|
|
26
|
+
height: 100%;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
.grid {
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
/* Tablet */
|
|
52
52
|
:global(.omrs-breakpoint-lt-desktop) {
|
|
53
53
|
.form {
|
|
54
|
-
height:
|
|
54
|
+
height: 100%;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
.buttonSet {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Button, OverflowMenu, OverflowMenuItem } from '@carbon/react';
|
|
3
|
-
import { showModal } from '@openmrs/esm-framework';
|
|
3
|
+
import { isDesktop, showModal, useLayoutType } from '@openmrs/esm-framework';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { type QueueTableColumnFunction, type QueueTableCellComponentProps } from '../../types';
|
|
6
6
|
import styles from './queue-table-action-cell.scss';
|
|
7
7
|
|
|
8
8
|
export function QueueTableActionCell({ queueEntry }: QueueTableCellComponentProps) {
|
|
9
9
|
const { t } = useTranslation();
|
|
10
|
+
const layout = useLayoutType();
|
|
10
11
|
|
|
11
12
|
return (
|
|
12
|
-
<div className={styles.
|
|
13
|
+
<div className={styles.actionsCell}>
|
|
13
14
|
<Button
|
|
14
15
|
kind="ghost"
|
|
15
16
|
aria-label={t('actions', 'Actions')}
|
|
@@ -18,10 +19,11 @@ export function QueueTableActionCell({ queueEntry }: QueueTableCellComponentProp
|
|
|
18
19
|
closeModal: () => dispose(),
|
|
19
20
|
queueEntry,
|
|
20
21
|
});
|
|
21
|
-
}}
|
|
22
|
+
}}
|
|
23
|
+
size={isDesktop(layout) ? 'sm' : 'lg'}>
|
|
22
24
|
{t('transition', 'Transition')}
|
|
23
25
|
</Button>
|
|
24
|
-
<OverflowMenu aria-label="Actions menu" size=
|
|
26
|
+
<OverflowMenu aria-label="Actions menu" size={isDesktop(layout) ? 'sm' : 'lg'} flipped>
|
|
25
27
|
<OverflowMenuItem
|
|
26
28
|
className={styles.menuItem}
|
|
27
29
|
aria-label={t('edit', 'Edit')}
|
|
@@ -13,18 +13,19 @@ import {
|
|
|
13
13
|
import { useTranslation } from 'react-i18next';
|
|
14
14
|
import ClearQueueEntries from '../clear-queue-entries-dialog/clear-queue-entries.component';
|
|
15
15
|
import {
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
updateSelectedQueueStatus,
|
|
17
|
+
updateSelectedService,
|
|
18
18
|
useSelectedQueueLocationUuid,
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
useSelectedQueueStatus,
|
|
20
|
+
useSelectedService,
|
|
21
21
|
} from '../helpers/helpers';
|
|
22
|
-
import { useQueues } from '../hooks/useQueues';
|
|
23
22
|
import { useQueueEntries } from '../hooks/useQueueEntries';
|
|
24
23
|
import QueueTableExpandedRow from './queue-table-expanded-row.component';
|
|
25
24
|
import QueueTable from './queue-table.component';
|
|
26
25
|
import styles from './queue-table.scss';
|
|
27
26
|
import { useColumns } from './cells/columns.resource';
|
|
27
|
+
import useQueueStatuses from '../hooks/useQueueStatuses';
|
|
28
|
+
import useQueueServices from '../hooks/useQueueService';
|
|
28
29
|
|
|
29
30
|
const serviceQueuesPatientSearchWorkspace = 'service-queues-patient-search';
|
|
30
31
|
|
|
@@ -33,12 +34,14 @@ Component with default values / sub-components passed into the more generic Queu
|
|
|
33
34
|
This is used in the main dashboard of the queues app. (Currently behind a feature flag)
|
|
34
35
|
*/
|
|
35
36
|
function DefaultQueueTable() {
|
|
36
|
-
const
|
|
37
|
+
const selectedService = useSelectedService();
|
|
37
38
|
const currentLocationUuid = useSelectedQueueLocationUuid();
|
|
38
|
-
const
|
|
39
|
-
|
|
39
|
+
const selectedQueueStatus = useSelectedQueueStatus();
|
|
40
|
+
const { queueEntries, isLoading, error, isValidating } = useQueueEntries({
|
|
41
|
+
service: selectedService?.serviceUuid,
|
|
40
42
|
location: currentLocationUuid,
|
|
41
43
|
isEnded: false,
|
|
44
|
+
status: selectedQueueStatus?.statusUuid,
|
|
42
45
|
});
|
|
43
46
|
|
|
44
47
|
const { t } = useTranslation();
|
|
@@ -83,10 +86,6 @@ function DefaultQueueTable() {
|
|
|
83
86
|
});
|
|
84
87
|
}, [queueEntries, searchTerm]);
|
|
85
88
|
|
|
86
|
-
if (isLoading && !queueEntries.length) {
|
|
87
|
-
return <DataTableSkeleton role="progressbar" />;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
89
|
return (
|
|
91
90
|
<div className={styles.container}>
|
|
92
91
|
<div className={styles.headerContainer}>
|
|
@@ -113,7 +112,7 @@ function DefaultQueueTable() {
|
|
|
113
112
|
setIsPatientSearchOpen(false);
|
|
114
113
|
launchWorkspace(serviceQueuesPatientSearchWorkspace, {
|
|
115
114
|
selectedPatientUuid,
|
|
116
|
-
currentServiceQueueUuid:
|
|
115
|
+
currentServiceQueueUuid: selectedService?.serviceUuid,
|
|
117
116
|
handleBackToSearchList,
|
|
118
117
|
});
|
|
119
118
|
},
|
|
@@ -121,23 +120,30 @@ function DefaultQueueTable() {
|
|
|
121
120
|
/>
|
|
122
121
|
</div>
|
|
123
122
|
</div>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
123
|
+
{!isLoading ? (
|
|
124
|
+
<div className={styles.paddedQueueTable}>
|
|
125
|
+
<QueueTable
|
|
126
|
+
queueEntries={filteredQueueEntries ?? []}
|
|
127
|
+
isValidating={isValidating}
|
|
128
|
+
queueUuid={null}
|
|
129
|
+
statusUuid={null}
|
|
130
|
+
ExpandedRow={QueueTableExpandedRow}
|
|
131
|
+
tableFilter={[
|
|
132
|
+
<QueueDropdownFilter />,
|
|
133
|
+
<StatusDropdownFilter />,
|
|
134
|
+
<TableToolbarSearch
|
|
135
|
+
className={styles.search}
|
|
136
|
+
onChange={(e) => setSearchTerm(e.target.value)}
|
|
137
|
+
placeholder={t('searchThisList', 'Search this list')}
|
|
138
|
+
size={isDesktop(layout) ? 'sm' : 'lg'}
|
|
139
|
+
/>,
|
|
140
|
+
<ClearQueueEntries queueEntries={filteredQueueEntries} />,
|
|
141
|
+
]}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
) : (
|
|
145
|
+
<DataTableSkeleton role="progressbar" />
|
|
146
|
+
)}
|
|
141
147
|
</div>
|
|
142
148
|
);
|
|
143
149
|
}
|
|
@@ -145,12 +151,10 @@ function DefaultQueueTable() {
|
|
|
145
151
|
function QueueDropdownFilter() {
|
|
146
152
|
const { t } = useTranslation();
|
|
147
153
|
const layout = useLayoutType();
|
|
148
|
-
const
|
|
149
|
-
const
|
|
150
|
-
const currentServiceName = useSelectedServiceName();
|
|
154
|
+
const { services } = useQueueServices();
|
|
155
|
+
const selectedService = useSelectedService();
|
|
151
156
|
const handleServiceChange = ({ selectedItem }) => {
|
|
152
|
-
|
|
153
|
-
updateSelectedServiceName(selectedItem.display);
|
|
157
|
+
updateSelectedService(selectedItem.uuid, selectedItem?.display);
|
|
154
158
|
};
|
|
155
159
|
|
|
156
160
|
return (
|
|
@@ -158,10 +162,37 @@ function QueueDropdownFilter() {
|
|
|
158
162
|
<div className={styles.filterContainer}>
|
|
159
163
|
<Dropdown
|
|
160
164
|
id="serviceFilter"
|
|
161
|
-
titleText={t('
|
|
162
|
-
label={
|
|
165
|
+
titleText={t('filterByService', 'Filter by service :')}
|
|
166
|
+
label={selectedService?.serviceDisplay ?? t('all', 'All')}
|
|
167
|
+
type="inline"
|
|
168
|
+
items={[{ display: `${t('all', 'All')}` }, ...(services ?? [])]}
|
|
169
|
+
itemToString={(item) => (item ? item.display : '')}
|
|
170
|
+
onChange={handleServiceChange}
|
|
171
|
+
size={isDesktop(layout) ? 'sm' : 'lg'}
|
|
172
|
+
/>
|
|
173
|
+
</div>
|
|
174
|
+
</>
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function StatusDropdownFilter() {
|
|
179
|
+
const { t } = useTranslation();
|
|
180
|
+
const layout = useLayoutType();
|
|
181
|
+
const { statuses } = useQueueStatuses();
|
|
182
|
+
const queueStatus = useSelectedQueueStatus();
|
|
183
|
+
const handleServiceChange = ({ selectedItem }) => {
|
|
184
|
+
updateSelectedQueueStatus(selectedItem.uuid, selectedItem?.display);
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<>
|
|
189
|
+
<div className={styles.filterContainer}>
|
|
190
|
+
<Dropdown
|
|
191
|
+
id="statusFilter"
|
|
192
|
+
titleText={t('filterByStatus', 'Filter by status :')}
|
|
193
|
+
label={queueStatus?.statusDisplay ?? t('all', 'All')}
|
|
163
194
|
type="inline"
|
|
164
|
-
items={[{ display: `${t('all', 'All')}` }, ...
|
|
195
|
+
items={[{ display: `${t('all', 'All')}` }, ...(statuses ?? [])]}
|
|
165
196
|
itemToString={(item) => (item ? item.display : '')}
|
|
166
197
|
onChange={handleServiceChange}
|
|
167
198
|
size={isDesktop(layout) ? 'sm' : 'lg'}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { type QueueEntry } from '../../types';
|
|
4
|
-
import QueueEntryActionModal from './queue-entry-actions
|
|
4
|
+
import QueueEntryActionModal from './queue-entry-actions.modal';
|
|
5
5
|
import { updateQueueEntry } from './queue-entry-actions.resource';
|
|
6
6
|
import { useQueues } from '../../hooks/useQueues';
|
|
7
7
|
import { convertTime12to24 } from '../../helpers/time-helpers';
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { type QueueEntry } from '../../types';
|
|
4
4
|
import { updateQueueEntry } from './queue-entry-actions.resource';
|
|
5
|
-
import QueueEntryConfirmActionModal from './queue-entry-confirm-action
|
|
5
|
+
import QueueEntryConfirmActionModal from './queue-entry-confirm-action.modal';
|
|
6
6
|
|
|
7
7
|
interface EndQueueEntryModalProps {
|
|
8
8
|
queueEntry: QueueEntry;
|
|
@@ -3,9 +3,9 @@ import { screen } from '@testing-library/react';
|
|
|
3
3
|
import { mockQueueEntryBrian, mockQueueSurgery, mockStatusInService, mockQueues } from '__mocks__';
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { renderWithSwr } from 'tools';
|
|
6
|
-
import TransitionQueueEntryModal from './transition-queue-entry
|
|
6
|
+
import TransitionQueueEntryModal from './transition-queue-entry.modal';
|
|
7
7
|
import userEvent from '@testing-library/user-event';
|
|
8
|
-
import EditQueueEntryModal from './edit-queue-entry
|
|
8
|
+
import EditQueueEntryModal from './edit-queue-entry.modal';
|
|
9
9
|
|
|
10
10
|
const mockedOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
11
11
|
|
|
@@ -4,9 +4,9 @@ import { mockQueues, mockQueueEntryAlice } from '__mocks__';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { renderWithSwr } from 'tools';
|
|
6
6
|
import userEvent from '@testing-library/user-event';
|
|
7
|
-
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry
|
|
8
|
-
import VoidQueueEntryModal from './void-queue-entry
|
|
9
|
-
import EndQueueEntryModal from './end-queue-entry
|
|
7
|
+
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry.modal';
|
|
8
|
+
import VoidQueueEntryModal from './void-queue-entry.modal';
|
|
9
|
+
import EndQueueEntryModal from './end-queue-entry.modal';
|
|
10
10
|
|
|
11
11
|
const mockedOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
12
12
|
|
|
@@ -4,8 +4,8 @@ import { mockQueues, mockQueueEntryAlice } from '__mocks__';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { renderWithSwr } from 'tools';
|
|
6
6
|
import userEvent from '@testing-library/user-event';
|
|
7
|
-
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry
|
|
8
|
-
import VoidQueueEntryModal from './void-queue-entry
|
|
7
|
+
import UndoTransitionQueueEntryModal from './undo-transition-queue-entry.modal';
|
|
8
|
+
import VoidQueueEntryModal from './void-queue-entry.modal';
|
|
9
9
|
|
|
10
10
|
const mockedOpenmrsFetch = openmrsFetch as jest.Mock;
|
|
11
11
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { type QueueEntry } from '../../types';
|
|
4
|
-
import QueueEntryActionModal from './queue-entry-actions
|
|
4
|
+
import QueueEntryActionModal from './queue-entry-actions.modal';
|
|
5
5
|
import { transitionQueueEntry } from './queue-entry-actions.resource';
|
|
6
6
|
import { convertTime12to24 } from '../../helpers/time-helpers';
|
|
7
7
|
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { useTranslation } from 'react-i18next';
|
|
3
3
|
import { type QueueEntry } from '../../types';
|
|
4
4
|
import { undoTransition } from './queue-entry-actions.resource';
|
|
5
|
-
import QueueEntryConfirmActionModal from './queue-entry-confirm-action
|
|
5
|
+
import QueueEntryConfirmActionModal from './queue-entry-confirm-action.modal';
|
|
6
6
|
|
|
7
7
|
interface UndoTransitionQueueEntryModalProps {
|
|
8
8
|
queueEntry: QueueEntry;
|