@openmrs/esm-appointments-app 4.3.1-pre.1421 → 4.3.1-pre.1435

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.
@@ -2,54 +2,54 @@
2
2
  "chunks": [
3
3
  {
4
4
  "rendered": true,
5
- "initial": true,
6
- "entry": true,
5
+ "initial": false,
6
+ "entry": false,
7
7
  "recorded": false,
8
- "size": 191064,
8
+ "size": 1302878,
9
9
  "sizes": {
10
- "consume-shared": 126,
11
- "javascript": 171154,
12
- "share-init": 168,
13
- "runtime": 19616
10
+ "javascript": 1302878
14
11
  },
15
- "names": [
16
- "main"
17
- ],
12
+ "names": [],
18
13
  "idHints": [],
19
14
  "runtime": [
15
+ "@openmrs/esm-appointments-app",
20
16
  "main"
21
17
  ],
22
18
  "files": [
23
- "main.js"
19
+ "75.js"
24
20
  ],
25
21
  "auxiliaryFiles": [
26
- "main.js.map"
22
+ "75.js.map"
27
23
  ],
28
- "hash": "258020d797f44832",
24
+ "hash": "98b7523ed9fbb92a",
29
25
  "childrenByOrder": {}
30
26
  },
31
27
  {
32
28
  "rendered": true,
33
- "initial": false,
34
- "entry": false,
29
+ "initial": true,
30
+ "entry": true,
35
31
  "recorded": false,
36
- "size": 1298484,
32
+ "size": 191064,
37
33
  "sizes": {
38
- "javascript": 1298484
34
+ "consume-shared": 126,
35
+ "javascript": 171154,
36
+ "share-init": 168,
37
+ "runtime": 19616
39
38
  },
40
- "names": [],
39
+ "names": [
40
+ "main"
41
+ ],
41
42
  "idHints": [],
42
43
  "runtime": [
43
- "@openmrs/esm-appointments-app",
44
44
  "main"
45
45
  ],
46
46
  "files": [
47
- "210.js"
47
+ "main.js"
48
48
  ],
49
49
  "auxiliaryFiles": [
50
- "210.js.map"
50
+ "main.js.map"
51
51
  ],
52
- "hash": "5af8a7780873d3de",
52
+ "hash": "396aad9ef4504791",
53
53
  "childrenByOrder": {}
54
54
  },
55
55
  {
@@ -140,7 +140,7 @@
140
140
  "auxiliaryFiles": [
141
141
  "437.js.map"
142
142
  ],
143
- "hash": "b20adca9f99373e4",
143
+ "hash": "9d7c1894e8913d4c",
144
144
  "childrenByOrder": {}
145
145
  },
146
146
  {
@@ -226,9 +226,9 @@
226
226
  "initial": false,
227
227
  "entry": false,
228
228
  "recorded": false,
229
- "size": 4645,
229
+ "size": 4599,
230
230
  "sizes": {
231
- "javascript": 4645
231
+ "javascript": 4599
232
232
  },
233
233
  "names": [],
234
234
  "idHints": [],
@@ -240,7 +240,7 @@
240
240
  "574.js"
241
241
  ],
242
242
  "auxiliaryFiles": [],
243
- "hash": "2a8b485375d1ba38",
243
+ "hash": "befb8842eb6eb2f7",
244
244
  "childrenByOrder": {}
245
245
  },
246
246
  {
@@ -498,9 +498,9 @@
498
498
  "initial": false,
499
499
  "entry": false,
500
500
  "recorded": false,
501
- "size": 110385,
501
+ "size": 110491,
502
502
  "sizes": {
503
- "javascript": 110385
503
+ "javascript": 110491
504
504
  },
505
505
  "names": [],
506
506
  "idHints": [],
@@ -514,7 +514,7 @@
514
514
  "auxiliaryFiles": [
515
515
  "990.js.map"
516
516
  ],
517
- "hash": "9e15aed25c200787",
517
+ "hash": "ad89890929bec485",
518
518
  "childrenByOrder": {}
519
519
  }
