@openmrs/esm-laboratory-app 1.0.1-pre.106

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 (157) hide show
  1. package/.editorconfig +12 -0
  2. package/.eslintignore +2 -0
  3. package/.eslintrc +32 -0
  4. package/.husky/pre-commit +4 -0
  5. package/.husky/pre-push +6 -0
  6. package/.prettierignore +14 -0
  7. package/.turbo/turbo-build.log +30 -0
  8. package/.turbo/turbo-lint.log +12 -0
  9. package/.turbo/turbo-typescript.log +0 -0
  10. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +541 -0
  11. package/.yarn/plugins/@yarnpkg/plugin-outdated.cjs +35 -0
  12. package/.yarn/plugins/@yarnpkg/plugin-version.cjs +550 -0
  13. package/.yarn/versions/3d4697b8.yml +0 -0
  14. package/README.md +39 -0
  15. package/__mocks__/react-i18next.js +50 -0
  16. package/assets/logo/logo.png +0 -0
  17. package/assets/logo/moh_logo_without_word.png +0 -0
  18. package/assets/screenshots/labs_enter_results.png +0 -0
  19. package/assets/screenshots/labs_general_dashboard.png +0 -0
  20. package/dist/142.js +1 -0
  21. package/dist/142.js.map +1 -0
  22. package/dist/319.js +1 -0
  23. package/dist/36.js +1 -0
  24. package/dist/36.js.map +1 -0
  25. package/dist/395.js +1 -0
  26. package/dist/395.js.map +1 -0
  27. package/dist/453.js +1 -0
  28. package/dist/453.js.map +1 -0
  29. package/dist/533.js +1 -0
  30. package/dist/533.js.map +1 -0
  31. package/dist/56.js +2 -0
  32. package/dist/56.js.LICENSE.txt +32 -0
  33. package/dist/56.js.map +1 -0
  34. package/dist/572.js +1 -0
  35. package/dist/572.js.map +1 -0
  36. package/dist/574.js +1 -0
  37. package/dist/581.js +1 -0
  38. package/dist/581.js.map +1 -0
  39. package/dist/66.js +1 -0
  40. package/dist/66.js.map +1 -0
  41. package/dist/757.js +1 -0
  42. package/dist/769.js +1 -0
  43. package/dist/769.js.map +1 -0
  44. package/dist/770.js +1 -0
  45. package/dist/770.js.map +1 -0
  46. package/dist/800.js +2 -0
  47. package/dist/800.js.LICENSE.txt +3 -0
  48. package/dist/800.js.map +1 -0
  49. package/dist/809.js +1 -0
  50. package/dist/809.js.map +1 -0
  51. package/dist/889.js +1 -0
  52. package/dist/889.js.map +1 -0
  53. package/dist/894.js +2 -0
  54. package/dist/894.js.LICENSE.txt +48 -0
  55. package/dist/894.js.map +1 -0
  56. package/dist/924.js +1 -0
  57. package/dist/924.js.map +1 -0
  58. package/dist/928.js +1 -0
  59. package/dist/928.js.map +1 -0
  60. package/dist/967b98e46b0984c4.png +0 -0
  61. package/dist/97.js +1 -0
  62. package/dist/97.js.map +1 -0
  63. package/dist/983.js +1 -0
  64. package/dist/983.js.map +1 -0
  65. package/dist/main.js +2 -0
  66. package/dist/main.js.LICENSE.txt +48 -0
  67. package/dist/main.js.map +1 -0
  68. package/dist/openmrs-esm-laboratory-app.js +1 -0
  69. package/dist/openmrs-esm-laboratory-app.js.buildmanifest.json +628 -0
  70. package/dist/openmrs-esm-laboratory-app.js.map +1 -0
  71. package/dist/routes.json +1 -0
  72. package/i18next-parser.config.js +89 -0
  73. package/jest.config.js +16 -0
  74. package/package.json +121 -0
  75. package/src/completed-list/completed-list.component.tsx +242 -0
  76. package/src/completed-list/completed-list.resource.ts +0 -0
  77. package/src/completed-list/completed-list.scss +232 -0
  78. package/src/components/create-dashboard-link.component.tsx +44 -0
  79. package/src/components/overlay/hook.ts +47 -0
  80. package/src/components/overlay/overlay.component.tsx +52 -0
  81. package/src/components/overlay/overlay.scss +93 -0
  82. package/src/config-schema.ts +36 -0
  83. package/src/constants.ts +5 -0
  84. package/src/declarations.d.ts +6 -0
  85. package/src/header/laboratory-header.component.tsx +35 -0
  86. package/src/header/laboratory-header.scss +68 -0
  87. package/src/header/laboratory-illustration.component.tsx +13 -0
  88. package/src/index.ts +92 -0
  89. package/src/laboratory.component.tsx +18 -0
  90. package/src/patient-chart/laboratory-item/view-laboratory-item.component.tsx +39 -0
  91. package/src/patient-chart/laboratory-item/view-laboratory-item.resource.ts +290 -0
  92. package/src/patient-chart/laboratory-item/view-laboratory-item.scss +0 -0
  93. package/src/patient-chart/laboratory-order.component.tsx +453 -0
  94. package/src/patient-chart/laboratory-order.resource.ts +437 -0
  95. package/src/patient-chart/laboratory-order.scss +66 -0
  96. package/src/patient-chart/results-summary/print-results-summary.component.tsx +240 -0
  97. package/src/patient-chart/results-summary/print-results-summary.scss +105 -0
  98. package/src/patient-chart/results-summary/print-results-table.component.tsx +163 -0
  99. package/src/patient-chart/results-summary/results/results.component.tsx +25 -0
  100. package/src/patient-chart/results-summary/results/results.resource.ts +50 -0
  101. package/src/patient-chart/results-summary/results/results.scss +0 -0
  102. package/src/patient-chart/results-summary/results-dialog/edit-results-dialog.component.tsx +46 -0
  103. package/src/patient-chart/results-summary/results-summary.component.tsx +98 -0
  104. package/src/patient-chart/results-summary/results-summary.resource.tsx +185 -0
  105. package/src/patient-chart/results-summary/results-summary.scss +154 -0
  106. package/src/patient-chart/results-summary/send-email-dialog.component.tsx +111 -0
  107. package/src/patient-chart/results-summary/test-children-results.component.tsx +221 -0
  108. package/src/patient-chart/results-summary/test-print-results-table.component.tsx +148 -0
  109. package/src/patient-chart/results-summary/test-results-delete-action-menu.component.tsx +27 -0
  110. package/src/patient-chart/results-summary/test-results-rescend-action-menu.component.tsx +26 -0
  111. package/src/patient-chart/results-summary/test-results-table.component.tsx +153 -0
  112. package/src/patient-chart/results-summary/tests-children-detail.component.tsx +54 -0
  113. package/src/patient-chart/results-summary/views/email.handlebars +13 -0
  114. package/src/queue-list/lab-dialogs/add-to-worklist-dialog.component.tsx +323 -0
  115. package/src/queue-list/lab-dialogs/add-to-worklist-dialog.resource.ts +155 -0
  116. package/src/queue-list/lab-dialogs/add-to-worklist-dialog.scss +20 -0
  117. package/src/queue-list/lab-tests/lab-tests.component.tsx +116 -0
  118. package/src/queue-list/lab-tests/lab-tests.resource.ts +17 -0
  119. package/src/queue-list/lab-tests/lab-tests.scss +12 -0
  120. package/src/queue-list/laboratory-patient-list.component.tsx +277 -0
  121. package/src/queue-list/laboratory-patient-list.resource.ts +86 -0
  122. package/src/queue-list/laboratory-queue.component.tsx +120 -0
  123. package/src/queue-list/laboratory-queue.scss +213 -0
  124. package/src/queue-list/laboratory-tabs.component.tsx +81 -0
  125. package/src/queue-list/pick-lab-request-menu.component.tsx +38 -0
  126. package/src/reject-order/reject-order-dialog.component.tsx +114 -0
  127. package/src/reject-order/reject-order-dialog.resource.ts +14 -0
  128. package/src/reject-order/reject-order-dialog.scss +14 -0
  129. package/src/results/result-form.component.tsx +223 -0
  130. package/src/results/result-form.resource.ts +328 -0
  131. package/src/results/result-form.scss +19 -0
  132. package/src/review-list/dialog/review-item.component.tsx +283 -0
  133. package/src/review-list/dialog/review-item.resource.ts +14 -0
  134. package/src/review-list/dialog/review-item.scss +0 -0
  135. package/src/review-list/review-list.component.tsx +277 -0
  136. package/src/review-list/review-list.resource.ts +0 -0
  137. package/src/review-list/review-list.scss +189 -0
  138. package/src/root.component.tsx +15 -0
  139. package/src/root.scss +50 -0
  140. package/src/routes.json +72 -0
  141. package/src/setup-tests.ts +1 -0
  142. package/src/summary-tiles/laboratory-summary-tiles.component.tsx +53 -0
  143. package/src/summary-tiles/laboratory-summary-tiles.scss +12 -0
  144. package/src/summary-tiles/laboratory-summary.resource.tsx +50 -0
  145. package/src/summary-tiles/summary-tile.component.tsx +48 -0
  146. package/src/summary-tiles/summary-tile.scss +43 -0
  147. package/src/types/index.ts +412 -0
  148. package/src/types/patient-queues.ts +189 -0
  149. package/src/utils/functions.ts +246 -0
  150. package/src/work-list/work-list.component.tsx +310 -0
  151. package/src/work-list/work-list.resource.ts +136 -0
  152. package/src/work-list/work-list.scss +215 -0
  153. package/translations/en.json +16 -0
  154. package/translations/es.json +3 -0
  155. package/translations/fr.json +3 -0
  156. package/tsconfig.json +23 -0
  157. package/webpack.config.js +29 -0
