@thrustdevs/esm-procedure-orders-app 1.0.2-pre.6

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 (207) hide show
  1. package/.turbo/turbo-build.log +41 -0
  2. package/README.md +7 -0
  3. package/dist/122.js +1 -0
  4. package/dist/122.js.map +1 -0
  5. package/dist/144.js +2 -0
  6. package/dist/144.js.LICENSE.txt +19 -0
  7. package/dist/144.js.map +1 -0
  8. package/dist/182.js +1 -0
  9. package/dist/182.js.map +1 -0
  10. package/dist/205.js +1 -0
  11. package/dist/205.js.map +1 -0
  12. package/dist/216.js +2 -0
  13. package/dist/216.js.LICENSE.txt +9 -0
  14. package/dist/216.js.map +1 -0
  15. package/dist/290.js +2 -0
  16. package/dist/290.js.LICENSE.txt +5 -0
  17. package/dist/290.js.map +1 -0
  18. package/dist/300.js +1 -0
  19. package/dist/341.js +2 -0
  20. package/dist/341.js.LICENSE.txt +29 -0
  21. package/dist/341.js.map +1 -0
  22. package/dist/41.js +2 -0
  23. package/dist/41.js.LICENSE.txt +9 -0
  24. package/dist/41.js.map +1 -0
  25. package/dist/470.js +1 -0
  26. package/dist/470.js.map +1 -0
  27. package/dist/495.js +1 -0
  28. package/dist/495.js.map +1 -0
  29. package/dist/506.js +2 -0
  30. package/dist/506.js.LICENSE.txt +39 -0
  31. package/dist/506.js.map +1 -0
  32. package/dist/537.js +1 -0
  33. package/dist/537.js.map +1 -0
  34. package/dist/647.js +2 -0
  35. package/dist/647.js.LICENSE.txt +5 -0
  36. package/dist/647.js.map +1 -0
  37. package/dist/7.js +1 -0
  38. package/dist/7.js.map +1 -0
  39. package/dist/719.js +2 -0
  40. package/dist/719.js.LICENSE.txt +5 -0
  41. package/dist/719.js.map +1 -0
  42. package/dist/720.js +1 -0
  43. package/dist/720.js.map +1 -0
  44. package/dist/876.js +1 -0
  45. package/dist/876.js.map +1 -0
  46. package/dist/883.js +1 -0
  47. package/dist/883.js.map +1 -0
  48. package/dist/89.js +1 -0
  49. package/dist/89.js.map +1 -0
  50. package/dist/892.js +1 -0
  51. package/dist/892.js.map +1 -0
  52. package/dist/895.js +1 -0
  53. package/dist/895.js.map +1 -0
  54. package/dist/913.js +2 -0
  55. package/dist/913.js.LICENSE.txt +32 -0
  56. package/dist/913.js.map +1 -0
  57. package/dist/924.js +1 -0
  58. package/dist/924.js.map +1 -0
  59. package/dist/943.js +1 -0
  60. package/dist/943.js.map +1 -0
  61. package/dist/99.js +2 -0
  62. package/dist/99.js.LICENSE.txt +5 -0
  63. package/dist/99.js.map +1 -0
  64. package/dist/kenyaemr-esm-procedure-orders-app.js +1 -0
  65. package/dist/kenyaemr-esm-procedure-orders-app.js.buildmanifest.json +786 -0
  66. package/dist/kenyaemr-esm-procedure-orders-app.js.map +1 -0
  67. package/dist/main.js +2 -0
  68. package/dist/main.js.LICENSE.txt +35 -0
  69. package/dist/main.js.map +1 -0
  70. package/dist/routes.json +1 -0
  71. package/jest.config.js +8 -0
  72. package/package.json +55 -0
  73. package/src/completed-list/completed-list.component.tsx +40 -0
  74. package/src/completed-list/completed-list.resource.ts +0 -0
  75. package/src/completed-list/completed-list.scss +223 -0
  76. package/src/components/create-dashboard-link.component.tsx +35 -0
  77. package/src/components/overlay/hook.ts +47 -0
  78. package/src/components/overlay/overlay.component.tsx +42 -0
  79. package/src/components/overlay/overlay.scss +92 -0
  80. package/src/config-schema.ts +78 -0
  81. package/src/constants.ts +5 -0
  82. package/src/declarations.d.ts +6 -0
  83. package/src/empty-state/empty-state-component.tsx +21 -0
  84. package/src/empty-state/empty-state.scss +23 -0
  85. package/src/form/post-procedures/post-procedure-form.component.tsx +468 -0
  86. package/src/form/post-procedures/post-procedure-form.scss +189 -0
  87. package/src/form/post-procedures/post-procedure.resource.tsx +71 -0
  88. package/src/form/procedures-orders/add-procedures-order/add-procedures-order.scss +44 -0
  89. package/src/form/procedures-orders/add-procedures-order/add-procedures-order.workspace.tsx +93 -0
  90. package/src/form/procedures-orders/add-procedures-order/procedures-order-form.component.tsx +476 -0
  91. package/src/form/procedures-orders/add-procedures-order/procedures-order-form.scss +80 -0
  92. package/src/form/procedures-orders/add-procedures-order/procedures-order.ts +17 -0
  93. package/src/form/procedures-orders/add-procedures-order/procedures-type-search.scss +115 -0
  94. package/src/form/procedures-orders/add-procedures-order/procedures-type-search.tsx +236 -0
  95. package/src/form/procedures-orders/add-procedures-order/useProceduresTypes.ts +93 -0
  96. package/src/form/procedures-orders/api.ts +282 -0
  97. package/src/form/procedures-orders/order-config.ts +48 -0
  98. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-icon.component.tsx +39 -0
  99. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-order-basket-item-tile.component.tsx +100 -0
  100. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-order-basket-item-tile.scss +72 -0
  101. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-order-basket-panel.extension.tsx +190 -0
  102. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-order-basket-panel.scss +74 -0
  103. package/src/form/procedures-orders/procedures-order-basket-panel/procedures-order-basket.scss +55 -0
  104. package/src/header/procedure-header.component.tsx +32 -0
  105. package/src/header/procedure-header.scss +70 -0
  106. package/src/header/procedure-illustration.component.tsx +52 -0
  107. package/src/hooks/useOrdersWorklist.ts +70 -0
  108. package/src/hooks/useSearchGroupedResults.ts +22 -0
  109. package/src/hooks/useSearchResults.ts +39 -0
  110. package/src/index.ts +59 -0
  111. package/src/left-panel-link.tsx +40 -0
  112. package/src/not-done-list/not-done-list.component.tsx +44 -0
  113. package/src/not-done-list/not-done.scss +207 -0
  114. package/src/patient-chart/patient-procedure-order-results-table.resource.ts +43 -0
  115. package/src/patient-chart/patient-procedure-order-results.component.tsx +12 -0
  116. package/src/patient-chart/patient-procedure-order-results.resource.ts +485 -0
  117. package/src/patient-chart/patient-procedure-results.component.tsx +30 -0
  118. package/src/patient-chart/procedure-active-order/procedure-active-order-results.component.tsx +390 -0
  119. package/src/patient-chart/procedure-active-order/procedure-active-order-results.scss +78 -0
  120. package/src/patient-chart/procedure-order-referals/procedure-order-referals.component.tsx +394 -0
  121. package/src/patient-chart/procedure-order-referals/procedure-order-referals.resource.tsx +0 -0
  122. package/src/patient-chart/procedure-order-referals/procedure-order-referals.scss +78 -0
  123. package/src/patient-chart/procedure-past-test/laboratory-past-test-order-results.component.tsx +366 -0
  124. package/src/patient-chart/procedure-past-test/laboratory-past-test-order-results.scss +74 -0
  125. package/src/patient-chart/procedure-tabs/laboratory-order-tabs.component.tsx +44 -0
  126. package/src/patient-chart/procedure-tabs/laboratory-order-tabs.scss +7 -0
  127. package/src/patient-chart/procedure-workspaces/laboratory-referral.workspace.component.tsx +11 -0
  128. package/src/patient-chart/procedure-workspaces/laboratory-referral.workspace.scss +0 -0
  129. package/src/patient-chart/results-summary/print-results-summary.component.tsx +152 -0
  130. package/src/patient-chart/results-summary/print-results-summary.scss +80 -0
  131. package/src/patient-chart/results-summary/print-results-table.component.tsx +134 -0
  132. package/src/patient-chart/results-summary/results-summary.resource.tsx +174 -0
  133. package/src/patient-chart/results-summary/results-summary.scss +158 -0
  134. package/src/patient-chart/results-summary/send-email-dialog.component.tsx +59 -0
  135. package/src/patient-chart/results-summary/test-children-results.component.tsx +177 -0
  136. package/src/patient-chart/results-summary/test-print-results-table.component.tsx +105 -0
  137. package/src/patient-chart/results-summary/test-results-table.component.tsx +103 -0
  138. package/src/print/print-procedure-results.component.tsx +49 -0
  139. package/src/print/print-procedure.component.tsx +105 -0
  140. package/src/print/print-procedure.scss +98 -0
  141. package/src/procedure-tabs/completed-tab.component.tsx +12 -0
  142. package/src/procedure-tabs/not-done-tab.component.tsx +12 -0
  143. package/src/procedure-tabs/referred-tab.component.tsx +12 -0
  144. package/src/procedure-tabs/work-list-tab.component.tsx +13 -0
  145. package/src/procedure.component.tsx +24 -0
  146. package/src/procedures-ordered/_pick-procedure-request-menu.component.tsx +33 -0
  147. package/src/procedures-ordered/pick-procedure-order/add-to-worklist-dialog.component.tsx +105 -0
  148. package/src/procedures-ordered/pick-procedure-order/add-to-worklist-dialog.resource.ts +106 -0
  149. package/src/procedures-ordered/pick-procedure-order/add-to-worklist-dialog.scss +38 -0
  150. package/src/procedures-ordered/pick-procedure-request-menu.component.tsx +32 -0
  151. package/src/procedures-ordered/procedure-dialogs/add-to-worklist-dialog.component.tsx +300 -0
  152. package/src/procedures-ordered/procedure-dialogs/add-to-worklist-dialog.resource.ts +153 -0
  153. package/src/procedures-ordered/procedure-dialogs/add-to-worklist-dialog.scss +38 -0
  154. package/src/procedures-ordered/procedure-instructions/instructions.scss +24 -0
  155. package/src/procedures-ordered/procedure-instructions/procedure-instructions-menu.component.tsx +32 -0
  156. package/src/procedures-ordered/procedure-instructions/procedure-instructions.component.tsx +78 -0
  157. package/src/procedures-ordered/procedure-instructions/procedure-instructions.scss +24 -0
  158. package/src/procedures-ordered/procedure-queue.scss +211 -0
  159. package/src/procedures-ordered/procedure-tabs.component.tsx +104 -0
  160. package/src/procedures-ordered/procedure-tests/procedure-tests.component.tsx +83 -0
  161. package/src/procedures-ordered/procedure-tests/procedure-tests.resource.ts +14 -0
  162. package/src/procedures-ordered/procedure-tests/procedure-tests.scss +12 -0
  163. package/src/procedures-ordered/procedures-ordered-list.component.tsx +38 -0
  164. package/src/procedures-ordered/reject-order-dialog/reject-order-dialog.scss +14 -0
  165. package/src/procedures-ordered/reject-order-dialog/reject-procedure-order-dialog.component.tsx +98 -0
  166. package/src/procedures-ordered/reject-reason/procedure-reject-reason-menu.component.tsx +32 -0
  167. package/src/procedures-ordered/reject-reason/procedure-reject-reason.component.tsx +40 -0
  168. package/src/procedures-ordered/transition-patient-new-queue/transition-latest-queue-entry-button.component.tsx +42 -0
  169. package/src/procedures-ordered/transition-patient-new-queue/transition-latest-queue-entry-button.scss +14 -0
  170. package/src/procedures-ordered/transition-patient-new-queue/transition-latest-queue-entry-button.test.tsx +67 -0
  171. package/src/referred-procedures/referred-procedures.component.tsx +37 -0
  172. package/src/results/result-form-field.component.tsx +141 -0
  173. package/src/results/result-form.component.tsx +120 -0
  174. package/src/results/result-form.resource.ts +361 -0
  175. package/src/results/result-form.scss +22 -0
  176. package/src/root.component.tsx +16 -0
  177. package/src/routes.json +152 -0
  178. package/src/setup-tests.ts +7 -0
  179. package/src/shared/ui/common/action-button/action-button.component.tsx +68 -0
  180. package/src/shared/ui/common/action-button/action-button.scss +12 -0
  181. package/src/shared/ui/common/action-button/order-action-extension.component.tsx +21 -0
  182. package/src/shared/ui/common/grouped-orders-table.component.tsx +176 -0
  183. package/src/shared/ui/common/grouped-orders-table.scss +30 -0
  184. package/src/shared/ui/common/grouped-procedure-types.ts +47 -0
  185. package/src/shared/ui/common/list-order-details.component.tsx +171 -0
  186. package/src/shared/ui/common/list-order-details.resource.ts +41 -0
  187. package/src/shared/ui/common/list-order-details.scss +118 -0
  188. package/src/shared/ui/common/orders-date-range-picker.scss +15 -0
  189. package/src/shared/ui/common/orders-date-range-picker.tsx +38 -0
  190. package/src/summary-tiles/procedure-summary-tiles.component.tsx +36 -0
  191. package/src/summary-tiles/procedure-summary-tiles.scss +11 -0
  192. package/src/summary-tiles/procedure-summary.resource.tsx +79 -0
  193. package/src/summary-tiles/summary-tile.component.tsx +41 -0
  194. package/src/summary-tiles/summary-tile.scss +53 -0
  195. package/src/types/index.ts +661 -0
  196. package/src/types/patient-queue.ts +77 -0
  197. package/src/ui-components/overflow-menu.component.tsx +74 -0
  198. package/src/ui-components/overflow-menu.scss +39 -0
  199. package/src/utils/functions.ts +236 -0
  200. package/src/utils/orders-table/orders-data-table.component.tsx +129 -0
  201. package/src/utils/orders-table/orders-data-table.scss +50 -0
  202. package/src/work-list/work-list.component.tsx +38 -0
  203. package/src/work-list/work-list.resource.ts +26 -0
  204. package/src/work-list/work-list.scss +207 -0
  205. package/translations/en.json +141 -0
  206. package/tsconfig.json +5 -0
  207. package/webpack.config.js +1 -0
