@kenyaemr/esm-service-queues-app 8.0.1-pre.95 → 8.0.2

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 (92) hide show
  1. package/.turbo/turbo-build.log +21 -22
  2. package/dist/130.js +1 -1
  3. package/dist/130.js.LICENSE.txt +2 -0
  4. package/dist/130.js.map +1 -1
  5. package/dist/199.js +1 -1
  6. package/dist/199.js.map +1 -1
  7. package/dist/2.js +1 -0
  8. package/dist/2.js.map +1 -0
  9. package/dist/271.js +1 -1
  10. package/dist/319.js +1 -1
  11. package/dist/325.js +1 -0
  12. package/dist/325.js.map +1 -0
  13. package/dist/372.js +2 -0
  14. package/dist/372.js.map +1 -0
  15. package/dist/392.js +1 -1
  16. package/dist/460.js +1 -1
  17. package/dist/574.js +1 -1
  18. package/dist/60.js +1 -0
  19. package/dist/60.js.map +1 -0
  20. package/dist/644.js +1 -1
  21. package/dist/660.js +2 -0
  22. package/dist/{484.js.LICENSE.txt → 660.js.LICENSE.txt} +10 -0
  23. package/dist/660.js.map +1 -0
  24. package/dist/670.js +1 -1
  25. package/dist/670.js.map +1 -1
  26. package/dist/727.js +1 -1
  27. package/dist/748.js +1 -0
  28. package/dist/748.js.map +1 -0
  29. package/dist/757.js +1 -1
  30. package/dist/760.js +1 -1
  31. package/dist/760.js.map +1 -1
  32. package/dist/788.js +1 -1
  33. package/dist/807.js +1 -1
  34. package/dist/818.js +1 -1
  35. package/dist/833.js +1 -1
  36. package/dist/911.js +1 -1
  37. package/dist/kenyaemr-esm-service-queues-app.js +1 -1
  38. package/dist/kenyaemr-esm-service-queues-app.js.buildmanifest.json +171 -174
  39. package/dist/kenyaemr-esm-service-queues-app.js.map +1 -1
  40. package/dist/main.js +1 -1
  41. package/dist/main.js.map +1 -1
  42. package/dist/routes.json +1 -1
  43. package/package-lock.json +5892 -0
  44. package/package.json +2 -3
  45. package/src/active-visits/change-status-dialog.component.tsx +141 -138
  46. package/src/active-visits/change-status-dialog.test.tsx +5 -5
  47. package/src/config-schema.ts +4 -10
  48. package/src/index.ts +7 -0
  49. package/src/patient-queue-header/patient-queue-header.component.tsx +25 -38
  50. package/src/patient-queue-header/patient-queue-header.scss +3 -41
  51. package/src/patient-queue-metrics/clinic-metrics.component.tsx +4 -4
  52. package/src/patient-queue-metrics/metrics-header.component.tsx +16 -15
  53. package/src/patient-search/patient-scheduled-visits.component.tsx +43 -52
  54. package/src/patient-search/visit-form/visit-form.component.tsx +43 -50
  55. package/src/queue-screen/queue-screen.component.tsx +67 -11
  56. package/src/queue-screen/queue-screen.test.tsx +1 -1
  57. package/src/queue-screen/useActiveTickets.tsx +1 -1
  58. package/src/queue-table/cells/columns.resource.ts +2 -2
  59. package/src/queue-table/default-queue-table.component.tsx +17 -15
  60. package/src/queue-table/queue-entry-actions/transition-queue-entry.modal.tsx +7 -2
  61. package/src/queue-table/queue-table-by-status-menu.component.tsx +1 -1
  62. package/src/queue-table/queue-table-metrics.component.tsx +6 -1
  63. package/src/queue-table/queue-table.component.tsx +11 -8
  64. package/src/queue-table/queue-table.scss +5 -0
  65. package/src/remove-queue-entry-dialog/remove-queue-entry.component.tsx +16 -15
  66. package/src/remove-queue-entry-dialog/remove-queue-entry.resource.ts +20 -26
  67. package/src/routes.json +34 -27
  68. package/src/transition-latest-queue-entry/transition-latest-queue-entry.component.tsx +33 -0
  69. package/src/transition-latest-queue-entry/transition-latest-queue-entry.resource.ts +30 -0
  70. package/translations/am.json +4 -3
  71. package/translations/ar.json +5 -4
  72. package/translations/en.json +9 -6
  73. package/translations/es.json +81 -80
  74. package/translations/fr.json +255 -254
  75. package/translations/he.json +5 -4
  76. package/translations/km.json +5 -4
  77. package/translations/zh.json +5 -4
  78. package/translations/zh_CN.json +5 -4
  79. package/dist/152.js +0 -1
  80. package/dist/152.js.map +0 -1
  81. package/dist/255.js +0 -2
  82. package/dist/255.js.map +0 -1
  83. package/dist/265.js +0 -1
  84. package/dist/265.js.map +0 -1
  85. package/dist/303.js +0 -1
  86. package/dist/303.js.map +0 -1
  87. package/dist/484.js +0 -2
  88. package/dist/484.js.map +0 -1
  89. package/dist/729.js +0 -1
  90. package/dist/729.js.map +0 -1
  91. package/src/patient-queue-header/patient-queue-illustration.component.tsx +0 -22
  92. /package/dist/{255.js.LICENSE.txt → 372.js.LICENSE.txt} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kenyaemr/esm-service-queues-app",
