@ampath/esm-dha-workflow-app 4.0.0-next.17 → 4.0.0-next.19

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.
Files changed (61) hide show
  1. package/dist/104.js +1 -1
  2. package/dist/104.js.map +1 -1
  3. package/dist/15.js +1 -1
  4. package/dist/15.js.map +1 -1
  5. package/dist/321.js +1 -0
  6. package/dist/321.js.map +1 -0
  7. package/dist/339.js +1 -1
  8. package/dist/339.js.map +1 -1
  9. package/dist/468.js +2 -0
  10. package/dist/468.js.map +1 -0
  11. package/dist/602.js +1 -0
  12. package/dist/602.js.map +1 -0
  13. package/dist/635.js +1 -0
  14. package/dist/635.js.map +1 -0
  15. package/dist/710.js +1 -1
  16. package/dist/733.js +1 -0
  17. package/dist/733.js.map +1 -0
  18. package/dist/{454.js → 844.js} +1 -1
  19. package/dist/844.js.map +1 -0
  20. package/dist/91.js +1 -1
  21. package/dist/91.js.map +1 -1
  22. package/dist/93.js +1 -1
  23. package/dist/esm-dha-workflow-app.js +1 -1
  24. package/dist/esm-dha-workflow-app.js.buildmanifest.json +104 -79
  25. package/dist/main.js +1 -1
  26. package/dist/main.js.map +1 -1
  27. package/dist/routes.json +1 -1
  28. package/package.json +1 -1
  29. package/src/appointments/appointments.component.tsx +13 -0
  30. package/src/laboratory/laboratory.component.tsx +13 -0
  31. package/src/pharmacy/pharmacy.component.tsx +13 -0
  32. package/src/registry/types/index.ts +20 -0
  33. package/src/root.component.tsx +9 -2
  34. package/src/service-queues/consultation/consultation.component.scss +7 -0
  35. package/src/service-queues/consultation/consultation.component.tsx +15 -0
  36. package/src/service-queues/modals/move/move-patient.component.scss +35 -0
  37. package/src/service-queues/modals/move/move-patient.component.tsx +138 -0
  38. package/src/service-queues/modals/serve/serve-patient.comppnent.scss +0 -0
  39. package/src/service-queues/modals/serve/serve-patient.comppnent.tsx +82 -0
  40. package/src/service-queues/modals/transition/transition-patient.component.scss +0 -0
  41. package/src/service-queues/modals/transition/transition-patient.component.tsx +122 -0
  42. package/src/service-queues/queue-list/queue-list.component.scss +19 -0
  43. package/src/service-queues/queue-list/queue-list.component.tsx +117 -0
  44. package/src/service-queues/service-queue/service-queue.component.scss +7 -0
  45. package/src/service-queues/service-queue/service-queue.component.tsx +165 -0
  46. package/src/service-queues/service-queues.resource.ts +73 -20
  47. package/src/service-queues/service.resource.ts +28 -0
  48. package/src/shared/constants/concepts.ts +8 -0
  49. package/src/shared/constants/index.ts +1 -0
  50. package/src/triage/triage.component.tsx +3 -26
  51. package/src/types/types.ts +17 -2
  52. package/dist/178.js +0 -1
  53. package/dist/178.js.map +0 -1
  54. package/dist/306.js +0 -1
  55. package/dist/306.js.map +0 -1
  56. package/dist/454.js.map +0 -1
  57. package/dist/827.js +0 -1
  58. package/dist/827.js.map +0 -1
  59. package/dist/875.js +0 -2
  60. package/dist/875.js.map +0 -1
  61. /package/dist/{875.js.LICENSE.txt → 468.js.LICENSE.txt} +0 -0
