@openmrs/esm-patient-orders-app 11.3.1-patch.9310 → 11.3.1-patch.9508
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 +15 -18
- package/dist/1119.js +1 -1
- package/dist/1197.js +1 -1
- package/dist/1571.js +1 -0
- package/dist/1571.js.map +1 -0
- package/dist/2146.js +1 -1
- package/dist/2690.js +1 -1
- package/dist/2717.js +1 -0
- package/dist/2717.js.map +1 -0
- package/dist/3099.js +1 -1
- package/dist/3584.js +1 -1
- package/dist/4055.js +1 -1
- package/dist/4132.js +1 -1
- package/dist/4300.js +1 -1
- package/dist/4335.js +1 -1
- package/dist/439.js +1 -0
- package/dist/4618.js +1 -1
- package/dist/4652.js +1 -1
- package/dist/4937.js +1 -1
- package/dist/4937.js.map +1 -1
- package/dist/4944.js +1 -1
- package/dist/5134.js +2 -0
- package/dist/5134.js.map +1 -0
- package/dist/5173.js +1 -1
- package/dist/5241.js +1 -1
- package/dist/5442.js +1 -1
- package/dist/5661.js +1 -1
- package/dist/5670.js +1 -1
- package/dist/5670.js.map +1 -1
- package/dist/6022.js +1 -1
- package/dist/6468.js +1 -1
- package/dist/6589.js +1 -0
- package/dist/6679.js +1 -1
- package/dist/6840.js +1 -1
- package/dist/6859.js +1 -1
- package/dist/7097.js +1 -1
- package/dist/7159.js +1 -1
- package/dist/723.js +1 -1
- package/dist/7617.js +1 -1
- package/dist/795.js +1 -1
- package/dist/8163.js +1 -1
- package/dist/8349.js +1 -1
- package/dist/8371.js +1 -0
- package/dist/8618.js +1 -1
- package/dist/8625.js +1 -0
- package/dist/8625.js.map +1 -0
- package/dist/8803.js +1 -0
- package/dist/8803.js.map +1 -0
- package/dist/890.js +1 -1
- package/dist/8960.js +1 -0
- package/dist/8960.js.map +1 -0
- package/dist/9214.js +1 -1
- package/dist/9538.js +1 -1
- package/dist/9569.js +1 -1
- package/dist/986.js +1 -1
- package/dist/9879.js +1 -1
- package/dist/9895.js +1 -1
- package/dist/9900.js +1 -1
- package/dist/9913.js +1 -1
- 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 +276 -259
- 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 +25 -0
- package/src/components/order-details-table.component.tsx +40 -53
- package/src/components/test-order.component.tsx +53 -49
- package/src/index.ts +9 -12
- package/src/lab-results/lab-results-form.component.tsx +343 -0
- package/src/lab-results/lab-results-form.test.tsx +455 -306
- package/src/lab-results/lab-results-schema.resource.tsx +13 -4
- package/src/lab-results/lab-results.resource.ts +113 -0
- package/src/order-basket/general-order-type/general-order-form/general-order-form.component.tsx +25 -71
- package/src/order-basket/general-order-type/{general-order-panel.component.tsx → general-order-type.component.tsx} +41 -23
- package/src/order-basket/general-order-type/{add-general-order/add-general-order.component.tsx → orderable-concept-search/orderable-concept-search.workspace.tsx} +83 -78
- package/src/order-basket/general-order-type/{add-general-order → orderable-concept-search}/search-results.component.tsx +14 -15
- package/src/order-basket/general-order-type/resources.ts +2 -3
- package/src/order-basket/order-basket.workspace.tsx +251 -35
- package/src/order-basket-action-button/order-basket-action-button.extension.tsx +31 -0
- package/src/order-basket-action-button/order-basket-action-button.test.tsx +36 -27
- package/src/order-cancellation-form/cancel-order-form.component.tsx +85 -82
- package/src/routes.json +25 -17
- package/src/utils/index.ts +3 -15
- package/translations/am.json +6 -20
- package/translations/ar.json +6 -20
- package/translations/ar_SY.json +6 -20
- package/translations/bn.json +6 -20
- package/translations/cs.json +114 -0
- package/translations/de.json +6 -20
- package/translations/en.json +12 -4
- package/translations/en_US.json +6 -20
- package/translations/es.json +6 -20
- package/translations/es_MX.json +6 -20
- package/translations/fr.json +7 -21
- package/translations/he.json +6 -20
- package/translations/hi.json +6 -20
- package/translations/hi_IN.json +6 -20
- package/translations/id.json +6 -20
- package/translations/it.json +6 -20
- package/translations/ka.json +6 -20
- package/translations/km.json +6 -20
- package/translations/ku.json +6 -20
- package/translations/ky.json +6 -20
- package/translations/lg.json +6 -20
- package/translations/ne.json +6 -20
- package/translations/pl.json +6 -20
- package/translations/pt.json +6 -20
- package/translations/pt_BR.json +6 -20
- package/translations/qu.json +6 -20
- package/translations/ro_RO.json +6 -20
- package/translations/ru_RU.json +6 -20
- package/translations/si.json +6 -20
- package/translations/sq.json +114 -0
- package/translations/sw.json +6 -20
- package/translations/sw_KE.json +6 -20
- package/translations/tr.json +6 -20
- package/translations/tr_TR.json +6 -20
- package/translations/uk.json +6 -20
- package/translations/uz.json +6 -20
- package/translations/uz@Latn.json +6 -20
- package/translations/uz_UZ.json +6 -20
- package/translations/vi.json +6 -20
- package/translations/zh.json +6 -20
- package/translations/zh_CN.json +6 -20
- package/translations/zh_TW.json +114 -0
- package/dist/1253.js +0 -1
- package/dist/1253.js.map +0 -1
- package/dist/1268.js +0 -2
- package/dist/1268.js.map +0 -1
- package/dist/375.js +0 -1
- package/dist/375.js.map +0 -1
- package/dist/4341.js +0 -1
- package/dist/4341.js.map +0 -1
- package/dist/4687.js +0 -1
- package/dist/4687.js.map +0 -1
- package/dist/6364.js +0 -1
- package/dist/6364.js.map +0 -1
- package/dist/6473.js +0 -1
- package/dist/6473.js.map +0 -1
- package/dist/8416.js +0 -1
- package/dist/8416.js.map +0 -1
- package/src/lab-results/exported-lab-results-form.workspace.tsx +0 -264
- package/src/lab-results/lab-results-form.workspace.tsx +0 -25
- package/src/order-basket/exported-order-basket.workspace.tsx +0 -54
- package/src/order-basket/general-order-type/add-general-order/add-general-order.workspace.tsx +0 -35
- package/src/order-basket/general-order-type/add-general-order/exported-add-general-order.workspace.tsx +0 -32
- package/src/order-basket/order-basket.component.tsx +0 -213
- package/src/order-basket-action-button/order-basket-action-button.component.tsx +0 -35
- /package/dist/{1268.js.LICENSE.txt → 5134.js.LICENSE.txt} +0 -0
- /package/src/order-basket/general-order-type/{add-general-order → orderable-concept-search}/orderable-concept-search.scss +0 -0
- /package/src/order-basket/general-order-type/{add-general-order → orderable-concept-search}/search-results.scss +0 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React, { type ComponentProps } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { ActionMenuButton, ShoppingCartIcon } from '@openmrs/esm-framework';
|
|
4
|
+
import { useLaunchWorkspaceRequiringVisit, useOrderBasket } from '@openmrs/esm-patient-common-lib';
|
|
5
|
+
|
|
6
|
+
interface OrderBasketActionButtonProps {
|
|
7
|
+
patientUuid: string;
|
|
8
|
+
patient: fhir.Patient;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This extension uses the patient chart store and MUST only be mounted within the patient chart
|
|
13
|
+
*/
|
|
14
|
+
const OrderBasketActionButton: React.FC<OrderBasketActionButtonProps> = ({ patientUuid, patient }) => {
|
|
15
|
+
const { t } = useTranslation();
|
|
16
|
+
const { orders } = useOrderBasket(patient);
|
|
17
|
+
const launchOrderBasket = useLaunchWorkspaceRequiringVisit(patientUuid, 'order-basket');
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<ActionMenuButton
|
|
21
|
+
getIcon={(props: ComponentProps<typeof ShoppingCartIcon>) => <ShoppingCartIcon {...props} />}
|
|
22
|
+
label={t('orderBasket', 'Order basket')}
|
|
23
|
+
iconDescription={t('medications', 'Medications')}
|
|
24
|
+
handler={launchOrderBasket}
|
|
25
|
+
type={'order'}
|
|
26
|
+
tagContent={orders?.length > 0 ? orders?.length : null}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export default OrderBasketActionButton;
|
|
@@ -1,13 +1,35 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { screen, render, renderHook } from '@testing-library/react';
|
|
3
3
|
import userEvent from '@testing-library/user-event';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ActionMenuButton,
|
|
6
|
+
launchWorkspace,
|
|
7
|
+
type OpenWorkspace,
|
|
8
|
+
useFeatureFlag,
|
|
9
|
+
useLayoutType,
|
|
10
|
+
useWorkspaces,
|
|
11
|
+
type WorkspacesInfo,
|
|
12
|
+
} from '@openmrs/esm-framework';
|
|
5
13
|
import { type OrderBasketItem, useOrderBasket } from '@openmrs/esm-patient-common-lib';
|
|
6
14
|
import { mockPatient } from 'tools';
|
|
7
15
|
import { orderBasketStore } from '@openmrs/esm-patient-common-lib/src/orders/store';
|
|
8
|
-
import OrderBasketActionButton from './order-basket-action-button.
|
|
16
|
+
import OrderBasketActionButton from './order-basket-action-button.extension';
|
|
9
17
|
|
|
18
|
+
const MockActionMenuButton = jest.mocked(ActionMenuButton);
|
|
19
|
+
const mockLaunchWorkspace = jest.mocked(launchWorkspace);
|
|
10
20
|
const mockUseLayoutType = jest.mocked(useLayoutType);
|
|
21
|
+
const mockUseWorkspaces = jest.mocked(useWorkspaces);
|
|
22
|
+
|
|
23
|
+
MockActionMenuButton.mockImplementation(({ handler, label, tagContent }) => (
|
|
24
|
+
<button onClick={handler}>
|
|
25
|
+
{tagContent} {label}
|
|
26
|
+
</button>
|
|
27
|
+
));
|
|
28
|
+
|
|
29
|
+
mockUseWorkspaces.mockReturnValue({
|
|
30
|
+
workspaces: [{ type: 'order-basket' } as OpenWorkspace],
|
|
31
|
+
workspaceWindowState: 'normal',
|
|
32
|
+
} as unknown as WorkspacesInfo);
|
|
11
33
|
|
|
12
34
|
// This pattern of mocking seems to be required: defining the mocked function here and
|
|
13
35
|
// then assigning it with an arrow function wrapper in jest.mock. It is very particular.
|
|
@@ -44,27 +66,23 @@ describe('<OrderBasketActionButton/>', () => {
|
|
|
44
66
|
it('should display tablet view action button', async () => {
|
|
45
67
|
const user = userEvent.setup();
|
|
46
68
|
mockUseLayoutType.mockReturnValue('tablet');
|
|
47
|
-
render(
|
|
48
|
-
<OrderBasketActionButton
|
|
49
|
-
groupProps={{ patient: mockPatient, patientUuid: mockPatient.id, visitContext: null, mutateVisitContext: null }}
|
|
50
|
-
/>,
|
|
51
|
-
);
|
|
69
|
+
render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
|
|
52
70
|
|
|
53
71
|
const orderBasketButton = screen.getByRole('button', { name: /Order Basket/i });
|
|
54
72
|
expect(orderBasketButton).toBeInTheDocument();
|
|
73
|
+
await user.click(orderBasketButton);
|
|
74
|
+
expect(mockLaunchWorkspace).toHaveBeenCalledWith('order-basket', expect.any(Object));
|
|
55
75
|
});
|
|
56
76
|
|
|
57
77
|
it('should display desktop view action button', async () => {
|
|
58
78
|
const user = userEvent.setup();
|
|
59
79
|
mockUseLayoutType.mockReturnValue('small-desktop');
|
|
60
|
-
render(
|
|
61
|
-
<OrderBasketActionButton
|
|
62
|
-
groupProps={{ patient: mockPatient, patientUuid: mockPatient.id, visitContext: null, mutateVisitContext: null }}
|
|
63
|
-
/>,
|
|
64
|
-
);
|
|
80
|
+
render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
|
|
65
81
|
|
|
66
82
|
const orderBasketButton = screen.getByRole('button', { name: /order basket/i });
|
|
67
83
|
expect(orderBasketButton).toBeInTheDocument();
|
|
84
|
+
await user.click(orderBasketButton);
|
|
85
|
+
expect(mockLaunchWorkspace).toHaveBeenCalledWith('order-basket', expect.any(Object));
|
|
68
86
|
});
|
|
69
87
|
|
|
70
88
|
it('should prompt user to start visit if no currentVisit found', async () => {
|
|
@@ -73,25 +91,20 @@ describe('<OrderBasketActionButton/>', () => {
|
|
|
73
91
|
mockUseLayoutType.mockReturnValue('small-desktop');
|
|
74
92
|
mockUseSystemVisitSetting.mockReturnValue({ systemVisitEnabled: true });
|
|
75
93
|
|
|
76
|
-
render(
|
|
77
|
-
<OrderBasketActionButton
|
|
78
|
-
groupProps={{ patient: mockPatient, patientUuid: mockPatient.id, visitContext: null, mutateVisitContext: null }}
|
|
79
|
-
/>,
|
|
80
|
-
);
|
|
94
|
+
render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
|
|
81
95
|
|
|
82
96
|
const orderBasketButton = screen.getByRole('button', { name: /order basket/i });
|
|
83
97
|
expect(orderBasketButton).toBeInTheDocument();
|
|
98
|
+
await user.click(orderBasketButton);
|
|
99
|
+
expect(mockLaunchWorkspace).not.toHaveBeenCalled();
|
|
100
|
+
expect(mockLaunchStartVisitPrompt).toHaveBeenCalled();
|
|
84
101
|
});
|
|
85
102
|
|
|
86
103
|
it('should display a count tag when orders are present on the desktop view', () => {
|
|
87
104
|
mockUseLayoutType.mockReturnValue('small-desktop');
|
|
88
105
|
const { result } = renderHook(() => useOrderBasket(mockPatient));
|
|
89
106
|
expect(result.current.orders).toHaveLength(1); // sanity check
|
|
90
|
-
render(
|
|
91
|
-
<OrderBasketActionButton
|
|
92
|
-
groupProps={{ patient: mockPatient, patientUuid: mockPatient.id, visitContext: null, mutateVisitContext: null }}
|
|
93
|
-
/>,
|
|
94
|
-
);
|
|
107
|
+
render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
|
|
95
108
|
|
|
96
109
|
expect(screen.getByText(/order basket/i)).toBeInTheDocument();
|
|
97
110
|
expect(screen.getByText(/1/i)).toBeInTheDocument();
|
|
@@ -99,11 +112,7 @@ describe('<OrderBasketActionButton/>', () => {
|
|
|
99
112
|
|
|
100
113
|
it('should display the count tag when orders are present on the tablet view', () => {
|
|
101
114
|
mockUseLayoutType.mockReturnValue('tablet');
|
|
102
|
-
render(
|
|
103
|
-
<OrderBasketActionButton
|
|
104
|
-
groupProps={{ patient: mockPatient, patientUuid: mockPatient.id, visitContext: null, mutateVisitContext: null }}
|
|
105
|
-
/>,
|
|
106
|
-
);
|
|
115
|
+
render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
|
|
107
116
|
|
|
108
117
|
expect(screen.getByRole('button', { name: /1 order basket/i })).toBeInTheDocument();
|
|
109
118
|
});
|
|
@@ -5,19 +5,20 @@ import { useTranslation } from 'react-i18next';
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
7
7
|
import { Button, TextArea, ButtonSet, Column, Form, InlineNotification, Stack, InlineLoading } from '@carbon/react';
|
|
8
|
-
import { OpenmrsDatePicker, showSnackbar, useLayoutType
|
|
9
|
-
import { type
|
|
8
|
+
import { OpenmrsDatePicker, showSnackbar, useLayoutType } from '@openmrs/esm-framework';
|
|
9
|
+
import { type DefaultPatientWorkspaceProps, usePatientOrders, type Order } from '@openmrs/esm-patient-common-lib';
|
|
10
10
|
import { cancelOrder } from './cancel-order.resource';
|
|
11
11
|
import styles from './cancel-order-form.scss';
|
|
12
12
|
|
|
13
|
-
interface OrderCancellationFormProps {
|
|
13
|
+
interface OrderCancellationFormProps extends DefaultPatientWorkspaceProps {
|
|
14
14
|
order: Order;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const OrderCancellationForm: React.FC<
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
const OrderCancellationForm: React.FC<OrderCancellationFormProps> = ({
|
|
18
|
+
order,
|
|
19
|
+
patientUuid,
|
|
20
20
|
closeWorkspace,
|
|
21
|
+
promptBeforeClosing,
|
|
21
22
|
}) => {
|
|
22
23
|
const { t } = useTranslation();
|
|
23
24
|
const isTablet = useLayoutType() === 'tablet';
|
|
@@ -56,6 +57,10 @@ const OrderCancellationForm: React.FC<PatientWorkspace2DefinitionProps<OrderCanc
|
|
|
56
57
|
}
|
|
57
58
|
}
|
|
58
59
|
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
promptBeforeClosing(() => isDirty);
|
|
62
|
+
}, [isDirty, promptBeforeClosing]);
|
|
63
|
+
|
|
59
64
|
const cancelOrderRequest = useCallback(
|
|
60
65
|
(data: CancelOrderFormData) => {
|
|
61
66
|
const formData = data;
|
|
@@ -93,84 +98,82 @@ const OrderCancellationForm: React.FC<PatientWorkspace2DefinitionProps<OrderCanc
|
|
|
93
98
|
);
|
|
94
99
|
|
|
95
100
|
return (
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
<
|
|
99
|
-
<
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
<
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
)}
|
|
119
|
-
/>
|
|
120
|
-
</section>
|
|
121
|
-
<section>
|
|
122
|
-
<Controller
|
|
123
|
-
name="reasonForCancellation"
|
|
124
|
-
control={control}
|
|
125
|
-
render={({ field: { onChange, value } }) => (
|
|
126
|
-
<div className={styles.row}>
|
|
127
|
-
<TextArea
|
|
128
|
-
type="text"
|
|
129
|
-
id="reasonForCancellation"
|
|
130
|
-
labelText={t('reasonForCancellation', 'Reason for cancellation')}
|
|
131
|
-
value={value}
|
|
132
|
-
onChange={(evt) => onChange(evt.target.value)}
|
|
133
|
-
invalid={!!errors['reasonForCancellation']}
|
|
134
|
-
invalidText={!!errors['reasonForCancellation'] && errors['reasonForCancellation'].message}
|
|
135
|
-
/>
|
|
136
|
-
</div>
|
|
137
|
-
)}
|
|
138
|
-
/>
|
|
139
|
-
</section>
|
|
140
|
-
</Stack>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
{showErrorNotification && (
|
|
144
|
-
<Column className={styles.errorContainer}>
|
|
145
|
-
<InlineNotification
|
|
146
|
-
lowContrast
|
|
147
|
-
title={t('error', 'Error')}
|
|
148
|
-
subtitle={t('pleaseFillRequiredFields', 'Please fill all the required fields') + '.'}
|
|
149
|
-
onClose={() => setShowErrorNotification(false)}
|
|
101
|
+
<Form className={styles.form}>
|
|
102
|
+
<div className={styles.grid}>
|
|
103
|
+
<Stack>
|
|
104
|
+
<section>
|
|
105
|
+
<h4 className={styles.orderDisplay}>{order?.display}</h4>
|
|
106
|
+
</section>
|
|
107
|
+
<section>
|
|
108
|
+
<Controller
|
|
109
|
+
name="cancellationDate"
|
|
110
|
+
control={control}
|
|
111
|
+
render={({ field, fieldState }) => (
|
|
112
|
+
<div className={styles.row}>
|
|
113
|
+
<OpenmrsDatePicker
|
|
114
|
+
{...field}
|
|
115
|
+
id="cancellationDate"
|
|
116
|
+
minDate={dayjs().startOf('day')}
|
|
117
|
+
labelText={t('cancellationDate', 'Cancellation date')}
|
|
118
|
+
invalid={Boolean(fieldState?.error?.message)}
|
|
119
|
+
invalidText={fieldState?.error?.message}
|
|
120
|
+
/>
|
|
121
|
+
</div>
|
|
122
|
+
)}
|
|
150
123
|
/>
|
|
151
|
-
</
|
|
152
|
-
|
|
124
|
+
</section>
|
|
125
|
+
<section>
|
|
126
|
+
<Controller
|
|
127
|
+
name="reasonForCancellation"
|
|
128
|
+
control={control}
|
|
129
|
+
render={({ field: { onChange, value } }) => (
|
|
130
|
+
<div className={styles.row}>
|
|
131
|
+
<TextArea
|
|
132
|
+
type="text"
|
|
133
|
+
id="reasonForCancellation"
|
|
134
|
+
labelText={t('reasonForCancellation', 'Reason for cancellation')}
|
|
135
|
+
value={value}
|
|
136
|
+
onChange={(evt) => onChange(evt.target.value)}
|
|
137
|
+
invalid={!!errors['reasonForCancellation']}
|
|
138
|
+
invalidText={!!errors['reasonForCancellation'] && errors['reasonForCancellation'].message}
|
|
139
|
+
/>
|
|
140
|
+
</div>
|
|
141
|
+
)}
|
|
142
|
+
/>
|
|
143
|
+
</section>
|
|
144
|
+
</Stack>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
{showErrorNotification && (
|
|
148
|
+
<Column className={styles.errorContainer}>
|
|
149
|
+
<InlineNotification
|
|
150
|
+
lowContrast
|
|
151
|
+
title={t('error', 'Error')}
|
|
152
|
+
subtitle={t('pleaseFillRequiredFields', 'Please fill all the required fields') + '.'}
|
|
153
|
+
onClose={() => setShowErrorNotification(false)}
|
|
154
|
+
/>
|
|
155
|
+
</Column>
|
|
156
|
+
)}
|
|
153
157
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
</Workspace2>
|
|
158
|
+
<ButtonSet className={isTablet ? styles.tablet : styles.desktop}>
|
|
159
|
+
<Button className={styles.button} kind="secondary" onClick={() => closeWorkspace()}>
|
|
160
|
+
{t('discard', 'Discard')}
|
|
161
|
+
</Button>
|
|
162
|
+
<Button
|
|
163
|
+
className={styles.button}
|
|
164
|
+
kind="primary"
|
|
165
|
+
onClick={handleSubmit(cancelOrderRequest, onError)}
|
|
166
|
+
disabled={isSubmitting}
|
|
167
|
+
type="submit"
|
|
168
|
+
>
|
|
169
|
+
{isSubmitting ? (
|
|
170
|
+
<InlineLoading description={t('saving', 'Saving') + '...'} />
|
|
171
|
+
) : (
|
|
172
|
+
t('saveAndClose', 'Save and close')
|
|
173
|
+
)}
|
|
174
|
+
</Button>
|
|
175
|
+
</ButtonSet>
|
|
176
|
+
</Form>
|
|
174
177
|
);
|
|
175
178
|
};
|
|
176
179
|
|
package/src/routes.json
CHANGED
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
"slot": "order-item-additional-info-slot",
|
|
22
22
|
"order": 1
|
|
23
23
|
},
|
|
24
|
+
{
|
|
25
|
+
"name": "order-basket-action-menu",
|
|
26
|
+
"component": "orderBasketActionMenu",
|
|
27
|
+
"slots": [
|
|
28
|
+
"action-menu-patient-chart-items-slot",
|
|
29
|
+
"action-menu-ward-patient-items-slot"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
24
32
|
{
|
|
25
33
|
"name": "lab-result",
|
|
26
34
|
"component": "labResult",
|
|
@@ -55,33 +63,33 @@
|
|
|
55
63
|
}
|
|
56
64
|
}
|
|
57
65
|
],
|
|
58
|
-
"
|
|
66
|
+
"workspaces": [
|
|
59
67
|
{
|
|
60
68
|
"name": "order-basket",
|
|
69
|
+
"title": "orderBasketWorkspaceTitle",
|
|
61
70
|
"component": "orderBasketWorkspace",
|
|
62
|
-
"
|
|
71
|
+
"type": "order",
|
|
72
|
+
"canHide": true
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "patient-orders-form-workspace",
|
|
76
|
+
"title": "orderCancellation",
|
|
77
|
+
"component": "patientOrdersFormWorkspace",
|
|
78
|
+
"type": "order",
|
|
79
|
+
"canHide": false
|
|
63
80
|
},
|
|
64
81
|
{
|
|
65
82
|
"name": "test-results-form-workspace",
|
|
83
|
+
"title": "enterTestResults",
|
|
66
84
|
"component": "testResultsFormWorkspace",
|
|
67
|
-
"
|
|
85
|
+
"type": "lab-results",
|
|
86
|
+
"canHide": false
|
|
68
87
|
},
|
|
69
88
|
{
|
|
70
89
|
"name": "orderable-concept-workspace",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
],
|
|
75
|
-
"workspaceWindows2": [
|
|
76
|
-
{
|
|
77
|
-
"name": "patient-chart-order-basket",
|
|
78
|
-
"icon": "ShoppingCartIcon",
|
|
79
|
-
"group": "patient-chart",
|
|
80
|
-
"order": 1
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
"name": "lab-results",
|
|
84
|
-
"group": "patient-chart"
|
|
90
|
+
"title": "searchOrderables",
|
|
91
|
+
"component": "orderableConceptSearch",
|
|
92
|
+
"type": "order"
|
|
85
93
|
}
|
|
86
94
|
],
|
|
87
95
|
"modals": [
|
package/src/utils/index.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type DrugOrderBasketItem,
|
|
3
|
-
type TestOrderBasketItem,
|
|
4
|
-
type Order,
|
|
5
|
-
type OrderAction,
|
|
6
|
-
type OrderBasketItem,
|
|
7
|
-
} from '@openmrs/esm-patient-common-lib';
|
|
1
|
+
import { type Order, type OrderAction, type OrderBasketItem } from '@openmrs/esm-patient-common-lib';
|
|
8
2
|
import { type ObservationValue } from '../types/encounter';
|
|
9
3
|
|
|
10
4
|
/**
|
|
@@ -30,7 +24,7 @@ export function compare<T>(x?: T, y?: T) {
|
|
|
30
24
|
/**
|
|
31
25
|
* Builds medication order object from the given order object
|
|
32
26
|
*/
|
|
33
|
-
export function buildMedicationOrder(order: Order, action?: OrderAction)
|
|
27
|
+
export function buildMedicationOrder(order: Order, action?: OrderAction) {
|
|
34
28
|
return {
|
|
35
29
|
display: order.drug?.display,
|
|
36
30
|
previousOrder: action !== 'NEW' ? order.uuid : null,
|
|
@@ -70,15 +64,13 @@ export function buildMedicationOrder(order: Order, action?: OrderAction): DrugOr
|
|
|
70
64
|
value: order.quantityUnits?.display,
|
|
71
65
|
valueCoded: order.quantityUnits?.uuid,
|
|
72
66
|
},
|
|
73
|
-
encounterUuid: order.encounter?.uuid,
|
|
74
|
-
visit: order.encounter.visit,
|
|
75
67
|
};
|
|
76
68
|
}
|
|
77
69
|
|
|
78
70
|
/**
|
|
79
71
|
* Builds lab order object from the given order object
|
|
80
72
|
*/
|
|
81
|
-
export function buildLabOrder(order: Order, action?: OrderAction)
|
|
73
|
+
export function buildLabOrder(order: Order, action?: OrderAction) {
|
|
82
74
|
return {
|
|
83
75
|
action: action,
|
|
84
76
|
display: order.display,
|
|
@@ -97,8 +89,6 @@ export function buildLabOrder(order: Order, action?: OrderAction): TestOrderBask
|
|
|
97
89
|
orderType: order.orderType.uuid,
|
|
98
90
|
specimenSource: null,
|
|
99
91
|
scheduledDate: order.scheduledDate ? new Date(order.scheduledDate) : null,
|
|
100
|
-
encounterUuid: order.encounter?.uuid,
|
|
101
|
-
visit: order.encounter.visit,
|
|
102
92
|
};
|
|
103
93
|
}
|
|
104
94
|
|
|
@@ -119,8 +109,6 @@ export function buildGeneralOrder(order: Order, action?: OrderAction): OrderBask
|
|
|
119
109
|
orderNumber: order.orderNumber,
|
|
120
110
|
orderType: order.orderType.uuid,
|
|
121
111
|
scheduledDate: order.scheduledDate ? new Date(order.scheduledDate) : null,
|
|
122
|
-
encounterUuid: order.encounter?.uuid,
|
|
123
|
-
visit: order.encounter.visit,
|
|
124
112
|
};
|
|
125
113
|
}
|
|
126
114
|
|
package/translations/am.json
CHANGED
|
@@ -4,31 +4,29 @@
|
|
|
4
4
|
"additionalInstructions": "Additional instructions",
|
|
5
5
|
"addMedication": "Add medication",
|
|
6
6
|
"addOrderableForOrderType": "Add {{orderTypeDisplay}}",
|
|
7
|
+
"addOrderTests": "Add Tests to this order",
|
|
7
8
|
"addResults": "Add results",
|
|
8
9
|
"allOrders": "All orders",
|
|
9
10
|
"backToOrderBasket": "Back to order basket",
|
|
10
11
|
"cancel": "Cancel",
|
|
11
|
-
"cancellationDate": "Cancellation date",
|
|
12
|
-
"cancellationDateRequired": "Cancellation date is required",
|
|
13
12
|
"cancelOrder": "Cancel order",
|
|
14
13
|
"checkFilters": "Check the filters above",
|
|
15
14
|
"chooseAnOption": "Choose an option",
|
|
16
15
|
"clearSearchResults": "Clear results",
|
|
17
|
-
"dateCannotBeBeforeToday": "Date cannot be before today",
|
|
18
16
|
"dateOfOrder": "Date of order",
|
|
19
17
|
"dateRange": "Date range",
|
|
20
18
|
"directlyAddToBasket": "Add to basket",
|
|
21
19
|
"discard": "Discard",
|
|
22
|
-
"discontinued": "Discontinued",
|
|
23
20
|
"dosage": "Dosage",
|
|
24
21
|
"dose": "Dose",
|
|
25
22
|
"drugOrders": "drug orders",
|
|
23
|
+
"editOrderableForOrderType": "Edit {{orderTypeDisplay}}",
|
|
26
24
|
"editResults": "Edit results",
|
|
27
25
|
"endDate": "End date",
|
|
28
26
|
"enterTestResults": "Enter test results",
|
|
29
27
|
"error": "Error",
|
|
30
|
-
"errorCancellingOrder": "Error cancelling order",
|
|
31
28
|
"errorFetchingTestTypes": "Error fetching results for \"{{searchTerm}}\"",
|
|
29
|
+
"errorSavingDrugOrder": "Error saving order",
|
|
32
30
|
"errorSavingLabResults": "Error saving lab results",
|
|
33
31
|
"goToDrugOrderForm": "Order form",
|
|
34
32
|
"indication": "Indication",
|
|
@@ -44,7 +42,6 @@
|
|
|
44
42
|
"loadingTestDetails": "Loading test details",
|
|
45
43
|
"medicationDurationAndUnit": "for {{duration}} {{durationUnit}}",
|
|
46
44
|
"medicationIndefiniteDuration": "Indefinite duration",
|
|
47
|
-
"medications": "Medications",
|
|
48
45
|
"modifyOrder": "Modify order",
|
|
49
46
|
"noIndicationProvided": "No indication provided",
|
|
50
47
|
"noMatchingOrdersToDisplay": "No matching orders to display",
|
|
@@ -63,11 +60,7 @@
|
|
|
63
60
|
"orderActionRevise": "Modify",
|
|
64
61
|
"orderBasket": "Order basket",
|
|
65
62
|
"orderBasketWorkspaceTitle": "Order basket",
|
|
66
|
-
"orderCancellation": "Order cancellation",
|
|
67
|
-
"orderCancelled": "Order cancelled",
|
|
68
|
-
"orderCompleted": "Placed orders",
|
|
69
63
|
"orderDetails": "Order details",
|
|
70
|
-
"ordered": "Placed order for",
|
|
71
64
|
"orderedBy": "Ordered by",
|
|
72
65
|
"ordererInformation": "Orderer information",
|
|
73
66
|
"orderNumber": "Order number",
|
|
@@ -77,7 +70,6 @@
|
|
|
77
70
|
"orderType": "Order type",
|
|
78
71
|
"outOfStock": "Out of stock",
|
|
79
72
|
"pleaseFillField": "Please fill at least one field",
|
|
80
|
-
"pleaseFillRequiredFields": "Please fill all the required fields",
|
|
81
73
|
"pleaseRequiredFields": "Please fill all required fields",
|
|
82
74
|
"price": "Price",
|
|
83
75
|
"priceDisclaimer": "This price is indicative and may not reflect final costs, which could vary due to discounts, insurance coverage, or other pricing rules",
|
|
@@ -87,8 +79,6 @@
|
|
|
87
79
|
"priority": "Priority",
|
|
88
80
|
"priorityRequired": "Priority is required",
|
|
89
81
|
"quantity": "Quantity",
|
|
90
|
-
"reasonForCancellation": "Reason for cancellation",
|
|
91
|
-
"reasonForCancellationRequired": "Reason for cancellation is required",
|
|
92
82
|
"referenceNumber": "Reference number",
|
|
93
83
|
"referenceNumberTableHeader": "{{orderType}} reference number",
|
|
94
84
|
"refills": "Refills",
|
|
@@ -99,30 +89,26 @@
|
|
|
99
89
|
"saveDrugOrderFailed": "Error ordering {{orderName}}",
|
|
100
90
|
"saveLabResults": "Save lab results",
|
|
101
91
|
"saveOrder": "Save order",
|
|
92
|
+
"saveTests": "Save tests",
|
|
102
93
|
"saving": "Saving",
|
|
103
94
|
"scheduledDate": "Scheduled date",
|
|
104
95
|
"scheduledDateRequired": "Scheduled date is required",
|
|
105
96
|
"searchAgain": "search again",
|
|
106
97
|
"searchFieldOrder": "Search for {{orderType}} order",
|
|
107
|
-
"searchOrderables": "Search orderables",
|
|
108
98
|
"searchResultsMatchesForTerm_one": "{{count}} results for \"{{searchTerm}}\"",
|
|
109
99
|
"searchResultsMatchesForTerm_other": "{{count}} results for \"{{searchTerm}}\"",
|
|
110
100
|
"searchTable": "Search table",
|
|
111
101
|
"selectOrderType": "Select order type",
|
|
112
102
|
"signAndClose": "Sign and close",
|
|
113
|
-
"startAVisitToRecordOrders": "Start a visit to order",
|
|
114
|
-
"startVisit": "Start visit",
|
|
115
103
|
"status": "Status",
|
|
116
|
-
"successfullyCancelledOrder": "Order {{orderNumber}} has been cancelled successfully",
|
|
117
104
|
"successfullySavedLabResults": "Lab results for {{orderNumber}} have been successfully updated",
|
|
105
|
+
"successSavingDrugOrder": "Order saved",
|
|
118
106
|
"test": "Test",
|
|
119
107
|
"testOrders": "test orders",
|
|
120
108
|
"testType": "Test type",
|
|
121
109
|
"tryReopeningTheWorkspaceAgain": "Please try launching the workspace again",
|
|
122
110
|
"trySearchingAgain": "Please try searching again",
|
|
123
111
|
"tryTo": "Try to",
|
|
124
|
-
"updated": "Updated",
|
|
125
112
|
"usingADifferentTerm": "using a different term",
|
|
126
|
-
"view": "View"
|
|
127
|
-
"visitRequired": "A visit is required to make orders"
|
|
113
|
+
"view": "View"
|
|
128
114
|
}
|