@openmrs/esm-service-queues-app 5.0.1-pre.2087

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 (254) hide show
  1. package/.turbo/turbo-build.log +40 -0
  2. package/LICENSE.md +401 -0
  3. package/README.md +23 -0
  4. package/__mocks__/active-visits.mock.ts +97 -0
  5. package/__mocks__/appointments-data.mock.ts +283 -0
  6. package/__mocks__/search.mock.ts +35 -0
  7. package/__mocks__/visits.mock.ts +42 -0
  8. package/dist/121.js +1 -0
  9. package/dist/121.js.map +1 -0
  10. package/dist/130.js +2 -0
  11. package/dist/130.js.LICENSE.txt +5 -0
  12. package/dist/130.js.map +1 -0
  13. package/dist/176.js +1 -0
  14. package/dist/176.js.map +1 -0
  15. package/dist/227.js +1 -0
  16. package/dist/227.js.map +1 -0
  17. package/dist/242.js +1 -0
  18. package/dist/242.js.map +1 -0
  19. package/dist/252.js +1 -0
  20. package/dist/252.js.map +1 -0
  21. package/dist/286.js +1 -0
  22. package/dist/286.js.map +1 -0
  23. package/dist/308.js +1 -0
  24. package/dist/308.js.map +1 -0
  25. package/dist/319.js +1 -0
  26. package/dist/328.js +1 -0
  27. package/dist/328.js.map +1 -0
  28. package/dist/330.js +1 -0
  29. package/dist/330.js.map +1 -0
  30. package/dist/364.js +1 -0
  31. package/dist/364.js.map +1 -0
  32. package/dist/425.js +1 -0
  33. package/dist/425.js.map +1 -0
  34. package/dist/457.js +1 -0
  35. package/dist/457.js.map +1 -0
  36. package/dist/469.js +1 -0
  37. package/dist/469.js.map +1 -0
  38. package/dist/521.js +1 -0
  39. package/dist/521.js.map +1 -0
  40. package/dist/53.js +1 -0
  41. package/dist/53.js.map +1 -0
  42. package/dist/574.js +1 -0
  43. package/dist/591.js +2 -0
  44. package/dist/591.js.LICENSE.txt +32 -0
  45. package/dist/591.js.map +1 -0
  46. package/dist/610.js +1 -0
  47. package/dist/610.js.map +1 -0
  48. package/dist/611.js +1 -0
  49. package/dist/611.js.map +1 -0
  50. package/dist/616.js +1 -0
  51. package/dist/616.js.map +1 -0
  52. package/dist/644.js +1 -0
  53. package/dist/644.js.map +1 -0
  54. package/dist/670.js +2 -0
  55. package/dist/670.js.LICENSE.txt +57 -0
  56. package/dist/670.js.map +1 -0
  57. package/dist/733.js +1 -0
  58. package/dist/733.js.map +1 -0
  59. package/dist/757.js +1 -0
  60. package/dist/764.js +1 -0
  61. package/dist/764.js.map +1 -0
  62. package/dist/766.js +1 -0
  63. package/dist/766.js.map +1 -0
  64. package/dist/784.js +2 -0
  65. package/dist/784.js.LICENSE.txt +9 -0
  66. package/dist/784.js.map +1 -0
  67. package/dist/788.js +1 -0
  68. package/dist/807.js +1 -0
  69. package/dist/833.js +1 -0
  70. package/dist/86.js +1 -0
  71. package/dist/86.js.map +1 -0
  72. package/dist/981.js +1 -0
  73. package/dist/981.js.map +1 -0
  74. package/dist/main.js +1 -0
  75. package/dist/main.js.map +1 -0
  76. package/dist/openmrs-esm-service-queues-app.js +1 -0
  77. package/dist/openmrs-esm-service-queues-app.js.buildmanifest.json +930 -0
  78. package/dist/openmrs-esm-service-queues-app.js.map +1 -0
  79. package/dist/routes.json +1 -0
  80. package/jest.config.js +3 -0
  81. package/package.json +53 -0
  82. package/src/active-visits/active-visits-tab.component.tsx +71 -0
  83. package/src/active-visits/active-visits-tab.test.tsx +19 -0
  84. package/src/active-visits/active-visits-table.component.tsx +543 -0
  85. package/src/active-visits/active-visits-table.resource.ts +443 -0
  86. package/src/active-visits/active-visits-table.scss +271 -0
  87. package/src/active-visits/active-visits-table.test.tsx +131 -0
  88. package/src/active-visits/change-status-dialog.component.tsx +233 -0
  89. package/src/active-visits/change-status-dialog.scss +32 -0
  90. package/src/active-visits/change-status-dialog.test.tsx +107 -0
  91. package/src/add-patient-toqueue/add-patient-toqueue-dialog.component.tsx +218 -0
  92. package/src/add-patient-toqueue/add-patient-toqueue-dialog.scss +32 -0
  93. package/src/add-provider-queue-room/add-provider-queue-room.component.tsx +236 -0
  94. package/src/add-provider-queue-room/add-provider-queue-room.resource.tsx +76 -0
  95. package/src/add-provider-queue-room/add-provider-queue-room.scss +17 -0
  96. package/src/add-provider-queue-room/add-provider-queue-room.test.tsx +98 -0
  97. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.component.tsx +74 -0
  98. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.resource.tsx +46 -0
  99. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.scss +15 -0
  100. package/src/clear-queue-entries-dialog/clear-queue-entries-dialog.test.tsx +42 -0
  101. package/src/clear-queue-entries-dialog/clear-queue-entries.component.tsx +36 -0
  102. package/src/config-schema.ts +177 -0
  103. package/src/constants.ts +7 -0
  104. package/src/createDashboardLink.tsx +35 -0
  105. package/src/current-visit/current-visit-summary.component.tsx +38 -0
  106. package/src/current-visit/current-visit-summary.test.tsx +47 -0
  107. package/src/current-visit/current-visit.resource.ts +84 -0
  108. package/src/current-visit/current-visit.scss +34 -0
  109. package/src/current-visit/hooks/useVitalsConceptMetadata.tsx +101 -0
  110. package/src/current-visit/visit-details/biometrics-config-schema.ts +14 -0
  111. package/src/current-visit/visit-details/current-visit-details.component.tsx +96 -0
  112. package/src/current-visit/visit-details/triage-note.component.tsx +53 -0
  113. package/src/current-visit/visit-details/triage-note.scss +89 -0
  114. package/src/current-visit/visit-details/vitals-config-schema.ts +17 -0
  115. package/src/current-visit/visit-details/vitals.component.tsx +164 -0
  116. package/src/dashboard.meta.ts +5 -0
  117. package/src/declarations.d.ts +2 -0
  118. package/src/helpers/functions.ts +67 -0
  119. package/src/helpers/helpers.ts +170 -0
  120. package/src/helpers/time-helpers.ts +15 -0
  121. package/src/home.component.tsx +29 -0
  122. package/src/home.test.tsx +58 -0
  123. package/src/index.ts +100 -0
  124. package/src/overlay.component.tsx +46 -0
  125. package/src/overlay.scss +96 -0
  126. package/src/overlay.test.tsx +49 -0
  127. package/src/past-visit/past-visit-details/encounter-list.component.tsx +51 -0
  128. package/src/past-visit/past-visit-details/medications-list.component.tsx +95 -0
  129. package/src/past-visit/past-visit-details/notes-list.component.tsx +40 -0
  130. package/src/past-visit/past-visit-details/past-visit-summary.component.tsx +172 -0
  131. package/src/past-visit/past-visit-details/past-visit-summary.scss +58 -0
  132. package/src/past-visit/past-visit.component.tsx +37 -0
  133. package/src/past-visit/past-visit.resource.ts +83 -0
  134. package/src/past-visit/past-visit.scss +126 -0
  135. package/src/past-visit/past-visit.test.tsx +41 -0
  136. package/src/patient-info/appointment-details.component.tsx +98 -0
  137. package/src/patient-info/appointment-details.scss +34 -0
  138. package/src/patient-info/appointment-details.test.tsx +36 -0
  139. package/src/patient-info/appointments.resource.tsx +43 -0
  140. package/src/patient-info/contact-details.component.tsx +71 -0
  141. package/src/patient-info/contact-details.scss +31 -0
  142. package/src/patient-info/contact-details.test.tsx +94 -0
  143. package/src/patient-info/hooks/usePatientAttributes.tsx +42 -0
  144. package/src/patient-info/patient-info.component.tsx +78 -0
  145. package/src/patient-info/patient-info.scss +60 -0
  146. package/src/patient-info/patient-info.test.tsx +45 -0
  147. package/src/patient-queue-header/patient-queue-header.component.tsx +64 -0
  148. package/src/patient-queue-header/patient-queue-header.scss +88 -0
  149. package/src/patient-queue-header/patient-queue-illustration.component.tsx +22 -0
  150. package/src/patient-queue-metrics/clinic-metrics.component.tsx +93 -0
  151. package/src/patient-queue-metrics/clinic-metrics.resource.tsx +51 -0
  152. package/src/patient-queue-metrics/clinic-metrics.scss +11 -0
  153. package/src/patient-queue-metrics/clinic-metrics.test.tsx +87 -0
  154. package/src/patient-queue-metrics/metrics-card.component.tsx +64 -0
  155. package/src/patient-queue-metrics/metrics-card.scss +80 -0
  156. package/src/patient-queue-metrics/metrics-header.component.tsx +74 -0
  157. package/src/patient-queue-metrics/metrics-header.scss +22 -0
  158. package/src/patient-queue-metrics/queue-metrics.resource.ts +54 -0
  159. package/src/patient-search/advanced-search.component.tsx +190 -0
  160. package/src/patient-search/advanced-search.scss +154 -0
  161. package/src/patient-search/advanced-search.test.tsx +29 -0
  162. package/src/patient-search/basic-search.component.tsx +112 -0
  163. package/src/patient-search/basic-search.scss +139 -0
  164. package/src/patient-search/basic-search.test.tsx +23 -0
  165. package/src/patient-search/empty-data-illustration.component.tsx +41 -0
  166. package/src/patient-search/hooks/useActivePatientEnrollment.tsx +29 -0
  167. package/src/patient-search/hooks/useDefaultLocation.tsx +14 -0
  168. package/src/patient-search/hooks/usePatients.tsx +25 -0
  169. package/src/patient-search/hooks/useQueueLocations.tsx +20 -0
  170. package/src/patient-search/hooks/useRecommendedVisitTypes.tsx +36 -0
  171. package/src/patient-search/hooks/useScheduledVisits.tsx +50 -0
  172. package/src/patient-search/patient-scheduled-visits.component.tsx +350 -0
  173. package/src/patient-search/patient-scheduled-visits.scss +131 -0
  174. package/src/patient-search/patient-scheduled-visits.test.tsx +55 -0
  175. package/src/patient-search/patient-search.component.tsx +64 -0
  176. package/src/patient-search/search-illustration.component.tsx +27 -0
  177. package/src/patient-search/search-results.component.tsx +75 -0
  178. package/src/patient-search/search-results.scss +80 -0
  179. package/src/patient-search/search-results.test.tsx +77 -0
  180. package/src/patient-search/search.resource.ts +10 -0
  181. package/src/patient-search/visit-form/base-visit-type.component.tsx +82 -0
  182. package/src/patient-search/visit-form/base-visit-type.scss +100 -0
  183. package/src/patient-search/visit-form/base-visit-type.test.tsx +41 -0
  184. package/src/patient-search/visit-form/queue.resource.ts +73 -0
  185. package/src/patient-search/visit-form/recommended-visit-type.component.tsx +38 -0
  186. package/src/patient-search/visit-form/visit-form.component.tsx +366 -0
  187. package/src/patient-search/visit-form/visit-form.scss +96 -0
  188. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.component.tsx +160 -0
  189. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.scss +21 -0
  190. package/src/patient-search/visit-form-queue-fields/visit-form-queue-fields.test.tsx +67 -0
  191. package/src/queue-entry-table-components/actions-menu.component.tsx +51 -0
  192. package/src/queue-entry-table-components/actions-menu.scss +3 -0
  193. package/src/queue-entry-table-components/edit-entry.component.tsx +28 -0
  194. package/src/queue-entry-table-components/edit-entry.scss +14 -0
  195. package/src/queue-entry-table-components/open-chart.component.tsx +33 -0
  196. package/src/queue-entry-table-components/open-chart.resource.tsx +14 -0
  197. package/src/queue-entry-table-components/open-chart.scss +14 -0
  198. package/src/queue-entry-table-components/status-icon.component.tsx +17 -0
  199. package/src/queue-entry-table-components/transition-entry.component.tsx +53 -0
  200. package/src/queue-entry-table-components/transition-entry.scss +22 -0
  201. package/src/queue-patient-linelists/queue-linelist-base-table.component.tsx +230 -0
  202. package/src/queue-patient-linelists/queue-linelist-base-table.scss +110 -0
  203. package/src/queue-patient-linelists/queue-linelist-base-table.test.tsx +118 -0
  204. package/src/queue-patient-linelists/queue-linelist-filter.component.tsx +172 -0
  205. package/src/queue-patient-linelists/queue-linelist-filter.scss +63 -0
  206. package/src/queue-patient-linelists/queue-linelist-filter.test.tsx +76 -0
  207. package/src/queue-patient-linelists/queue-linelist.component.tsx +29 -0
  208. package/src/queue-patient-linelists/queue-linelist.resource.tsx +84 -0
  209. package/src/queue-patient-linelists/queue-linelist.test.tsx +22 -0
  210. package/src/queue-patient-linelists/queue-services-table.component.tsx +63 -0
  211. package/src/queue-patient-linelists/scheduled-appointments-table.component.tsx +300 -0
  212. package/src/queue-patient-linelists/scheduled-appointments-table.test.tsx +42 -0
  213. package/src/queue-rooms/queue-room-form.component.tsx +168 -0
  214. package/src/queue-rooms/queue-room-form.test.tsx +65 -0
  215. package/src/queue-rooms/queue-room.resource.tsx +20 -0
  216. package/src/queue-rooms/queue-room.scss +58 -0
  217. package/src/queue-screen/queue-screen.component.tsx +47 -0
  218. package/src/queue-screen/queue-screen.scss +39 -0
  219. package/src/queue-screen/queue-screen.test.tsx +47 -0
  220. package/src/queue-screen/useActiveTickets.tsx +13 -0
  221. package/src/queue-services/queue-service-form.component.tsx +183 -0
  222. package/src/queue-services/queue-service-form.test.tsx +56 -0
  223. package/src/queue-services/queue-service.resource.tsx +38 -0
  224. package/src/queue-services/queue-service.scss +54 -0
  225. package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +95 -0
  226. package/src/remove-queue-entry-dialog/remove-queue-entry.resource.tsx +93 -0
  227. package/src/remove-queue-entry-dialog/remove-queue-entry.scss +8 -0
  228. package/src/remove-queue-entry-dialog/remove-queue-entry.test.tsx +44 -0
  229. package/src/root.component.tsx +28 -0
  230. package/src/root.scss +15 -0
  231. package/src/root.test.tsx +28 -0
  232. package/src/routes.json +91 -0
  233. package/src/side-menu/nav-group/createNavGroup.tsx +17 -0
  234. package/src/side-menu/nav-group/nav-group.component.tsx +24 -0
  235. package/src/side-menu/nav-group/nav-group.test.tsx +32 -0
  236. package/src/side-menu/nav-group/nav-group.ts +10 -0
  237. package/src/side-menu/side-menu.component.tsx +6 -0
  238. package/src/side-menu/side-menu.test.tsx +17 -0
  239. package/src/transition-queue-entry/transition-queue-entry-dialog.component.tsx +174 -0
  240. package/src/transition-queue-entry/transition-queue-entry-dialog.scss +12 -0
  241. package/src/transition-queue-entry/transition-queue-entry-dialog.test.tsx +95 -0
  242. package/src/transition-queue-entry/transition-queue-entry.resource.ts +16 -0
  243. package/src/types/index.ts +434 -0
  244. package/src/visits-missing-inqueue/visits-missing-inqueue.component.tsx +298 -0
  245. package/src/visits-missing-inqueue/visits-missing-inqueue.resource.ts +93 -0
  246. package/src/visits-missing-inqueue/visits-missing-inqueue.scss +108 -0
  247. package/translations/am.json +258 -0
  248. package/translations/en.json +258 -0
  249. package/translations/es.json +258 -0
  250. package/translations/fr.json +258 -0
  251. package/translations/he.json +262 -0
  252. package/translations/km.json +258 -0
  253. package/tsconfig.json +5 -0
  254. package/webpack.config.js +1 -0
