@openmrs/esm-laboratory-app 1.2.1-pre.734 → 1.2.1-pre.740
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/cache/8773ecc69845448d-meta.json +1 -0
- package/.turbo/cache/8773ecc69845448d.tar.zst +0 -0
- package/.turbo/turbo-build.log +2 -2
- package/dist/1120.js +1 -1
- package/dist/1120.js.map +1 -1
- package/dist/1788.js +1 -1
- package/dist/1788.js.map +1 -1
- package/dist/3656.js +1 -1
- package/dist/3656.js.map +1 -1
- package/dist/4069.js +1 -1
- package/dist/4069.js.map +1 -1
- package/dist/4300.js +1 -1
- package/dist/5085.js +1 -1
- package/dist/5085.js.map +1 -1
- package/dist/6134.js +1 -1
- package/dist/6134.js.map +1 -1
- package/dist/7423.js +1 -1
- package/dist/7423.js.map +1 -1
- package/dist/8554.js +1 -1
- package/dist/8554.js.map +1 -1
- package/dist/8667.js +1 -1
- package/dist/8667.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-laboratory-app.js.buildmanifest.json +33 -33
- package/dist/routes.json +1 -1
- package/package.json +1 -1
- package/src/components/orders-table/list-order-details.component.tsx +31 -24
- package/src/components/orders-table/list-order-details.scss +0 -1
- package/src/components/orders-table/orders-data-table.component.tsx +143 -56
- package/src/components/orders-table/orders-data-table.test.tsx +215 -0
- package/src/config-schema.ts +20 -1
- package/src/lab-tabs/data-table-extensions/tests-ordered-table.extension.tsx +1 -1
- package/src/lab-tiles/all-lab-requests-tile.component.tsx +1 -1
- package/src/lab-tiles/completed-lab-requests-tile.component.tsx +1 -1
- package/src/lab-tiles/in-progress-lab-requests-tile.component.tsx +1 -1
- package/src/laboratory-resource.ts +24 -33
- package/src/types.ts +20 -17
- package/translations/en.json +2 -2
- package/.turbo/cache/8b374b02de72bb4b-meta.json +0 -1
- package/.turbo/cache/8b374b02de72bb4b.tar.zst +0 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen, within } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import OrdersDataTable from './orders-data-table.component';
|
|
5
|
+
import { useConfig, getDefaultsFromConfigSchema, type Patient, Person } from '@openmrs/esm-framework';
|
|
6
|
+
import { configSchema, type Config } from '../../config-schema';
|
|
7
|
+
import { useLabOrders, type UseLabOrdersParams } from '../../laboratory-resource';
|
|
8
|
+
import { type Order } from '@openmrs/esm-patient-common-lib';
|
|
9
|
+
|
|
10
|
+
jest.mock('../../laboratory-resource', () => ({
|
|
11
|
+
useLabOrders: jest.fn(),
|
|
12
|
+
}));
|
|
13
|
+
|
|
14
|
+
const mockUseConfig = jest.mocked(useConfig<Config>);
|
|
15
|
+
const mockUseLabOrders = jest.mocked(useLabOrders);
|
|
16
|
+
|
|
17
|
+
function mockUseLabOrdersImplementation(props: Partial<UseLabOrdersParams>) {
|
|
18
|
+
const mockPatient1: Partial<Patient> = {
|
|
19
|
+
uuid: 'patient-uuid-1',
|
|
20
|
+
display: 'PAT-001 - Pete Seeger',
|
|
21
|
+
identifiers: props.includePatientId
|
|
22
|
+
? [
|
|
23
|
+
{
|
|
24
|
+
uuid: 'identifier-uuid-1',
|
|
25
|
+
identifier: 'PAT-001',
|
|
26
|
+
preferred: true,
|
|
27
|
+
voided: false,
|
|
28
|
+
identifierType: {
|
|
29
|
+
uuid: 'identifier-type-uuid-1',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
uuid: 'identifier-uuid-2',
|
|
34
|
+
identifier: 'BAD-ID-NOT-PREFERRED',
|
|
35
|
+
preferred: false,
|
|
36
|
+
voided: false,
|
|
37
|
+
identifierType: {
|
|
38
|
+
uuid: 'identifier-type-uuid-1',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
]
|
|
42
|
+
: undefined,
|
|
43
|
+
person: {
|
|
44
|
+
uuid: 'person-uuid-1',
|
|
45
|
+
display: 'Pete Seeger',
|
|
46
|
+
age: 70,
|
|
47
|
+
gender: 'M',
|
|
48
|
+
},
|
|
49
|
+
};
|
|
50
|
+
const mockPatient2: Partial<Patient> = {
|
|
51
|
+
uuid: 'patient-uuid-2',
|
|
52
|
+
display: 'PAT-002 - Bob Dylan',
|
|
53
|
+
identifiers: props.includePatientId
|
|
54
|
+
? [
|
|
55
|
+
{
|
|
56
|
+
uuid: 'identifier-uuid-3',
|
|
57
|
+
identifier: 'BAD-ID-WRONG-TYPE',
|
|
58
|
+
preferred: true,
|
|
59
|
+
voided: false,
|
|
60
|
+
identifierType: {
|
|
61
|
+
uuid: '05a29f94-c0ed-11e2-94be-8c13b969e334',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
uuid: 'identifier-uuid-4',
|
|
66
|
+
identifier: 'PAT-002',
|
|
67
|
+
preferred: true,
|
|
68
|
+
voided: false,
|
|
69
|
+
identifierType: {
|
|
70
|
+
uuid: 'identifier-type-uuid-1',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
]
|
|
74
|
+
: undefined,
|
|
75
|
+
person: {
|
|
76
|
+
uuid: 'person-uuid-2',
|
|
77
|
+
display: 'Bob Dylan',
|
|
78
|
+
age: 60,
|
|
79
|
+
gender: 'M',
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const mockOrderer = {
|
|
84
|
+
uuid: 'orderer-uuid-1',
|
|
85
|
+
display: 'Dr. John Doe',
|
|
86
|
+
person: {
|
|
87
|
+
display: 'Dr. John Doe',
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const labOrders = [
|
|
92
|
+
{
|
|
93
|
+
uuid: 'order-uuid-1',
|
|
94
|
+
orderNumber: 'ORD-001',
|
|
95
|
+
patient: mockPatient1 as Patient,
|
|
96
|
+
dateActivated: '2021-01-01',
|
|
97
|
+
fulfillerStatus: 'RECEIVED',
|
|
98
|
+
urgency: 'ROUTINE',
|
|
99
|
+
orderer: mockOrderer,
|
|
100
|
+
instructions: 'Inspect banjo & check tuning',
|
|
101
|
+
fulfillerComment: null,
|
|
102
|
+
display: 'Banjo Inspection',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
uuid: 'order-uuid-2',
|
|
106
|
+
orderNumber: 'ORD-002',
|
|
107
|
+
patient: mockPatient1 as Patient,
|
|
108
|
+
dateActivated: '2021-01-01',
|
|
109
|
+
fulfillerStatus: 'RECEIVED',
|
|
110
|
+
urgency: 'ROUTINE',
|
|
111
|
+
orderer: mockOrderer,
|
|
112
|
+
instructions: 'Give it a strum',
|
|
113
|
+
fulfillerComment: null,
|
|
114
|
+
display: 'Guitar Inspection',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
uuid: 'order-uuid-3',
|
|
118
|
+
orderNumber: 'ORD-003',
|
|
119
|
+
patient: mockPatient2 as Patient,
|
|
120
|
+
dateActivated: '2021-01-01',
|
|
121
|
+
fulfillerStatus: 'RECEIVED',
|
|
122
|
+
urgency: 'EMERGENCY',
|
|
123
|
+
orderer: mockOrderer,
|
|
124
|
+
instructions: 'Make some noise',
|
|
125
|
+
fulfillerComment: null,
|
|
126
|
+
display: 'Sound Check',
|
|
127
|
+
},
|
|
128
|
+
]
|
|
129
|
+
.filter((order) => !props.status || order.fulfillerStatus === props.status)
|
|
130
|
+
.filter((order) => !props.excludeCanceled || order.fulfillerStatus !== 'CANCELLED') as Array<Order>;
|
|
131
|
+
return {
|
|
132
|
+
labOrders,
|
|
133
|
+
isLoading: false,
|
|
134
|
+
isError: false,
|
|
135
|
+
mutate: jest.fn(),
|
|
136
|
+
isValidating: false,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
describe('OrdersDataTable', () => {
|
|
141
|
+
beforeEach(() => {
|
|
142
|
+
mockUseLabOrders.mockImplementation(mockUseLabOrdersImplementation);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should render one row per patient and show lab details', async () => {
|
|
146
|
+
mockUseConfig.mockReturnValue({
|
|
147
|
+
...getDefaultsFromConfigSchema(configSchema),
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
render(<OrdersDataTable />);
|
|
151
|
+
const table = screen.getByRole('table');
|
|
152
|
+
expect(table).toBeInTheDocument();
|
|
153
|
+
const rows = screen.getAllByRole('row');
|
|
154
|
+
expect(rows).toHaveLength(5);
|
|
155
|
+
const dataRows = rows.slice(1).filter((row) => !row.classList.contains('hiddenRow'));
|
|
156
|
+
expect(dataRows).toHaveLength(2);
|
|
157
|
+
const headerRow = rows[0];
|
|
158
|
+
expect(headerRow).toHaveTextContent('Patient');
|
|
159
|
+
expect(headerRow).toHaveTextContent('Age');
|
|
160
|
+
expect(headerRow).toHaveTextContent('Sex');
|
|
161
|
+
expect(headerRow).toHaveTextContent('Total Orders');
|
|
162
|
+
const row1 = dataRows[0];
|
|
163
|
+
expect(row1).toHaveTextContent('Pete Seeger');
|
|
164
|
+
expect(row1).toHaveTextContent('70');
|
|
165
|
+
expect(row1).toHaveTextContent('M');
|
|
166
|
+
expect(row1).toHaveTextContent('2');
|
|
167
|
+
const row2 = dataRows[1];
|
|
168
|
+
expect(row2).toHaveTextContent('Bob Dylan');
|
|
169
|
+
expect(row2).toHaveTextContent('60');
|
|
170
|
+
expect(row2).toHaveTextContent('M');
|
|
171
|
+
expect(row2).toHaveTextContent('1');
|
|
172
|
+
|
|
173
|
+
const user = userEvent.setup();
|
|
174
|
+
await user.click(within(row1).getByLabelText('Expand current row'));
|
|
175
|
+
|
|
176
|
+
const orderDetailsTables = within(table).getAllByRole('table');
|
|
177
|
+
expect(orderDetailsTables).toHaveLength(2);
|
|
178
|
+
const orderDetailsTable1 = orderDetailsTables[0];
|
|
179
|
+
const orderDetailsTable2 = orderDetailsTables[1];
|
|
180
|
+
expect(orderDetailsTable1).toHaveTextContent('Banjo Inspection');
|
|
181
|
+
expect(orderDetailsTable1).toHaveTextContent('Inspect banjo & check tuning');
|
|
182
|
+
expect(orderDetailsTable1).toHaveTextContent('Dr. John Doe');
|
|
183
|
+
expect(orderDetailsTable1).toHaveTextContent('01-Jan-2021');
|
|
184
|
+
expect(orderDetailsTable1).toHaveTextContent('Received');
|
|
185
|
+
expect(orderDetailsTable1).toHaveTextContent('Routine');
|
|
186
|
+
expect(orderDetailsTable2).toHaveTextContent('Guitar Inspection');
|
|
187
|
+
expect(orderDetailsTable2).toHaveTextContent('Give it a strum');
|
|
188
|
+
expect(orderDetailsTable2).toHaveTextContent('Dr. John Doe');
|
|
189
|
+
expect(orderDetailsTable2).toHaveTextContent('01-Jan-2021');
|
|
190
|
+
expect(orderDetailsTable2).toHaveTextContent('Received');
|
|
191
|
+
expect(orderDetailsTable2).toHaveTextContent('Routine');
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should show patient identifier if it is configured', () => {
|
|
195
|
+
mockUseConfig.mockReturnValue({
|
|
196
|
+
...getDefaultsFromConfigSchema(configSchema),
|
|
197
|
+
labTableColumns: ['patientId', 'age', 'totalOrders'],
|
|
198
|
+
patientIdIdentifierTypeUuid: 'identifier-type-uuid-1',
|
|
199
|
+
});
|
|
200
|
+
render(<OrdersDataTable />);
|
|
201
|
+
const rows = screen.getAllByRole('row');
|
|
202
|
+
expect(rows).toHaveLength(5);
|
|
203
|
+
const dataRows = rows.slice(1).filter((row) => !row.classList.contains('hiddenRow'));
|
|
204
|
+
expect(dataRows).toHaveLength(2);
|
|
205
|
+
const row1 = dataRows[0];
|
|
206
|
+
expect(row1).toHaveTextContent('PAT-001');
|
|
207
|
+
expect(row1).toHaveTextContent('70');
|
|
208
|
+
expect(row1).toHaveTextContent('2');
|
|
209
|
+
const row2 = dataRows[1];
|
|
210
|
+
expect(row2).toHaveTextContent('PAT-002');
|
|
211
|
+
expect(row2).toHaveTextContent('60');
|
|
212
|
+
expect(row2).toHaveTextContent('1');
|
|
213
|
+
expect(screen.queryByText(/BAD-ID/)).not.toBeInTheDocument();
|
|
214
|
+
});
|
|
215
|
+
});
|
package/src/config-schema.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import { Type } from '@openmrs/esm-framework';
|
|
1
|
+
import { Type, validators } from '@openmrs/esm-framework';
|
|
2
|
+
|
|
3
|
+
const allowedLabTableColumns = ['name', 'age', 'sex', 'totalOrders', 'action', 'patientId'] as const;
|
|
4
|
+
type LabTableColumnName = (typeof allowedLabTableColumns)[number];
|
|
2
5
|
|
|
3
6
|
export const configSchema = {
|
|
4
7
|
laboratoryOrderTypeUuid: {
|
|
@@ -24,6 +27,20 @@ export const configSchema = {
|
|
|
24
27
|
},
|
|
25
28
|
_description: 'The patient chart dashboard to navigate to from the lab app.',
|
|
26
29
|
},
|
|
30
|
+
labTableColumns: {
|
|
31
|
+
_type: Type.Array,
|
|
32
|
+
_default: ['name', 'age', 'sex', 'totalOrders', 'action'] as Array<LabTableColumnName>,
|
|
33
|
+
_description: 'The columns to display in the lab table. Allowed values: ' + allowedLabTableColumns.join(', '),
|
|
34
|
+
_elements: {
|
|
35
|
+
_type: Type.String,
|
|
36
|
+
_validators: [validators.oneOf(allowedLabTableColumns)],
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
patientIdIdentifierTypeUuid: {
|
|
40
|
+
_type: Type.UUID,
|
|
41
|
+
_default: '05a29f94-c0ed-11e2-94be-8c13b969e334',
|
|
42
|
+
_description: 'Needed if the "id" column of "labTableColumns" is used. Is the OpenMRS ID by default.',
|
|
43
|
+
},
|
|
27
44
|
};
|
|
28
45
|
|
|
29
46
|
export type Config = {
|
|
@@ -33,4 +50,6 @@ export type Config = {
|
|
|
33
50
|
redirectToResultsViewer: string;
|
|
34
51
|
redirectToOrders: string;
|
|
35
52
|
};
|
|
53
|
+
labTableColumns: Array<LabTableColumnName>;
|
|
54
|
+
patientIdIdentifierTypeUuid: string;
|
|
36
55
|
};
|
|
@@ -6,7 +6,7 @@ const TestsOrderedTable: React.FC = () => {
|
|
|
6
6
|
<OrdersDataTable
|
|
7
7
|
excludeColumns={[]}
|
|
8
8
|
actionsSlotName="tests-ordered-actions-slot"
|
|
9
|
-
|
|
9
|
+
newOrdersOnly={true}
|
|
10
10
|
actions={[
|
|
11
11
|
{ actionName: 'pickupLabRequest', order: 0 },
|
|
12
12
|
{ actionName: 'rejectLabRequest', order: 1 },
|
|
@@ -6,7 +6,7 @@ import LabSummaryTile from '../components/summary-tile/lab-summary-tile.componen
|
|
|
6
6
|
const AllLabRequestsTile = () => {
|
|
7
7
|
const { t } = useTranslation();
|
|
8
8
|
|
|
9
|
-
const { labOrders } = useLabOrders(
|
|
9
|
+
const { labOrders } = useLabOrders({ newOrdersOnly: true });
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
12
|
<LabSummaryTile
|
|
@@ -5,7 +5,7 @@ import LabSummaryTile from '../components/summary-tile/lab-summary-tile.componen
|
|
|
5
5
|
|
|
6
6
|
const CompletedLabRequestsTile = () => {
|
|
7
7
|
const { t } = useTranslation();
|
|
8
|
-
const { labOrders } = useLabOrders('COMPLETED', false);
|
|
8
|
+
const { labOrders } = useLabOrders({ status: 'COMPLETED', excludeCanceled: false });
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<LabSummaryTile
|
|
@@ -5,7 +5,7 @@ import LabSummaryTile from '../components/summary-tile/lab-summary-tile.componen
|
|
|
5
5
|
|
|
6
6
|
const InProgressLabRequestsTile = () => {
|
|
7
7
|
const { t } = useTranslation();
|
|
8
|
-
const { labOrders } = useLabOrders('IN_PROGRESS');
|
|
8
|
+
const { labOrders } = useLabOrders({ status: 'IN_PROGRESS' });
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<LabSummaryTile
|
|
@@ -1,9 +1,22 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
1
|
import dayjs from 'dayjs';
|
|
3
2
|
import useSWR from 'swr';
|
|
4
3
|
import { openmrsFetch, restBaseUrl, useAppContext, useConfig } from '@openmrs/esm-framework';
|
|
5
|
-
import { type Order } from '@openmrs/esm-patient-common-lib';
|
|
6
|
-
import type { DateFilterContext
|
|
4
|
+
import { type Order, type FulfillerStatus } from '@openmrs/esm-patient-common-lib';
|
|
5
|
+
import type { DateFilterContext } from './types';
|
|
6
|
+
|
|
7
|
+
const useLabOrdersDefaultParams: UseLabOrdersParams = {
|
|
8
|
+
status: null,
|
|
9
|
+
newOrdersOnly: false,
|
|
10
|
+
excludeCanceled: true,
|
|
11
|
+
includePatientId: false,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface UseLabOrdersParams {
|
|
15
|
+
status: FulfillerStatus;
|
|
16
|
+
newOrdersOnly: boolean;
|
|
17
|
+
excludeCanceled: boolean;
|
|
18
|
+
includePatientId: boolean;
|
|
19
|
+
}
|
|
7
20
|
|
|
8
21
|
/**
|
|
9
22
|
* Custom hook for retrieving laboratory orders based on the specified status.
|
|
@@ -11,18 +24,18 @@ import type { DateFilterContext, FulfillerStatus, GroupedOrders } from './types'
|
|
|
11
24
|
* @param status - The status of the orders to retrieve
|
|
12
25
|
* @param excludeCanceled - Whether to exclude canceled, discontinued and expired orders
|
|
13
26
|
*/
|
|
14
|
-
export function useLabOrders(
|
|
27
|
+
export function useLabOrders(params: Partial<UseLabOrdersParams> = useLabOrdersDefaultParams) {
|
|
28
|
+
const { status, newOrdersOnly, excludeCanceled, includePatientId } = { ...useLabOrdersDefaultParams, ...params };
|
|
15
29
|
const { dateRange } = useAppContext<DateFilterContext>('laboratory-date-filter') ?? {
|
|
16
30
|
dateRange: [dayjs().startOf('day').toDate(), new Date()],
|
|
17
31
|
};
|
|
18
32
|
|
|
19
33
|
const { laboratoryOrderTypeUuid } = useConfig();
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'custom:(uuid,orderNumber,patient:(uuid,display,person:(uuid,display,age,gender)),concept:(uuid,display),action,careSetting:(uuid,display,description,careSettingType,display),previousOrder,dateActivated,scheduledDate,dateStopped,autoExpireDate,encounter:(uuid,display),orderer:(uuid,display),orderReason,orderReasonNonCoded,orderType:(uuid,display,name,description,conceptClasses,parent),urgency,instructions,commentToFulfiller,display,fulfillerStatus,fulfillerComment,specimenSource,laterality,clinicalHistory,frequency,numberOfRepeats)';
|
|
34
|
+
const customRepresentation = `custom:(uuid,orderNumber,patient:(uuid,display,person:(uuid,display,age,gender)${
|
|
35
|
+
includePatientId ? ',identifiers' : ''
|
|
36
|
+
}),concept:(uuid,display),action,careSetting:(uuid,display,description,careSettingType,display),previousOrder,dateActivated,scheduledDate,dateStopped,autoExpireDate,encounter:(uuid,display),orderer:(uuid,display),orderReason,orderReasonNonCoded,orderType:(uuid,display,name,description,conceptClasses,parent),urgency,instructions,commentToFulfiller,display,fulfillerStatus,fulfillerComment,specimenSource,laterality,clinicalHistory,frequency,numberOfRepeats)`;
|
|
24
37
|
let url = `${restBaseUrl}/order?orderTypes=${laboratoryOrderTypeUuid}&v=${customRepresentation}`;
|
|
25
|
-
url =
|
|
38
|
+
url = status ? url + `&fulfillerStatus=${status}` : url;
|
|
26
39
|
url = excludeCanceled ? `${url}&excludeCanceledAndExpired=true&excludeDiscontinueOrders=true` : url;
|
|
27
40
|
// The usage of SWR's mutator seems to only suffice for cases where we don't apply a status filter
|
|
28
41
|
url = dateRange
|
|
@@ -36,11 +49,9 @@ export function useLabOrders(status: 'NEW' | FulfillerStatus = null, excludeCanc
|
|
|
36
49
|
}>(`${url}`, openmrsFetch);
|
|
37
50
|
|
|
38
51
|
const filteredOrders =
|
|
39
|
-
data?.data &&
|
|
40
|
-
newOrdersOnly &&
|
|
41
|
-
data.data.results.filter((order) => order?.action === 'NEW' && order?.fulfillerStatus === null);
|
|
52
|
+
data?.data?.results?.filter((order) => !newOrdersOnly || (order?.action === 'NEW' && order?.fulfillerStatus === null));
|
|
42
53
|
return {
|
|
43
|
-
labOrders: filteredOrders
|
|
54
|
+
labOrders: filteredOrders ?? [],
|
|
44
55
|
isLoading,
|
|
45
56
|
isError: error,
|
|
46
57
|
mutate,
|
|
@@ -48,26 +59,6 @@ export function useLabOrders(status: 'NEW' | FulfillerStatus = null, excludeCanc
|
|
|
48
59
|
};
|
|
49
60
|
}
|
|
50
61
|
|
|
51
|
-
export function useSearchGroupedResults(data: Array<GroupedOrders>, searchString: string) {
|
|
52
|
-
const searchResults = useMemo(() => {
|
|
53
|
-
if (searchString && searchString.trim() !== '') {
|
|
54
|
-
// Normalize the search string to lowercase
|
|
55
|
-
const lowerSearchString = searchString.toLowerCase();
|
|
56
|
-
return data.filter((orderGroup) =>
|
|
57
|
-
orderGroup.orders.some(
|
|
58
|
-
(order) =>
|
|
59
|
-
order.orderNumber.toLowerCase().includes(lowerSearchString) ||
|
|
60
|
-
order.patient.display.toLowerCase().includes(lowerSearchString),
|
|
61
|
-
),
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return data;
|
|
66
|
-
}, [searchString, data]);
|
|
67
|
-
|
|
68
|
-
return searchResults;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
62
|
export function setFulfillerStatus(orderId: string, status: FulfillerStatus, abortController: AbortController) {
|
|
72
63
|
return openmrsFetch(`${restBaseUrl}/order/${orderId}/fulfillerdetails/`, {
|
|
73
64
|
method: 'POST',
|
package/src/types.ts
CHANGED
|
@@ -1,15 +1,27 @@
|
|
|
1
|
-
import { type Order } from '@openmrs/esm-patient-common-lib';
|
|
1
|
+
import { type Order, type FulfillerStatus, type OrderUrgency } from '@openmrs/esm-patient-common-lib';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export interface FlattenedOrder {
|
|
4
|
+
id: string;
|
|
5
|
+
patientUuid: string;
|
|
6
|
+
orderNumber: string;
|
|
7
|
+
display: string;
|
|
8
|
+
dateActivated: string;
|
|
9
|
+
fulfillerStatus: FulfillerStatus;
|
|
10
|
+
urgency: OrderUrgency;
|
|
11
|
+
orderer: string;
|
|
12
|
+
instructions: string;
|
|
13
|
+
fulfillerComment: string;
|
|
14
|
+
}
|
|
4
15
|
|
|
5
16
|
export interface GroupedOrders {
|
|
17
|
+
patientUuid: string;
|
|
6
18
|
patientId: string;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
patientName: string;
|
|
20
|
+
patientAge: number;
|
|
21
|
+
patientSex: string;
|
|
22
|
+
totalOrders: number;
|
|
23
|
+
orders: Array<FlattenedOrder>;
|
|
24
|
+
originalOrders: Array<Order>;
|
|
13
25
|
}
|
|
14
26
|
|
|
15
27
|
export interface OrderAction {
|
|
@@ -17,15 +29,6 @@ export interface OrderAction {
|
|
|
17
29
|
order: 0 | number;
|
|
18
30
|
}
|
|
19
31
|
|
|
20
|
-
export interface OrdersDataTableProps {
|
|
21
|
-
useFilter?: boolean;
|
|
22
|
-
actionsSlotName?: string;
|
|
23
|
-
excludeColumns?: string[];
|
|
24
|
-
fulfillerStatus?: FulfillerStatus;
|
|
25
|
-
excludeCanceledAndDiscontinuedOrders?: boolean;
|
|
26
|
-
actions: Array<OrderAction>;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
32
|
export type DateFilterContext = {
|
|
30
33
|
dateRange: Array<Date>;
|
|
31
34
|
setDateRange: React.Dispatch<React.SetStateAction<Array<Date>>>;
|
package/translations/en.json
CHANGED
|
@@ -18,14 +18,12 @@
|
|
|
18
18
|
"exceptionStatus": "EXCEPTION",
|
|
19
19
|
"filterOrdersByStatus": "Filter orders by status",
|
|
20
20
|
"fulfillerComment": "Fulfiller comment",
|
|
21
|
-
"gender": "Gender",
|
|
22
21
|
"In progress": "In progress",
|
|
23
22
|
"inProgress": "In progress",
|
|
24
23
|
"inProgressStatus": "IN_PROGRESS",
|
|
25
24
|
"laboratory": "Laboratory",
|
|
26
25
|
"Laboratory": "Laboratory",
|
|
27
26
|
"loading": "Loading",
|
|
28
|
-
"newStatus": "NEW",
|
|
29
27
|
"nextPage": "Next page",
|
|
30
28
|
"NoInstructionLeft": "No instructions are provided.",
|
|
31
29
|
"noLabRequestsFound": "No lab requests found",
|
|
@@ -40,6 +38,7 @@
|
|
|
40
38
|
"orders": "Orders",
|
|
41
39
|
"orderStatus": "Status:",
|
|
42
40
|
"patient": "Patient",
|
|
41
|
+
"patientId": "Patient ID",
|
|
43
42
|
"pickedAnOrder": "Picked an order",
|
|
44
43
|
"pickRequest": "Pick lab request",
|
|
45
44
|
"pickRequestConfirmationText": "Continuing will update the request status to \"In Progress\" and advance it to the next stage. Are you sure you want to proceed?",
|
|
@@ -55,6 +54,7 @@
|
|
|
55
54
|
"rejectLabRequestTitle": "Lab request rejected",
|
|
56
55
|
"results": "Results",
|
|
57
56
|
"searchThisList": "Search this list",
|
|
57
|
+
"sex": "Sex",
|
|
58
58
|
"tabletOverlay": "Tablet overlay",
|
|
59
59
|
"testOrdered": "Test ordered: ",
|
|
60
60
|
"Tests ordered": "Tests ordered",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"hash":"8b374b02de72bb4b","duration":50422}
|
|
Binary file
|