@openmrs/esm-patient-orders-app 11.3.1-pre.9452 → 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
|
@@ -1,53 +1,40 @@
|
|
|
1
|
-
import React, { type ComponentProps, useCallback,
|
|
1
|
+
import React, { type ComponentProps, useCallback, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { Button, Search } from '@carbon/react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import {
|
|
5
5
|
ArrowLeftIcon,
|
|
6
|
-
launchWorkspace,
|
|
7
6
|
ResponsiveWrapper,
|
|
8
7
|
useConfig,
|
|
9
8
|
useDebounce,
|
|
10
9
|
useLayoutType,
|
|
11
|
-
type
|
|
10
|
+
type Visit,
|
|
11
|
+
Workspace2,
|
|
12
|
+
type Workspace2DefinitionProps,
|
|
12
13
|
} from '@openmrs/esm-framework';
|
|
13
|
-
import {
|
|
14
|
-
type DefaultPatientWorkspaceProps,
|
|
15
|
-
type OrderBasketItem,
|
|
16
|
-
useOrderBasket,
|
|
17
|
-
useOrderType,
|
|
18
|
-
} from '@openmrs/esm-patient-common-lib';
|
|
14
|
+
import { type OrderBasketItem, useOrderBasket, useOrderType } from '@openmrs/esm-patient-common-lib';
|
|
19
15
|
import { OrderForm } from '../general-order-form/general-order-form.component';
|
|
20
16
|
import { prepOrderPostData } from '../resources';
|
|
21
17
|
import { type ConfigObject } from '../../../config-schema';
|
|
22
18
|
import OrderableConceptSearchResults from './search-results.component';
|
|
23
19
|
import styles from './orderable-concept-search.scss';
|
|
24
20
|
|
|
25
|
-
interface
|
|
26
|
-
|
|
21
|
+
interface AddGeneralOrderProps {
|
|
22
|
+
initialOrder: OrderBasketItem;
|
|
27
23
|
orderTypeUuid: string;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
export const careSettingUuid = '6f0c9a92-6f24-11e3-af88-005056821db0';
|
|
33
|
-
|
|
34
|
-
type DrugsOrOrders = Pick<OrderBasketItem, 'action' | 'concept'>;
|
|
35
|
-
|
|
36
|
-
export function ordersEqual(order1: DrugsOrOrders, order2: DrugsOrOrders) {
|
|
37
|
-
return order1.action === order2.action && order1.concept.uuid === order2.concept.uuid;
|
|
24
|
+
patient: fhir.Patient;
|
|
25
|
+
visitContext: Visit;
|
|
26
|
+
closeWorkspace: Workspace2DefinitionProps['closeWorkspace'];
|
|
38
27
|
}
|
|
39
28
|
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
/**
|
|
30
|
+
* This workspace displays the drug order form for adding or editing a general order.
|
|
31
|
+
*/
|
|
32
|
+
const AddGeneralOrder: React.FC<AddGeneralOrderProps> = ({
|
|
33
|
+
initialOrder,
|
|
42
34
|
orderTypeUuid,
|
|
43
|
-
closeWorkspace,
|
|
44
|
-
closeWorkspaceWithSavedChanges,
|
|
45
|
-
promptBeforeClosing,
|
|
46
|
-
setTitle,
|
|
47
|
-
patientUuid,
|
|
48
35
|
patient,
|
|
49
36
|
visitContext,
|
|
50
|
-
|
|
37
|
+
closeWorkspace,
|
|
51
38
|
}) => {
|
|
52
39
|
const { t } = useTranslation();
|
|
53
40
|
const isTablet = useLayoutType() === 'tablet';
|
|
@@ -55,16 +42,23 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
|
|
|
55
42
|
const { orderTypes } = useConfig<ConfigObject>();
|
|
56
43
|
const [currentOrder, setCurrentOrder] = useState(initialOrder);
|
|
57
44
|
const { orderType } = useOrderType(orderTypeUuid);
|
|
45
|
+
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
|
|
58
46
|
|
|
59
|
-
|
|
47
|
+
const title = useMemo(() => {
|
|
60
48
|
if (orderType) {
|
|
61
|
-
|
|
62
|
-
t(`
|
|
49
|
+
if (initialOrder?.action == 'REVISE') {
|
|
50
|
+
return t(`editOrderableForOrderType`, 'Edit {{orderTypeDisplay}}', {
|
|
63
51
|
orderTypeDisplay: orderType.display.toLocaleLowerCase(),
|
|
64
|
-
})
|
|
65
|
-
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
return t(`addOrderableForOrderType`, 'Add {{orderTypeDisplay}}', {
|
|
55
|
+
orderTypeDisplay: orderType.display.toLocaleLowerCase(),
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
return '';
|
|
66
60
|
}
|
|
67
|
-
}, [orderType, t,
|
|
61
|
+
}, [orderType, t, initialOrder?.action]);
|
|
68
62
|
|
|
69
63
|
const orderableConceptSets = useMemo(
|
|
70
64
|
() => orderTypes.find((orderType) => orderType.orderTypeUuid === orderTypeUuid).orderableConceptSets,
|
|
@@ -72,10 +66,7 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
|
|
|
72
66
|
);
|
|
73
67
|
|
|
74
68
|
const cancelDrugOrder = useCallback(() => {
|
|
75
|
-
closeWorkspace(
|
|
76
|
-
onWorkspaceClose: () => launchWorkspace('order-basket'),
|
|
77
|
-
closeWorkspaceGroup: false,
|
|
78
|
-
});
|
|
69
|
+
closeWorkspace();
|
|
79
70
|
}, [closeWorkspace]);
|
|
80
71
|
|
|
81
72
|
const openOrderForm = useCallback(
|
|
@@ -91,53 +82,51 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
|
|
|
91
82
|
);
|
|
92
83
|
|
|
93
84
|
return (
|
|
94
|
-
<
|
|
95
|
-
{
|
|
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
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
/>
|
|
130
|
-
)}
|
|
131
|
-
</div>
|
|
85
|
+
<Workspace2 title={title} hasUnsavedChanges={hasUnsavedChanges}>
|
|
86
|
+
<div className={styles.workspaceWrapper}>
|
|
87
|
+
{!isTablet && (
|
|
88
|
+
<div className={styles.backButton}>
|
|
89
|
+
<Button
|
|
90
|
+
iconDescription="Return to order basket"
|
|
91
|
+
kind="ghost"
|
|
92
|
+
onClick={cancelDrugOrder}
|
|
93
|
+
renderIcon={(props: ComponentProps<typeof ArrowLeftIcon>) => <ArrowLeftIcon size={24} {...props} />}
|
|
94
|
+
size="sm"
|
|
95
|
+
>
|
|
96
|
+
<span>{t('backToOrderBasket', 'Back to order basket')}</span>
|
|
97
|
+
</Button>
|
|
98
|
+
</div>
|
|
99
|
+
)}
|
|
100
|
+
{currentOrder ? (
|
|
101
|
+
<OrderForm
|
|
102
|
+
initialOrder={currentOrder}
|
|
103
|
+
closeWorkspace={closeWorkspace}
|
|
104
|
+
setHasUnsavedChanges={setHasUnsavedChanges}
|
|
105
|
+
orderTypeUuid={orderTypeUuid}
|
|
106
|
+
patient={patient}
|
|
107
|
+
/>
|
|
108
|
+
) : (
|
|
109
|
+
<ConceptSearch
|
|
110
|
+
openOrderForm={openOrderForm}
|
|
111
|
+
closeWorkspace={closeWorkspace}
|
|
112
|
+
orderableConceptSets={orderableConceptSets}
|
|
113
|
+
orderTypeUuid={orderTypeUuid}
|
|
114
|
+
patient={patient}
|
|
115
|
+
visit={visitContext}
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
118
|
+
</div>
|
|
119
|
+
</Workspace2>
|
|
132
120
|
);
|
|
133
121
|
};
|
|
134
122
|
|
|
135
123
|
interface ConceptSearchProps {
|
|
136
|
-
closeWorkspace:
|
|
124
|
+
closeWorkspace: Workspace2DefinitionProps['closeWorkspace'];
|
|
137
125
|
openOrderForm: (search: OrderBasketItem) => void;
|
|
138
126
|
orderTypeUuid: string;
|
|
139
127
|
orderableConceptSets: Array<string>;
|
|
140
128
|
patient: fhir.Patient;
|
|
129
|
+
visit: Visit;
|
|
141
130
|
}
|
|
142
131
|
|
|
143
132
|
function ConceptSearch({
|
|
@@ -146,6 +135,7 @@ function ConceptSearch({
|
|
|
146
135
|
openOrderForm,
|
|
147
136
|
orderableConceptSets,
|
|
148
137
|
patient,
|
|
138
|
+
visit,
|
|
149
139
|
}: ConceptSearchProps) {
|
|
150
140
|
const { t } = useTranslation();
|
|
151
141
|
const { orderType } = useOrderType(orderTypeUuid);
|
|
@@ -155,9 +145,7 @@ function ConceptSearch({
|
|
|
155
145
|
const searchInputRef = useRef(null);
|
|
156
146
|
|
|
157
147
|
const cancelDrugOrder = useCallback(() => {
|
|
158
|
-
closeWorkspace(
|
|
159
|
-
onWorkspaceClose: () => launchWorkspace('order-basket'),
|
|
160
|
-
});
|
|
148
|
+
closeWorkspace();
|
|
161
149
|
}, [closeWorkspace]);
|
|
162
150
|
|
|
163
151
|
const focusAndClearSearchInput = () => {
|
|
@@ -191,11 +179,12 @@ function ConceptSearch({
|
|
|
191
179
|
searchTerm={debouncedSearchTerm}
|
|
192
180
|
openOrderForm={openOrderForm}
|
|
193
181
|
focusAndClearSearchInput={focusAndClearSearchInput}
|
|
194
|
-
closeWorkspace={closeWorkspace}
|
|
195
182
|
orderTypeUuid={orderTypeUuid}
|
|
196
183
|
cancelOrder={() => {}}
|
|
197
184
|
orderableConceptSets={orderableConceptSets}
|
|
185
|
+
closeWorkspace={closeWorkspace}
|
|
198
186
|
patient={patient}
|
|
187
|
+
visit={visit}
|
|
199
188
|
/>
|
|
200
189
|
{isTablet && (
|
|
201
190
|
<div className={styles.separatorContainer}>
|
|
@@ -209,4 +198,10 @@ function ConceptSearch({
|
|
|
209
198
|
);
|
|
210
199
|
}
|
|
211
200
|
|
|
212
|
-
|
|
201
|
+
type DrugsOrOrders = Pick<OrderBasketItem, 'action' | 'concept'>;
|
|
202
|
+
|
|
203
|
+
function ordersEqual(order1: DrugsOrOrders, order2: DrugsOrOrders) {
|
|
204
|
+
return order1.action === order2.action && order1.concept.uuid === order2.concept.uuid;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export default AddGeneralOrder;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
type OrderBasketItem,
|
|
4
|
+
type OrderBasketWindowProps,
|
|
5
|
+
type PatientWorkspace2DefinitionProps,
|
|
6
|
+
} from '@openmrs/esm-patient-common-lib';
|
|
7
|
+
import AddGeneralOrder from './add-general-order.component';
|
|
8
|
+
|
|
9
|
+
interface OrderableConceptSearchWorkspaceProps {
|
|
10
|
+
order: OrderBasketItem;
|
|
11
|
+
orderTypeUuid: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* This workspace displays the order form for adding or editing a general order.
|
|
16
|
+
*
|
|
17
|
+
* This workspace must only be used within the patient chart.
|
|
18
|
+
* @see exported-add-general-order.workspace.tsx
|
|
19
|
+
*/
|
|
20
|
+
const AddGeneralOrderWorkspace: React.FC<
|
|
21
|
+
PatientWorkspace2DefinitionProps<OrderableConceptSearchWorkspaceProps, OrderBasketWindowProps>
|
|
22
|
+
> = ({
|
|
23
|
+
workspaceProps: { order: initialOrder, orderTypeUuid },
|
|
24
|
+
groupProps: { patient, visitContext, mutateVisitContext },
|
|
25
|
+
closeWorkspace,
|
|
26
|
+
}) => {
|
|
27
|
+
return (
|
|
28
|
+
<AddGeneralOrder
|
|
29
|
+
initialOrder={initialOrder}
|
|
30
|
+
orderTypeUuid={orderTypeUuid}
|
|
31
|
+
patient={patient}
|
|
32
|
+
visitContext={visitContext}
|
|
33
|
+
closeWorkspace={closeWorkspace}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default AddGeneralOrderWorkspace;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type Workspace2DefinitionProps } from '@openmrs/esm-framework';
|
|
3
|
+
import { type ExportedOrderBasketWindowProps, type OrderBasketItem } from '@openmrs/esm-patient-common-lib';
|
|
4
|
+
import AddGeneralOrder from './add-general-order.component';
|
|
5
|
+
|
|
6
|
+
interface OrderableConceptSearchWorkspaceProps {
|
|
7
|
+
order: OrderBasketItem;
|
|
8
|
+
orderTypeUuid: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* This workspace displays the drug order form for adding or editing a general order.
|
|
13
|
+
*
|
|
14
|
+
* This workspace is meant for use outside the patient chart.
|
|
15
|
+
* @see exported-add-general-order.workspace.tsx
|
|
16
|
+
*/
|
|
17
|
+
const ExportedAddGeneralOrderWorkspace: React.FC<
|
|
18
|
+
Workspace2DefinitionProps<OrderableConceptSearchWorkspaceProps, ExportedOrderBasketWindowProps, {}>
|
|
19
|
+
> = ({
|
|
20
|
+
workspaceProps: { order: initialOrder, orderTypeUuid },
|
|
21
|
+
windowProps: { patient, visitContext },
|
|
22
|
+
closeWorkspace,
|
|
23
|
+
}) => {
|
|
24
|
+
return (
|
|
25
|
+
<AddGeneralOrder
|
|
26
|
+
initialOrder={initialOrder}
|
|
27
|
+
orderTypeUuid={orderTypeUuid}
|
|
28
|
+
patient={patient}
|
|
29
|
+
visitContext={visitContext}
|
|
30
|
+
closeWorkspace={closeWorkspace}
|
|
31
|
+
/>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default ExportedAddGeneralOrderWorkspace;
|
|
@@ -4,12 +4,12 @@ import { ShoppingCartArrowUp } from '@carbon/react/icons';
|
|
|
4
4
|
import { Tile, Button, SkeletonText, ButtonSkeleton } from '@carbon/react';
|
|
5
5
|
import { useTranslation } from 'react-i18next';
|
|
6
6
|
import {
|
|
7
|
+
type Workspace2DefinitionProps,
|
|
7
8
|
ArrowRightIcon,
|
|
8
|
-
type DefaultWorkspaceProps,
|
|
9
9
|
ShoppingCartArrowDownIcon,
|
|
10
10
|
useLayoutType,
|
|
11
11
|
useSession,
|
|
12
|
-
|
|
12
|
+
type Visit,
|
|
13
13
|
} from '@openmrs/esm-framework';
|
|
14
14
|
import {
|
|
15
15
|
useOrderBasket,
|
|
@@ -27,8 +27,9 @@ interface OrderableConceptSearchResultsProps {
|
|
|
27
27
|
cancelOrder: () => void;
|
|
28
28
|
orderableConceptSets: Array<string>;
|
|
29
29
|
orderTypeUuid: string;
|
|
30
|
-
closeWorkspace:
|
|
30
|
+
closeWorkspace: Workspace2DefinitionProps['closeWorkspace'];
|
|
31
31
|
patient: fhir.Patient;
|
|
32
|
+
visit: Visit;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps> = ({
|
|
@@ -40,6 +41,7 @@ const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps
|
|
|
40
41
|
orderTypeUuid,
|
|
41
42
|
closeWorkspace,
|
|
42
43
|
patient,
|
|
44
|
+
visit,
|
|
43
45
|
}) => {
|
|
44
46
|
const { t } = useTranslation();
|
|
45
47
|
const isTablet = useLayoutType() === 'tablet';
|
|
@@ -92,6 +94,7 @@ const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps
|
|
|
92
94
|
orderTypeUuid={orderTypeUuid}
|
|
93
95
|
closeWorkspace={closeWorkspace}
|
|
94
96
|
patient={patient}
|
|
97
|
+
visit={visit}
|
|
95
98
|
/>
|
|
96
99
|
))}
|
|
97
100
|
</div>
|
|
@@ -156,8 +159,9 @@ interface TestTypeSearchResultItemProps {
|
|
|
156
159
|
concept: OrderableConcept;
|
|
157
160
|
openOrderForm: (searchResult: OrderBasketItem) => void;
|
|
158
161
|
orderTypeUuid: string;
|
|
159
|
-
closeWorkspace:
|
|
162
|
+
closeWorkspace: Workspace2DefinitionProps['closeWorkspace'];
|
|
160
163
|
patient: fhir.Patient;
|
|
164
|
+
visit: Visit;
|
|
161
165
|
}
|
|
162
166
|
|
|
163
167
|
const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
|
|
@@ -166,6 +170,7 @@ const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
|
|
|
166
170
|
orderTypeUuid,
|
|
167
171
|
closeWorkspace,
|
|
168
172
|
patient,
|
|
173
|
+
visit,
|
|
169
174
|
}) => {
|
|
170
175
|
const { t } = useTranslation();
|
|
171
176
|
const isTablet = useLayoutType() === 'tablet';
|
|
@@ -178,22 +183,18 @@ const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
|
|
|
178
183
|
);
|
|
179
184
|
|
|
180
185
|
const createOrderBasketItem = useCallback(
|
|
181
|
-
(testType: OrderableConcept) => {
|
|
182
|
-
return createEmptyOrder(testType, session.currentProvider?.uuid);
|
|
186
|
+
(testType: OrderableConcept, visit: Visit) => {
|
|
187
|
+
return createEmptyOrder(testType, session.currentProvider?.uuid, visit);
|
|
183
188
|
},
|
|
184
189
|
[session.currentProvider.uuid],
|
|
185
190
|
);
|
|
186
191
|
|
|
187
192
|
const addToBasket = useCallback(() => {
|
|
188
|
-
const orderBasketItem = createOrderBasketItem(concept);
|
|
193
|
+
const orderBasketItem = createOrderBasketItem(concept, visit);
|
|
189
194
|
orderBasketItem.isOrderIncomplete = true;
|
|
190
195
|
setOrders([...orders, orderBasketItem]);
|
|
191
|
-
closeWorkspace({
|
|
192
|
-
|
|
193
|
-
onWorkspaceClose: () => launchWorkspace('order-basket'),
|
|
194
|
-
closeWorkspaceGroup: false,
|
|
195
|
-
});
|
|
196
|
-
}, [orders, setOrders, createOrderBasketItem, concept, closeWorkspace]);
|
|
196
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
197
|
+
}, [orders, setOrders, createOrderBasketItem, concept, closeWorkspace, visit]);
|
|
197
198
|
|
|
198
199
|
const removeFromBasket = useCallback(() => {
|
|
199
200
|
setOrders(orders.filter((order) => order?.concept?.uuid !== concept?.uuid));
|
|
@@ -232,7 +233,7 @@ const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
|
|
|
232
233
|
<Button
|
|
233
234
|
kind="ghost"
|
|
234
235
|
renderIcon={(props: ComponentProps<typeof ArrowRightIcon>) => <ArrowRightIcon size={16} {...props} />}
|
|
235
|
-
onClick={() => openOrderForm(createOrderBasketItem(concept))}
|
|
236
|
+
onClick={() => openOrderForm(createOrderBasketItem(concept, visit))}
|
|
236
237
|
>
|
|
237
238
|
{t('goToDrugOrderForm', 'Order form')}
|
|
238
239
|
</Button>
|
package/src/order-basket/general-order-type/general-order-form/general-order-form.component.tsx
CHANGED
|
@@ -19,11 +19,12 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
19
19
|
import { z } from 'zod';
|
|
20
20
|
import {
|
|
21
21
|
priorityOptions,
|
|
22
|
-
type DefaultPatientWorkspaceProps,
|
|
23
22
|
type OrderBasketItem,
|
|
24
23
|
type OrderUrgency,
|
|
25
24
|
useOrderBasket,
|
|
26
25
|
useOrderType,
|
|
26
|
+
postOrder,
|
|
27
|
+
useMutatePatientOrders,
|
|
27
28
|
} from '@openmrs/esm-patient-common-lib';
|
|
28
29
|
import {
|
|
29
30
|
useLayoutType,
|
|
@@ -31,37 +32,40 @@ import {
|
|
|
31
32
|
useConfig,
|
|
32
33
|
ExtensionSlot,
|
|
33
34
|
OpenmrsDatePicker,
|
|
34
|
-
|
|
35
|
+
type Workspace2DefinitionProps,
|
|
36
|
+
showSnackbar,
|
|
37
|
+
useAbortController,
|
|
35
38
|
} from '@openmrs/esm-framework';
|
|
36
39
|
import { ordersEqual, prepOrderPostData } from '../resources';
|
|
37
40
|
import { type ConfigObject } from '../../../config-schema';
|
|
38
41
|
import styles from './general-order-form.scss';
|
|
39
42
|
|
|
40
|
-
export interface OrderFormProps
|
|
43
|
+
export interface OrderFormProps {
|
|
41
44
|
initialOrder: OrderBasketItem;
|
|
42
45
|
orderTypeUuid: string;
|
|
43
|
-
|
|
46
|
+
closeWorkspace: Workspace2DefinitionProps['closeWorkspace'];
|
|
47
|
+
setHasUnsavedChanges: (hasUnsavedChanges: boolean) => void;
|
|
48
|
+
patient: fhir.Patient;
|
|
44
49
|
}
|
|
45
50
|
|
|
46
51
|
// Designs:
|
|
47
52
|
// https://app.zeplin.io/project/60d5947dd636aebbd63dce4c/screen/640b06c440ee3f7af8747620
|
|
48
53
|
// https://app.zeplin.io/project/60d5947dd636aebbd63dce4c/screen/640b06d286e0aa7b0316db4a
|
|
49
54
|
export function OrderForm({
|
|
50
|
-
initialOrder,
|
|
51
|
-
closeWorkspace,
|
|
52
|
-
closeWorkspaceWithSavedChanges,
|
|
53
|
-
promptBeforeClosing,
|
|
54
55
|
patient,
|
|
56
|
+
initialOrder,
|
|
55
57
|
orderTypeUuid,
|
|
58
|
+
closeWorkspace,
|
|
59
|
+
setHasUnsavedChanges,
|
|
56
60
|
}: OrderFormProps) {
|
|
57
61
|
const { t } = useTranslation();
|
|
58
62
|
const isTablet = useLayoutType() === 'tablet';
|
|
59
63
|
const session = useSession();
|
|
60
|
-
const
|
|
61
|
-
const { orders, setOrders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
|
|
64
|
+
const { orders, setOrders, clearOrders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
|
|
62
65
|
const [showErrorNotification, setShowErrorNotification] = useState(false);
|
|
63
66
|
const { orderType } = useOrderType(orderTypeUuid);
|
|
64
67
|
const config = useConfig<ConfigObject>();
|
|
68
|
+
const { mutate: mutateOrders } = useMutatePatientOrders(patient.id);
|
|
65
69
|
|
|
66
70
|
const OrderFormSchema = useMemo(
|
|
67
71
|
() =>
|
|
@@ -108,7 +112,7 @@ export function OrderForm({
|
|
|
108
112
|
return menu?.item?.value?.toLowerCase().includes(menu?.inputValue?.toLowerCase());
|
|
109
113
|
}, []);
|
|
110
114
|
|
|
111
|
-
const
|
|
115
|
+
const saveOrderToBasket = useCallback(
|
|
112
116
|
(data: OrderBasketItem) => {
|
|
113
117
|
const finalizedOrder: OrderBasketItem = {
|
|
114
118
|
...initialOrder,
|
|
@@ -131,22 +135,55 @@ export function OrderForm({
|
|
|
131
135
|
|
|
132
136
|
setOrders(newOrders);
|
|
133
137
|
|
|
134
|
-
|
|
135
|
-
onWorkspaceClose: () => launchWorkspace('order-basket'),
|
|
136
|
-
closeWorkspaceGroup: false,
|
|
137
|
-
});
|
|
138
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
138
139
|
},
|
|
139
|
-
[orders, setOrders, session?.currentProvider?.uuid,
|
|
140
|
+
[orders, setOrders, session?.currentProvider?.uuid, initialOrder, closeWorkspace],
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const submitDrugOrderToServer = useCallback(
|
|
144
|
+
(data: OrderBasketItem) => {
|
|
145
|
+
const finalizedOrder: OrderBasketItem = {
|
|
146
|
+
...initialOrder,
|
|
147
|
+
...data,
|
|
148
|
+
};
|
|
149
|
+
finalizedOrder.orderer = session.currentProvider.uuid;
|
|
150
|
+
|
|
151
|
+
postOrder(prepOrderPostData(finalizedOrder, patient.id, finalizedOrder?.encounterUuid))
|
|
152
|
+
.then(() => {
|
|
153
|
+
clearOrders();
|
|
154
|
+
mutateOrders();
|
|
155
|
+
showSnackbar({
|
|
156
|
+
isLowContrast: false,
|
|
157
|
+
kind: 'success',
|
|
158
|
+
title: t('successSavingDrugOrder', 'Order saved'),
|
|
159
|
+
});
|
|
160
|
+
closeWorkspace({ discardUnsavedChanges: true });
|
|
161
|
+
})
|
|
162
|
+
.catch((error) => {
|
|
163
|
+
showSnackbar({
|
|
164
|
+
isLowContrast: false,
|
|
165
|
+
kind: 'error',
|
|
166
|
+
title: t('errorSavingDrugOrder', 'Error saving order'),
|
|
167
|
+
subtitle: error,
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
},
|
|
171
|
+
[clearOrders, closeWorkspace, initialOrder, mutateOrders, patient.id, session.currentProvider.uuid, t],
|
|
140
172
|
);
|
|
141
173
|
|
|
142
174
|
const cancelOrder = useCallback(() => {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
175
|
+
closeWorkspace().then((didClose: boolean) => {
|
|
176
|
+
if (didClose) {
|
|
177
|
+
setOrders(orders.filter((order) => order.concept.uuid !== defaultValues.concept.conceptUuid));
|
|
178
|
+
}
|
|
147
179
|
});
|
|
148
180
|
}, [closeWorkspace, orders, setOrders, defaultValues]);
|
|
149
181
|
|
|
182
|
+
const closeModifyOrderWorkspace = useCallback(() => {
|
|
183
|
+
clearOrders();
|
|
184
|
+
closeWorkspace();
|
|
185
|
+
}, [clearOrders, closeWorkspace]);
|
|
186
|
+
|
|
150
187
|
const onError = (errors: FieldErrors<OrderBasketItem>) => {
|
|
151
188
|
if (errors) {
|
|
152
189
|
setShowErrorNotification(true);
|
|
@@ -164,20 +201,24 @@ export function OrderForm({
|
|
|
164
201
|
};
|
|
165
202
|
|
|
166
203
|
useEffect(() => {
|
|
167
|
-
|
|
168
|
-
}, [isDirty,
|
|
204
|
+
setHasUnsavedChanges(isDirty);
|
|
205
|
+
}, [isDirty, setHasUnsavedChanges]);
|
|
169
206
|
|
|
170
207
|
const responsiveSize = isTablet ? 'lg' : 'sm';
|
|
171
208
|
|
|
172
209
|
return (
|
|
173
210
|
<>
|
|
174
|
-
<Form
|
|
211
|
+
<Form
|
|
212
|
+
className={styles.orderForm}
|
|
213
|
+
onSubmit={handleSubmit(initialOrder?.action == 'REVISE' ? submitDrugOrderToServer : saveOrderToBasket, onError)}
|
|
214
|
+
id="drugOrderForm"
|
|
215
|
+
>
|
|
175
216
|
<div className={styles.form}>
|
|
176
217
|
<ExtensionSlot name="top-of-lab-order-form-slot" state={{ order: initialOrder }} />
|
|
177
218
|
<Grid className={styles.gridRow}>
|
|
178
219
|
<Column lg={16} md={8} sm={4}>
|
|
179
220
|
<InputWrapper>
|
|
180
|
-
<
|
|
221
|
+
<label className={styles.testTypeLabel}>{t('testType', 'Test type')}</label>
|
|
181
222
|
<p className={styles.testType}>{initialOrder?.concept?.display}</p>
|
|
182
223
|
</InputWrapper>
|
|
183
224
|
</Column>
|
|
@@ -294,7 +335,12 @@ export function OrderForm({
|
|
|
294
335
|
<ButtonSet
|
|
295
336
|
className={classNames(styles.buttonSet, isTablet ? styles.tabletButtonSet : styles.desktopButtonSet)}
|
|
296
337
|
>
|
|
297
|
-
<Button
|
|
338
|
+
<Button
|
|
339
|
+
className={styles.button}
|
|
340
|
+
kind="secondary"
|
|
341
|
+
onClick={initialOrder?.action == 'REVISE' ? closeModifyOrderWorkspace : cancelOrder}
|
|
342
|
+
size="xl"
|
|
343
|
+
>
|
|
298
344
|
{t('discard', 'Discard')}
|
|
299
345
|
</Button>
|
|
300
346
|
<Button className={styles.button} kind="primary" size="xl" type="submit">
|