@@ -0,0 +1,24 @@
1
+ import React, { useState } from 'react';
2
+ import { ProcedureHeader } from './header/procedure-header.component';
3
+ import ProcedureSummaryTiles from './summary-tiles/procedure-summary-tiles.component';
4
+ import ProcedureOrdersList from './procedures-ordered/procedure-tabs.component';
5
+ import Overlay from './components/overlay/overlay.component';
6
+ import { useDefineAppContext } from '@openmrs/esm-framework';
7
+ import { type DateFilterContext } from './types';
8
+ import dayjs from 'dayjs';
9
+
10
+ const Procedure: React.FC = () => {
11
+ const [dateRange, setDateRange] = useState<Date[]>([dayjs().startOf('day').toDate(), new Date()]);
12
+ useDefineAppContext<DateFilterContext>('procedures-date-filter', { dateRange, setDateRange });
13
+
14
+ return (
15
+ <div className={`omrs-main-content`}>
16
+ <ProcedureHeader />
17
+ <ProcedureSummaryTiles />
18
+ <ProcedureOrdersList />
19
+ <Overlay />
20
+ </div>
21
+ );
22
+ };
23
+
24
+ export default Procedure;
@@ -0,0 +1,33 @@
1
+ import { OverflowMenuItem } from '@carbon/react';
2
+ import { showModal } from '@openmrs/esm-framework';
3
+ import React, { useCallback } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { type Order } from '../types/patient-queue';
6
+
7
+ interface PickLabRequestActionMenuProps {
8
+ order: Order;
9
+ closeModal: () => void;
10
+ }
11
+
12
+ const PickProcedureRequestActionMenu: React.FC<PickLabRequestActionMenuProps> = ({ order }) => {
13
+ const { t } = useTranslation();
14
+
15
+ const launchSelectProcedureRequestModal = useCallback(() => {
16
+ const dispose = showModal('add-procedure-to-worklist-dialog', {
17
+ closeModal: () => dispose(),
18
+ order,
19
+ });
20
+ }, [order]);
21
+
22
+ return (
23
+ <OverflowMenuItem
24
+ itemText={t('pickProcedureRequest', 'Pick Procedure Request')}
25
+ onClick={launchSelectProcedureRequestModal}
26
+ style={{
27
+ maxWidth: '100vw',
28
+ }}
29
+ />
30
+ );
31
+ };
32
+
33
+ export default PickProcedureRequestActionMenu;
@@ -0,0 +1,105 @@
1
+ import React, { useState } from 'react';
2
+ import { Button, Form, ModalBody, ModalFooter, ModalHeader, Checkbox, TextInput } from '@carbon/react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import styles from './add-to-worklist-dialog.scss';
5
+ import { showNotification, showSnackbar } from '@openmrs/esm-framework';
6
+ import { updateOrder } from './add-to-worklist-dialog.resource';
7
+ import { mutate } from 'swr';
8
+ import { type Result } from '../../types';
9
+ import capitalize from 'lodash-es/capitalize';
10
+
11
+ interface AddProcedureToWorklistDialogProps {
12
+ queueId;
13
+ order: Result;
14
+ closeModal: () => void;
15
+ }
16
+
17
+ const AddProcedureToWorklistDialog: React.FC<AddProcedureToWorklistDialogProps> = ({ queueId, order, closeModal }) => {
18
+ const { t } = useTranslation();
19
+
20
+ const [isReferredChecked, setIsReferredChecked] = useState(false);
21
+ const [referredLocation, setReferredLocation] = useState('');
22
+
23
+ const pickProcedureRequestQueue = async (event) => {
24
+ event.preventDefault();
25
+
26
+ const body = {
27
+ fulfillerComment: '',
28
+ fulfillerStatus: isReferredChecked ? 'EXCEPTION' : 'IN_PROGRESS',
29
+ // referralLocation: isReferredChecked ? referredLocation : "",
30
+ };
31
+
32
+ updateOrder(order.uuid, body)
33
+ .then(() => {
34
+ showSnackbar({
35
+ isLowContrast: true,
36
+ title: t('pickedAnOrder', 'Picked an order'),
37
+ kind: 'success',
38
+ subtitle: t('pickSuccessfully', 'You have successfully picked an Order'),
39
+ });
40
+ closeModal();
41
+ mutate((key) => typeof key === 'string' && key.startsWith('/ws/rest/v1/order'), undefined, {
42
+ revalidate: true,
43
+ });
44
+ })
45
+ .catch((error) => {
46
+ showNotification({
47
+ title: t(`errorPicking an order', 'Error Picking an Order`),
48
+ kind: 'error',
49
+ critical: true,
50
+ description: error?.message,
51
+ });
52
+ });
53
+ };
54
+
55
+ const handleCheckboxChange = () => {
56
+ setIsReferredChecked(!isReferredChecked);
57
+ };
58
+ const orderName = capitalize(order?.concept?.display);
59
+ const orderNumber = order?.orderNumber;
60
+
61
+ return (
62
+ <div>
63
+ <Form onSubmit={pickProcedureRequestQueue}>
64
+ <div className="cds--modal-header">
65
+ <h3 className="cds--modal-header__heading">{t('pickRequest', 'Pick Request')}</h3>
66
+ </div>
67
+ <div className="cds--modal-content">
68
+ <p>
69
+ {t('confirmationPickupMessages', `Do you want to pick this order: {{orderName}} - {{orderNumber}}?`, {
70
+ orderName,
71
+ orderNumber,
72
+ })}
73
+ </p>
74
+ <section className={styles.section}>
75
+ <Checkbox
76
+ checked={isReferredChecked}
77
+ onChange={handleCheckboxChange}
78
+ labelText={'Referred'}
79
+ id="test-referred"
80
+ />
81
+ {isReferredChecked && (
82
+ <TextInput
83
+ type="text"
84
+ id="referredLocation"
85
+ labelText={'Enter Referred Location'}
86
+ value={referredLocation}
87
+ onChange={(e) => setReferredLocation(e.target.value)}
88
+ />
89
+ )}
90
+ </section>
91
+ </div>
92
+ <ModalFooter>
93
+ <Button kind="secondary" onClick={closeModal}>
94
+ {t('cancel', 'Cancel')}
95
+ </Button>
96
+ <Button type="submit" onClick={pickProcedureRequestQueue}>
97
+ {t('pickRequest', 'Pick Request')}
98
+ </Button>
99
+ </ModalFooter>
100
+ </Form>
101
+ </div>
102
+ );
103
+ };
104
+
105
+ export default AddProcedureToWorklistDialog;
@@ -0,0 +1,106 @@
1
+ import { type FetchResponse, openmrsFetch, restBaseUrl, useConfig } from '@openmrs/esm-framework';
2
+ import useSWRImmutable from 'swr/immutable';
3
+
4
+ export interface QueueRoomsResponse {
5
+ uuid: string;
6
+ display: string;
7
+ name: string;
8
+ description: string;
9
+ address1: string;
10
+ address2: string;
11
+ cityvillage: string;
12
+ stateprovince: string;
13
+ country: string;
14
+ postalcode: string;
15
+ latitude: string;
16
+ longitude: string;
17
+ countydistrict: string;
18
+ address3: string;
19
+ address4: string;
20
+ address5: string;
21
+ address6: string;
22
+ parentLocation: ParentLocation;
23
+ childLocations: string[];
24
+ retired: boolean;
25
+ attributes: string[];
26
+ address7: string;
27
+ address8: string;
28
+ address9: string;
29
+ address10: string;
30
+ address11: string;
31
+ address12: string;
32
+ address13: string;
33
+ address14: string;
34
+ address15: string;
35
+ resourceVersion: string;
36
+ }
37
+
38
+ export interface ParentLocation {
39
+ uuid: string;
40
+ display: string;
41
+ name: string;
42
+ description: string;
43
+ address1: string;
44
+ address2: string;
45
+ cityVillage: string;
46
+ stateProvince: string;
47
+ country: string;
48
+ postalcode: string;
49
+ latitude: string;
50
+ longitude: string;
51
+ countydistrict: string;
52
+ address3: string;
53
+ address4: string;
54
+ address5: string;
55
+ address6: string;
56
+ parentLocation: ParentLocation;
57
+ childLocations: ChildLocations[];
58
+ retired: boolean;
59
+ attributes: string[];
60
+ address7: string;
61
+ address8: string;
62
+ address9: string;
63
+ address10: string;
64
+ address11: string;
65
+ address12: string;
66
+ address13: string;
67
+ address14: string;
68
+ address15: string;
69
+ resourceversion: string;
70
+ }
71
+
72
+ export interface ChildLocations {
73
+ uuid: string;
74
+ display: string;
75
+ }
76
+
77
+ export interface ParentLocation {
78
+ uuid: string;
79
+ display: string;
80
+ }
81
+
82
+ // get referral locations
83
+ export function useReferralLocations() {
84
+ const config = useConfig();
85
+ const { laboratoryReferalDestinationUuid } = config;
86
+ const apiUrl = `${restBaseUrl}/concept/${laboratoryReferalDestinationUuid}`;
87
+ const { data, isLoading } = useSWRImmutable<FetchResponse>(apiUrl, openmrsFetch);
88
+
89
+ return {
90
+ referrals: data ? data?.data?.answers : [],
91
+ isLoading,
92
+ };
93
+ }
94
+
95
+ // update Order
96
+ export async function updateOrder(uuid: string, body: any) {
97
+ const abortController = new AbortController();
98
+ return openmrsFetch(`${restBaseUrl}/order/${uuid}/fulfillerdetails`, {
99
+ method: 'POST',
100
+ headers: {
101
+ 'Content-Type': 'application/json',
102
+ },
103
+ signal: abortController.signal,
104
+ body: body,
105
+ });
106
+ }
@@ -0,0 +1,38 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+
4
+ .radioButton {
5
+ padding: spacing.$spacing-02 spacing.$spacing-02;
6
+ margin: spacing.$spacing-03 0;
7
+ }
8
+
9
+ .section {
10
+ margin: spacing.$spacing-03;
11
+ }
12
+
13
+ .sectionTitle {
14
+ margin-bottom: spacing.$spacing-04;
15
+ }
16
+
17
+ .modalBody {
18
+ padding-bottom: spacing.$spacing-05;
19
+ }
20
+
21
+ .container {
22
+ display: 'flex';
23
+ align-items: 'center';
24
+ justify-content: 'space-between';
25
+ align-content: 'stretch';
26
+ }
27
+
28
+ .specimenContainer {
29
+ display: 'flex';
30
+ align-items: 'center';
31
+ justify-content: 'space-between';
32
+ column-gap: '10px';
33
+ }
34
+
35
+ .inputText {
36
+ display: 'flex';
37
+ align-items: 'center';
38
+ }
@@ -0,0 +1,32 @@
1
+ import { OverflowMenuItem } from '@carbon/react';
2
+ import { showModal } from '@openmrs/esm-framework';
3
+ import React, { useCallback } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ interface PickProcedureRequestActionMenuProps {
7
+ order: any;
8
+ closeModal: () => void;
9
+ }
10
+
11
+ const PickProcedureRequestActionMenu: React.FC<PickProcedureRequestActionMenuProps> = ({ order }) => {
12
+ const { t } = useTranslation();
13
+
14
+ const launchPickProcedureRequestModal = useCallback(() => {
15
+ const dispose = showModal('add-procedure-to-worklist-dialog', {
16
+ closeModal: () => dispose(),
17
+ order,
18
+ });
19
+ }, [order]);
20
+
21
+ return (
22
+ <OverflowMenuItem
23
+ itemText={t('pickRequest', 'Pick Request')}
24
+ onClick={launchPickProcedureRequestModal}
25
+ style={{
26
+ maxWidth: '100vw',
27
+ }}
28
+ />
29
+ );
30
+ };
31
+
32
+ export default PickProcedureRequestActionMenu;
@@ -0,0 +1,300 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import {
3
+ Button,
4
+ Form,
5
+ ModalBody,
6
+ ModalFooter,
7
+ ModalHeader,
8
+ Select,
9
+ SelectItem,
10
+ Checkbox,
11
+ TextInput,
12
+ } from '@carbon/react';
13
+ import { useTranslation } from 'react-i18next';
14
+ import styles from './add-to-worklist-dialog.scss';
15
+ import { showNotification, showSnackbar, useConfig } from '@openmrs/esm-framework';
16
+ import { Renew } from '@carbon/react/icons';
17
+ import {
18
+ GenerateSpecimenId,
19
+ UpdateOrder,
20
+ useReferralLocations,
21
+ useSpecimenTypes,
22
+ } from './add-to-worklist-dialog.resource';
23
+ import { type Order } from '../../types';
24
+
25
+ interface AddToWorklistDialogProps {
26
+ queueId;
27
+ order: Order;
28
+ closeModal: () => void;
29
+ }
30
+
31
+ const AddToWorklistDialog: React.FC<AddToWorklistDialogProps> = ({ queueId, order, closeModal }) => {
32
+ const { t } = useTranslation();
33
+
34
+ const [preferred, setPreferred] = useState(false);
35
+
36
+ const [specimenID, setSpecimenID] = useState('');
37
+
38
+ const { specimenTypes } = useSpecimenTypes();
39
+
40
+ const { referrals } = useReferralLocations();
41
+
42
+ const [specimenType, setSpecimenType] = useState();
43
+
44
+ const [selectedReferral, setSelectedReferral] = useState('');
45
+
46
+ const [barcode, setBarcode] = useState('');
47
+
48
+ const [confirmBarcode, setConfirmBarcode] = useState('');
49
+
50
+ const [externalReferralName, setExternalReferralName] = useState('');
51
+
52
+ const config = useConfig();
53
+
54
+ const pickProcedureRequestQueue = async (event) => {
55
+ event.preventDefault();
56
+ // pick procedure
57
+ const body = {
58
+ sampleId: specimenID,
59
+ specimenSourceId: specimenType,
60
+ unProcessedOrders: '',
61
+ patientQueueId: queueId,
62
+ };
63
+
64
+ UpdateOrder(order.uuid, body).then(
65
+ () => {
66
+ showSnackbar({
67
+ isLowContrast: true,
68
+ title: t('pickedAnOrder', 'Picked an order'),
69
+ kind: 'success',
70
+ subtitle: t('pickSuccessfully', 'You have successfully picked an Order'),
71
+ });
72
+ closeModal();
73
+ },
74
+ (error) => {
75
+ showNotification({
76
+ title: t(`errorPicking an order', 'Error Picking an Order`),
77
+ kind: 'error',
78
+ critical: true,
79
+ description: error?.message,
80
+ });
81
+ },
82
+ );
83
+ };
84
+
85
+ const onChecked = () => {
86
+ setPreferred(!preferred);
87
+ };
88
+
89
+ const generateId = async (e) => {
90
+ e.preventDefault();
91
+ // generate sample Id
92
+ GenerateSpecimenId(order.uuid).then(
93
+ (resp) => {
94
+ setSpecimenID(resp.data.results[0].sampleId);
95
+ showSnackbar({
96
+ isLowContrast: true,
97
+ title: t('generatesampleID', 'Generate Sample Id'),
98
+ kind: 'success',
99
+ subtitle: t('generateSuccessfully', 'You have successfully generated a Sample Id'),
100
+ });
101
+ },
102
+ (err) => {
103
+ showNotification({
104
+ title: t(`errorGeneratingId', 'Error Generating Sample Id`),
105
+ kind: 'error',
106
+ critical: true,
107
+ description: err?.message,
108
+ });
109
+ },
110
+ );
111
+ };
112
+
113
+ useEffect(() => {
114
+ if (barcode !== '' && confirmBarcode !== '' && barcode == confirmBarcode) {
115
+ setSpecimenID(barcode);
116
+ }
117
+ }, [barcode, confirmBarcode]);
118
+
119
+ return (
120
+ <div>
121
+ <Form onSubmit={pickProcedureRequestQueue}>
122
+ <ModalHeader closeModal={closeModal} title={t('pickRequest', 'Pick Request')} />
123
+ <ModalBody>
124
+ <div className={styles.modalBody}>
125
+ <section className={styles.section}>
126
+ <div
127
+ style={{
128
+ display: 'flex',
129
+ alignItems: 'center',
130
+ justifyContent: 'space-between',
131
+ alignContent: 'stretch',
132
+ }}>
133
+ <div className={styles.sectionTitle}>
134
+ {preferred ? t('barcode', 'Barcode') : t('specimenID', 'Procedure Id')}
135
+ </div>
136
+
137
+ <div
138
+ style={{
139
+ display: 'flex',
140
+ alignItems: 'center',
141
+ justifyContent: 'space-between',
142
+ columnGap: '10px',
143
+ }}>
144
+ <div style={{ width: '430px' }}>
145
+ <TextInput
146
+ type="text"
147
+ id="specimentId"
148
+ value={specimenID}
149
+ readOnly={
150
+ config.enableSpecimenIdAutoGeneration ? config.enableSpecimenIdAutoGeneration : preferred
151
+ }
152
+ hideReadOnly={preferred}
153
+ onChange={(e) => setSpecimenID(e.target.value)}
154
+ />
155
+ </div>
156
+
157
+ <div style={{ width: '50px' }}>
158
+ {config.enableSpecimenIdAutoGeneration && (
159
+ <Button
160
+ hasIconOnly
161
+ onClick={(e) => generateId(e)}
162
+ renderIcon={(props) => <Renew size={16} {...props} />}
163
+ disabled={preferred}
164
+ />
165
+ )}
166
+ </div>
167
+ </div>
168
+ </div>
169
+ </section>
170
+ <section className={styles.section}>
171
+ <div
172
+ style={{
173
+ display: 'flex',
174
+ alignItems: 'center',
175
+ justifyContent: 'space-between',
176
+ alignContent: 'stretch',
177
+ }}>
178
+ <div className={styles.sectionTitle}>{t('specimenType', 'Specimen Type')}</div>
179
+ <div style={{ width: '500px' }}>
180
+ <section className={styles.section}>
181
+ <Select
182
+ labelText=""
183
+ id="speciment-types"
184
+ name="specimen-types"
185
+ value={specimenType}
186
+ onChange={(event) => setSpecimenType(event.target.value)}>
187
+ {!specimenType ? <SelectItem text={t('specimenType', 'Select Specimen Type')} value="" /> : null}
188
+ {specimenTypes.map((type) => (
189
+ <SelectItem key={type.uuid} text={type.display} value={type.uuid}>
190
+ {type.display}
191
+ </SelectItem>
192
+ ))}
193
+ </Select>
194
+ </section>
195
+ </div>
196
+ </div>
197
+ </section>
198
+ <section
199
+ style={{
200
+ display: 'flex',
201
+ alignItems: 'center',
202
+ justifyContent: 'space-between',
203
+ alignContent: 'stretch',
204
+ }}>
205
+ <div>
206
+ <Checkbox checked={preferred} onChange={onChecked} labelText={'Referred'} id="test-referred" />
207
+ </div>
208
+ {preferred && (
209
+ <div style={{ width: '500px' }}>
210
+ <section className={styles.section}>
211
+ <Select
212
+ labelText={t('locationReferral', 'Referral Location ')}
213
+ id="nextQueueLocation"
214
+ name="nextQueueLocation"
215
+ invalidText="Required"
216
+ value={selectedReferral}
217
+ onChange={(event) => setSelectedReferral(event.target.value)}>
218
+ {referrals.map((referral) => (
219
+ <SelectItem key={referral.uuid} text={referral.display} value={referral.uuid}>
220
+ {referral.display}
221
+ </SelectItem>
222
+ ))}
223
+ </Select>
224
+ </section>
225
+
226
+ <section className={styles.section}>
227
+ {selectedReferral === '3476fd97-71da-4e9c-bf57-2b6318dc0c9f' && (
228
+ <div
229
+ style={{
230
+ display: 'flex',
231
+ alignItems: 'center',
232
+ }}>
233
+ <div style={{ width: '500px' }}>
234
+ <TextInput
235
+ type="text"
236
+ id="locationName"
237
+ labelText={'Enter Name'}
238
+ value={externalReferralName}
239
+ required={true}
240
+ onChange={(e) => setExternalReferralName(e.target.value)}
241
+ />
242
+ </div>
243
+ </div>
244
+ )}
245
+ <div
246
+ style={{
247
+ display: 'flex',
248
+ alignItems: 'center',
249
+ }}>
250
+ <div style={{ width: '500px' }}>
251
+ <TextInput
252
+ type="text"
253
+ id="enterBarcode"
254
+ labelText={'Enter Barcode'}
255
+ value={barcode}
256
+ required={true}
257
+ onChange={(e) => {
258
+ setBarcode(e.target.value);
259
+ }}
260
+ />
261
+ </div>
262
+ </div>
263
+ <div
264
+ style={{
265
+ display: 'flex',
266
+ alignItems: 'center',
267
+ }}>
268
+ <div style={{ width: '500px' }}>
269
+ <TextInput
270
+ type="text"
271
+ id="confirmBarcode"
272
+ labelText={'Confirm Barcode'}
273
+ value={confirmBarcode}
274
+ required={true}
275
+ onChange={(e) => {
276
+ setConfirmBarcode(e.target.value);
277
+ }}
278
+ />
279
+ </div>
280
+ </div>
281
+ </section>
282
+ </div>
283
+ )}
284
+ </section>
285
+ </div>
286
+ </ModalBody>
287
+ <ModalFooter>
288
+ <Button kind="secondary" onClick={closeModal}>
289
+ {t('cancel', 'Cancel')}
290
+ </Button>
291
+ <Button type="submit" onClick={pickProcedureRequestQueue}>
292
+ {t('pickPatient', 'Pick Order Request')}
293
+ </Button>
294
+ </ModalFooter>
295
+ </Form>
296
+ </div>
297
+ );
298
+ };
299
+
300
+ export default AddToWorklistDialog;