@@ -0,0 +1,96 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+ @import '~@openmrs/esm-styleguide/src/vars';
4
+
5
+ .container {
6
+ margin: spacing.$spacing-05 0rem;
7
+ background-color: $ui-background;
8
+
9
+ & section {
10
+ margin: spacing.$spacing-02 spacing.$spacing-05 0;
11
+ }
12
+ }
13
+
14
+ .heading {
15
+ @include type.type-style('heading-03');
16
+ margin: spacing.$spacing-05;
17
+ }
18
+
19
+ .sectionTitle {
20
+ @include type.type-style('heading-compact-02');
21
+ color: $text-02;
22
+ margin-bottom: spacing.$spacing-05;
23
+ }
24
+
25
+ .dateTimeSection {
26
+ display: flex;
27
+ }
28
+
29
+ .radioButton {
30
+ margin: spacing.$spacing-05 0;
31
+ }
32
+
33
+ .headerGridRow {
34
+ border-bottom: 0.0625rem solid $grey-2;
35
+ margin: 0;
36
+ }
37
+
38
+ .dataGridRow {
39
+ display: grid;
40
+ grid-template-columns: 50% 10% 1fr;
41
+ margin: spacing.$spacing-03 spacing.$spacing-05;
42
+ width: 100%;
43
+ }
44
+
45
+ .form {
46
+ background-color: $ui-background;
47
+ display: flex;
48
+ flex-direction: column;
49
+ justify-content: space-between;
50
+ }
51
+
52
+ .button {
53
+ height: 4rem;
54
+ display: flex;
55
+ align-content: flex-start;
56
+ align-items: baseline;
57
+ min-width: 50%;
58
+ }
59
+
60
+ .tablet {
61
+ padding: spacing.$spacing-06 spacing.$spacing-05;
62
+ background-color: $ui-02;
63
+ }
64
+
65
+ .desktop {
66
+ padding: 0rem;
67
+ }
68
+
69
+ @media screen and (max-width: 600px) {
70
+ .dateTimeSection {
71
+ flex-direction: column;
72
+ }
73
+ }
74
+
75
+ .backButton {
76
+ align-items: center;
77
+ display: flex;
78
+ justify-content: flex-start;
79
+ margin: spacing.$spacing-03 0;
80
+ padding: 0;
81
+ @include type.type-style('body-compact-01');
82
+
83
+ button {
84
+ display: flex;
85
+
86
+ svg {
87
+ order: 1;
88
+ margin-right: spacing.$spacing-03;
89
+ margin-left: 0rem !important;
90
+ }
91
+
92
+ span {
93
+ order: 2;
94
+ }
95
+ }
96
+ }
@@ -0,0 +1,160 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import { InlineNotification, Layer, Select, SelectItem, RadioButtonGroup, RadioButton, TextInput } from '@carbon/react';
3
+ import { useQueueLocations } from '../hooks/useQueueLocations';
4
+ import { usePriority, useStatus } from '../../active-visits/active-visits-table.resource';
5
+ import { useServices } from '../../patient-queue-metrics/queue-metrics.resource';
6
+ import styles from './visit-form-queue-fields.scss';
7
+ import { ConfigObject, useConfig, useLayoutType } from '@openmrs/esm-framework';
8
+ import { useTranslation } from 'react-i18next';
9
+
10
+ const StartVisitQueueFields: React.FC = () => {
11
+ const { t } = useTranslation();
12
+ const isTablet = useLayoutType() === 'tablet';
13
+ const { priorities } = usePriority();
14
+ const { statuses } = useStatus();
15
+ const { queueLocations } = useQueueLocations();
16
+ const config = useConfig() as ConfigObject;
17
+ const defaultStatus = config.concepts.defaultStatusConceptUuid;
18
+ const defaultPriority = config.concepts.defaultPriorityConceptUuid;
19
+ const emergencyPriorityConceptUuid = config.concepts.emergencyPriorityConceptUuid;
20
+ const [selectedQueueLocation, setSelectedQueueLocation] = useState(queueLocations[0]?.id);
21
+ const { allServices, isLoading } = useServices(selectedQueueLocation);
22
+ const [priority, setPriority] = useState(defaultPriority);
23
+ const [status, setStatus] = useState(defaultStatus);
24
+ const [sortWeight, setSortWeight] = useState(0);
25
+ const [service, setSelectedService] = useState('');
26
+
27
+ useEffect(() => {
28
+ if (priority === emergencyPriorityConceptUuid) {
29
+ setSortWeight(1);
30
+ }
31
+ }, [priority]);
32
+
33
+ useEffect(() => {
34
+ if (allServices?.length > 0) {
35
+ setSelectedService(allServices[0].uuid);
36
+ }
37
+ }, [allServices]);
38
+
39
+ useEffect(() => {
40
+ if (queueLocations?.length > 0) {
41
+ setSelectedQueueLocation(queueLocations[0].id);
42
+ }
43
+ }, [queueLocations]);
44
+
45
+ return (
46
+ <div className={styles.container}>
47
+ <section className={styles.section}>
48
+ <div className={styles.sectionTitle}>{t('queueLocation', 'Queue Location')}</div>
49
+ <ResponsiveWrapper isTablet={isTablet}>
50
+ <Select
51
+ labelText={t('selectQueueLocation', 'Select a queue location')}
52
+ id="queueLocation"
53
+ name="queueLocation"
54
+ invalidText="Required"
55
+ value={selectedQueueLocation}
56
+ onChange={(event) => setSelectedQueueLocation(event.target.value)}>
57
+ {!selectedQueueLocation ? (
58
+ <SelectItem text={t('selectLocation', 'Select a queue location')} value="" />
59
+ ) : null}
60
+ {queueLocations?.length > 0 &&
61
+ queueLocations.map((location) => (
62
+ <SelectItem key={location.id} text={location.name} value={location.id}>
63
+ {location.name}
64
+ </SelectItem>
65
+ ))}
66
+ </Select>
67
+ </ResponsiveWrapper>
68
+ </section>
69
+
70
+ <section className={styles.section}>
71
+ <div className={styles.sectionTitle}>{t('service', 'Service')}</div>
72
+ {!allServices?.length ? (
73
+ <InlineNotification
74
+ className={styles.inlineNotification}
75
+ kind={'error'}
76
+ lowContrast
77
+ subtitle={t('configureServices', 'Please configure services to continue.')}
78
+ title={t('noServicesConfigured', 'No services configured')}
79
+ />
80
+ ) : (
81
+ <Select
82
+ labelText={t('selectService', 'Select a service')}
83
+ id="service"
84
+ name="service"
85
+ invalidText="Required"
86
+ value={service}
87
+ onChange={(event) => setSelectedService(event.target.value)}>
88
+ {!service ? <SelectItem text={t('selectService', 'Select a queue service')} value="" /> : null}
89
+ {allServices?.length > 0 &&
90
+ allServices.map((service) => (
91
+ <SelectItem key={service.uuid} text={service.name} value={service.uuid}>
92
+ {service.name}
93
+ </SelectItem>
94
+ ))}
95
+ </Select>
96
+ )}
97
+ </section>
98
+
99
+ <section className={`${styles.section} ${styles.sectionHidden}`}>
100
+ <div className={styles.sectionTitle}>{t('status', 'Status')}</div>
101
+ <Select
102
+ labelText={t('selectStatus', 'Select a status')}
103
+ id="status"
104
+ name="status"
105
+ invalidText="Required"
106
+ value={status}
107
+ onChange={(event) => setStatus(event.target.value)}>
108
+ {!statuses ? <SelectItem text={t('chooseStatus', 'Select a status')} value="" /> : null}
109
+ {statuses?.length > 0 &&
110
+ statuses.map((status) => (
111
+ <SelectItem key={status.uuid} text={status.display} value={status.uuid}>
112
+ {status.display}
113
+ </SelectItem>
114
+ ))}
115
+ </Select>
116
+ </section>
117
+
118
+ <section className={styles.section}>
119
+ <div className={styles.sectionTitle}>{t('priority', 'Priority')}</div>
120
+ {!priorities?.length ? (
121
+ <InlineNotification
122
+ className={styles.inlineNotification}
123
+ kind={'error'}
124
+ lowContrast
125
+ subtitle={t('configurePriorities', 'Please configure priorities to continue.')}
126
+ title={t('noPrioritiesConfigured', 'No priorities configured')}
127
+ />
128
+ ) : (
129
+ <RadioButtonGroup
130
+ className={styles.radioButtonWrapper}
131
+ name="priority"
132
+ id="priority"
133
+ defaultSelected={defaultPriority}
134
+ onChange={(uuid) => {
135
+ setPriority(uuid);
136
+ }}>
137
+ {priorities?.length > 0 &&
138
+ priorities.map(({ uuid, display }) => <RadioButton key={uuid} labelText={display} value={uuid} />)}
139
+ </RadioButtonGroup>
140
+ )}
141
+ </section>
142
+
143
+ <section className={`${styles.section} ${styles.sectionHidden}`}>
144
+ <TextInput
145
+ type="number"
146
+ id="sortWeight"
147
+ name="sortWeight"
148
+ labelText={t('sortWeight', 'Sort weight')}
149
+ value={sortWeight}
150
+ />
151
+ </section>
152
+ </div>
153
+ );
154
+ };
155
+
156
+ function ResponsiveWrapper({ children, isTablet }) {
157
+ return isTablet ? <Layer>{children}</Layer> : <div>{children}</div>;
158
+ }
159
+
160
+ export default StartVisitQueueFields;
@@ -0,0 +1,21 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+ @import '~@openmrs/esm-styleguide/src/vars';
4
+
5
+ .sectionTitle {
6
+ @include type.type-style('heading-compact-02');
7
+ color: $text-02;
8
+ margin-bottom: spacing.$spacing-05;
9
+ }
10
+
11
+ .section {
12
+ margin: spacing.$spacing-03;
13
+ }
14
+
15
+ .sectionHidden {
16
+ display: none;
17
+ }
18
+
19
+ .container {
20
+ margin: spacing.$spacing-05;
21
+ }
@@ -0,0 +1,67 @@
1
+ import React from 'react';
2
+ import { render, fireEvent } from '@testing-library/react';
3
+ import StartVisitQueueFields from './visit-form-queue-fields.component';
4
+
5
+ jest.mock('@openmrs/esm-framework', () => ({
6
+ ...jest.requireActual('@openmrs/esm-framework'),
7
+ useLayoutType: () => 'desktop',
8
+ showNotification: jest.fn(),
9
+ showToast: jest.fn(),
10
+ useConfig: jest.fn(() => ({
11
+ concepts: {
12
+ visitQueueNumberAttributeUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
13
+ defaultStatusConceptUuid: 'c61ce16f-272a-41e7-9924-4c555d0932c5',
14
+ },
15
+ })),
16
+ }));
17
+ jest.mock('../hooks/useQueueLocations', () => ({
18
+ useQueueLocations: jest.fn(() => ({
19
+ queueLocations: [{ id: '1', name: 'Location 1' }],
20
+ })),
21
+ }));
22
+
23
+ jest.mock('../../active-visits/active-visits-table.resource', () => ({
24
+ usePriority: jest.fn(() => ({
25
+ priorities: [{ uuid: '197852c7-5fd4-4b33-89cc-7bae6848c65a', display: 'High' }],
26
+ })),
27
+ useStatus: jest.fn(() => ({
28
+ statuses: [{ uuid: '176052c7-5fd4-4b33-89cc-7bae6848c65a', display: 'In Progress' }],
29
+ })),
30
+ }));
31
+
32
+ jest.mock('../../patient-queue-metrics/queue-metrics.resource', () => ({
33
+ useServices: jest.fn((selectedQueueLocation) => ({
34
+ allServices: [{ uuid: 'e2ec9cf0-ec38-4d2b-af6c-59c82fa30b90', name: 'Service 1' }],
35
+ isLoading: false,
36
+ })),
37
+ }));
38
+
39
+ describe('StartVisitQueueFields', () => {
40
+ it('renders the form fields', () => {
41
+ const { getByLabelText, getByText } = render(<StartVisitQueueFields />);
42
+
43
+ expect(getByLabelText('Select a queue location')).toBeInTheDocument();
44
+ expect(getByLabelText('Select a service')).toBeInTheDocument();
45
+ expect(getByLabelText('Select a status')).toBeInTheDocument();
46
+ expect(getByText('High')).toBeInTheDocument();
47
+ expect(getByLabelText('Sort weight')).toBeInTheDocument();
48
+ });
49
+
50
+ it('updates the selected queue location', () => {
51
+ const { getByLabelText } = render(<StartVisitQueueFields />);
52
+
53
+ const selectQueueLocation = getByLabelText('Select a queue location') as HTMLInputElement;
54
+ fireEvent.change(selectQueueLocation, { target: { value: '1' } });
55
+
56
+ expect(selectQueueLocation.value).toBe('1');
57
+ });
58
+
59
+ it('updates the selected service', () => {
60
+ const { getByLabelText } = render(<StartVisitQueueFields />);
61
+
62
+ const selectService = getByLabelText('Select a service') as HTMLInputElement;
63
+ fireEvent.change(selectService, { target: { value: 'service-1' } });
64
+
65
+ expect(selectService.value).toBe('e2ec9cf0-ec38-4d2b-af6c-59c82fa30b90');
66
+ });
67
+ });
@@ -0,0 +1,51 @@
1
+ import React, { useCallback } from 'react';
2
+ import { navigate, showModal } from '@openmrs/esm-framework';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { MappedVisitQueueEntry } from '../active-visits/active-visits-table.resource';
5
+ import { Layer, OverflowMenu, OverflowMenuItem } from '@carbon/react';
6
+ import styles from './actions-menu.scss';
7
+
8
+ interface ActionsMenuProps {
9
+ queueEntry: MappedVisitQueueEntry;
10
+ closeModal: () => void;
11
+ }
12
+
13
+ const ActionsMenu: React.FC<ActionsMenuProps> = ({ queueEntry, closeModal }) => {
14
+ const { t } = useTranslation();
15
+
16
+ const launchEndVisitModal = useCallback(() => {
17
+ const dispose = showModal('remove-queue-entry', {
18
+ closeModal: () => dispose(),
19
+ queueEntry,
20
+ });
21
+ }, [queueEntry]);
22
+
23
+ return (
24
+ <Layer>
25
+ <OverflowMenu ariaLabel="Actions menu" selectorPrimaryFocus={'#editPatientDetails'} size="sm" flipped>
26
+ <OverflowMenuItem
27
+ className={styles.menuItem}
28
+ id="#editPatientDetails"
29
+ itemText={t('editPatientDetails', 'Edit patient details')}
30
+ onClick={() =>
31
+ navigate({
32
+ to: `\${openmrsSpaBase}/patient/${queueEntry.patientUuid}/edit`,
33
+ })
34
+ }>
35
+ {t('editPatientDetails', 'Edit patient details')}
36
+ </OverflowMenuItem>
37
+ <OverflowMenuItem
38
+ className={styles.menuItem}
39
+ id="#endVisit"
40
+ onClick={launchEndVisitModal}
41
+ hasDivider
42
+ isDelete
43
+ itemText={t('endVisit', 'End visit')}>
44
+ {t('endVisit', 'End Visit')}
45
+ </OverflowMenuItem>
46
+ </OverflowMenu>
47
+ </Layer>
48
+ );
49
+ };
50
+
51
+ export default ActionsMenu;
@@ -0,0 +1,3 @@
1
+ .menuItem {
2
+ max-width: none;
3
+ }
@@ -0,0 +1,28 @@
1
+ import React, { useCallback } from 'react';
2
+ import { MappedVisitQueueEntry } from '../active-visits/active-visits-table.resource';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { showModal } from '@openmrs/esm-framework';
5
+ import { Button } from '@carbon/react';
6
+ import styles from './edit-entry.scss';
7
+
8
+ interface EditMenuProps {
9
+ queueEntry: MappedVisitQueueEntry;
10
+ closeModal: () => void;
11
+ }
12
+ const EditMenu: React.FC<EditMenuProps> = ({ queueEntry, closeModal }) => {
13
+ const { t } = useTranslation();
14
+ const launchEditPriorityModal = useCallback(() => {
15
+ const dispose = showModal('edit-queue-entry-status-modal', {
16
+ closeModal: () => dispose(),
17
+ queueEntry,
18
+ });
19
+ }, [queueEntry]);
20
+
21
+ return (
22
+ <Button onClick={launchEditPriorityModal} className={styles.editIcon} kind="ghost">
23
+ {t('transfer', 'Transfer')}
24
+ </Button>
25
+ );
26
+ };
27
+
28
+ export default EditMenu;
@@ -0,0 +1,14 @@
1
+ @import '~@openmrs/esm-styleguide/src/vars';
2
+
3
+ .editIcon {
4
+ background-color: transparent;
5
+
6
+ & svg {
7
+ fill: var(--omrs-color-brand-orange);
8
+ color: var(--omrs-color-brand-orange);
9
+ }
10
+ }
11
+
12
+ .editIcon:hover {
13
+ background-color: transparent;
14
+ }
@@ -0,0 +1,33 @@
1
+ import React, { useCallback } from 'react';
2
+ import { useTranslation } from 'react-i18next';
3
+ import { ConfigObject, navigate, useConfig } from '@openmrs/esm-framework';
4
+ import { Button } from '@carbon/react';
5
+ import styles from './open-chart.scss';
6
+ import usePatientId from './open-chart.resource';
7
+
8
+ interface OpenChartMenuProps {
9
+ patientUuid: string;
10
+ }
11
+ const OpenChartMenu: React.FC<OpenChartMenuProps> = ({ patientUuid }) => {
12
+ const { t } = useTranslation();
13
+ const { isLoading, patient } = usePatientId(patientUuid);
14
+ const config = useConfig() as ConfigObject;
15
+
16
+ const redirectPatientChart = useCallback(() => {
17
+ if (!isLoading) {
18
+ navigate({
19
+ to: config.customPatientChartUrl
20
+ ? `${config.customPatientChartUrl}=${patient?.patientId}&`
21
+ : `\${openmrsSpaBase}/patient/${patientUuid}/chart`,
22
+ });
23
+ }
24
+ }, [patient, config.customPatientChartUrl]);
25
+
26
+ return (
27
+ <Button onClick={redirectPatientChart} className={styles.editIcon} kind="ghost">
28
+ {config.customPatientChartText ? config.customPatientChartText : t('profile', 'Profile')}
29
+ </Button>
30
+ );
31
+ };
32
+
33
+ export default OpenChartMenu;
@@ -0,0 +1,14 @@
1
+ import { ConfigObject, openmrsFetch, useConfig } from '@openmrs/esm-framework';
2
+ import useSWR from 'swr';
3
+
4
+ const usePatientId = (patientUuid: string) => {
5
+ const config = useConfig() as ConfigObject;
6
+
7
+ const { isLoading, data, error } = useSWR<{ data: { results: { patientId: string; age: number } } }>(
8
+ `${config.customPatientIdUrl}=${patientUuid}`,
9
+ openmrsFetch,
10
+ );
11
+ return { patient: data?.data?.results, error, isLoading };
12
+ };
13
+
14
+ export default usePatientId;
@@ -0,0 +1,14 @@
1
+ @import '~@openmrs/esm-styleguide/src/vars';
2
+
3
+ .editIcon {
4
+ background-color: transparent;
5
+
6
+ & svg {
7
+ fill: $color-blue-60-2;
8
+ color: $color-blue-60-2;
9
+ }
10
+ }
11
+
12
+ .editIcon:hover {
13
+ background-color: transparent;
14
+ }
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { Group, InProgress } from '@carbon/react/icons';
3
+
4
+ function StatusIcon({ status }) {
5
+ switch (status) {
6
+ case 'waiting':
7
+ return <InProgress size={16} />;
8
+ case 'in service':
9
+ return <Group size={16} />;
10
+ case 'finished service':
11
+ return <Group size={16} />;
12
+ default:
13
+ return null;
14
+ }
15
+ }
16
+
17
+ export default StatusIcon;
@@ -0,0 +1,53 @@
1
+ import React, { useCallback } from 'react';
2
+ import { Notification } from '@carbon/react/icons';
3
+ import { MappedVisitQueueEntry, serveQueueEntry } from '../active-visits/active-visits-table.resource';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { showModal, showNotification } from '@openmrs/esm-framework';
6
+ import { Button } from '@carbon/react';
7
+ import styles from './transition-entry.scss';
8
+ import { mutate } from 'swr';
9
+ interface TransitionMenuProps {
10
+ queueEntry: MappedVisitQueueEntry;
11
+ closeModal: () => void;
12
+ }
13
+ const TransitionMenu: React.FC<TransitionMenuProps> = ({ queueEntry, closeModal }) => {
14
+ const { t } = useTranslation();
15
+
16
+ const launchTransitionPriorityModal = useCallback(() => {
17
+ serveQueueEntry(queueEntry?.service, queueEntry?.visitQueueNumber, 'calling').then(
18
+ ({ status }) => {
19
+ if (status === 200) {
20
+ mutate(`/ws/rest/v1/queueutil/assignticket`);
21
+ }
22
+ },
23
+ (error) => {
24
+ showNotification({
25
+ title: t('errorPostingToScreen', 'Error posting to screen'),
26
+ kind: 'error',
27
+ critical: true,
28
+ description: error?.message,
29
+ });
30
+ },
31
+ );
32
+ const dispose = showModal('transition-queue-entry-status-modal', {
33
+ closeModal: () => dispose(),
34
+ queueEntry,
35
+ });
36
+ }, [queueEntry]);
37
+
38
+ return (
39
+ <Button
40
+ renderIcon={(props) => <Notification size={16} {...props} />}
41
+ className={`${styles.callBtn} ${
42
+ queueEntry?.priorityComment === 'Requeued' ? styles.requeueIcon : styles.normalIcon
43
+ }`}
44
+ onClick={launchTransitionPriorityModal}
45
+ iconDescription={t('call', 'Call')}
46
+ hasIconOnly
47
+ tooltipAlignment="end"
48
+ tooltipPosition="bottom"
49
+ />
50
+ );
51
+ };
52
+
53
+ export default TransitionMenu;
@@ -0,0 +1,22 @@
1
+ @import '~@openmrs/esm-styleguide/src/vars';
2
+
3
+ .callBtn:hover {
4
+ background-color: transparent;
5
+ }
6
+
7
+ .requeueIcon {
8
+ background-color: transparent;
9
+
10
+ & svg {
11
+ fill: $danger;
12
+ color: $danger;
13
+ }
14
+ }
15
+
16
+ .normalIcon {
17
+ background-color: transparent;
18
+
19
+ & svg {
20
+ fill: var(--omrs-color-success);
21
+ }
22
+ }