3
- "version": "8.0.1-pre.95",
3
+ "version": "8.0.2",
4
4
  "description": "Outpatient front-end module for the OpenMRS SPA",
5
5
  "browser": "dist/kenyaemr-esm-service-queues-app.js",
6
6
  "main": "src/index.ts",
@@ -49,6 +49,5 @@
49
49
  },
50
50
  "devDependencies": {
51
51
  "webpack": "^5.74.0"
52
- },
53
- "stableVersion": "8.0.0"
52
+ }
54
53
  }
@@ -1,31 +1,32 @@
1
1
  import React, { useMemo } from 'react';
2
2
  import {
3
3
  Button,
4
+ ContentSwitcher,
5
+ Form,
6
+ InlineLoading,
7
+ InlineNotification,
4
8
  ModalBody,
5
9
  ModalFooter,
6
10
  ModalHeader,
7
- Form,
8
- ContentSwitcher,
9
- Switch,
10
- Select,
11
- SelectItem,
12
- InlineNotification,
13
11
  RadioButton,
14
12
  RadioButtonGroup,
15
- InlineLoading,
13
+ Select,
14
+ SelectItem,
15
+ Stack,
16
+ Switch,
16
17
  } from '@carbon/react';
17
18
  import { useTranslation } from 'react-i18next';
18
- import { navigate, showSnackbar, useConfig } from '@openmrs/esm-framework';
19
- import { type MappedQueueEntry } from '../types';
20
- import { updateQueueEntry } from './active-visits-table.resource';
21
- import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
22
- import styles from './change-status-dialog.scss';
23
- import { useQueues } from '../hooks/useQueues';
24
19
  import { useForm, Controller } from 'react-hook-form';
25
20
  import { z } from 'zod';
26
21
  import { zodResolver } from '@hookform/resolvers/zod';
22
+ import { navigate, showSnackbar, useConfig } from '@openmrs/esm-framework';
23
+ import { type MappedQueueEntry } from '../types';
27
24
  import { type ConfigObject } from '../config-schema';
25
+ import { useQueues } from '../hooks/useQueues';
26
+ import { updateQueueEntry } from './active-visits-table.resource';
28
27
  import { useMutateQueueEntries } from '../hooks/useQueueEntries';
28
+ import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
29
+ import styles from './change-status-dialog.scss';
29
30
 
30
31
  interface ChangeStatusDialogProps {
31
32
  queueEntry: MappedQueueEntry;
@@ -41,9 +42,9 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
41
42
  () =>
42
43
  z.object({
43
44
  location: z.string({ required_error: t('queueLocationRequired', 'Queue location is required') }),
45
+ priority: z.string({ required_error: t('priorityIsRequired', 'Priority is required') }),
44
46
  service: z.string({ required_error: t('serviceIsRequired', 'Service is required') }),
45
47
  status: z.string({ required_error: t('statusIsRequired', 'Status is required') }),
46
- priority: z.string({ required_error: t('priorityIsRequired', 'Priority is required') }),
47
48
  }),
48
49
  [],
49
50
  );
@@ -82,18 +83,16 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
82
83
  endDate,
83
84
  sortWeight,
