@openmrs/esm-patient-orders-app 11.3.1-pre.9294 → 11.3.1-pre.9304

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/.turbo/turbo-build.log +5 -5
  2. package/dist/1119.js +1 -1
  3. package/dist/1197.js +1 -1
  4. package/dist/2146.js +1 -1
  5. package/dist/2690.js +1 -1
  6. package/dist/3099.js +1 -1
  7. package/dist/3584.js +1 -1
  8. package/dist/4055.js +1 -1
  9. package/dist/4132.js +1 -1
  10. package/dist/4300.js +1 -1
  11. package/dist/4335.js +1 -1
  12. package/dist/4618.js +1 -1
  13. package/dist/4652.js +1 -1
  14. package/dist/4944.js +1 -1
  15. package/dist/5173.js +1 -1
  16. package/dist/5241.js +1 -1
  17. package/dist/5442.js +1 -1
  18. package/dist/5661.js +1 -1
  19. package/dist/6022.js +1 -1
  20. package/dist/6468.js +1 -1
  21. package/dist/6679.js +1 -1
  22. package/dist/6840.js +1 -1
  23. package/dist/6859.js +1 -1
  24. package/dist/7097.js +1 -1
  25. package/dist/7159.js +1 -1
  26. package/dist/7202.js +1 -1
  27. package/dist/7202.js.map +1 -1
  28. package/dist/723.js +1 -1
  29. package/dist/7617.js +1 -1
  30. package/dist/795.js +1 -1
  31. package/dist/8163.js +1 -1
  32. package/dist/8349.js +1 -1
  33. package/dist/8618.js +1 -1
  34. package/dist/8625.js +1 -1
  35. package/dist/8625.js.map +1 -1
  36. package/dist/8803.js +1 -1
  37. package/dist/8803.js.map +1 -1
  38. package/dist/890.js +1 -1
  39. package/dist/8960.js +1 -1
  40. package/dist/8960.js.map +1 -1
  41. package/dist/9214.js +1 -1
  42. package/dist/9538.js +1 -1
  43. package/dist/9569.js +1 -1
  44. package/dist/986.js +1 -1
  45. package/dist/9879.js +1 -1
  46. package/dist/9895.js +1 -1
  47. package/dist/9900.js +1 -1
  48. package/dist/9913.js +1 -1
  49. package/dist/main.js +1 -1
  50. package/dist/main.js.map +1 -1
  51. package/dist/openmrs-esm-patient-orders-app.js +1 -1
  52. package/dist/openmrs-esm-patient-orders-app.js.buildmanifest.json +133 -133
  53. package/dist/routes.json +1 -1
  54. package/package.json +2 -2
  55. package/src/api/api.ts +16 -9
  56. package/src/components/order-details-table.component.tsx +16 -6
  57. package/src/lab-results/lab-results-form.test.tsx +2 -0
  58. package/src/order-basket/general-order-type/general-order-form/general-order-form.component.tsx +2 -1
  59. package/src/order-basket/general-order-type/general-order-type.component.tsx +3 -2
  60. package/src/order-basket/general-order-type/orderable-concept-search/orderable-concept-search.workspace.tsx +19 -5
  61. package/src/order-basket/general-order-type/orderable-concept-search/search-results.component.tsx +6 -1
  62. package/src/order-basket/order-basket.workspace.tsx +37 -16
  63. package/src/order-basket-action-button/order-basket-action-button.extension.tsx +11 -3
  64. package/src/order-basket-action-button/order-basket-action-button.test.tsx +6 -30
  65. package/translations/am.json +0 -1
  66. package/translations/ar.json +0 -1
  67. package/translations/ar_SY.json +0 -1
  68. package/translations/bn.json +0 -1
  69. package/translations/de.json +0 -1
  70. package/translations/en.json +0 -1
  71. package/translations/en_US.json +0 -1
  72. package/translations/es.json +0 -1
  73. package/translations/es_MX.json +0 -1
  74. package/translations/fr.json +0 -1
  75. package/translations/he.json +0 -1
  76. package/translations/hi.json +0 -1
  77. package/translations/hi_IN.json +0 -1
  78. package/translations/id.json +0 -1
  79. package/translations/it.json +0 -1
  80. package/translations/ka.json +0 -1
  81. package/translations/km.json +0 -1
  82. package/translations/ku.json +0 -1
  83. package/translations/ky.json +0 -1
  84. package/translations/lg.json +0 -1
  85. package/translations/ne.json +0 -1
  86. package/translations/pl.json +0 -1
  87. package/translations/pt.json +0 -1
  88. package/translations/pt_BR.json +0 -1
  89. package/translations/qu.json +0 -1
  90. package/translations/ro_RO.json +0 -1
  91. package/translations/ru_RU.json +0 -1
  92. package/translations/si.json +0 -1
  93. package/translations/sw.json +0 -1
  94. package/translations/sw_KE.json +0 -1
  95. package/translations/tr.json +0 -1
  96. package/translations/tr_TR.json +0 -1
  97. package/translations/uk.json +0 -1
  98. package/translations/uz.json +0 -1
  99. package/translations/uz@Latn.json +0 -1
  100. package/translations/uz_UZ.json +0 -1
  101. package/translations/vi.json +0 -1
  102. package/translations/zh.json +0 -1
  103. package/translations/zh_CN.json +0 -1
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.2.0"},"optionalBackendDependencies":{"fhirproxy":"^1.0.0-SNAPSHOT","stockmanagement":"^1.4.0 || ^2.0.0 || >=3.0.0-0","billing":"^1.2.0-SNAPSHOT"},"extensions":[{"name":"order-price-details","component":"orderPriceDetailsExtension","slot":"order-item-additional-info-slot","order":0},{"name":"order-stock-details","component":"orderStockDetailsExtension","slot":"order-item-additional-info-slot","order":1},{"name":"order-basket-action-menu","component":"orderBasketActionMenu","slots":["action-menu-patient-chart-items-slot","action-menu-ward-patient-items-slot"]},{"name":"lab-result","component":"labResult","slot":"completed-lab-order-results-slot","meta":{"fullWidth":false}},{"name":"print-lab-results-action-button","component":"printLabResultsButton","slot":"print-lab-results-action-button-slot","meta":{"fullWidth":false}},{"name":"patient-orders-summary-dashboard","component":"ordersDashboardLink","slot":"patient-chart-dashboard-slot","meta":{"slot":"patient-chart-orders-dashboard-slot","path":"Orders","hideDashboardTitle":true},"order":4},{"name":"patient-orders-dashboard","component":"ordersDashboard","slot":"patient-chart-orders-dashboard-slot","meta":{"fullWidth":false}}],"workspaces":[{"name":"order-basket","title":"orderBasketWorkspaceTitle","component":"orderBasketWorkspace","type":"order","canHide":true},{"name":"patient-orders-form-workspace","title":"orderCancellation","component":"patientOrdersFormWorkspace","type":"order","canHide":false},{"name":"test-results-form-workspace","title":"enterTestResults","component":"testResultsFormWorkspace","type":"lab-results","canHide":false},{"name":"orderable-concept-workspace","title":"searchOrderables","component":"orderableConceptSearch","type":"order"}],"modals":[{"component":"printLabResultModal","name":"print-lab-results-modal"}],"version":"11.3.1-pre.9294"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"webservices.rest":">=2.2.0"},"optionalBackendDependencies":{"fhirproxy":"^1.0.0-SNAPSHOT","stockmanagement":"^1.4.0 || ^2.0.0 || >=3.0.0-0","billing":"^1.2.0-SNAPSHOT"},"extensions":[{"name":"order-price-details","component":"orderPriceDetailsExtension","slot":"order-item-additional-info-slot","order":0},{"name":"order-stock-details","component":"orderStockDetailsExtension","slot":"order-item-additional-info-slot","order":1},{"name":"order-basket-action-menu","component":"orderBasketActionMenu","slots":["action-menu-patient-chart-items-slot","action-menu-ward-patient-items-slot"]},{"name":"lab-result","component":"labResult","slot":"completed-lab-order-results-slot","meta":{"fullWidth":false}},{"name":"print-lab-results-action-button","component":"printLabResultsButton","slot":"print-lab-results-action-button-slot","meta":{"fullWidth":false}},{"name":"patient-orders-summary-dashboard","component":"ordersDashboardLink","slot":"patient-chart-dashboard-slot","meta":{"slot":"patient-chart-orders-dashboard-slot","path":"Orders","hideDashboardTitle":true},"order":4},{"name":"patient-orders-dashboard","component":"ordersDashboard","slot":"patient-chart-orders-dashboard-slot","meta":{"fullWidth":false}}],"workspaces":[{"name":"order-basket","title":"orderBasketWorkspaceTitle","component":"orderBasketWorkspace","type":"order","canHide":true},{"name":"patient-orders-form-workspace","title":"orderCancellation","component":"patientOrdersFormWorkspace","type":"order","canHide":false},{"name":"test-results-form-workspace","title":"enterTestResults","component":"testResultsFormWorkspace","type":"lab-results","canHide":false},{"name":"orderable-concept-workspace","title":"searchOrderables","component":"orderableConceptSearch","type":"order"}],"modals":[{"component":"printLabResultModal","name":"print-lab-results-modal"}],"version":"11.3.1-pre.9304"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-patient-orders-app",
3
- "version": "11.3.1-pre.9294",
3
+ "version": "11.3.1-pre.9304",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Microfrontend for the OpenMRS SPA providing the order basket for the patient chart",
6
6
  "browser": "dist/openmrs-esm-patient-orders-app.js",