@@ -0,0 +1,277 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
2
+ import {
3
+ DataTable,
4
+ DataTableSkeleton,
5
+ Pagination,
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableContainer,
10
+ TableExpandHeader,
11
+ TableExpandRow,
12
+ TableHead,
13
+ TableHeader,
14
+ TableRow,
15
+ TabPanel,
16
+ TableToolbar,
17
+ TableToolbarContent,
18
+ TableToolbarSearch,
19
+ Layer,
20
+ Tag,
21
+ TableExpandedRow,
22
+ Tile,
23
+ Button,
24
+ DatePicker,
25
+ DatePickerInput,
26
+ } from "@carbon/react";
27
+ import { TrashCan } from "@carbon/react/icons";
28
+
29
+ import { useTranslation } from "react-i18next";
30
+ import {
31
+ age,
32
+ formatDate,
33
+ formatDatetime,
34
+ parseDate,
35
+ showModal,
36
+ usePagination,
37
+ useSession,
38
+ } from "@openmrs/esm-framework";
39
+ import styles from "./laboratory-queue.scss";
40
+ import { getStatusColor } from "../utils/functions";
41
+ import { Result, useGetOrdersWorklist } from "../work-list/work-list.resource";
42
+ import PickLabRequestActionMenu from "./pick-lab-request-menu.component";
43
+
44
+ interface LaboratoryPatientListProps {}
45
+
46
+ interface RejectOrderProps {
47
+ order: Result;
48
+ }
49
+
50
+ const LaboratoryPatientList: React.FC<LaboratoryPatientListProps> = () => {
51
+ const { t } = useTranslation();
52
+
53
+ const [activatedOnOrAfterDate, setActivatedOnOrAfterDate] = useState("");
54
+
55
+ const { workListEntries, isLoading } = useGetOrdersWorklist(
56
+ activatedOnOrAfterDate,
57
+ ""
58
+ );
59
+
60
+ const pageSizes = [10, 20, 30, 40, 50];
61
+ const [currentPageSize, setPageSize] = useState(10);
62
+
63
+ const {
64
+ goTo,
65
+ results: paginatedWorklistQueueEntries,
66
+ currentPage,
67
+ } = usePagination(workListEntries, currentPageSize);
68
+
69
+ const RejectOrder: React.FC<RejectOrderProps> = ({ order }) => {
70
+ const launchRejectOrderModal = useCallback(() => {
71
+ const dispose = showModal("reject-order-dialog", {
72
+ closeModal: () => dispose(),
73
+ order,
74
+ });
75
+ }, [order]);
76
+ return (
77
+ <Button
78
+ kind="ghost"
79
+ onClick={launchRejectOrderModal}
80
+ renderIcon={(props) => <TrashCan size={16} {...props} />}
81
+ />
82
+ );
83
+ };
84
+
85
+ // get picked orders
86
+ let columns = [
87
+ { id: 0, header: t("date", "Date"), key: "date" },
88
+
89
+ { id: 1, header: t("orderNumber", "Order Number"), key: "orderNumber" },
90
+ { id: 2, header: t("patient", "Patient"), key: "patient" },
91
+
92
+ {
93
+ id: 3,
94
+ header: t("accessionNumber", "Accession Number"),
95
+ key: "accessionNumber",
96
+ },
97
+ { id: 4, header: t("test", "Test"), key: "test" },
98
+ { id: 5, header: t("action", "Action"), key: "action" },
99
+ { id: 6, header: t("status", "Status"), key: "status" },
100
+ { id: 8, header: t("orderer", "Orderer"), key: "orderer" },
101
+ { id: 9, header: t("urgency", "Urgency"), key: "urgency" },
102
+ { id: 10, header: t("actions", "Actions"), key: "actions" },
103
+ ];
104
+
105
+ const tableRows = useMemo(() => {
106
+ return paginatedWorklistQueueEntries
107
+ ?.filter((item) => item.action === "NEW")
108
+ .map((entry, index) => ({
109
+ ...entry,
110
+ id: entry.uuid,
111
+ date: {
112
+ content: (
113
+ <>
114
+ <span>{formatDate(parseDate(entry.dateActivated))}</span>
115
+ </>
116
+ ),
117
+ },
118
+ patient: {
119
+ content: (
120
+ <>
121
+ <span>{entry.patient.display.split("-")[1]}</span>
122
+ </>
123
+ ),
124
+ },
125
+ orderNumber: { content: <span>{entry.orderNumber}</span> },
126
+ accessionNumber: { content: <span>{entry.accessionNumber}</span> },
127
+ test: { content: <span>{entry.concept.display}</span> },
128
+ action: { content: <span>{entry.action}</span> },
129
+ status: {
130
+ content: (
131
+ <>
132
+ <Tag>
133
+ <span
134
+ className={styles.statusContainer}
135
+ style={{ color: `${getStatusColor(entry.fulfillerStatus)}` }}
136
+ >
137
+ <span>{entry.fulfillerStatus}</span>
138
+ </span>
139
+ </Tag>
140
+ </>
141
+ ),
142
+ },
143
+ orderer: { content: <span>{entry.orderer.display}</span> },
144
+ urgency: { content: <span>{entry.urgency}</span> },
145
+ actions: {
146
+ content: (
147
+ <>
148
+ <PickLabRequestActionMenu
149
+ order={paginatedWorklistQueueEntries[index]}
150
+ closeModal={() => true}
151
+ />
152
+ <RejectOrder order={paginatedWorklistQueueEntries[index]} />
153
+ </>
154
+ ),
155
+ },
156
+ }));
157
+ }, [paginatedWorklistQueueEntries]);
158
+
159
+ if (isLoading) {
160
+ return <DataTableSkeleton role="progressbar" />;
161
+ }
162
+
163
+ if (paginatedWorklistQueueEntries?.length >= 0) {
164
+ return (
165
+ <div>
166
+ <div className={styles.headerBtnContainer}></div>
167
+ <DataTable rows={tableRows} headers={columns} useZebraStyles>
168
+ {({
169
+ rows,
170
+ headers,
171
+ getHeaderProps,
172
+ getTableProps,
173
+ getRowProps,
174
+ onInputChange,
175
+ }) => (
176
+ <TableContainer className={styles.tableContainer}>
177
+ <TableToolbar
178
+ style={{
179
+ position: "static",
180
+ height: "3rem",
181
+ overflow: "visible",
182
+ backgroundColor: "color",
183
+ }}
184
+ >
185
+ <TableToolbarContent>
186
+ <Layer style={{ margin: "5px" }}>
187
+ <DatePicker dateFormat="Y-m-d" datePickerType="single">
188
+ <DatePickerInput
189
+ labelText={""}
190
+ id="activatedOnOrAfterDate"
191
+ placeholder="YYYY-MM-DD"
192
+ onChange={(event) => {
193
+ setActivatedOnOrAfterDate(event.target.value);
194
+ }}
195
+ type="date"
196
+ value={activatedOnOrAfterDate}
197
+ />
198
+ </DatePicker>
199
+ </Layer>
200
+ <Layer>
201
+ <TableToolbarSearch
202
+ onChange={onInputChange}
203
+ placeholder={t("searchThisList", "Search this list")}
204
+ size="sm"
205
+ />
206
+ </Layer>
207
+ </TableToolbarContent>
208
+ </TableToolbar>
209
+ <Table
210
+ {...getTableProps()}
211
+ className={styles.activePatientsTable}
212
+ >
213
+ <TableHead>
214
+ <TableRow>
215
+ {headers.map((header) => (
216
+ <TableHeader {...getHeaderProps({ header })}>
217
+ {header.header?.content ?? header.header}
218
+ </TableHeader>
219
+ ))}
220
+ </TableRow>
221
+ </TableHead>
222
+ <TableBody>
223
+ {rows.map((row, index) => {
224
+ return (
225
+ <React.Fragment key={row.id}>
226
+ <TableRow {...getRowProps({ row })} key={row.id}>
227
+ {row.cells.map((cell) => (
228
+ <TableCell key={cell.id}>
229
+ {cell.value?.content ?? cell.value}
230
+ </TableCell>
231
+ ))}
232
+ </TableRow>
233
+ </React.Fragment>
234
+ );
235
+ })}
236
+ </TableBody>
237
+ </Table>
238
+ {rows.length === 0 ? (
239
+ <div className={styles.tileContainer}>
240
+ <Tile className={styles.tile}>
241
+ <div className={styles.tileContent}>
242
+ <p className={styles.content}>
243
+ {t(
244
+ "noWorklistsToDisplay",
245
+ "No worklists orders to display"
246
+ )}
247
+ </p>
248
+ </div>
249
+ </Tile>
250
+ </div>
251
+ ) : null}
252
+ <Pagination
253
+ forwardText="Next page"
254
+ backwardText="Previous page"
255
+ page={currentPage}
256
+ pageSize={currentPageSize}
257
+ pageSizes={pageSizes}
258
+ totalItems={workListEntries?.length}
259
+ className={styles.pagination}
260
+ onChange={({ pageSize, page }) => {
261
+ if (pageSize !== currentPageSize) {
262
+ setPageSize(pageSize);
263
+ }
264
+ if (page !== currentPage) {
265
+ goTo(page);
266
+ }
267
+ }}
268
+ />
269
+ </TableContainer>
270
+ )}
271
+ </DataTable>
272
+ </div>
273
+ );
274
+ }
275
+ };
276
+
277
+ export default LaboratoryPatientList;
@@ -0,0 +1,86 @@
1
+ import { PatientQueue, UuidDisplay } from "../types/patient-queues";
2
+ import dayjs from "dayjs";
3
+ import useSWR from "swr";
4
+
5
+ import { formatDate, openmrsFetch, parseDate } from "@openmrs/esm-framework";
6
+
7
+ export interface MappedPatientQueueEntry {
8
+ id: string;
9
+ name: string;
10
+ patientAge: number;
11
+ patientSex: string;
12
+ patientDob: string;
13
+ patientUuid: string;
14
+ priority: string;
15
+ priorityComment: string;
16
+ status: string;
17
+ waitTime: string;
18
+ locationFrom?: string;
19
+ locationToName?: string;
20
+ visitNumber: string;
21
+ identifiers: Array<UuidDisplay>;
22
+ dateCreated: string;
23
+ creatorUuid: string;
24
+ creatorUsername: string;
25
+ creatorDisplay: string;
26
+ }
27
+
28
+ export function usePatientQueuesList(
29
+ currentQueueRoomLocationUuid: string,
30
+ status: string
31
+ ) {
32
+ const apiUrl = `/ws/rest/v1/patientqueue?v=full&room=${currentQueueRoomLocationUuid}&status=${status}`;
33
+ return usePatientQueueRequest(apiUrl);
34
+ }
35
+
36
+ export function usePatientQueueRequest(apiUrl: string) {
37
+ const { data, error, isLoading, isValidating, mutate } = useSWR<
38
+ { data: { results: Array<PatientQueue> } },
39
+ Error
40
+ >(apiUrl, openmrsFetch, { refreshInterval: 3000 });
41
+
42
+ const mappedQueues = data?.data?.results.map((queue: PatientQueue) => {
43
+ return {
44
+ ...queue,
45
+ id: queue.uuid,
46
+ name: queue.patient?.person.display,
47
+ patientUuid: queue.patient?.uuid,
48
+ priorityComment: queue.priorityComment,
49
+ encounter: queue.encounter,
50
+ priority:
51
+ queue.priorityComment === "Urgent" ? "Priority" : queue.priorityComment,
52
+ priorityLevel: queue.priority,
53
+ waitTime: queue.dateCreated
54
+ ? `${dayjs().diff(dayjs(queue.dateCreated), "minutes")}`
55
+ : "--",
56
+ status: queue.status,
57
+ patientAge: queue.patient?.person?.age,
58
+ patientSex: queue.patient?.person?.gender === "M" ? "MALE" : "FEMALE",
59
+ patientDob: queue.patient?.person?.birthdate
60
+ ? formatDate(parseDate(queue.patient.person.birthdate), { time: false })
61
+ : "--",
62
+ identifiers: queue.patient?.identifiers,
63
+ locationFrom: queue.locationFrom?.uuid,
64
+ locationFromName: queue.locationFrom?.name,
65
+ locationTo: queue.locationTo?.uuid,
66
+ locationToName: queue.locationTo?.name,
67
+ queueRoom: queue.locationTo?.display,
68
+ visitNumber: queue.visitNumber,
69
+ dateCreated: queue.dateCreated
70
+ ? formatDate(parseDate(queue.dateCreated), { time: false })
71
+ : "--",
72
+ creatorUuid: queue.creator?.uuid,
73
+ creatorUsername: queue.creator?.username,
74
+ creatorDisplay: queue.creator?.display,
75
+ };
76
+ });
77
+
78
+ return {
79
+ patientQueueEntries: mappedQueues || [],
80
+ patientQueueCount: mappedQueues?.length ?? 0,
81
+ isLoading,
82
+ isError: error,
83
+ isValidating,
84
+ mutate,
85
+ };
86
+ }
@@ -0,0 +1,120 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import { Tab, Tabs, TabList, TabPanels, Search } from "@carbon/react";
3
+ import { useTranslation } from "react-i18next";
4
+ import styles from "./laboratory-queue.scss";
5
+ import LaboratoryPatientList from "./laboratory-patient-list.component";
6
+
7
+ enum TabTypes {
8
+ STARRED,
9
+ SYSTEM,
10
+ USER,
11
+ ALL,
12
+ }
13
+
14
+ const LaboratoryQueueList: React.FC = () => {
15
+ const { t } = useTranslation();
16
+ const [selectedTab, setSelectedTab] = useState(TabTypes.STARRED);
17
+ const [searchTermUserInput, setSearchTermUserInput] = useState("");
18
+ const [searchTerm, setSearchTerm] = useState("");
19
+ const [location, setLocation] = useState("");
20
+
21
+ const tabs = [
22
+ {
23
+ key: "testedOrders",
24
+ header: t("testedOrders", "Tests ordered"),
25
+ },
26
+ {
27
+ key: "worklist",
28
+ header: t("worklist", "Worklist"),
29
+ },
30
+ {
31
+ key: "referredTests",
32
+ header: t("referredTests", "Referred tests"),
33
+ },
34
+ {
35
+ key: "completedTests",
36
+ header: t("completedTests", "Completed tests"),
37
+ },
38
+ {
39
+ key: "reviewList",
40
+ header: t("reviewList", "Review List"),
41
+ },
42
+ {
43
+ key: "approveList",
44
+ header: t("approveList", "Approval List"),
45
+ },
46
+ ];
47
+
48
+ useEffect(() => {
49
+ const debounceFn = setTimeout(() => {
50
+ setSearchTerm(searchTermUserInput);
51
+ }, 500);
52
+
53
+ return () => clearTimeout(debounceFn);
54
+ }, [searchTermUserInput]);
55
+
56
+ return (
57
+ <main className={`omrs-main-content`}>
58
+ <section className={styles.orderTabsContainer}>
59
+ <Tabs
60
+ className={styles.orderTabs}
61
+ type="container"
62
+ tabContentClassName={styles.hiddenTabsContent}
63
+ onSelectionChange={setSelectedTab}
64
+ >
65
+ <TabList
66
+ aria-label={t("tabList", "Tab List")}
67
+ contained
68
+ className={styles.tabsContainer}
69
+ >
70
+ {tabs.map((tab, index) => {
71
+ return (
72
+ <Tab
73
+ title={t(tab.key)}
74
+ key={index}
75
+ id={"tab-" + index}
76
+ className={styles.tab}
77
+ >
78
+ {t(tab.header)}
79
+ </Tab>
80
+ );
81
+ })}
82
+ </TabList>
83
+ <div className={styles.searchContainer}>
84
+ <Search
85
+ closeButtonLabelText={t("clearSearchInput", "Clear search input")}
86
+ defaultValue={searchTermUserInput}
87
+ placeholder={t(
88
+ "searchByPatientIdOrName",
89
+ "Search by patient ID or name"
90
+ )}
91
+ labelText={t(
92
+ "searchByPatientIdOrName",
93
+ "Search by patient ID or name"
94
+ )}
95
+ onChange={(e) => {
96
+ e.preventDefault();
97
+ setSearchTermUserInput(e.target.value);
98
+ }}
99
+ size="md"
100
+ className={styles.patientSearch}
101
+ />
102
+ </div>
103
+ {/* <TabPanels>
104
+ {tabs.map((tab, index) => {
105
+ return (
106
+ <LaboratoryPatientList
107
+ location={location}
108
+ searchTerm={searchTerm}
109
+ status={tab.status}
110
+ />
111
+ );
112
+ })}
113
+ </TabPanels> */}
114
+ </Tabs>
115
+ </section>
116
+ </main>
117
+ );
118
+ };
119
+
120
+ export default LaboratoryQueueList;
@@ -0,0 +1,213 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+ @import "~@openmrs/esm-styleguide/src/vars";
4
+ @import '../root.scss';
5
+
6
+ title {
7
+ width: 6.938rem;
8
+ height: 1.75rem;
9
+ margin: 0.438rem 22.875rem 0.813rem 0;
10
+ font-family: IBMPlexSans;
11
+ font-size: 1.25rem;
12
+ font-weight: normal;
13
+ font-stretch: normal;
14
+ font-style: normal;
15
+ line-height: 1.4;
16
+ letter-spacing: normal;
17
+ }
18
+
19
+ .link {
20
+ text-decoration: none;
21
+ }
22
+
23
+ .breadcrumbsSlot {
24
+ grid-row: 1 / 2;
25
+ grid-column: 1 / 2;
26
+ }
27
+
28
+ .orderTabsContainer {
29
+ height: 100%;
30
+ width: 100%;
31
+
32
+ :global(.cds--tab-content) {
33
+ padding: 0 !important;
34
+ }
35
+ }
36
+
37
+ .orderTabs {
38
+ grid-column: 'span 2';
39
+ padding: 0 spacing.$spacing-05;
40
+ }
41
+
42
+ .newListButton {
43
+ width: fit-content;
44
+ justify-self: end;
45
+ align-self: center;
46
+ }
47
+
48
+ .tabsContainer {
49
+ background-color: $ui-02;
50
+
51
+ :global(.cds--tabs__nav-item--selected) {
52
+ box-shadow: inset 0 2px 0 0 var(--brand-03) !important;
53
+ }
54
+
55
+ :global(.cds--tab--list) button {
56
+ max-width: 12rem !important;
57
+ }
58
+ }
59
+
60
+ .hiddenTabsContent,
61
+ .tabs .hiddenTabsContent {
62
+ display: none;
63
+ }
64
+
65
+ .patientListTableContainer {
66
+ grid-row: 3 / 4;
67
+ grid-column: 1 / 2;
68
+ height: 100%;
69
+ margin: 0.5rem spacing.$spacing-05;
70
+ background-color: $ui-01;
71
+ border: 0.5px solid #e0e0e0;
72
+
73
+ :global(.cds--data-table-container) {
74
+ padding-top: 0 !important;
75
+ }
76
+
77
+ tbody>tr>:nth-child(2) {
78
+ white-space: nowrap;
79
+ }
80
+
81
+ :global(.cds--data-table td) {
82
+ height: unset !important;
83
+ }
84
+
85
+ :global(.cds--data-table--zebra) tbody tr[data-parent-row]:nth-child(4n + 1) td {
86
+ background-color: $ui-02;
87
+ border-bottom: 1px solid $ui-03;
88
+ border-top: 1px solid $ui-03;
89
+ }
90
+
91
+ :global(.cds--data-table--zebra) tbody tr[data-parent-row]:nth-child(4n + 3) td {
92
+ background-color: $ui-01;
93
+ border-bottom: 1px solid $ui-03;
94
+ }
95
+ }
96
+
97
+ .tableContainer {
98
+ background-color: $ui-01;
99
+ margin: 0 spacing.$spacing-05;
100
+ padding: 0;
101
+
102
+ a {
103
+ text-decoration: none;
104
+ }
105
+
106
+ th {
107
+ color: $text-02;
108
+ }
109
+
110
+ :global(.cds--data-table) {
111
+ background-color: $ui-03;
112
+ }
113
+
114
+ .toolbarContent {
115
+ height: spacing.$spacing-07;
116
+ margin-bottom: spacing.$spacing-02;
117
+ }
118
+ }
119
+
120
+ .activePatientsTable tr:last-of-type {
121
+ td {
122
+ border-bottom: none;
123
+ }
124
+ }
125
+ .headerBtnContainer {
126
+ background-color: $ui-background;
127
+ padding: spacing.$spacing-05;
128
+ text-align: right;
129
+ }
130
+
131
+ .searchContainer {
132
+ display: flex;
133
+ align-items: center;
134
+ flex-direction: row-reverse;
135
+ padding-top: 0.5rem;
136
+
137
+ :global(.cds--search-magnifier-icon) {
138
+ z-index: 0 !important;
139
+ }
140
+
141
+ input {
142
+ background-color: #fff;
143
+ }
144
+ }
145
+
146
+ .addOrderBtn {
147
+ width: 10rem !important;
148
+ padding: 0.5rem !important;
149
+ margin-left: 1rem;
150
+ margin-right: 1rem;
151
+ }
152
+
153
+ .patientSearch {
154
+ width: 25rem;
155
+ border-bottom-color: $ui-03;
156
+ }
157
+
158
+ .locationFilter {
159
+ width: 25rem;
160
+ }
161
+
162
+ .search {
163
+ width: 100%;
164
+ max-width: 16rem;
165
+ background-color: $ui-02;
166
+ border-bottom-color: $ui-03;
167
+ }
168
+
169
+ .container {
170
+ background-color: $ui-01;
171
+ }
172
+
173
+ .expandedLabQueueVisitRow {
174
+ :global(.cds--tab-content) {
175
+ padding: 0.5rem 0;
176
+ }
177
+
178
+ td {
179
+ padding: 0.5rem;
180
+
181
+ > div {
182
+ max-height: max-content !important;
183
+ background-color: $ui-02;
184
+ }
185
+ }
186
+
187
+ th[colspan] td[colspan] > div:first-child {
188
+ padding: 0 1rem;
189
+ }
190
+ }
191
+
192
+ .tileContainer {
193
+ background-color: $ui-02;
194
+ border-top: 1px solid $ui-03;
195
+ padding: 5rem 0;
196
+ }
197
+
198
+ .tile {
199
+ margin: auto;
200
+ width: fit-content;
201
+ }
202
+
203
+ .tileContent {
204
+ display: flex;
205
+ flex-direction: column;
206
+ align-items: center;
207
+ }
208
+
209
+ .content {
210
+ @include type.type-style('heading-compact-02');
211
+ color: $text-02;
212
+ margin-bottom: 0.5rem;
213
+ }