@openmrs/esm-patient-orders-app 11.3.1-pre.9447 → 11.3.1-pre.9455
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 -14
- package/dist/1253.js +1 -0
- package/dist/1253.js.map +1 -0
- package/dist/375.js +1 -0
- package/dist/375.js.map +1 -0
- package/dist/4300.js +1 -1
- package/dist/4341.js +1 -0
- package/dist/4341.js.map +1 -0
- package/dist/4558.js +1 -0
- package/dist/4558.js.map +1 -0
- package/dist/5937.js +1 -0
- package/dist/5937.js.map +1 -0
- package/dist/6473.js +1 -0
- package/dist/6473.js.map +1 -0
- package/dist/6483.js +1 -0
- package/dist/6483.js.map +1 -0
- package/dist/8376.js +1 -0
- package/dist/8376.js.map +1 -0
- package/dist/8389.js +1 -0
- package/dist/8389.js.map +1 -0
- package/dist/8416.js +1 -0
- package/dist/8416.js.map +1 -0
- package/dist/8894.js +1 -0
- package/dist/8894.js.map +1 -0
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/openmrs-esm-patient-orders-app.js +1 -1
- package/dist/openmrs-esm-patient-orders-app.js.buildmanifest.json +230 -107
- package/dist/openmrs-esm-patient-orders-app.js.map +1 -1
- package/dist/routes.json +1 -1
- package/package.json +2 -2
- package/src/api/api.ts +0 -25
- package/src/components/order-details-table.component.tsx +53 -40
- package/src/index.ts +19 -11
- package/src/lab-results/{lab-results-form.component.tsx → exported-lab-results-form.workspace.tsx} +105 -108
- package/src/lab-results/lab-results-form.test.tsx +24 -38
- package/src/lab-results/lab-results-form.workspace.tsx +26 -0
- package/src/order-basket/exported-order-basket.workspace.tsx +59 -0
- package/src/order-basket/general-order-type/{orderable-concept-search/orderable-concept-search.workspace.tsx → add-general-order/add-general-order.component.tsx} +78 -83
- package/src/order-basket/general-order-type/add-general-order/add-general-order.workspace.tsx +38 -0
- package/src/order-basket/general-order-type/add-general-order/exported-add-general-order.workspace.tsx +35 -0
- package/src/order-basket/general-order-type/{orderable-concept-search → add-general-order}/search-results.component.tsx +15 -14
- package/src/order-basket/general-order-type/general-order-form/general-order-form.component.tsx +71 -25
- package/src/order-basket/general-order-type/{general-order-type.component.tsx → general-order-panel.component.tsx} +23 -41
- package/src/order-basket/general-order-type/resources.ts +3 -2
- package/src/order-basket/order-basket.component.tsx +213 -0
- package/src/order-basket/order-basket.workspace.tsx +42 -252
- package/src/order-basket-action-button/order-basket-action-button.component.tsx +35 -0
- package/src/order-basket-action-button/order-basket-action-button.test.tsx +27 -36
- package/src/routes.json +17 -25
- package/src/utils/index.ts +15 -3
- package/translations/en.json +4 -20
- package/dist/1571.js +0 -1
- package/dist/1571.js.map +0 -1
- package/dist/2717.js +0 -1
- package/dist/2717.js.map +0 -1
- package/dist/4937.js +0 -1
- package/dist/4937.js.map +0 -1
- package/dist/8625.js +0 -1
- package/dist/8625.js.map +0 -1
- package/dist/8803.js +0 -1
- package/dist/8803.js.map +0 -1
- package/dist/8960.js +0 -1
- package/dist/8960.js.map +0 -1
- package/src/order-basket-action-button/order-basket-action-button.extension.tsx +0 -31
- package/src/order-cancellation-form/cancel-order-form.component.tsx +0 -180
- package/src/order-cancellation-form/cancel-order-form.scss +0 -87
- package/src/order-cancellation-form/cancel-order.resource.tsx +0 -15
- /package/src/order-basket/general-order-type/{orderable-concept-search → add-general-order}/orderable-concept-search.scss +0 -0
- /package/src/order-basket/general-order-type/{orderable-concept-search → add-general-order}/search-results.scss +0 -0
package/src/lab-results/{lab-results-form.component.tsx → exported-lab-results-form.workspace.tsx}
RENAMED
|
@@ -6,14 +6,15 @@ import { useTranslation } from 'react-i18next';
|
|
|
6
6
|
import { useSWRConfig } from 'swr';
|
|
7
7
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
8
8
|
import {
|
|
9
|
+
ExtensionSlot,
|
|
9
10
|
restBaseUrl,
|
|
10
11
|
showSnackbar,
|
|
11
12
|
useAbortController,
|
|
12
13
|
useLayoutType,
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
Workspace2,
|
|
15
|
+
type Workspace2DefinitionProps,
|
|
15
16
|
} from '@openmrs/esm-framework';
|
|
16
|
-
import {
|
|
17
|
+
import { useOrderBasket, type Order } from '@openmrs/esm-patient-common-lib';
|
|
17
18
|
import { type ObservationValue } from '../types/encounter';
|
|
18
19
|
import {
|
|
19
20
|
createCompositeObservationPayload,
|
|
@@ -31,8 +32,12 @@ import ResultFormField from './lab-results-form-field.component';
|
|
|
31
32
|
import styles from './lab-results-form.scss';
|
|
32
33
|
import orderStyles from '../order-basket/order-basket.scss';
|
|
33
34
|
|
|
34
|
-
export interface LabResultsFormProps
|
|
35
|
+
export interface LabResultsFormProps {
|
|
36
|
+
patient: fhir.Patient;
|
|
35
37
|
order: Order;
|
|
38
|
+
/** Callback to refresh lab orders in the Laboratory app after results are saved.
|
|
39
|
+
* This ensures the orders list stays in sync across the different tabs in the Laboratory app.
|
|
40
|
+
* @see https://github.com/openmrs/openmrs-esm-laboratory-app/pull/117 */
|
|
36
41
|
invalidateLabOrders?: () => void;
|
|
37
42
|
}
|
|
38
43
|
|
|
@@ -40,16 +45,9 @@ interface OrderBasketSlotProps {
|
|
|
40
45
|
patient: fhir.Patient;
|
|
41
46
|
}
|
|
42
47
|
|
|
43
|
-
const
|
|
48
|
+
const ExportedLabResultsForm: React.FC<Workspace2DefinitionProps<LabResultsFormProps, {}, {}>> = ({
|
|
49
|
+
workspaceProps: { patient, order, invalidateLabOrders },
|
|
44
50
|
closeWorkspace,
|
|
45
|
-
closeWorkspaceWithSavedChanges,
|
|
46
|
-
order,
|
|
47
|
-
promptBeforeClosing,
|
|
48
|
-
/* Callback to refresh lab orders in the Laboratory app after results are saved.
|
|
49
|
-
* This ensures the orders list stays in sync across the different tabs in the Laboratory app.
|
|
50
|
-
* @see https://github.com/openmrs/openmrs-esm-laboratory-app/pull/117
|
|
51
|
-
*/
|
|
52
|
-
invalidateLabOrders,
|
|
53
51
|
}) => {
|
|
54
52
|
const { t } = useTranslation();
|
|
55
53
|
const abortController = useAbortController();
|
|
@@ -59,7 +57,6 @@ const LabResultsForm: React.FC<LabResultsFormProps> = ({
|
|
|
59
57
|
const [showEmptyFormErrorNotification, setShowEmptyFormErrorNotification] = useState(false);
|
|
60
58
|
const compositeSchema = useMemo(() => createLabResultsFormCompositeSchema(conceptArray), [conceptArray]);
|
|
61
59
|
const { mutate } = useSWRConfig();
|
|
62
|
-
const { isLoading: isLoadingPatient, patient } = usePatient(order.patient.uuid);
|
|
63
60
|
const { orders, clearOrders } = useOrderBasket(patient);
|
|
64
61
|
const [isSavingOrders, setIsSavingOrders] = useState(false);
|
|
65
62
|
const { isLoading, completeLabResults, mutate: mutateResults } = useCompletedLabResultsArray(order);
|
|
@@ -131,10 +128,6 @@ const LabResultsForm: React.FC<LabResultsFormProps> = ({
|
|
|
131
128
|
});
|
|
132
129
|
}, [conceptArray, completeLabResults, order?.fulfillerStatus, setValue]);
|
|
133
130
|
|
|
134
|
-
useEffect(() => {
|
|
135
|
-
promptBeforeClosing(() => isDirty);
|
|
136
|
-
}, [isDirty, promptBeforeClosing]);
|
|
137
|
-
|
|
138
131
|
if (isLoadingResultConcepts) {
|
|
139
132
|
return (
|
|
140
133
|
<div className={styles.loaderContainer}>
|
|
@@ -186,7 +179,7 @@ const LabResultsForm: React.FC<LabResultsFormProps> = ({
|
|
|
186
179
|
if (failedObsconceptUuids.length) {
|
|
187
180
|
showNotification('error', 'Could not save obs with concept uuids ' + failedObsconceptUuids.join(', '));
|
|
188
181
|
} else {
|
|
189
|
-
|
|
182
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
190
183
|
showNotification(
|
|
191
184
|
'success',
|
|
192
185
|
t('successfullySavedLabResults', 'Lab results for {{orderNumber}} have been successfully updated', {
|
|
@@ -227,7 +220,7 @@ const LabResultsForm: React.FC<LabResultsFormProps> = ({
|
|
|
227
220
|
abortController,
|
|
228
221
|
);
|
|
229
222
|
|
|
230
|
-
|
|
223
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
231
224
|
mutateOrderData();
|
|
232
225
|
mutateResults();
|
|
233
226
|
invalidateLabOrders?.();
|
|
@@ -246,98 +239,102 @@ const LabResultsForm: React.FC<LabResultsFormProps> = ({
|
|
|
246
239
|
};
|
|
247
240
|
|
|
248
241
|
return (
|
|
249
|
-
<
|
|
250
|
-
<
|
|
251
|
-
<
|
|
252
|
-
{
|
|
253
|
-
|
|
254
|
-
{
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<div className={
|
|
268
|
-
<
|
|
242
|
+
<Workspace2 title={t('enterTestResults', 'Enter test results')} hasUnsavedChanges={isDirty}>
|
|
243
|
+
<Form className={styles.form} onSubmit={handleSubmit(saveLabResults)}>
|
|
244
|
+
<Layer level={isTablet ? 1 : 0}>
|
|
245
|
+
<div className={styles.grid}>
|
|
246
|
+
{conceptArray?.length > 0 && (
|
|
247
|
+
<Stack gap={5}>
|
|
248
|
+
{!isLoading ? (
|
|
249
|
+
conceptArray.map((c) => (
|
|
250
|
+
<ResultFormField
|
|
251
|
+
defaultValue={completeLabResults.find((r) => r.concept.uuid === c.uuid)}
|
|
252
|
+
concept={c}
|
|
253
|
+
control={control as unknown as Control<Record<string, unknown>>}
|
|
254
|
+
/>
|
|
255
|
+
))
|
|
256
|
+
) : (
|
|
257
|
+
<InlineLoading description={t('loadingInitialValues', 'Loading initial values') + '...'} />
|
|
258
|
+
)}
|
|
259
|
+
{order.fulfillerStatus !== 'COMPLETED' && (
|
|
260
|
+
<div className={orderStyles.orderBasketContainer}>
|
|
261
|
+
<div className={styles.heading}>
|
|
262
|
+
<span>{t('addOrderTests', 'Add Tests to this order')}</span>
|
|
263
|
+
</div>
|
|
264
|
+
<ExtensionSlot
|
|
265
|
+
className={classNames(orderStyles.orderBasketSlot, {
|
|
266
|
+
[orderStyles.orderBasketSlotTablet]: isTablet,
|
|
267
|
+
})}
|
|
268
|
+
name="result-order-basket-slot"
|
|
269
|
+
state={extensionProps}
|
|
270
|
+
/>
|
|
269
271
|
</div>
|
|
270
|
-
|
|
271
|
-
className={classNames(orderStyles.orderBasketSlot, {
|
|
272
|
-
[orderStyles.orderBasketSlotTablet]: isTablet,
|
|
273
|
-
})}
|
|
274
|
-
name="result-order-basket-slot"
|
|
275
|
-
state={extensionProps}
|
|
276
|
-
/>
|
|
277
|
-
</div>
|
|
278
|
-
)}
|
|
272
|
+
)}
|
|
279
273
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
274
|
+
{orders?.length > 0 && (
|
|
275
|
+
<div className={orderStyles.orderBasketContainer}>
|
|
276
|
+
<ButtonSet className={styles.buttonSet}>
|
|
277
|
+
<Button size="sm" className={styles.actionButton} kind="secondary" onClick={handleCancel}>
|
|
278
|
+
{t('cancelOrder', 'Cancel order')}
|
|
279
|
+
</Button>
|
|
280
|
+
<Button
|
|
281
|
+
className={styles.actionButton}
|
|
282
|
+
kind="primary"
|
|
283
|
+
onClick={handleSave}
|
|
284
|
+
size="sm"
|
|
285
|
+
disabled={
|
|
286
|
+
isSavingOrders ||
|
|
287
|
+
!orders?.length ||
|
|
288
|
+
orders?.some(({ isOrderIncomplete }) => isOrderIncomplete)
|
|
289
|
+
}
|
|
290
|
+
>
|
|
291
|
+
{isSavingOrders ? (
|
|
292
|
+
<InlineLoading description={t('saving', 'Saving') + '...'} />
|
|
293
|
+
) : (
|
|
294
|
+
<span>{t('saveTests', 'Save Tests')}</span>
|
|
295
|
+
)}
|
|
296
|
+
</Button>
|
|
297
|
+
</ButtonSet>
|
|
298
|
+
</div>
|
|
299
|
+
)}
|
|
300
|
+
</Stack>
|
|
301
|
+
)}
|
|
302
|
+
{showEmptyFormErrorNotification && (
|
|
303
|
+
<InlineNotification
|
|
304
|
+
className={styles.emptyFormError}
|
|
305
|
+
lowContrast
|
|
306
|
+
title={t('error', 'Error')}
|
|
307
|
+
subtitle={t('pleaseFillField', 'Please fill at least one field') + '.'}
|
|
308
|
+
/>
|
|
309
|
+
)}
|
|
310
|
+
</div>
|
|
311
|
+
</Layer>
|
|
316
312
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
>
|
|
323
|
-
<Button className={styles.button} kind="secondary" disabled={isSubmitting} onClick={() => closeWorkspace()}>
|
|
324
|
-
{t('discard', 'Discard')}
|
|
325
|
-
</Button>
|
|
326
|
-
<Button
|
|
327
|
-
className={styles.button}
|
|
328
|
-
kind="primary"
|
|
329
|
-
disabled={isSubmitting || Object.keys(errors).length > 0}
|
|
330
|
-
type="submit"
|
|
313
|
+
<ButtonSet
|
|
314
|
+
className={classNames({
|
|
315
|
+
[styles.tablet]: isTablet,
|
|
316
|
+
[styles.desktop]: !isTablet,
|
|
317
|
+
})}
|
|
331
318
|
>
|
|
332
|
-
{isSubmitting
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
319
|
+
<Button className={styles.button} kind="secondary" disabled={isSubmitting} onClick={() => closeWorkspace()}>
|
|
320
|
+
{t('discard', 'Discard')}
|
|
321
|
+
</Button>
|
|
322
|
+
<Button
|
|
323
|
+
className={styles.button}
|
|
324
|
+
kind="primary"
|
|
325
|
+
disabled={isSubmitting || Object.keys(errors).length > 0}
|
|
326
|
+
type="submit"
|
|
327
|
+
>
|
|
328
|
+
{isSubmitting ? (
|
|
329
|
+
<InlineLoading description={t('saving', 'Saving') + '...'} />
|
|
330
|
+
) : (
|
|
331
|
+
t('saveAndClose', 'Save and close')
|
|
332
|
+
)}
|
|
333
|
+
</Button>
|
|
334
|
+
</ButtonSet>
|
|
335
|
+
</Form>
|
|
336
|
+
</Workspace2>
|
|
340
337
|
);
|
|
341
338
|
};
|
|
342
339
|
|
|
343
|
-
export default
|
|
340
|
+
export default ExportedLabResultsForm;
|
|
@@ -10,9 +10,8 @@ import {
|
|
|
10
10
|
type Datatype,
|
|
11
11
|
useCompletedLabResultsArray,
|
|
12
12
|
} from './lab-results.resource';
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import { type Order } from '@openmrs/esm-patient-common-lib';
|
|
13
|
+
import LabResultsForm, { type LabResultsFormProps } from './lab-results-form.workspace';
|
|
14
|
+
import { type PatientWorkspace2DefinitionProps, type Order } from '@openmrs/esm-patient-common-lib';
|
|
16
15
|
import { type Encounter } from '../types/encounter';
|
|
17
16
|
import { mockPatient } from 'tools';
|
|
18
17
|
|
|
@@ -20,7 +19,6 @@ const mockUseOrderConceptByUuids = jest.mocked(useOrderConceptsByUuids);
|
|
|
20
19
|
const mockUseLabEncounter = jest.mocked(useLabEncounter);
|
|
21
20
|
const mockUseObservation = jest.mocked(useObservation);
|
|
22
21
|
const mockUseCompletedLabResultsArray = jest.mocked(useCompletedLabResultsArray);
|
|
23
|
-
const mockUsePatient = jest.mocked(usePatient);
|
|
24
22
|
|
|
25
23
|
jest.mock('./lab-results.resource', () => ({
|
|
26
24
|
...jest.requireActual('./lab-results.resource'),
|
|
@@ -42,16 +40,24 @@ const mockOrder = {
|
|
|
42
40
|
orderer: { uuid: 'orderer-uuid' },
|
|
43
41
|
};
|
|
44
42
|
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
const mockCloseWorkspace = jest.fn();
|
|
44
|
+
|
|
45
|
+
const testProps: PatientWorkspace2DefinitionProps<LabResultsFormProps, {}> = {
|
|
46
|
+
closeWorkspace: mockCloseWorkspace,
|
|
47
|
+
workspaceProps: {
|
|
48
|
+
order: mockOrder as Order,
|
|
49
|
+
},
|
|
50
|
+
groupProps: {
|
|
51
|
+
patientUuid: mockPatient.id,
|
|
52
|
+
patient: mockPatient,
|
|
53
|
+
visitContext: null,
|
|
54
|
+
mutateVisitContext: null,
|
|
55
|
+
},
|
|
56
|
+
launchChildWorkspace: jest.fn(),
|
|
57
|
+
windowProps: {},
|
|
58
|
+
workspaceName: '',
|
|
59
|
+
windowName: '',
|
|
60
|
+
isRootWorkspace: false,
|
|
55
61
|
};
|
|
56
62
|
|
|
57
63
|
describe('LabResultsForm', () => {
|
|
@@ -98,12 +104,6 @@ describe('LabResultsForm', () => {
|
|
|
98
104
|
error: null,
|
|
99
105
|
mutate: jest.fn(),
|
|
100
106
|
});
|
|
101
|
-
mockUsePatient.mockReturnValue({
|
|
102
|
-
isLoading: false,
|
|
103
|
-
patient: mockPatient,
|
|
104
|
-
patientUuid: '',
|
|
105
|
-
error: null,
|
|
106
|
-
});
|
|
107
107
|
});
|
|
108
108
|
|
|
109
109
|
test('validates numeric input correctly', async () => {
|
|
@@ -339,16 +339,8 @@ describe('LabResultsForm', () => {
|
|
|
339
339
|
|
|
340
340
|
test('submits form with valid data', async () => {
|
|
341
341
|
const user = userEvent.setup();
|
|
342
|
-
const mockCloseWorkspace = jest.fn();
|
|
343
|
-
const mockCloseWorkspaceWithSavedChanges = jest.fn();
|
|
344
342
|
|
|
345
|
-
render(
|
|
346
|
-
<LabResultsForm
|
|
347
|
-
{...testProps}
|
|
348
|
-
closeWorkspace={mockCloseWorkspace}
|
|
349
|
-
closeWorkspaceWithSavedChanges={mockCloseWorkspaceWithSavedChanges}
|
|
350
|
-
/>,
|
|
351
|
-
);
|
|
343
|
+
render(<LabResultsForm {...testProps} />);
|
|
352
344
|
|
|
353
345
|
const input = await screen.findByLabelText(`Test Concept (0 - 100 mg/dL)`);
|
|
354
346
|
await user.type(input, '50');
|
|
@@ -357,7 +349,7 @@ describe('LabResultsForm', () => {
|
|
|
357
349
|
await user.click(saveButton);
|
|
358
350
|
|
|
359
351
|
await waitFor(() => {
|
|
360
|
-
expect(
|
|
352
|
+
expect(mockCloseWorkspace).toHaveBeenCalled();
|
|
361
353
|
});
|
|
362
354
|
});
|
|
363
355
|
|
|
@@ -402,13 +394,7 @@ describe('LabResultsForm', () => {
|
|
|
402
394
|
const mockCloseWorkspace = jest.fn();
|
|
403
395
|
const mockCloseWorkspaceWithSavedChanges = jest.fn();
|
|
404
396
|
|
|
405
|
-
render(
|
|
406
|
-
<LabResultsForm
|
|
407
|
-
{...testProps}
|
|
408
|
-
closeWorkspace={mockCloseWorkspace}
|
|
409
|
-
closeWorkspaceWithSavedChanges={mockCloseWorkspaceWithSavedChanges}
|
|
410
|
-
/>,
|
|
411
|
-
);
|
|
397
|
+
render(<LabResultsForm {...testProps} closeWorkspace={mockCloseWorkspace} />);
|
|
412
398
|
|
|
413
399
|
const input = await screen.findByLabelText(`Test Concept (0 - 60 mg/dL)`);
|
|
414
400
|
await user.type(input, '50');
|
|
@@ -420,7 +406,7 @@ describe('LabResultsForm', () => {
|
|
|
420
406
|
await user.click(saveButton);
|
|
421
407
|
|
|
422
408
|
await waitFor(() => {
|
|
423
|
-
expect(
|
|
409
|
+
expect(mockCloseWorkspace).toHaveBeenCalled();
|
|
424
410
|
});
|
|
425
411
|
});
|
|
426
412
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type Order, type PatientWorkspace2DefinitionProps } from '@openmrs/esm-patient-common-lib';
|
|
3
|
+
import ExportedLabResultsForm from './exported-lab-results-form.workspace';
|
|
4
|
+
|
|
5
|
+
export interface LabResultsFormProps {
|
|
6
|
+
order: Order;
|
|
7
|
+
/** Callback to refresh lab orders in the Laboratory app after results are saved.
|
|
8
|
+
* This ensures the orders list stays in sync across the different tabs in the Laboratory app.
|
|
9
|
+
* @see https://github.com/openmrs/openmrs-esm-laboratory-app/pull/117 */
|
|
10
|
+
invalidateLabOrders?: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* This workspace displays the form to input lab results for orders.
|
|
15
|
+
* This workspace should only be used within the patient chart. Use ExportedLabResultsForm
|
|
16
|
+
* for use cases outside the patient chart.
|
|
17
|
+
*/
|
|
18
|
+
const LabResultsForm: React.FC<PatientWorkspace2DefinitionProps<LabResultsFormProps, {}>> = ({
|
|
19
|
+
workspaceProps: { order, invalidateLabOrders },
|
|
20
|
+
groupProps: { patient },
|
|
21
|
+
...rest
|
|
22
|
+
}) => {
|
|
23
|
+
return <ExportedLabResultsForm workspaceProps={{ patient, order, invalidateLabOrders }} groupProps={{}} {...rest} />;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default LabResultsForm;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { type Workspace2DefinitionProps } from '@openmrs/esm-framework';
|
|
3
|
+
import {
|
|
4
|
+
type OrderBasketExtensionProps,
|
|
5
|
+
type OrderBasketItem,
|
|
6
|
+
type ExportedOrderBasketWindowProps,
|
|
7
|
+
} from '@openmrs/esm-patient-common-lib';
|
|
8
|
+
import OrderBasket from './order-basket.component';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This workspace renders the main order basket, which contains the buttons to add a drug order and to add a lab order.
|
|
12
|
+
*
|
|
13
|
+
* This workspace is meant for use outside the the patient chart
|
|
14
|
+
*/
|
|
15
|
+
const ExportedOrderBasketWorkspace: React.FC<Workspace2DefinitionProps<{}, ExportedOrderBasketWindowProps, {}>> = ({
|
|
16
|
+
windowProps: {
|
|
17
|
+
patientUuid,
|
|
18
|
+
patient,
|
|
19
|
+
visitContext,
|
|
20
|
+
mutateVisitContext,
|
|
21
|
+
drugOrderWorkspaceName,
|
|
22
|
+
labOrderWorkspaceName,
|
|
23
|
+
generalOrderWorkspaceName,
|
|
24
|
+
},
|
|
25
|
+
closeWorkspace,
|
|
26
|
+
launchChildWorkspace,
|
|
27
|
+
}) => {
|
|
28
|
+
const orderBasketExtensionProps = useMemo(() => {
|
|
29
|
+
const launchDrugOrderForm = (order: OrderBasketItem) => {
|
|
30
|
+
launchChildWorkspace(drugOrderWorkspaceName, { order });
|
|
31
|
+
};
|
|
32
|
+
const launchLabOrderForm = (orderTypeUuid: string, order: OrderBasketItem) => {
|
|
33
|
+
launchChildWorkspace(labOrderWorkspaceName, { orderTypeUuid, order });
|
|
34
|
+
};
|
|
35
|
+
const launchGeneralOrderForm = (orderTypeUuid: string, order: OrderBasketItem) => {
|
|
36
|
+
launchChildWorkspace(generalOrderWorkspaceName, { orderTypeUuid, order });
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
patient,
|
|
41
|
+
launchDrugOrderForm,
|
|
42
|
+
launchLabOrderForm,
|
|
43
|
+
launchGeneralOrderForm,
|
|
44
|
+
} satisfies OrderBasketExtensionProps;
|
|
45
|
+
}, [launchChildWorkspace, drugOrderWorkspaceName, labOrderWorkspaceName, generalOrderWorkspaceName, patient]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<OrderBasket
|
|
49
|
+
patientUuid={patientUuid}
|
|
50
|
+
patient={patient}
|
|
51
|
+
visitContext={visitContext}
|
|
52
|
+
mutateVisitContext={mutateVisitContext}
|
|
53
|
+
closeWorkspace={closeWorkspace}
|
|
54
|
+
orderBasketExtensionProps={orderBasketExtensionProps}
|
|
55
|
+
/>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default ExportedOrderBasketWorkspace;
|