@@ -52,7 +52,7 @@
52
52
  "swr": "2.x"
53
53
  },
54
54
  "devDependencies": {
55
- "@openmrs/esm-patient-common-lib": "11.3.1-pre.9294",
55
+ "@openmrs/esm-patient-common-lib": "11.3.1-pre.9304",
56
56
  "webpack": "^5.99.9"
57
57
  },
58
58
  "stableVersion": "11.3.0"
package/src/api/api.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import { useCallback, useMemo } from 'react';
2
2
  import useSWR, { useSWRConfig } from 'swr';
3
- import { type FetchResponse, openmrsFetch, type OpenmrsResource, restBaseUrl } from '@openmrs/esm-framework';
4
- import { useSystemVisitSetting, useVisitOrOfflineVisit } from '@openmrs/esm-patient-common-lib';
3
+ import {
4
+ type FetchResponse,
5
+ openmrsFetch,
6
+ type OpenmrsResource,
7
+ restBaseUrl,
8
+ type Visit,
9
+ } from '@openmrs/esm-framework';
10
+ import { useSystemVisitSetting } from '@openmrs/esm-patient-common-lib';
5
11
 
6
12
  export const careSettingUuid = '6f0c9a92-6f24-11e3-af88-005056821db0';
7
13
 
@@ -43,6 +49,8 @@ export function getMedicationByUuid(abortController: AbortController, orderUuid:
43
49
 
44
50
  export function useOrderEncounter(
45
51
  patientUuid: string,
52
+ visit: Visit,
53
+ mutateVisit: () => void,
46
54
  encounterTypeUuid: string,
47
55
  ): {
48
56
  visitRequired: boolean;
@@ -61,7 +69,6 @@ export function useOrderEncounter(
61
69
  : null,
62
70
  openmrsFetch,
63
71
  );
64
- const visit = useVisitOrOfflineVisit(patientUuid);
65
72
 
66
73
  const results = useMemo(() => {
67
74
  if (isLoadingSystemVisitSetting || errorFetchingSystemVisitSetting) {
@@ -76,12 +83,11 @@ export function useOrderEncounter(
76
83
  return systemVisitEnabled
77
84
  ? {
78
85
  visitRequired: true,
79
- isLoading: visit?.isLoading,
80
- encounterUuid: visit?.currentVisit?.encounters?.find(
81
- (encounter) => encounter.encounterType?.uuid === encounterTypeUuid,
82
- )?.uuid,
83
- error: visit?.error,
84
- mutate: visit?.mutate,
86
+ isLoading: false,
87
+ encounterUuid: visit?.encounters?.find((encounter) => encounter.encounterType?.uuid === encounterTypeUuid)
88
+ ?.uuid,
89
+ error: null,
90
+ mutate: mutateVisit,
85
91
  }
86
92
  : {
87
93
  visitRequired: false,
@@ -94,6 +100,7 @@ export function useOrderEncounter(
94
100
  isLoadingSystemVisitSetting,
95
101
  errorFetchingSystemVisitSetting,
96
102
  visit,
103
+ mutateVisit,
97
104
  todayEncounter,
98
105
  systemVisitEnabled,
99
106
  encounterTypeUuid,
@@ -78,6 +78,8 @@ interface OrderBasketItemActionsProps {
78
78
  openOrderBasket: () => void;
79
79
  launchOrderForm: (additionalProps?: { order: MutableOrderBasketItem }) => void;
80
80
  orderItem: Order;
81
+ responsiveSize: 'lg' | 'md' | 'sm';
82
+ patient: fhir.Patient;
81
83
  }
82
84
 
83
85
  interface OrderHeaderProps {
@@ -101,10 +103,10 @@ const OrderDetailsTable: React.FC<OrderDetailsProps> = ({
101
103
  const headerTitle = t('orders', 'Orders');
102
104
  const isTablet = useLayoutType() === 'tablet';
103
105
  const responsiveSize = isTablet ? 'lg' : 'md';
104
- const launchOrderBasket = useLaunchWorkspaceRequiringVisit('order-basket');
105
- const launchAddDrugOrder = useLaunchWorkspaceRequiringVisit('add-drug-order');
106
- const launchModifyLabOrder = useLaunchWorkspaceRequiringVisit('add-lab-order');
107
- const launchModifyGeneralOrder = useLaunchWorkspaceRequiringVisit('orderable-concept-workspace');
106
+ const launchOrderBasket = useLaunchWorkspaceRequiringVisit(patientUuid, 'order-basket');
107
+ const launchAddDrugOrder = useLaunchWorkspaceRequiringVisit(patientUuid, 'add-drug-order');
108
+ const launchModifyLabOrder = useLaunchWorkspaceRequiringVisit(patientUuid, 'add-lab-order');
109
+ const launchModifyGeneralOrder = useLaunchWorkspaceRequiringVisit(patientUuid, 'orderable-concept-workspace');
108
110
  const contentToPrintRef = useRef<HTMLDivElement | null>(null);
109
111
  const { excludePatientIdentifierCodeTypes } = useConfig();
110
112
  const [isPrinting, setIsPrinting] = useState(false);
@@ -523,6 +525,8 @@ const OrderDetailsTable: React.FC<OrderDetailsProps> = ({
523
525
  launchOrderForm={() => launchOrderForm(matchingOrder)}
524
526
  openOrderBasket={launchOrderBasket}
525
527
  orderItem={matchingOrder}
528
+ responsiveSize={responsiveSize}
529
+ patient={patient}
526
530
  />
527
531
  ) : (
528
532
  <ExtensionSlot
@@ -605,7 +609,13 @@ const OrderDetailsTable: React.FC<OrderDetailsProps> = ({
605
609
  );
606
610
  };
607
611
 
608
- function OrderBasketItemActions({ orderItem, openOrderBasket, launchOrderForm }: OrderBasketItemActionsProps) {
612
+ function OrderBasketItemActions({
613
+ orderItem,
614
+ openOrderBasket,
615
+ launchOrderForm,
616
+ responsiveSize,
617
+ patient,
618
+ }: OrderBasketItemActionsProps) {
609
619
  const { t } = useTranslation();
610
620
 
611
621
  // Use the appropriate grouping key and postDataPrepFunction based on order type
@@ -629,7 +639,7 @@ function OrderBasketItemActions({ orderItem, openOrderBasket, launchOrderForm }:
629
639
  }, [orderItem.type, orderItem.orderType.uuid]);
630
640
 
631
641
  const { grouping, postDataPrepFn } = getOrderBasketConfig();
632
- const { orders, setOrders } = useOrderBasket<MutableOrderBasketItem>(grouping, postDataPrepFn);
642
+ const { orders, setOrders } = useOrderBasket<MutableOrderBasketItem>(patient, grouping, postDataPrepFn);
633
643
  const alreadyInBasket = orders.some((x) => x.uuid === orderItem.uuid);
634
644
 
635
645
  const handleAddOrEditTestResults = useCallback(() => {
@@ -47,6 +47,8 @@ const testProps = {
47
47
  setTitle: jest.fn(),
48
48
  patientUuid: mockPatient.id,
49
49
  patient: mockPatient,
50
+ visitContext: null,
51
+ mutateVisitContext: null,
50
52
  };
51
53
 
52
54
  describe('LabResultsForm', () => {
@@ -51,13 +51,14 @@ export function OrderForm({
51
51
  closeWorkspace,
52
52
  closeWorkspaceWithSavedChanges,
53
53
  promptBeforeClosing,
54
+ patient,
54
55
  orderTypeUuid,
55
56
  }: OrderFormProps) {
56
57
  const { t } = useTranslation();
57
58
  const isTablet = useLayoutType() === 'tablet';
58
59
  const session = useSession();
59
60
  const isEditing = useMemo(() => initialOrder && initialOrder.action === 'REVISE', [initialOrder]);
60
- const { orders, setOrders } = useOrderBasket<OrderBasketItem>(orderTypeUuid, prepOrderPostData);
61
+ const { orders, setOrders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
61
62
  const [showErrorNotification, setShowErrorNotification] = useState(false);
62
63
  const { orderType } = useOrderType(orderTypeUuid);
63
64
  const config = useConfig<ConfigObject>();
@@ -19,14 +19,15 @@ import styles from './general-order-panel.scss';
19
19
 
20
20
  interface GeneralOrderTypeProps extends OrderTypeDefinition {
21
21
  closeWorkspace: DefaultWorkspaceProps['closeWorkspace'];
22
+ patient: fhir.Patient;
22
23
  }
23
24
 
24
- const GeneralOrderType: React.FC<GeneralOrderTypeProps> = ({ orderTypeUuid, closeWorkspace, label, icon }) => {
25
+ const GeneralOrderType: React.FC<GeneralOrderTypeProps> = ({ patient, orderTypeUuid, closeWorkspace, label, icon }) => {
25
26
  const { t } = useTranslation();
26
27
  const isTablet = useLayoutType() === 'tablet';
27
28
  const { orderType, isLoadingOrderType } = useOrderType(orderTypeUuid);
28
29
 
29
- const { orders, setOrders } = useOrderBasket<OrderBasketItem>(orderTypeUuid, prepOrderPostData);
30
+ const { orders, setOrders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
30
31
  const [isExpanded, setIsExpanded] = useState(orders.length > 0);
31
32
  const {
32
33
  incompleteOrderBasketItems,
@@ -11,10 +11,10 @@ import {
11
11
  type DefaultWorkspaceProps,
12
12
  } from '@openmrs/esm-framework';
13
13
  import {
14
+ type DefaultPatientWorkspaceProps,
14
15
  type OrderBasketItem,
15
16
  useOrderBasket,
16
17
  useOrderType,
17
- usePatientChartStore,
18
18
  } from '@openmrs/esm-patient-common-lib';
19
19
  import { OrderForm } from '../general-order-form/general-order-form.component';
20
20
  import { prepOrderPostData } from '../resources';
@@ -22,7 +22,7 @@ import { type ConfigObject } from '../../../config-schema';
22
22
  import OrderableConceptSearchResults from './search-results.component';
23
23
  import styles from './orderable-concept-search.scss';
24
24
 
25
- interface OrderableConceptSearchWorkspaceProps extends DefaultWorkspaceProps {
25
+ interface OrderableConceptSearchWorkspaceProps extends DefaultPatientWorkspaceProps {
26
26
  order: OrderBasketItem;
27
27
  orderTypeUuid: string;
28
28
  orderableConceptClasses: Array<string>;
@@ -44,11 +44,14 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
44
44
  closeWorkspaceWithSavedChanges,
45
45
  promptBeforeClosing,
46
46
  setTitle,
47
+ patientUuid,
48
+ patient,
49
+ visitContext,
50
+ mutateVisitContext,
47
51
  }) => {
48
52
  const { t } = useTranslation();
49
53
  const isTablet = useLayoutType() === 'tablet';
50
- const { orders } = useOrderBasket<OrderBasketItem>(orderTypeUuid, prepOrderPostData);
51
- const { patientUuid, patient } = usePatientChartStore();
54
+ const { orders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
52
55
  const { orderTypes } = useConfig<ConfigObject>();
53
56
  const [currentOrder, setCurrentOrder] = useState(initialOrder);
54
57
  const { orderType } = useOrderType(orderTypeUuid);
@@ -112,6 +115,8 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
112
115
  orderableConceptSets={orderableConceptSets}
113
116
  patientUuid={patientUuid}
114
117
  patient={patient}
118
+ visitContext={visitContext}
119
+ mutateVisitContext={mutateVisitContext}
115
120
  setTitle={() => {}}
116
121
  />
117
122
  ) : (
@@ -120,6 +125,7 @@ const OrderableConceptSearchWorkspace: React.FC<OrderableConceptSearchWorkspaceP
120
125
  closeWorkspace={closeWorkspace}
121
126
  orderableConceptSets={orderableConceptSets}
122
127
  orderTypeUuid={orderTypeUuid}
128
+ patient={patient}
123
129
  />
124
130
  )}
125
131
  </div>
@@ -131,9 +137,16 @@ interface ConceptSearchProps {
131
137
  openOrderForm: (search: OrderBasketItem) => void;
132
138
  orderTypeUuid: string;
133
139
  orderableConceptSets: Array<string>;
140
+ patient: fhir.Patient;
134
141
  }
135
142
 
136
- function ConceptSearch({ closeWorkspace, orderTypeUuid, openOrderForm, orderableConceptSets }: ConceptSearchProps) {
143
+ function ConceptSearch({
144
+ closeWorkspace,
145
+ orderTypeUuid,
146
+ openOrderForm,
147
+ orderableConceptSets,
148
+ patient,
149
+ }: ConceptSearchProps) {
137
150
  const { t } = useTranslation();
138
151
  const { orderType } = useOrderType(orderTypeUuid);
139
152
  const isTablet = useLayoutType() === 'tablet';
@@ -182,6 +195,7 @@ function ConceptSearch({ closeWorkspace, orderTypeUuid, openOrderForm, orderable
182
195
  orderTypeUuid={orderTypeUuid}
183
196
  cancelOrder={() => {}}
184
197
  orderableConceptSets={orderableConceptSets}
198
+ patient={patient}
185
199
  />
186
200
  {isTablet && (
187
201
  <div className={styles.separatorContainer}>
@@ -28,6 +28,7 @@ interface OrderableConceptSearchResultsProps {
28
28
  orderableConceptSets: Array<string>;
29
29
  orderTypeUuid: string;
30
30
  closeWorkspace: DefaultWorkspaceProps['closeWorkspace'];
31
+ patient: fhir.Patient;
31
32
  }
32
33
 
33
34
  const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps> = ({
@@ -38,6 +39,7 @@ const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps
38
39
  orderableConceptSets,
39
40
  orderTypeUuid,
40
41
  closeWorkspace,
42
+ patient,
41
43
  }) => {
42
44
  const { t } = useTranslation();
43
45
  const isTablet = useLayoutType() === 'tablet';
@@ -89,6 +91,7 @@ const OrderableConceptSearchResults: React.FC<OrderableConceptSearchResultsProps
89
91
  concept={concept}
90
92
  orderTypeUuid={orderTypeUuid}
91
93
  closeWorkspace={closeWorkspace}
94
+ patient={patient}
92
95
  />
93
96
  ))}
94
97
  </div>
@@ -154,6 +157,7 @@ interface TestTypeSearchResultItemProps {
154
157
  openOrderForm: (searchResult: OrderBasketItem) => void;
155
158
  orderTypeUuid: string;
156
159
  closeWorkspace: DefaultWorkspaceProps['closeWorkspace'];
160
+ patient: fhir.Patient;
157
161
  }
158
162
 
159
163
  const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
@@ -161,11 +165,12 @@ const TestTypeSearchResultItem: React.FC<TestTypeSearchResultItemProps> = ({
161
165
  openOrderForm,
162
166
  orderTypeUuid,
163
167
  closeWorkspace,
168
+ patient,
164
169
  }) => {
165
170
  const { t } = useTranslation();
166
171
  const isTablet = useLayoutType() === 'tablet';
167
172
  const session = useSession();
168
- const { orders, setOrders } = useOrderBasket<OrderBasketItem>(orderTypeUuid, prepOrderPostData);
173
+ const { orders, setOrders } = useOrderBasket<OrderBasketItem>(patient, orderTypeUuid, prepOrderPostData);
169
174
 
170
175
  const orderAlreadyInBasket = useMemo(
171
176
  () => orders?.some((order) => order.concept.uuid === concept.uuid),
@@ -10,7 +10,7 @@ import {
10
10
  useConfig,
11
11
  useLayoutType,
12
12
  useSession,
13
- useVisit,
13
+ type Visit,
14
14
  } from '@openmrs/esm-framework';
15
15
  import {
16
16
  type DefaultPatientWorkspaceProps,
@@ -19,7 +19,6 @@ import {
19
19
  postOrders,
20
20
  postOrdersOnNewEncounter,
21
21
  useOrderBasket,
22
- useVisitOrOfflineVisit,
23
22
  } from '@openmrs/esm-patient-common-lib';
24
23
  import { useSWRConfig } from 'swr';
25
24
  import { type ConfigObject } from '../config-schema';
@@ -27,18 +26,27 @@ import { useMutatePatientOrders, useOrderEncounter } from '../api/api';
27
26
  import GeneralOrderType from './general-order-type/general-order-type.component';
28
27
  import styles from './order-basket.scss';
29
28
 
29
+ interface OrderBasketSlotProps {
30
+ patientUuid: string;
31
+ patient: fhir.Patient;
32
+ visitContext: Visit;
33
+ mutateVisitContext: () => void;
34
+ }
35
+
30
36
  const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
31
37
  patientUuid,
38
+ patient,
32
39
  closeWorkspace,
33
40
  closeWorkspaceWithSavedChanges,
34
41
  promptBeforeClosing,
42
+ visitContext,
43
+ mutateVisitContext,
35
44
  }) => {
36
45
  const { t } = useTranslation();
37
46
  const isTablet = useLayoutType() === 'tablet';
38
47
  const config = useConfig<ConfigObject>();
39
48
  const session = useSession();
40
- const { currentVisit } = useVisitOrOfflineVisit(patientUuid);
41
- const { orders, clearOrders } = useOrderBasket();
49
+ const { orders, clearOrders } = useOrderBasket(patient);
42
50
  const [ordersWithErrors, setOrdersWithErrors] = useState<OrderBasketItem[]>([]);
43
51
  const {
44
52
  visitRequired,
@@ -46,11 +54,10 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
46
54
  encounterUuid,
47
55
  error: errorFetchingEncounterUuid,
48
56
  mutate: mutateEncounterUuid,
49
- } = useOrderEncounter(patientUuid, config.orderEncounterType);
57
+ } = useOrderEncounter(patientUuid, visitContext, mutateVisitContext, config.orderEncounterType);
50
58
  const [isSavingOrders, setIsSavingOrders] = useState(false);
51
59
  const [creatingEncounterError, setCreatingEncounterError] = useState('');
52
60
  const { mutate: mutateOrders } = useMutatePatientOrders(patientUuid);
53
- const { mutate: mutateCurrentVisit } = useVisit(patientUuid);
54
61
  const { mutate } = useSWRConfig();
55
62
 
56
63
  useEffect(() => {
@@ -75,14 +82,13 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
75
82
  await postOrdersOnNewEncounter(
76
83
  patientUuid,
77
84
  config?.orderEncounterType,
78
- visitRequired ? currentVisit : null,
85
+ visitRequired ? visitContext : null,
79
86
  session?.sessionLocation?.uuid,
80
87
  abortController,
81
88
  );
82
89
  mutateEncounterUuid();
83
90
  // Only revalidate current visit since orders create new encounters
84
- mutateCurrentVisit();
85
- invalidateVisitAndEncounterData(mutate, patientUuid);
91
+ mutateVisitContext?.();
86
92
  clearOrders();
87
93
  await mutateOrders();
88
94
 
@@ -99,7 +105,7 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
99
105
  const erroredItems = await postOrders(patientUuid, orderEncounterUuid, abortController);
100
106
  clearOrders({ exceptThoseMatching: (item) => erroredItems.map((e) => e.display).includes(item.display) });
101
107
  // Only revalidate current visit since orders create new encounters
102
- mutateCurrentVisit();
108
+ mutateVisitContext?.();
103
109
  await mutateOrders();
104
110
  invalidateVisitAndEncounterData(mutate, patientUuid);
105
111
 
@@ -113,7 +119,7 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
113
119
  setIsSavingOrders(false);
114
120
  return () => abortController.abort();
115
121
  }, [
116
- currentVisit,
122
+ visitContext,
117
123
  visitRequired,
118
124
  clearOrders,
119
125
  closeWorkspaceWithSavedChanges,
@@ -121,7 +127,7 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
121
127
  encounterUuid,
122
128
  mutateEncounterUuid,
123
129
  mutateOrders,
124
- mutateCurrentVisit,
130
+ mutateVisitContext,
125
131
  orders,
126
132
  patientUuid,
127
133
  session,
@@ -133,21 +139,36 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
133
139
  closeWorkspace({ onWorkspaceClose: clearOrders });
134
140
  }, [clearOrders, closeWorkspace]);
135
141
 
142
+ const extensionProps = {
143
+ patientUuid,
144
+ patient,
145
+ visitContext,
146
+ mutateVisitContext,
147
+ } satisfies OrderBasketSlotProps;
148
+
136
149
  return (
137
150
  <>
138
151
  <div className={styles.container}>
139
- <ExtensionSlot name="visit-context-header-slot" state={{ patientUuid }} />
152
+ <ExtensionSlot name="visit-context-header-slot" state={extensionProps} />
140
153
  <div className={styles.orderBasketContainer}>
141
154
  <ExtensionSlot
142
155
  className={classNames(styles.orderBasketSlot, {
143
156
  [styles.orderBasketSlotTablet]: isTablet,
144
157
  })}
145
158
  name="order-basket-slot"
159
+ state={extensionProps}
146
160
  />
147
161
  {config?.orderTypes?.length > 0 &&
148
162
  config.orderTypes.map((orderType) => (
149
163
  <div className={styles.orderPanel} key={orderType.orderTypeUuid}>
150
- <GeneralOrderType key={orderType.orderTypeUuid} {...orderType} closeWorkspace={closeWorkspace} />
164
+ <GeneralOrderType
165
+ key={orderType.orderTypeUuid}
166
+ orderTypeUuid={orderType.orderTypeUuid}
167
+ label={orderType.label}
168
+ orderableConceptSets={orderType.orderableConceptSets}
169
+ closeWorkspace={closeWorkspace}
170
+ patient={patient}
171
+ />
151
172
  </div>
152
173
  ))}
153
174
  </div>
@@ -183,7 +204,7 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
183
204
  isSavingOrders ||
184
205
  !orders?.length ||
185
206
  isLoadingEncounterUuid ||
186
- (visitRequired && !currentVisit) ||
207
+ (visitRequired && !visitContext) ||
187
208
  orders?.some(({ isOrderIncomplete }) => isOrderIncomplete)
188
209
  }
189
210
  >
@@ -196,7 +217,7 @@ const OrderBasket: React.FC<DefaultPatientWorkspaceProps> = ({
196
217
  </ButtonSet>
197
218
  </div>
198
219
  </div>
199
- {visitRequired && !currentVisit && (
220
+ {visitRequired && !visitContext && (
200
221
  <ActionableNotification
201
222
  kind="error"
202
223
  actionButtonLabel={t('startVisit', 'Start visit')}
@@ -3,10 +3,18 @@ import { useTranslation } from 'react-i18next';
3
3
  import { ActionMenuButton, ShoppingCartIcon } from '@openmrs/esm-framework';
4
4
  import { useLaunchWorkspaceRequiringVisit, useOrderBasket } from '@openmrs/esm-patient-common-lib';
5
5
 
6
- const OrderBasketActionButton: React.FC = () => {
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 }) => {
7
15
  const { t } = useTranslation();
8
- const { orders } = useOrderBasket();
9
- const launchOrderBasket = useLaunchWorkspaceRequiringVisit('order-basket');
16
+ const { orders } = useOrderBasket(patient);
17
+ const launchOrderBasket = useLaunchWorkspaceRequiringVisit(patientUuid, 'order-basket');
10
18
 
11
19
  return (
12
20
  <ActionMenuButton
@@ -36,15 +36,6 @@ mockUseWorkspaces.mockReturnValue({
36
36
  // I think it is related to this: https://github.com/swc-project/jest/issues/14#issuecomment-1238621942
37
37
 
38
38
  const mockLaunchStartVisitPrompt = jest.fn();
39
- const mockUseVisitOrOfflineVisit = jest.fn(() => ({
40
- activeVisit: {
41
- uuid: '8ef90c91-14be-42dd-a1c0-e67fbf904470',
42
- },
43
- currentVisit: {
44
- uuid: '8ef90c91-14be-42dd-a1c0-e67fbf904470',
45
- },
46
- }));
47
- const mockGetPatientUuidFromUrl = jest.fn(() => mockPatient.id);
48
39
  const mockUseSystemVisitSetting = jest.fn();
49
40
 
50
41
  jest.mock('@openmrs/esm-patient-common-lib/src/useSystemVisitSetting', () => {
@@ -57,17 +48,6 @@ jest.mock('@openmrs/esm-patient-common-lib/src/launchStartVisitPrompt', () => {
57
48
  return { launchStartVisitPrompt: () => mockLaunchStartVisitPrompt() };
58
49
  });
59
50
 
60
- jest.mock('@openmrs/esm-patient-common-lib/src/store/patient-chart-store', () => {
61
- return {
62
- getPatientUuidFromStore: () => mockGetPatientUuidFromUrl(),
63
- usePatientChartStore: () => ({ patientUuid: mockPatient.id }),
64
- };
65
- });
66
-
67
- jest.mock('@openmrs/esm-patient-common-lib/src/offline/visit', () => {
68
- return { useVisitOrOfflineVisit: () => mockUseVisitOrOfflineVisit() };
69
- });
70
-
71
51
  mockUseSystemVisitSetting.mockReturnValue({ systemVisitEnabled: false });
72
52
 
73
53
  const mockedUseFeatureFlag = jest.mocked(useFeatureFlag);
@@ -86,7 +66,7 @@ describe('<OrderBasketActionButton/>', () => {
86
66
  it('should display tablet view action button', async () => {
87
67
  const user = userEvent.setup();
88
68
  mockUseLayoutType.mockReturnValue('tablet');
89
- render(<OrderBasketActionButton />);
69
+ render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
90
70
 
91
71
  const orderBasketButton = screen.getByRole('button', { name: /Order Basket/i });
92
72
  expect(orderBasketButton).toBeInTheDocument();
@@ -97,7 +77,7 @@ describe('<OrderBasketActionButton/>', () => {
97
77
  it('should display desktop view action button', async () => {
98
78
  const user = userEvent.setup();
99
79
  mockUseLayoutType.mockReturnValue('small-desktop');
100
- render(<OrderBasketActionButton />);
80
+ render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
101
81
 
102
82
  const orderBasketButton = screen.getByRole('button', { name: /order basket/i });
103
83
  expect(orderBasketButton).toBeInTheDocument();
@@ -110,12 +90,8 @@ describe('<OrderBasketActionButton/>', () => {
110
90
  const user = userEvent.setup();
111
91
  mockUseLayoutType.mockReturnValue('small-desktop');
112
92
  mockUseSystemVisitSetting.mockReturnValue({ systemVisitEnabled: true });
113
- mockUseVisitOrOfflineVisit.mockImplementation(() => ({
114
- activeVisit: null,
115
- currentVisit: null,
116
- }));
117
93
 
118
- render(<OrderBasketActionButton />);
94
+ render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
119
95
 
120
96
  const orderBasketButton = screen.getByRole('button', { name: /order basket/i });
121
97
  expect(orderBasketButton).toBeInTheDocument();
@@ -126,9 +102,9 @@ describe('<OrderBasketActionButton/>', () => {
126
102
 
127
103
  it('should display a count tag when orders are present on the desktop view', () => {
128
104
  mockUseLayoutType.mockReturnValue('small-desktop');
129
- const { result } = renderHook(useOrderBasket);
105
+ const { result } = renderHook(() => useOrderBasket(mockPatient));
130
106
  expect(result.current.orders).toHaveLength(1); // sanity check
131
- render(<OrderBasketActionButton />);
107
+ render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
132
108
 
133
109
  expect(screen.getByText(/order basket/i)).toBeInTheDocument();
134
110
  expect(screen.getByText(/1/i)).toBeInTheDocument();
@@ -136,7 +112,7 @@ describe('<OrderBasketActionButton/>', () => {
136
112
 
137
113
  it('should display the count tag when orders are present on the tablet view', () => {
138
114
  mockUseLayoutType.mockReturnValue('tablet');
139
- render(<OrderBasketActionButton />);
115
+ render(<OrderBasketActionButton patient={mockPatient} patientUuid={mockPatient.id} />);
140
116
 
141
117
  expect(screen.getByRole('button', { name: /1 order basket/i })).toBeInTheDocument();
142
118
  });
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "سلة الطلب",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Order basket",
66
66
  "orderCancellation": "Order cancellation",
67
67
  "orderCancelled": "Order cancelled",
68
- "orderCompleted": "Placed orders",
69
68
  "orderDetails": "Order details",
70
69
  "ordered": "Placed order for",
71
70
  "orderedBy": "Ordered by",
@@ -65,7 +65,6 @@
65
65
  "orderBasketWorkspaceTitle": "Canasta de órdenes",
66
66
  "orderCancellation": "Cancelación de orden",
67
67
  "orderCancelled": "Orden cancelada",
68
- "orderCompleted": "Órdenes realizadas",
69
68
  "orderDetails": "Detalles de la orden",
70
69
  "ordered": "Orden realizada para",
71
70
  "orderedBy": "Ordenado por",