520
520
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-appointments-app",
3
- "version": "4.3.1-pre.1421",
3
+ "version": "4.3.1-pre.1435",
4
4
  "description": "Appointments front-end module for the OpenMRS SPA",
5
5
  "browser": "dist/openmrs-esm-appointments-app.js",
6
6
  "main": "src/index.ts",
@@ -48,5 +48,5 @@
48
48
  "devDependencies": {
49
49
  "webpack": "^5.74.0"
50
50
  },
51
- "gitHead": "fc7b491b60edfe70bdcacba191544199bded43de"
51
+ "gitHead": "b6bca54f01b3ac03e87afd9a600f82a2fa90fc24"
52
52
  }
@@ -30,9 +30,9 @@ import PatientSearch from '../../patient-search/patient-search.component';
30
30
  import { MappedAppointment } from '../../types';
31
31
  import { getPageSizes, useSearchResults } from '../utils';
32
32
  import AppointmentActions from './appointments-actions.component';
33
- import styles from './appointments-base-table.scss';
33
+ import styles from './appointments-table.scss';
34
34
 
35
- interface AppointmentsBaseTableProps {
35
+ interface AppointmentsTableProps {
36
36
  appointments: Array<MappedAppointment>;
37
37
  isLoading: boolean;
38
38
  tableHeading: string;
@@ -41,7 +41,7 @@ interface AppointmentsBaseTableProps {
41
41
  scheduleType?: string;
42
42
  }
43
43
 
44
- const AppointmentsBaseTable: React.FC<AppointmentsBaseTableProps> = ({
44
+ const AppointmentsTable: React.FC<AppointmentsTableProps> = ({
45
45
  appointments,
46
46
  isLoading,
47
47
  tableHeading,
@@ -63,14 +63,6 @@ const AppointmentsBaseTable: React.FC<AppointmentsBaseTableProps> = ({
63
63
  header: t('identifier', 'Identifier'),
64
64
  key: 'identifier',
65
65
  },
66
- {
67
- header: t('nextAppointmentDate', 'Next appointment date'),
68
- key: 'nextAppointmentDate',
69
- },
70
- {
71
- header: t('dateTime', 'Date & Time'),
72
- key: 'dateTime',
73
- },
74
66
  {
75
67
  header: t('serviceType', 'Service Type'),
76
68
  key: 'serviceType',
@@ -115,7 +107,7 @@ const AppointmentsBaseTable: React.FC<AppointmentsBaseTableProps> = ({
115
107
 
116
108
  return (
117
109
  <>
118
- <DataTable rows={rowData} headers={headerData} isSortable>
110
+ <DataTable rows={rowData} headers={headerData} isSortable useZebraStyles>
119
111
  {({ rows, headers, getHeaderProps, getRowProps, getTableProps, getToolbarProps, getTableContainerProps }) => (
120
112
  <TableContainer
121
113
  title={`${startCase(tableHeading)} ${t('appointments', 'appointment')}`}
@@ -158,10 +150,14 @@ const AppointmentsBaseTable: React.FC<AppointmentsBaseTableProps> = ({
158
150
  <TableCell key={cell.id}>{cell.value?.content ?? cell.value}</TableCell>
159
151
  ))}
160
152
  </TableExpandRow>
161
- {row.isExpanded && (
162
- <TableExpandedRow colSpan={headers.length + 1}>
163
- <AppointmentDetails appointment={appointments[row.id]} />
164
- </TableExpandedRow>
153
+ {row.isExpanded ? (
154
+ <TableRow className={styles.expandedActiveVisitRow}>
155
+ <th colSpan={headers.length + 2}>
156
+ <AppointmentDetails appointment={appointments[row.id]} />
157
+ </th>
158
+ </TableRow>
159
+ ) : (
160
+ <TableExpandedRow className={styles.hiddenRow} colSpan={headers.length + 2} />
165
161
  )}
166
162
  </React.Fragment>
167
163
  ))}
@@ -188,4 +184,4 @@ const AppointmentsBaseTable: React.FC<AppointmentsBaseTableProps> = ({
188
184
  );
189
185
  };
190
186
 
191
- export default AppointmentsBaseTable;
187
+ export default AppointmentsTable;
@@ -0,0 +1,18 @@
1
+ @use '@carbon/styles/scss/spacing';
2
+ @use '@carbon/styles/scss/type';
3
+
4
+ .expandedActiveVisitRow > td > div {
5
+ max-height: max-content !important;
6
+ }
7
+
8
+ .expandedActiveVisitRow td {
9
+ padding: 0 2rem;
10
+ }
11
+
12
+ .expandedActiveVisitRow th[colspan] td[colspan] > div:first-child {
13
+ padding: 0 1rem;
14
+ }
15
+
16
+ .hiddenRow {
17
+ display: none;
18
+ }
@@ -0,0 +1,158 @@
1
+ import React from 'react';
2
+ import { fireEvent, render, screen, waitFor } from '@testing-library/react';
3
+ import AppointmentsTable from './appointments-table.component';
4
+ import { MappedAppointment } from '../../types';
5
+ import { usePagination } from '@openmrs/esm-framework';
6
+ import { downloadAppointmentsAsExcel } from '../../helpers/excel';
7
+ import { launchOverlay } from '../../hooks/useOverlay';
8
+ import PatientSearch from '../../patient-search/patient-search.component';
9
+
10
+ // Define mock appointments data for testing purposes
11
+ const appointments: Array<MappedAppointment> = [
12
+ {
13
+ patientUuid: '1234',
14
+ name: 'John Smith',
15
+ identifier: '12345',
16
+ dateTime: '2023-04-13T12:00:00.000Z',
17
+ serviceType: 'Service',
18
+ provider: 'Dr. Jane Doe',
19
+ id: '1234',
20
+ age: '50',
21
+ gender: 'F',
22
+ providers: [],
23
+ appointmentKind: 'Scheduled',
24
+ appointmentNumber: '1234',
25
+ location: 'location',
26
+ phoneNumber: '1234567890',
27
+ status: 'status',
28
+ comments: 'some comments',
29
+ dob: '2020-04-13T12:00:00.000Z',
30
+ serviceUuid: '1234',
31
+ },
32
+ ];
33
+
34
+ const mockUsePagination = usePagination as jest.Mock;
35
+ const mockGoToPage = jest.fn();
36
+ const mockDownloadAppointmentsAsExcel = downloadAppointmentsAsExcel as jest.Mock;
37
+ const mockLaunchOverlay = launchOverlay as jest.Mock;
38
+
39
+ jest.mock('../../helpers/excel');
40
+ jest.mock('../../hooks/useOverlay');
41
+
42
+ jest.mock('@openmrs/esm-framework', () => {
43
+ const originalModule = jest.requireActual('@openmrs/esm-framework');
44
+ return {
45
+ ...originalModule,
46
+ openmrsFetch: jest.fn(),
47
+ };
48
+ });
49
+
50
+ describe('AppointmentsBaseTable', () => {
51
+ const props = {
52
+ appointments: [],
53
+ isLoading: false,
54
+ tableHeading: 'Scheduled',
55
+ visits: [],
56
+ scheduleType: 'Scheduled',
57
+ };
58
+
59
+ it('should render empty state if appointments are not provided', () => {
60
+ render(<AppointmentsTable {...props} />);
61
+ expect(screen.getByText(/Scheduled appointments/)).toBeInTheDocument();
62
+ const emptyScreenText = screen.getByText(/There are no scheduled appointments to display/);
63
+ expect(emptyScreenText).toBeInTheDocument();
64
+
65
+ const launchAppointmentsForm = screen.getByRole('button', { name: /Create appointment/ });
66
+ fireEvent.click(launchAppointmentsForm);
67
+ expect(mockLaunchOverlay).toHaveBeenCalledWith('Search', <PatientSearch />);
68
+ });
69
+
70
+ it('should render loading state when loading data', () => {
71
+ render(<AppointmentsTable {...props} isLoading={true} />);
72
+ expect(screen.getByRole('progressbar')).toBeInTheDocument();
73
+ });
74
+
75
+ it('should render table with headers and rows if appointments are provided', async () => {
76
+ mockUsePagination.mockReturnValue({
77
+ results: appointments.slice(0, 2),
78
+ goTo: mockGoToPage,
79
+ currentPage: 1,
80
+ });
81
+
82
+ render(<AppointmentsTable {...props} appointments={appointments} />);
83
+ waitFor(() => {
84
+ expect(screen.getByText('Patient name')).toBeInTheDocument();
85
+ expect(screen.getByText('Identifier')).toBeInTheDocument();
86
+ expect(screen.getByText('Service Type')).toBeInTheDocument();
87
+ expect(screen.getByText('Actions')).toBeInTheDocument();
88
+ expect(screen.getByText('John Smith')).toBeInTheDocument();
89
+ expect(screen.getByText('12345')).toBeInTheDocument();
90
+ expect(screen.getByText('Service')).toBeInTheDocument();
91
+ });
92
+ });
93
+
94
+ it('should update search string when search input is changed', () => {
95
+ render(<AppointmentsTable {...props} appointments={appointments} />);
96
+ const searchInput = screen.getByRole('searchbox');
97
+ fireEvent.change(searchInput, { target: { value: 'John' } });
98
+ expect(searchInput).toHaveValue('John');
99
+ });
100
+
101
+ it("should contain the title 'Scheduled appointments' and Total count", () => {
102
+ render(<AppointmentsTable {...props} appointments={appointments} />);
103
+ expect(screen.getByText(/Scheduled appointment/)).toBeInTheDocument();
104
+ expect(screen.getByText(/Total 1/)).toBeInTheDocument();
105
+ });
106
+
107
+ it('should execute the download function when download button is clicked', () => {
108
+ render(<AppointmentsTable {...props} appointments={appointments} />);
109
+ const downloadButton = screen.getByRole('button', { name: /Download/ });
110
+ fireEvent.click(downloadButton);
111
+ expect(downloadButton).toBeInTheDocument();
112
+ expect(mockDownloadAppointmentsAsExcel).toHaveBeenCalledWith(appointments, expect.anything());
113
+ });
114
+
115
+ it('should have pagination when there are more than 25 appointments', () => {
116
+ const mockAppointments = Array.from({ length: 100 }, (_, i) => ({
117
+ patientUuid: `${i}`,
118
+ name: `Patient ${i}`,
119
+ identifier: `${i}${i}${i}${i}${i}`,
120
+ dateTime: new Date().toISOString(),
121
+ serviceType: 'Service',
122
+ provider: `Dr. Provider ${i}`,
123
+ id: `${i}`,
124
+ age: `${i + 20}`,
125
+ gender: i % 2 === 0 ? 'M' : 'F',
126
+ providers: [],
127
+ appointmentKind: 'Scheduled',
128
+ appointmentNumber: `${i}${i}${i}${i}${i}`,
129
+ location: 'Location',
130
+ phoneNumber: '1234567890',
131
+ status: 'Status',
132
+ comments: 'Some comments',
133
+ dob: new Date(`${i + 1950}-01-01T00:00:00.000Z`).toISOString(),
134
+ serviceUuid: `${i}${i}${i}${i}${i}`,
135
+ }));
136
+ mockUsePagination.mockReturnValue({
137
+ results: appointments.slice(0, 2),
138
+ goTo: mockGoToPage,
139
+ currentPage: 1,
140
+ });
141
+
142
+ render(<AppointmentsTable {...props} appointments={mockAppointments} />);
143
+ expect(screen.getByText(/1–25 of 100 items/)).toBeInTheDocument();
144
+ const nextPageButton = screen.getByRole('button', { name: /Next page/ });
145
+ const previousPageButton = screen.getByRole('button', { name: /Previous page/ });
146
+
147
+ // Clicking the next page button should call the goTo function with the next page number
148
+ fireEvent.click(nextPageButton);
149
+ expect(mockGoToPage).toHaveBeenCalledWith(2);
150
+ expect(screen.getByText(/26–50 of 100 items/)).toBeInTheDocument();
151
+
152
+ // Clicking the previous page button should call the goTo function with the previous page number
153
+ fireEvent.click(previousPageButton);
154
+ expect(mockGoToPage).toHaveBeenCalledWith(1);
155
+
156
+ expect(screen.getByText(/1–25 of 100 items/)).toBeInTheDocument();
157
+ });
158
+ });
@@ -6,6 +6,7 @@
6
6
  min-height: fit-content;
7
7
  background-color: colors.$white;
8
8
  padding: spacing.$spacing-05;
9
+ margin: spacing.$spacing-03;
9
10
  }
10
11
 
11
12
  .title {
@@ -1,22 +1,62 @@
1
1
  import React from 'react';
2
- import { screen, render } from '@testing-library/react';
3
- import { mockMappedAppointmentsData } from '../../../../../__mocks__/appointments.mock';
2
+ import { render } from '@testing-library/react';
4
3
  import AppointmentDetails from './appointment-details.component';
5
4
 
6
- describe('AppointmentTablePatientDetails ', () => {
7
- it('renders a tabular view of the patient details', () => {
8
- renderPatientDetailsExpansionSlot();
5
+ const appointment = {
6
+ patientUuid: '12345',
7
+ name: 'John Doe',
8
+ identifier: '1234567890',
9
+ dateTime: new Date().toISOString(),
10
+ serviceType: 'Service',
11
+ provider: 'Dr. Provider',
12
+ id: '1',
13
+ age: '30',
14
+ gender: 'M',
15
+ providers: [],
16
+ appointmentKind: 'Scheduled',
17
+ appointmentNumber: '12345',
18
+ location: 'Location',
19
+ phoneNumber: '1234567890',
20
+ status: 'Status',
21
+ comments: 'Some comments',
22
+ dob: new Date('1992-01-01T00:00:00.000Z').toISOString(),
23
+ serviceUuid: '12345',
24
+ };
9
25
 
10
- expect(screen.getByText(/patient details/i)).toBeInTheDocument();
11
- expect(screen.getByText(/appointment notes/i)).toBeInTheDocument();
12
- expect(screen.getByText(/appointment history/i)).toBeInTheDocument();
13
- expect(screen.getByText(/john wilson/i)).toBeInTheDocument();
14
- expect(screen.queryAllByText(/45/i));
15
- expect(screen.queryAllByText(/M/i));
16
- expect(screen.getByText(/HIV Clinic/i)).toBeInTheDocument();
17
- });
18
- });
26
+ jest.mock('../../hooks/usePatientAppointmentHistory', () => ({
27
+ usePatientAppointmentHistory: () => ({
28
+ appointmentsCount: {
29
+ completedAppointments: 1,
30
+ missedAppointments: 2,
31
+ cancelledAppointments: 3,
32
+ upcomingAppointments: 4,
33
+ },
34
+ }),
35
+ }));
19
36
 
20
- const renderPatientDetailsExpansionSlot = () => {
21
- render(<AppointmentDetails appointment={mockMappedAppointmentsData.data[0]} />);
22
- };
37
+ test('renders appointment details correctly', () => {
38
+ const { getByText } = render(<AppointmentDetails appointment={appointment} />);
39
+ expect(getByText('Service')).toBeInTheDocument();
40
+ expect(getByText('1992-01-01T00:00:00.000Z')).toBeInTheDocument();
41
+ expect(getByText('Patient name :')).toBeInTheDocument();
42
+ expect(getByText('John Doe')).toBeInTheDocument();
43
+ expect(getByText('Age :')).toBeInTheDocument();
44
+ expect(getByText('30')).toBeInTheDocument();
45
+ expect(getByText('Gender :')).toBeInTheDocument();
46
+ expect(getByText('Male')).toBeInTheDocument();
47
+ expect(getByText('Dob :')).toBeInTheDocument();
48
+ expect(getByText('1992-01-01T00:00:00.000Z')).toBeInTheDocument();
49
+ expect(getByText('Phone number :')).toBeInTheDocument();
50
+ expect(getByText('1234567890')).toBeInTheDocument();
51
+ expect(getByText('Appointment Notes')).toBeInTheDocument();
52
+ expect(getByText('Some comments')).toBeInTheDocument();
53
+ expect(getByText('Appointment History')).toBeInTheDocument();
54
+ expect(getByText('Completed')).toBeInTheDocument();
55
+ expect(getByText('1')).toBeInTheDocument();
56
+ expect(getByText('Missed')).toBeInTheDocument();
57
+ expect(getByText('2')).toBeInTheDocument();
58
+ expect(getByText('Cancelled')).toBeInTheDocument();
59
+ expect(getByText('3')).toBeInTheDocument();
60
+ expect(getByText('Upcoming')).toBeInTheDocument();
61
+ expect(getByText('4')).toBeInTheDocument();
62
+ });
@@ -7,7 +7,7 @@ import dayjs from 'dayjs';
7
7
  import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
8
8
  dayjs.extend(isSameOrBefore);
9
9
  import styles from './scheduled-appointments.scss';
10
- import AppointmentsBaseTable from '../common-components/appointments-base-table.component';
10
+ import AppointmentsTable from '../common-components/appointments-table.component';
11
11
 
12
12
  interface ScheduledAppointmentsProps {
13
13
  visits: Array<any>;
@@ -75,7 +75,7 @@ const ScheduledAppointments: React.FC<ScheduledAppointmentsProps> = ({ visits, a
75
75
  Pending: {
76
76
  appointments: filteredRow,
77
77
  isLoading,
78
- tableHeading: isDateInPast ? t('notArrived', 'Not arrived') : t('missed', 'Missed'),
78
+ tableHeading: isDateInPast ? t('missed', 'Missed') : t('notArrived', 'Not arrived'),
79
79
  visits,
80
80
  scheduleType,
81
81
  },
@@ -106,7 +106,7 @@ const ScheduledAppointments: React.FC<ScheduledAppointmentsProps> = ({ visits, a
106
106
  </ContentSwitcher>
107
107
  )}
108
108
  <div className={styles.container}>
109
- <AppointmentsBaseTable {...currentConfig} />
109
+ <AppointmentsTable {...currentConfig} />
110
110
  </div>
111
111
  </>
112
112
  );
@@ -1,4 +1,4 @@
1
- import React, { useMemo } from 'react';
1
+ import React, { useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import isEmpty from 'lodash-es/isEmpty';
4
4
  import {
@@ -22,10 +22,15 @@ import { ConfigurableLink, usePagination } from '@openmrs/esm-framework';
22
22
  import { useUnscheduledAppointments } from '../../hooks/useUnscheduledAppointments';
23
23
  import { downloadUnscheduledAppointments } from '../../helpers/excel';
24
24
  import { EmptyState } from '../../empty-state/empty-state.component';
25
+ import { getPageSizes, useSearchResults } from '../utils';
25
26
 
26
27
  const UnscheduledAppointments: React.FC = () => {
27
28
  const { t } = useTranslation();
29
+ const [pageSize, setPageSize] = useState(25);
30
+
31
+ const [searchString, setSearchString] = useState('');
28
32
  const { data: unscheduledAppointments, isLoading, error } = useUnscheduledAppointments();
33
+ const searchResults = useSearchResults(unscheduledAppointments, searchString);
29
34
  const headerData = [
30
35
  {
31
36
  header: 'Patient Name',
@@ -45,7 +50,7 @@ const UnscheduledAppointments: React.FC = () => {
45
50
  },
46
51
  ];
47
52
 
48
- const { results, currentPage, goTo } = usePagination(unscheduledAppointments, 10);
53
+ const { results, currentPage, goTo } = usePagination(searchResults, pageSize);
49
54
 
50
55
  const rowData = results?.map((visit) => ({
51
56
  id: `${visit.uuid}`,
@@ -59,18 +64,11 @@ const UnscheduledAppointments: React.FC = () => {
59
64
  phoneNumber: visit.phoneNumber === '' ? '--' : visit.phoneNumber,
60
65
  }));
61
66
 
62
- const pageSizes = useMemo(() => {
63
- const numberOfPages = Math.ceil(unscheduledAppointments.length / 10);
64
- return [...Array(numberOfPages).keys()].map((x) => {
65
- return (x + 1) * 10;
66
- });
67
- }, [unscheduledAppointments]);
68
-
69
67
  if (isLoading) {
70
68
  return <DataTableSkeleton />;
71
69
  }
72
70
 
73
- if (isEmpty(unscheduledAppointments)) {
71
+ if (!unscheduledAppointments?.length) {
74
72
  return (
75
73
  <EmptyState
76
74
  displayText={t('unscheduledAppointments_lower', 'unscheduled appointments')}
@@ -83,14 +81,20 @@ const UnscheduledAppointments: React.FC = () => {
83
81
  return (
84
82
  <div>
85
83
  <DataTable rows={rowData} headers={headerData} isSortable>
86
- {({ rows, headers, getHeaderProps, getTableProps, onInputChange }) => (
87
- <TableContainer title={`${t('unscheduledAppointments', 'Unscheduled appointments')} ${rowData.length}`}>
84
+ {({ rows, headers, getHeaderProps, getTableProps }) => (
85
+ <TableContainer
86
+ title={`${t('unscheduledAppointments', 'Unscheduled appointments')} ${unscheduledAppointments.length}`}
87
+ description={`${t(`Total ${unscheduledAppointments.length ?? 0}`)}`}>
88
88
  <TableToolbar>
89
89
  <TableToolbarContent>
90
- <TableToolbarSearch style={{ backgroundColor: '#f4f4f4' }} tabIndex={0} onChange={onInputChange} />
90
+ <TableToolbarSearch
91
+ style={{ backgroundColor: '#f4f4f4' }}
92
+ tabIndex={0}
93
+ onChange={(event) => setSearchString(event.target.value)}
94
+ />
91
95
  <Button
92
96
  size="lg"
93
- kind="ghost"
97
+ kind="tertiary"
94
98
  renderIcon={Download}
95
99
  onClick={() => downloadUnscheduledAppointments(unscheduledAppointments)}>
96
100
  {t('download', 'Download')}
@@ -124,9 +128,12 @@ const UnscheduledAppointments: React.FC = () => {
124
128
  forwardText="Next page"
125
129
  page={currentPage}
126
130
  pageNumberText="Page Number"
127
- pageSize={10}
128
- onChange={({ page }) => goTo(page)}
129
- pageSizes={pageSizes.length > 0 ? pageSizes : [10]}
131
+ pageSize={pageSize}
132
+ onChange={({ page, pageSize }) => {
133
+ goTo(page);
134
+ setPageSize(pageSize);
135
+ }}
136
+ pageSizes={getPageSizes(unscheduledAppointments, pageSize) ?? []}
130
137
  totalItems={unscheduledAppointments.length ?? 0}
131
138
  />
132
139
  </div>