@@ -0,0 +1,35 @@
1
+ .modelLayout{
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ padding: 15px 15px;
6
+ }
7
+ .formSection{
8
+ display: flex;
9
+ flex-direction: column;
10
+ width: 100%;
11
+ row-gap: 5px;
12
+ }
13
+ .sectionHeader{
14
+ display: flex;
15
+ flex-direction: column;
16
+ width: 100%;
17
+ row-gap: 5px;
18
+ }
19
+ .formRow{
20
+ display: flex;
21
+ flex-direction: row;
22
+ width: 100%;
23
+ column-gap: 5px;
24
+ }
25
+ .formControl{
26
+ display: flex;
27
+ flex-direction: column;
28
+ width: 45%;
29
+ }
30
+ .actionSection{
31
+ display: flex;
32
+ flex-direction: row;
33
+ width: 100%;
34
+ column-gap: 5px;
35
+ }
@@ -0,0 +1,138 @@
1
+ import { Button, Modal, ModalBody, Select, SelectItem, TextArea } from '@carbon/react';
2
+ import React, { useEffect, useState } from 'react';
3
+ import styles from './move-patient.component.scss';
4
+ import { type ServiceQueue } from '../../../registry/types';
5
+ import { getServiceQueueByLocation, transitionQueueEntry } from '../../service.resource';
6
+ import { type TransitionQueueEntryDto } from '../../../types/types';
7
+ import { QUEUE_PRIORITIES_UUIDS, QUEUE_STATUS_UUIDS } from '../../../shared/constants/concepts';
8
+ import { showSnackbar } from '@openmrs/esm-framework';
9
+ interface MovePatientModalProps {
10
+ open: boolean;
11
+ onModalClose: () => void;
12
+ locationUuid: string;
13
+ serviceUuid: string;
14
+ currentQueueEntryUuid: string;
15
+ }
16
+ const MovePatientModal: React.FC<MovePatientModalProps> = ({
17
+ open,
18
+ onModalClose,
19
+ locationUuid,
20
+ serviceUuid,
21
+ currentQueueEntryUuid,
22
+ }) => {
23
+ const [serviceQueues, setServiceQueues] = useState<ServiceQueue[]>([]);
24
+ const [selectedComment, setSelectedComment] = useState<string>();
25
+ const [selectedPriority, setSelectedPriority] = useState<string>();
26
+ const [selectedNewService, setSelectedNewService] = useState<ServiceQueue>();
27
+ useEffect(() => {
28
+ getQueues();
29
+ }, [locationUuid]);
30
+ const serviceChangeHandler = (serviceQueueUuid: string) => {
31
+ const serviceQueue = serviceQueues.find((sq) => {
32
+ return sq.uuid === serviceQueueUuid;
33
+ });
34
+ setSelectedNewService(serviceQueue);
35
+ };
36
+ const getQueues = async () => {
37
+ const res = await getServiceQueueByLocation(locationUuid);
38
+ setServiceQueues(res);
39
+ };
40
+ const transtionQueueEntry = async () => {
41
+ const payload = getTransitionQueueEntryPayload();
42
+ try {
43
+ const resp = await transitionQueueEntry(payload);
44
+ showAlert('success', 'Cleint succesfully moved', '');
45
+ onModalClose();
46
+ } catch (e) {
47
+ showAlert('error', e.message, '');
48
+ }
49
+ };
50
+
51
+ const showAlert = (alertType: 'error' | 'success', title: string, subtitle: string) => {
52
+ showSnackbar({
53
+ kind: alertType,
54
+ title: title,
55
+ subtitle: subtitle,
56
+ });
57
+ };
58
+ const getTransitionQueueEntryPayload = (): TransitionQueueEntryDto => {
59
+ const payload: TransitionQueueEntryDto = {
60
+ queueEntryToTransition: currentQueueEntryUuid,
61
+ newQueue: selectedNewService.uuid,
62
+ newStatus: QUEUE_STATUS_UUIDS.WAITING_UUID,
63
+ newPriority: selectedPriority,
64
+ newPriorityComment: selectedComment,
65
+ };
66
+
67
+ return payload;
68
+ };
69
+ const priorityChangeHandler = (priorityUuid: string) => {
70
+ setSelectedPriority(priorityUuid);
71
+ };
72
+ const handleCommentChange = (comment: string) => {};
73
+ return (
74
+ <>
75
+ <Modal
76
+ open={open}
77
+ size="md"
78
+ onSecondarySubmit={() => onModalClose()}
79
+ onRequestClose={() => onModalClose()}
80
+ onRequestSubmit={transtionQueueEntry}
81
+ primaryButtonText="Move"
82
+ secondaryButtonText="Cancel"
83
+ >
84
+ <ModalBody>
85
+ <div className={styles.modelLayout}>
86
+ <div className={styles.sectionHeader}>
87
+ <h4>Move Client</h4>
88
+ </div>
89
+ <div className={styles.formSection}>
90
+ <div className={styles.formRow}>
91
+ <div className={styles.formControl}>
92
+ <Select
93
+ id="service-queue"
94
+ labelText="Select the new Queue"
95
+ onChange={(e) => serviceChangeHandler(e.target.value)}
96
+ >
97
+ <SelectItem value="" text="" />;
98
+ {serviceQueues &&
99
+ serviceQueues.map((vt) => {
100
+ return <SelectItem value={vt.uuid} text={vt.name} />;
101
+ })}
102
+ </Select>
103
+ </div>
104
+ <div className={styles.formControl}>
105
+ <Select
106
+ id="priority"
107
+ labelText="Select a Priority"
108
+ onChange={(e) => priorityChangeHandler(e.target.value)}
109
+ >
110
+ <SelectItem value="" text="Select" />;
111
+ <SelectItem value={QUEUE_PRIORITIES_UUIDS.NORMAL_PRIORITY_UUID} text="NORMAL" />;
112
+ <SelectItem value={QUEUE_PRIORITIES_UUIDS.EMERGENCY_PRIORITY_UUID} text="EMERGENCY" />;
113
+ </Select>
114
+ </div>
115
+ </div>
116
+ <div className={styles.formRow}>
117
+ <div className={styles.formControl}>
118
+ <TextArea
119
+ enableCounter
120
+ helperText="Comment"
121
+ id="comment"
122
+ labelText="Comment"
123
+ maxCount={500}
124
+ placeholder="Comment"
125
+ onChange={(e) => handleCommentChange(e.target.value)}
126
+ rows={4}
127
+ />
128
+ </div>
129
+ </div>
130
+ </div>
131
+ </div>
132
+ </ModalBody>
133
+ </Modal>
134
+ </>
135
+ );
136
+ };
137
+
138
+ export default MovePatientModal;
@@ -0,0 +1,82 @@
1
+ import React from 'react';
2
+ import { Modal, ModalBody } from '@carbon/react';
3
+ import { type QueueEntryResult } from '../../../registry/types';
4
+ import styles from './serve-patient.comppnent.scss';
5
+ import { type TransitionQueueEntryDto } from '../../../types/types';
6
+ import { QUEUE_STATUS_UUIDS } from '../../../shared/constants/concepts';
7
+ import { transitionQueueEntry } from '../../service.resource';
8
+ import { showSnackbar } from '@openmrs/esm-framework';
9
+
10
+ interface ServePatientModal {
11
+ open: boolean;
12
+ onModalClose: () => void;
13
+ currentQueueEntry: QueueEntryResult;
14
+ onSuccessfullServe: () => void;
15
+ }
16
+
17
+ const ServePatientModal: React.FC<ServePatientModal> = ({
18
+ open,
19
+ onModalClose,
20
+ currentQueueEntry,
21
+ onSuccessfullServe,
22
+ }) => {
23
+ const servePatient = async () => {
24
+ const payload = getServePatientPayload();
25
+ try {
26
+ await transitionQueueEntry(payload);
27
+ showAlert('success', 'Cleint succesfully served', '');
28
+ onSuccessfullServe();
29
+ } catch (e) {
30
+ showAlert('error', e.message, '');
31
+ }
32
+ };
33
+ const showAlert = (alertType: 'error' | 'success', title: string, subtitle: string) => {
34
+ showSnackbar({
35
+ kind: alertType,
36
+ title: title,
37
+ subtitle: subtitle,
38
+ });
39
+ };
40
+ const getServePatientPayload = (): TransitionQueueEntryDto => {
41
+ const payload: TransitionQueueEntryDto = {
42
+ queueEntryToTransition: currentQueueEntry.queue_entry_uuid,
43
+ newQueue: currentQueueEntry.service_uuid,
44
+ newStatus: QUEUE_STATUS_UUIDS.IN_SERVICE_UUID,
45
+ };
46
+
47
+ return payload;
48
+ };
49
+ return (
50
+ <>
51
+ <Modal
52
+ open={open}
53
+ size="md"
54
+ onSecondarySubmit={() => onModalClose()}
55
+ onRequestClose={() => onModalClose()}
56
+ onRequestSubmit={servePatient}
57
+ primaryButtonText="Serve"
58
+ secondaryButtonText="Cancel"
59
+ >
60
+ <ModalBody>
61
+ <div className={styles.serveModalLayout}>
62
+ <div className={styles.serveModalSectionHeader}>
63
+ <h4>Serve Client</h4>
64
+ </div>
65
+ <div className={styles.serveModalContentSection}>
66
+ <div className={styles.formRow}>
67
+ <p>
68
+ Name: {currentQueueEntry.family_name} {currentQueueEntry.family_name}
69
+ </p>
70
+ <p>Ticket No: {currentQueueEntry.queue_entry_id}</p>
71
+ <p>Status: {currentQueueEntry.status}</p>
72
+ <p>Priority: {currentQueueEntry.priority}</p>
73
+ </div>
74
+ </div>
75
+ </div>
76
+ </ModalBody>
77
+ </Modal>
78
+ </>
79
+ );
80
+ };
81
+
82
+ export default ServePatientModal;
@@ -0,0 +1,122 @@
1
+ import React, { useState } from 'react';
2
+ import { Modal, ModalBody, Select, SelectItem, TextArea } from '@carbon/react';
3
+ import styles from './transition-patient.component.scss';
4
+ import { type QueueEntryResult } from '../../../registry/types';
5
+ import { transitionQueueEntry } from '../../service.resource';
6
+ import { type TransitionQueueEntryDto } from '../../../types/types';
7
+ import { QUEUE_PRIORITIES_UUIDS, QUEUE_STATUS_UUIDS } from '../../../shared/constants/concepts';
8
+ import { showSnackbar } from '@openmrs/esm-framework';
9
+ interface TransitionPatientModalProps {
10
+ open: boolean;
11
+ onModalClose: () => void;
12
+ currentQueueEntry: QueueEntryResult;
13
+ }
14
+ const TransitionPatientModal: React.FC<TransitionPatientModalProps> = ({ open, onModalClose, currentQueueEntry }) => {
15
+ const [selectedComment, setSelectedComment] = useState<string>();
16
+ const [selectedPriority, setSelectedPriority] = useState<string>();
17
+ const [selectedStatus, setSelectedStatus] = useState<string>();
18
+
19
+ const statusChangeHandler = (statusUuid: string) => {
20
+ setSelectedStatus(statusUuid);
21
+ };
22
+
23
+ const transtionQueueEntry = async () => {
24
+ const payload = getTransitionQueueEntryPayload();
25
+ try {
26
+ await transitionQueueEntry(payload);
27
+ showAlert('success', 'Cleint succesfully Transitioned', '');
28
+ onModalClose();
29
+ } catch (e) {
30
+ showAlert('error', e.message, '');
31
+ }
32
+ };
33
+
34
+ const showAlert = (alertType: 'error' | 'success', title: string, subtitle: string) => {
35
+ showSnackbar({
36
+ kind: alertType,
37
+ title: title,
38
+ subtitle: subtitle,
39
+ });
40
+ };
41
+ const getTransitionQueueEntryPayload = (): TransitionQueueEntryDto => {
42
+ const payload: TransitionQueueEntryDto = {
43
+ queueEntryToTransition: currentQueueEntry.queue_entry_uuid,
44
+ newQueue: currentQueueEntry.service_uuid,
45
+ newStatus: selectedStatus,
46
+ newPriority: selectedPriority,
47
+ newPriorityComment: selectedComment,
48
+ };
49
+
50
+ return payload;
51
+ };
52
+ const priorityChangeHandler = (priorityUuid: string) => {
53
+ setSelectedPriority(priorityUuid);
54
+ };
55
+ const handleCommentChange = (comment: string) => {
56
+ setSelectedComment(comment);
57
+ };
58
+ return (
59
+ <>
60
+ <Modal
61
+ open={open}
62
+ size="md"
63
+ onSecondarySubmit={() => onModalClose()}
64
+ onRequestClose={() => onModalClose()}
65
+ onRequestSubmit={transtionQueueEntry}
66
+ primaryButtonText="Transition"
67
+ secondaryButtonText="Cancel"
68
+ >
69
+ <ModalBody>
70
+ <div className={styles.modelLayout}>
71
+ <div className={styles.sectionHeader}>
72
+ <h4>Move Client</h4>
73
+ </div>
74
+ <div className={styles.formSection}>
75
+ <div className={styles.formRow}>
76
+ <div className={styles.formControl}>
77
+ <Select
78
+ id="queue-status"
79
+ labelText="Select Queue Status"
80
+ onChange={(e) => statusChangeHandler(e.target.value)}
81
+ >
82
+ <SelectItem value="" text="" />;
83
+ <SelectItem value={QUEUE_STATUS_UUIDS.WAITING_UUID} text="IN WAITING" />;
84
+ <SelectItem value={QUEUE_STATUS_UUIDS.IN_SERVICE_UUID} text="IN SERVICE" />;
85
+ <SelectItem value={QUEUE_STATUS_UUIDS.COMPLETED_UUID} text="COMPLETED" />;
86
+ </Select>
87
+ </div>
88
+ <div className={styles.formControl}>
89
+ <Select
90
+ id="priority"
91
+ labelText="Select a Priority"
92
+ onChange={(e) => priorityChangeHandler(e.target.value)}
93
+ >
94
+ <SelectItem value="" text="Select" />;
95
+ <SelectItem value={QUEUE_PRIORITIES_UUIDS.NORMAL_PRIORITY_UUID} text="NORMAL" />;
96
+ <SelectItem value={QUEUE_PRIORITIES_UUIDS.EMERGENCY_PRIORITY_UUID} text="EMERGENCY" />;
97
+ </Select>
98
+ </div>
99
+ </div>
100
+ <div className={styles.formRow}>
101
+ <div className={styles.formControl}>
102
+ <TextArea
103
+ enableCounter
104
+ helperText="Comment"
105
+ id="comment"
106
+ labelText="Comment"
107
+ maxCount={500}
108
+ placeholder="Comment"
109
+ onChange={(e) => handleCommentChange(e.target.value)}
110
+ rows={4}
111
+ />
112
+ </div>
113
+ </div>
114
+ </div>
115
+ </div>
116
+ </ModalBody>
117
+ </Modal>
118
+ </>
119
+ );
120
+ };
121
+
122
+ export default TransitionPatientModal;
@@ -0,0 +1,19 @@
1
+ .queueListLayout{
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ row-gap: 15px;
6
+ padding: 5px 5px;
7
+ }
8
+ .actionHeader{
9
+ display: flex;
10
+ flex-direction: row;
11
+ justify-content: flex-end;
12
+ width: 100%;
13
+ }
14
+ .tableSection{
15
+ display: flex;
16
+ flex-direction: column;
17
+ width: 100%;
18
+ row-gap: 10px;
19
+ }
@@ -0,0 +1,117 @@
1
+ import {
2
+ Button,
3
+ Link,
4
+ OverflowMenu,
5
+ OverflowMenuItem,
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableHead,
10
+ TableHeader,
11
+ TableRow,
12
+ } from '@carbon/react';
13
+ import { type QueueEntryResult } from '../../registry/types';
14
+ import React, { useState } from 'react';
15
+ import styles from './queue-list.component.scss';
16
+
17
+ interface QueueListProps {
18
+ queueEntries: QueueEntryResult[];
19
+ handleMovePatient: (queueEntryResult: QueueEntryResult) => void;
20
+ handleTransitionPatient: (queueEntryResult: QueueEntryResult) => void;
21
+ handleServePatient: (queueEntryResult: QueueEntryResult) => void;
22
+ }
23
+
24
+ const QueueList: React.FC<QueueListProps> = ({
25
+ queueEntries,
26
+ handleMovePatient,
27
+ handleTransitionPatient,
28
+ handleServePatient,
29
+ }) => {
30
+ const [checkIn, setCheckIn] = useState<boolean>(false);
31
+ const handleCheckin = () => {
32
+ setCheckIn((prev) => !prev);
33
+ };
34
+ return (
35
+ <>
36
+ <div className={styles.queueListLayout}>
37
+ <div className={styles.actionHeader}>
38
+ {checkIn ? (
39
+ <>
40
+ <Button kind="danger" onClick={handleCheckin}>
41
+ {' '}
42
+ Check Out
43
+ </Button>
44
+ </>
45
+ ) : (
46
+ <>
47
+ <Button kind="primary" onClick={handleCheckin}>
48
+ {' '}
49
+ Check In
50
+ </Button>
51
+ </>
52
+ )}
53
+ </div>
54
+ <div className={styles.tableSection}>
55
+ <Table>
56
+ <TableHead>
57
+ <TableRow>
58
+ <TableHeader>No</TableHeader>
59
+ <TableHeader>Name</TableHeader>
60
+ <TableHeader>Ticket</TableHeader>
61
+ <TableHeader>Status</TableHeader>
62
+ <TableHeader>Priority</TableHeader>
63
+ <TableHeader>Action</TableHeader>
64
+ </TableRow>
65
+ </TableHead>
66
+ <TableBody>
67
+ {queueEntries.map((val, index) => (
68
+ <TableRow>
69
+ <TableCell>{index + 1}</TableCell>
70
+ <TableCell>
71
+ {checkIn ? (
72
+ <Link href={`${window.spaBase}/patient/${val.patient_uuid}/chart/`}>
73
+ {val.family_name} {val.middle_name}
74
+ </Link>
75
+ ) : (
76
+ <>
77
+ {val.family_name} {val.middle_name}
78
+ </>
79
+ )}
80
+ </TableCell>
81
+ <TableCell>{val.queue_entry_id}</TableCell>
82
+ <TableCell>{val.status}</TableCell>
83
+ <TableCell>{val.priority}</TableCell>
84
+ <TableCell>
85
+ {val.status === 'WAITING' ? (
86
+ <>
87
+ <Button kind="ghost" disabled={!checkIn} onClick={() => handleServePatient(val)}>
88
+ Serve
89
+ </Button>
90
+ </>
91
+ ) : (
92
+ <>
93
+ {checkIn ? (
94
+ <>
95
+ <OverflowMenu aria-label="overflow-menu">
96
+ <OverflowMenuItem itemText="Move" onClick={() => handleMovePatient(val)} />
97
+ <OverflowMenuItem itemText="Transition" onClick={() => handleTransitionPatient(val)} />
98
+ <OverflowMenuItem itemText="Remove Patient" />
99
+ </OverflowMenu>
100
+ </>
101
+ ) : (
102
+ <></>
103
+ )}
104
+ </>
105
+ )}
106
+ </TableCell>
107
+ </TableRow>
108
+ ))}
109
+ </TableBody>
110
+ </Table>
111
+ </div>
112
+ </div>
113
+ </>
114
+ );
115
+ };
116
+
117
+ export default QueueList;
@@ -0,0 +1,7 @@
1
+ .consultationLayout{
2
+ display: flex;
3
+ flex-direction: column;
4
+ width: 100%;
5
+ padding: 15px 15px;
6
+ row-gap: 15px;
7
+ }
@@ -0,0 +1,165 @@
1
+ import React, { useEffect, useMemo, useState } from 'react';
2
+ import { type QueueEntryResult } from '../../registry/types';
3
+ import { useSession } from '@openmrs/esm-framework';
4
+ import { getServiceQueueByLocationUuid } from '../service-queues.resource';
5
+ import { Tab, TabList, TabPanel, TabPanels, Tabs } from '@carbon/react';
6
+ import QueueList from '../queue-list/queue-list.component';
7
+ import styles from './service-queue.component.scss';
8
+ import MovePatientModal from '../modals/move/move-patient.component';
9
+ import TransitionPatientModal from '../modals/transition/transition-patient.component';
10
+ import ServePatientModal from '../modals/serve/serve-patient.comppnent';
11
+
12
+ interface ServiceQueueComponentProps {
13
+ serviceTypeUuid: string;
14
+ title: string;
15
+ }
16
+
17
+ const ServiceQueueComponent: React.FC<ServiceQueueComponentProps> = ({ serviceTypeUuid, title }) => {
18
+ const [queueEntries, setQueueEntries] = useState<QueueEntryResult[]>([]);
19
+ const [selectedQueueEntry, setSelectedQueueEntry] = useState<QueueEntryResult>();
20
+ const [displayMoveModal, setDisplayMoveModal] = useState<boolean>();
21
+ const [displayTransitionModal, setDisplayTransitionModal] = useState<boolean>();
22
+ const [displayServeModal, setDisplayServeModal] = useState<boolean>();
23
+ const session = useSession();
24
+ const locationUuid = session.sessionLocation.uuid;
25
+
26
+ const groupEntriesByRooms = () => {
27
+ const roomEntries = {};
28
+ if (!queueEntries || queueEntries.length === 0) return {};
29
+ queueEntries.forEach((qe) => {
30
+ const room = qe.queue_room;
31
+ if (!roomEntries[room]) {
32
+ roomEntries[room] = [qe];
33
+ } else {
34
+ roomEntries[room].push(qe);
35
+ }
36
+ });
37
+ return roomEntries;
38
+ };
39
+
40
+ const groupedByRoom: { [key: string]: QueueEntryResult[] } = useMemo(() => groupEntriesByRooms(), [queueEntries]);
41
+
42
+ useEffect(() => {
43
+ getEntryQueues();
44
+ }, []);
45
+
46
+ const getEntryQueues = async () => {
47
+ const res = await getServiceQueueByLocationUuid(serviceTypeUuid, locationUuid);
48
+ setQueueEntries(res);
49
+ };
50
+
51
+ if (!groupedByRoom) {
52
+ return <>No Data to Display</>;
53
+ }
54
+ const handleMovePatient = (queueEntry: QueueEntryResult) => {
55
+ setDisplayMoveModal(true);
56
+ setSelectedQueueEntry(queueEntry);
57
+ };
58
+ const handleModalCloes = () => {
59
+ setDisplayMoveModal(false);
60
+ setDisplayTransitionModal(false);
61
+ setDisplayServeModal(false);
62
+ };
63
+
64
+ const handleTransitionPatient = (queueEntry: QueueEntryResult) => {
65
+ setDisplayTransitionModal(true);
66
+ setSelectedQueueEntry(queueEntry);
67
+ };
68
+
69
+ const handleServePatient = (queueEntry: QueueEntryResult) => {
70
+ setDisplayServeModal(true);
71
+ setSelectedQueueEntry(queueEntry);
72
+ };
73
+
74
+ const navigateToPatientChart = () => {
75
+ if (selectedQueueEntry && selectedQueueEntry.patient_uuid) {
76
+ window.location.href = `${window.spaBase}/patient/${selectedQueueEntry.patient_uuid}/chart`;
77
+ }
78
+ };
79
+
80
+ const handleSuccessfullServe = () => {
81
+ handleModalCloes();
82
+ navigateToPatientChart();
83
+ };
84
+
85
+ if (!serviceTypeUuid) {
86
+ return <>No service type defined</>;
87
+ }
88
+
89
+ return (
90
+ <>
91
+ <div className={styles.consultationLayout}>
92
+ <div className={styles.headerSection}>
93
+ <h4>{title}</h4>
94
+ </div>
95
+ <div className={styles.contentSection}>
96
+ <Tabs>
97
+ <TabList contained>
98
+ {groupedByRoom &&
99
+ Object.keys(groupedByRoom).map((key) => {
100
+ return <Tab>{key}</Tab>;
101
+ })}
102
+ </TabList>
103
+ <TabPanels>
104
+ {groupedByRoom &&
105
+ Object.keys(groupedByRoom).map((key) => {
106
+ return (
107
+ <TabPanel>
108
+ {
109
+ <QueueList
110
+ queueEntries={groupedByRoom[key]}
111
+ handleMovePatient={handleMovePatient}
112
+ handleTransitionPatient={handleTransitionPatient}
113
+ handleServePatient={handleServePatient}
114
+ />
115
+ }
116
+ </TabPanel>
117
+ );
118
+ })}
119
+ </TabPanels>
120
+ </Tabs>
121
+ </div>
122
+ </div>
123
+ {displayMoveModal && selectedQueueEntry ? (
124
+ <>
125
+ <MovePatientModal
126
+ open={displayMoveModal}
127
+ locationUuid={locationUuid}
128
+ serviceUuid={serviceTypeUuid}
129
+ onModalClose={handleModalCloes}
130
+ currentQueueEntryUuid={selectedQueueEntry.queue_entry_uuid}
131
+ />
132
+ </>
133
+ ) : (
134
+ <></>
135
+ )}
136
+
137
+ {displayTransitionModal ? (
138
+ <>
139
+ <TransitionPatientModal
140
+ open={displayTransitionModal}
141
+ onModalClose={handleModalCloes}
142
+ currentQueueEntry={selectedQueueEntry}
143
+ />
144
+ </>
145
+ ) : (
146
+ <></>
147
+ )}
148
+
149
+ {displayServeModal ? (
150
+ <>
151
+ <ServePatientModal
152
+ open={displayServeModal}
153
+ onModalClose={handleModalCloes}
154
+ currentQueueEntry={selectedQueueEntry}
155
+ onSuccessfullServe={handleSuccessfullServe}
156
+ />
157
+ </>
158
+ ) : (
159
+ <></>
160
+ )}
161
+ </>
162
+ );
163
+ };
164
+
165
+ export default ServiceQueueComponent;