84
85
  ).then(
85
- ({ status }) => {
86
- if (status === 201) {
87
- showSnackbar({
88
- isLowContrast: true,
89
- title: t('updateEntry', 'Update entry'),
90
- kind: 'success',
91
- subtitle: t('queueEntryUpdateSuccessfully', 'Queue Entry Updated Successfully'),
92
- });
93
- closeModal();
94
- mutateQueueEntries();
95
- navigate({ to: `${window.spaBase}/home/service-queues` });
96
- }
86
+ () => {
87
+ showSnackbar({
88
+ isLowContrast: true,
89
+ title: t('updateEntry', 'Update entry'),
90
+ kind: 'success',
91
+ subtitle: t('queueEntryUpdateSuccessfully', 'Queue Entry Updated Successfully'),
92
+ });
93
+ closeModal();
94
+ mutateQueueEntries();
95
+ navigate({ to: `${window.spaBase}/home/service-queues` });
97
96
  },
98
97
  (error) => {
99
98
  showSnackbar({
@@ -121,127 +120,131 @@ const ChangeStatus: React.FC<ChangeStatusDialogProps> = ({ queueEntry, closeModa
121
120
  <ModalBody>
122
121
  <div className={styles.modalBody}>
123
122
  <h5>
124
- {queueEntry.name} &nbsp; · &nbsp;{queueEntry.patientSex} &nbsp; · &nbsp;{queueEntry.patientAge}&nbsp;
125
- {t('years', 'Years')}
123
+ {t('patientInfo', '{{name}}{{sexInfo}}{{ageInfo}}', {
124
+ name: queueEntry.name,
125
+ sexInfo: queueEntry.patientSex ? ` · ${queueEntry.patientSex} · ` : '',
126
+ ageInfo: queueEntry.patientAge ? `${queueEntry.patientAge} ${t('years', 'Years')}` : '',
127
+ })}
126
128
  </h5>
127
129
  </div>
128
- <section>
129
- <Controller
130
- name="location"
131
- control={control}
132
- render={({ field: { onChange, value } }) => (
133
- <Select
134
- labelText={t('selectQueueLocation', 'Select a queue location')}
135
- id="location"
136
- invalid={!!errors.location}
137
- invalidText={errors.location?.message}
138
- value={value}
139
- onChange={(event) => {
140
- onChange(event.target.value);
141
- }}>
142
- {!getValues()?.location && (
143
- <SelectItem text={t('selectQueueLocation', 'Select a queue location')} value="" />
144
- )}
145
- {queueLocations?.length > 0 &&
146
- queueLocations.map((location) => (
147
- <SelectItem key={location.id} text={location.name} value={location.id}>
148
- {location.name}
149
- </SelectItem>
150
- ))}
151
- </Select>
152
- )}
153
- />
154
- </section>
155
-
156
- <section className={styles.section}>
157
- <div className={styles.sectionTitle}>{t('queueService', 'Queue service')}</div>
158
- <Controller
159
- name="service"
160
- control={control}
161
- render={({ field: { onChange, value } }) => (
162
- <Select
163
- labelText={t('selectService', 'Select a service')}
164
- id="service"
165
- invalid={!!errors.service}
166
- invalidText={errors.service?.message}
167
- value={value}
168
- onChange={(event) => onChange(event.target.value)}>
169
- {!getValues()?.service && <SelectItem text={t('selectService', 'Select a service')} value="" />}
170
- {queues?.length > 0 &&
171
- queues.map((service) => (
172
- <SelectItem key={service.uuid} text={service.display} value={service.uuid}>
173
- {service.display}
174
- </SelectItem>
175
- ))}
176
- </Select>
177
- )}
178
- />
179
- </section>
180
-
181
- <section className={styles.section}>
182
- <div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
183
- {!allowedStatuses?.length ? (
184
- <InlineNotification
185
- className={styles.inlineNotification}
186
- kind={'error'}
187
- lowContrast
188
- subtitle={t('configureStatus', 'Please configure status to continue.')}
189
- title={t('noStatusConfigured', 'No status configured')}
190
- />
191
- ) : (
130
+ <Stack gap={4}>
131
+ <section>
132
+ <div className={styles.sectionTitle}>{t('queueLocation', 'Queue location')}</div>
192
133
  <Controller
193
- name="status"
134
+ name="location"
194
135
  control={control}
195
- render={({ field: { value, onChange } }) => (
196
- <RadioButtonGroup
197
- className={styles.radioButtonWrapper}
198
- name="status"
199
- invalid={!!errors.status}
200
- invalidText={errors.status?.message}
201
- defaultSelected={value}
202
- onChange={(uuid) => {
203
- onChange(uuid);
136
+ render={({ field: { onChange, value } }) => (
137
+ <Select
138
+ labelText={t('selectQueueLocation', 'Select a queue location')}
139
+ id="location"
140
+ invalid={!!errors.location}
141
+ invalidText={errors.location?.message}
142
+ value={value}
143
+ onChange={(event) => {
144
+ onChange(event.target.value);
204
145
  }}>
205
- {allowedStatuses?.length > 0 &&
206
- allowedStatuses.map(({ uuid, display }) => (
207
- <RadioButton key={uuid} labelText={display} value={uuid} />
146
+ {!getValues()?.location && (
147
+ <SelectItem text={t('selectQueueLocation', 'Select a queue location')} value="" />
148
+ )}
149
+ {queueLocations?.length > 0 &&
150
+ queueLocations.map((location) => (
151
+ <SelectItem key={location.id} text={location.name} value={location.id}>
152
+ {location.name}
153
+ </SelectItem>
208
154
  ))}
209
- </RadioButtonGroup>
155
+ </Select>
210
156
  )}
211
157
  />
212
- )}
213
- </section>
214
-
215
- <section className={styles.section}>
216
- <div className={styles.sectionTitle}>{t('queuePriority', 'Queue priority')}</div>
217
- <Controller
218
- control={control}
219
- name="priority"
220
- render={({ field: { onChange } }) => (
221
- <>
222
- <ContentSwitcher
223
- size="sm"
224
- selectedIndex={1}
225
- onChange={(event) => {
226
- onChange(event.name as any);
227
- }}>
228
- {allowedPriorities?.length > 0 ? (
229
- allowedPriorities.map(({ uuid, display }) => {
230
- return <Switch name={uuid} text={display} key={uuid} value={uuid} />;
231
- })
232
- ) : (
233
- <Switch
234
- name={t('noPriorityFound', 'No priority found')}
235
- text={t('noPriorityFound', 'No priority found')}
236
- value={null}
237
- />
238
- )}
239
- </ContentSwitcher>
240
- {errors.priority && <div className={styles.error}>{errors.priority.message}</div>}
241
- </>
158
+ </section>
159
+ <section className={styles.section}>
160
+ <div className={styles.sectionTitle}>{t('queueService', 'Queue service')}</div>
161
+ <Controller
162
+ name="service"
163
+ control={control}
164
+ render={({ field: { onChange, value } }) => (
165
+ <Select
166
+ labelText={t('selectService', 'Select a service')}
167
+ id="service"
168
+ invalid={!!errors.service}
169
+ invalidText={errors.service?.message}
170
+ value={value}
171
+ onChange={(event) => onChange(event.target.value)}>
172
+ {!getValues()?.service && <SelectItem text={t('selectService', 'Select a service')} value="" />}
173
+ {queues?.length > 0 &&
174
+ queues.map((service) => (
175
+ <SelectItem key={service.uuid} text={service.display} value={service.uuid}>
176
+ {service.display}
177
+ </SelectItem>
178
+ ))}
179
+ </Select>
180
+ )}
181
+ />
182
+ </section>
183
+ <section className={styles.section}>
184
+ <div className={styles.sectionTitle}>{t('queueStatus', 'Queue status')}</div>
185
+ {!allowedStatuses?.length ? (
186
+ <InlineNotification
187
+ className={styles.inlineNotification}
188
+ kind={'error'}
189
+ lowContrast
190
+ subtitle={t('configureStatus', 'Please configure status to continue.')}
191
+ title={t('noStatusConfigured', 'No status configured')}
192
+ />
193
+ ) : (
194
+ <Controller
195
+ name="status"
196
+ control={control}
197
+ render={({ field: { value, onChange } }) => (
198
+ <RadioButtonGroup
199
+ className={styles.radioButtonWrapper}
200
+ id="status"
201
+ name="status"
202
+ invalid={!!errors.status}
203
+ invalidText={errors.status?.message}
204
+ defaultSelected={value}
205
+ onChange={(uuid) => {
206
+ onChange(uuid);
207
+ }}>
208
+ {allowedStatuses?.length > 0 &&
209
+ allowedStatuses.map(({ uuid, display }) => (
210
+ <RadioButton key={uuid} labelText={display} value={uuid} />
211
+ ))}
212
+ </RadioButtonGroup>
213
+ )}
214
+ />
242
215
  )}
243
- />
244
- </section>
216
+ </section>
217
+ <section className={styles.section}>
218
+ <div className={styles.sectionTitle}>{t('queuePriority', 'Queue priority')}</div>
219
+ <Controller
220
+ control={control}
221
+ name="priority"
222
+ render={({ field: { onChange } }) => (
223
+ <>
224
+ <ContentSwitcher
225
+ size="sm"
226
+ selectedIndex={1}
227
+ onChange={(event) => {
228
+ onChange(event.name as any);
229
+ }}>
230
+ {allowedPriorities?.length > 0 ? (
231
+ allowedPriorities.map(({ uuid, display }) => {
232
+ return <Switch name={uuid} text={display} key={uuid} value={uuid} />;
233
+ })
234
+ ) : (
235
+ <Switch
236
+ name={t('noPriorityFound', 'No priority found')}
237
+ text={t('noPriorityFound', 'No priority found')}
238
+ value={null}
239
+ />
240
+ )}
241
+ </ContentSwitcher>
242
+ {errors.priority && <div className={styles.error}>{errors.priority.message}</div>}
243
+ </>
244
+ )}
245
+ />
246
+ </section>
247
+ </Stack>
245
248
  </ModalBody>
246
249
  <ModalFooter>
247
250
  <Button kind="secondary" onClick={closeModal}>
@@ -39,7 +39,7 @@ jest.mock('../hooks/useQueues', () => {
39
39
  };
40
40
  });
41
41
 
42
- describe('Queue entry details', () => {
42
+ describe('ChangeStatusDialog', () => {
43
43
  beforeEach(() => {
44
44
  mockUseConfig.mockReturnValue({
45
45
  ...getDefaultsFromConfigSchema(configSchema),
@@ -62,14 +62,14 @@ describe('Queue entry details', () => {
62
62
  expect(screen.getByText(/queue service/i)).toBeInTheDocument();
63
63
  expect(screen.getByText(/queue priority/i)).toBeInTheDocument();
64
64
 
65
- // user selects a service
66
- const queueServiceTypes = screen.getByRole('combobox', { name: /select a service/i });
67
- await user.selectOptions(queueServiceTypes, '176052c7-5fd4-4b33-89cc-7bae6848c65a');
68
-
69
65
  // user selects queue location
70
66
  const queueLocation = screen.getByRole('combobox', { name: /Select a queue location/i });
71
67
  await user.selectOptions(queueLocation, 'some-uuid1');
72
68
 
69
+ // user selects a service
70
+ const queueServiceTypes = screen.getByRole('combobox', { name: /select a service/i });
71
+ await user.selectOptions(queueServiceTypes, '176052c7-5fd4-4b33-89cc-7bae6848c65a');
72
+
73
73
  // user selects queue status
74
74
  const queueStatus = screen.getByRole('radio', { name: /Waiting/i });
75
75
  await user.click(queueStatus);
@@ -82,6 +82,10 @@ export const configSchema = {
82
82
  _description: 'The UUID of the default status for attending a service in the queues eg In Service.',
83
83
  _default: 'ca7494ae-437f-4fd0-8aae-b88b9a2ba47d',
84
84
  },
85
+ systolicBloodPressureUuid: {
86
+ _type: Type.ConceptUuid,
87
+ _default: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
88
+ },
85
89
  diastolicBloodPressureUuid: {
86
90
  _type: Type.ConceptUuid,
87
91
  _default: '5086AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
@@ -112,10 +116,6 @@ export const configSchema = {
112
116
  _type: Type.ConceptUuid,
113
117
  _default: '5242AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
114
118
  },
115
- systolicBloodPressureUuid: {
116
- _type: Type.ConceptUuid,
117
- _default: '5085AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
118
- },
119
119
  temperatureUuid: {
120
120
  _type: Type.ConceptUuid,
121
121
  _default: '5088AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
@@ -242,11 +242,6 @@ export const configSchema = {
242
242
  'The header text for the column. Will be translated if it is a valid translation key. If not provided, the header will be based on the columnType.',
243
243
  _default: null,
244
244
  },
245
- headerI18nModule: {
246
- _type: Type.String,
247
- _description: 'The module to use for translation of the header.',
248
- _default: '@openmrs/esm-service-queues-app',
249
- },
250
245
  config: {
251
246
  identifierTypeUuid: {
252
247
  _type: Type.UUID,
@@ -440,7 +435,6 @@ export type ColumnDefinition = {
440
435
  id: string;
441
436
  columnType?: ColumnType;
442
437
  header?: string;
443
- headerI18nModule?: string;
444
438
  config: ColumnConfig;
445
439
  };
446
440
 
package/src/index.ts CHANGED
@@ -138,6 +138,13 @@ export const addNewQueueServiceWorkspace = getAsyncLifecycle(
138
138
  moduleName,
139
139
  },
140
140
  );
141
+ export const transitionPatientToLatestQueue = getAsyncLifecycle(
142
+ () => import('./transition-latest-queue-entry/transition-latest-queue-entry.component'),
143
+ {
144
+ featureName: 'transition patient to new queue',
145
+ moduleName,
146
+ },
147
+ );
141
148
 
142
149
  // t('addNewQueueServiceRoom', 'Add new queue service room')
143
150
  export const addNewQueueServiceRoomWorkspace = getAsyncLifecycle(
@@ -1,11 +1,8 @@
1
1
  import React, { useCallback, useEffect } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
- import { Location } from '@carbon/react/icons';
4
3
  import { Dropdown } from '@carbon/react';
5
- import { useConfig, useSession } from '@openmrs/esm-framework';
6
- import PatientQueueIllustration from './patient-queue-illustration.component';
4
+ import { useConfig, useSession, PageHeader, PageHeaderContent, ServiceQueuesPictogram } from '@openmrs/esm-framework';
7
5
  import { useQueueLocations } from '../patient-search/hooks/useQueueLocations';
8
-
9
6
  import {
10
7
  updateSelectedQueueLocationUuid,
11
8
  updateSelectedQueueLocationName,
@@ -13,8 +10,8 @@ import {
13
10
  useSelectedQueueLocationName,
14
11
  useSelectedQueueLocationUuid,
15
12
  } from '../helpers/helpers';
16
- import styles from './patient-queue-header.scss';
17
13
  import type { ConfigObject } from '../config-schema';
14
+ import styles from './patient-queue-header.scss';
18
15
 
19
16
  interface PatientQueueHeaderProps {
20
17
  title?: string | JSX.Element;
@@ -27,7 +24,6 @@ const PatientQueueHeader: React.FC<PatientQueueHeaderProps> = ({ title, showLoca
27
24
  const { queueLocations, isLoading, error } = useQueueLocations();
28
25
  const { dashboardTitle } = useConfig<ConfigObject>();
29
26
  const userSession = useSession();
30
- const userLocation = userSession?.sessionLocation?.display;
31
27
  const currentQueueLocationName = useSelectedQueueLocationName();
32
28
  const currentQueueLocationUuid = useSelectedQueueLocationUuid();
33
29
 
@@ -69,39 +65,30 @@ const PatientQueueHeader: React.FC<PatientQueueHeaderProps> = ({ title, showLoca
69
65
  ]);
70
66
 
71
67
  return (
72
- <div className={styles.header} data-testid="patient-queue-header">
73
- <div className={styles['left-justified-items']}>
74
- <PatientQueueIllustration />
75
- <div className={styles['page-labels']}>
76
- <p>{dashboardTitle ? t(dashboardTitle.key, dashboardTitle.value) : t('serviceQueues', 'Service queues')}</p>
77
- <p className={styles['page-name']}>{title ?? t('home', 'Home')}</p>
78
- </div>
79
- </div>
80
- <div className={styles['right-justified-items']}>
81
- <div className={styles['date-and-location']}>
82
- <Location size={16} />
83
- <span className={styles.value}>{userLocation}</span>
84
- </div>
85
- <div className={styles.dropdownContainer}>
86
- {showLocationDropdown && (
87
- <Dropdown
88
- aria-label="Select queue location"
89
- className={styles.dropdown}
90
- id="queueLocationDropdown"
91
- label={currentQueueLocationName ?? t('all', 'All')}
92
- items={
93
- queueLocations.length !== 1 ? [{ id: 'all', name: t('all', 'All') }, ...queueLocations] : queueLocations
94
- }
95
- itemToString={(item) => (item ? item.name : '')}
96
- titleText={t('location', 'Location')}
97
- type="inline"
98
- onChange={handleQueueLocationChange}
99
- />
100
- )}
101
- {actions}
102
- </div>
68
+ <PageHeader className={styles.header} data-testid="patient-queue-header">
69
+ <PageHeaderContent
70
+ title={title ? title : t(dashboardTitle.key, dashboardTitle.value)}
71
+ illustration={<ServiceQueuesPictogram />}
72
+ />
73
+ <div className={styles.dropdownContainer}>
74
+ {showLocationDropdown && (
75
+ <Dropdown
76
+ aria-label={t('selectQueueLocation', 'Select queue location')}
77
+ className={styles.dropdown}
78
+ id="queueLocationDropdown"
79
+ label={currentQueueLocationName ?? t('all', 'All')}
80
+ items={
81
+ queueLocations.length !== 1 ? [{ id: 'all', name: t('all', 'All') }, ...queueLocations] : queueLocations
82
+ }
83
+ itemToString={(item) => (item ? item.name : '')}
84
+ titleText={t('location', 'Location')}
85
+ type="inline"
86
+ onChange={handleQueueLocationChange}
87
+ />
88
+ )}
89
+ {actions}
103
90
  </div>
104
- </div>
91
+ </PageHeader>
105
92
  );
106
93
  };
107
94
 
@@ -3,63 +3,25 @@
3
3
  @use '@openmrs/esm-styleguide/src/vars' as *;
4
4
 
5
5
  .header {
6
- @include type.type-style('body-compact-02');
7
- color: $text-02;
8
6
  background-color: $ui-02;
9
7
  border: 1px solid $ui-03;
10
8
  border-left: 0px;
11
9
  display: flex;
12
10
  justify-content: space-between;
13
- padding-right: layout.$spacing-05;
11
+ padding-right: layout.$spacing-03;
14
12
  }
15
13
 
16
- .left-justified-items {
14
+ .dropdownContainer {
17
15
  display: flex;
18
- flex-direction: row;
19
16
  align-items: center;
20
- }
21
-
22
- .right-justified-items {
23
- @include type.type-style('body-compact-02');
24
- color: $text-02;
25
- padding-top: layout.$spacing-05;
26
- }
27
-
28
- .page-name {
29
- @include type.type-style('heading-04');
30
- }
31
-
32
- .page-labels {
33
- p:first-of-type {
34
- margin-bottom: layout.$spacing-02;
35
- }
36
- }
37
-
38
- .date-and-location {
39
- display: flex;
40
17
  justify-content: flex-end;
41
- align-items: center;
42
- }
43
-
44
- .value {
45
- margin-left: layout.$spacing-02;
46
- }
47
-
48
- .middot {
49
- margin: 0 layout.$spacing-03;
18
+ margin-top: layout.$spacing-03;
50
19
  }
51
20
 
52
21
  .view {
53
22
  @include type.type-style('label-01');
54
23
  }
55
24
 
56
- .dropdownContainer {
57
- display: flex;
58
- align-items: center;
59
- justify-content: flex-end;
60
- margin-top: layout.$spacing-03;
61
- }
62
-
63
25
  .dropdown {
64
26
  :global(.cds--list-box__field) {
65
27
  width: 14rem;
@@ -1,15 +1,15 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Dropdown } from '@carbon/react';
4
- import MetricsCard from './metrics-card.component';
5
- import MetricsHeader from './metrics-header.component';
4
+ import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
6
5
  import { updateSelectedService, useSelectedService, useSelectedQueueLocationUuid } from '../helpers/helpers';
7
6
  import { useActiveVisits, useAverageWaitTime } from './clinic-metrics.resource';
8
7
  import { useServiceMetricsCount } from './queue-metrics.resource';
9
- import styles from './clinic-metrics.scss';
8
+ import MetricsCard from './metrics-card.component';
9
+ import MetricsHeader from './metrics-header.component';
10
10
  import { useMutateQueueEntries, useQueueEntries } from '../hooks/useQueueEntries';
11
11
  import useQueueServices from '../hooks/useQueueService';
12
- import { isDesktop, useLayoutType } from '@openmrs/esm-framework';
12
+ import styles from './clinic-metrics.scss';
13
13
 
14
14
  export interface Service {
15
15
  uuid: string;