Skip to content

Commit c39793b

Browse files
committed
Update Table pagination in the system admin
1 parent e68ad00 commit c39793b

8 files changed

Lines changed: 197 additions & 113 deletions

File tree

src/pages/system-admin/schedule-tasks/schedule-tasks.component.tsx

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React, { useState, useMemo, useCallback } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import {
44
DataTable,
5+
DataTableSkeleton,
56
Table,
67
TableHead,
78
TableRow,
@@ -15,6 +16,7 @@ import {
1516
Button,
1617
OverflowMenuItem,
1718
Tag,
19+
Pagination,
1820
} from '@carbon/react';
1921
import {
2022
Add,
@@ -24,7 +26,7 @@ import {
2426
Time,
2527
Restart,
2628
} from '@carbon/react/icons';
27-
import { showNotification, showSnackbar } from '@openmrs/esm-framework';
29+
import { showNotification, showSnackbar, usePagination } from '@openmrs/esm-framework';
2830
import styles from './schedule-tasks.scss';
2931

3032
interface ScheduledTask {
@@ -90,6 +92,16 @@ const ScheduleTasksContent: React.FC<ScheduleTasksContentProps> = () => {
9092
);
9193
}, [scheduledTasks, searchQuery]);
9294

95+
// Pagination setup
96+
const pageSizes = [10, 20, 30, 40, 50];
97+
const [currentPageSize, setPageSize] = useState(10);
98+
99+
const {
100+
goTo,
101+
results: paginatedTasks,
102+
currentPage,
103+
} = usePagination(filteredTasks, currentPageSize);
104+
93105
const handleToggleTaskStatus = useCallback((taskId: string) => {
94106
setScheduledTasks((prev) =>
95107
prev.map((task) =>
@@ -167,7 +179,7 @@ const ScheduleTasksContent: React.FC<ScheduleTasksContentProps> = () => {
167179

168180
const tableRows = useMemo(
169181
() =>
170-
filteredTasks.map((task) => ({
182+
paginatedTasks.map((task) => ({
171183
id: task.id,
172184
name: task.name,
173185
schedule: task.schedule,
@@ -198,7 +210,7 @@ const ScheduleTasksContent: React.FC<ScheduleTasksContentProps> = () => {
198210
</div>
199211
),
200212
})),
201-
[filteredTasks, t, getLastStatusIcon, getStatusTag, handleRunNow, handleToggleTaskStatus, handleDeleteTask]
213+
[paginatedTasks, t, getLastStatusIcon, getStatusTag, handleRunNow, handleToggleTaskStatus, handleDeleteTask]
202214
);
203215

204216
return (
@@ -254,6 +266,23 @@ const ScheduleTasksContent: React.FC<ScheduleTasksContentProps> = () => {
254266
))}
255267
</TableBody>
256268
</Table>
269+
<Pagination
270+
forwardText="Next page"
271+
backwardText="Previous page"
272+
page={currentPage}
273+
pageSize={currentPageSize}
274+
pageSizes={pageSizes}
275+
totalItems={filteredTasks.length}
276+
className={styles.pagination}
277+
onChange={({ pageSize, page }) => {
278+
if (pageSize !== currentPageSize) {
279+
setPageSize(pageSize);
280+
}
281+
if (page !== currentPage) {
282+
goTo(page);
283+
}
284+
}}
285+
/>
257286
</TableContainer>
258287
)}
259288
</DataTable>

src/pages/system-admin/schedule-tasks/schedule-tasks.scss

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,7 @@
5151
color: #525252;
5252
margin-bottom: 1.5rem;
5353
}
54+
55+
.pagination {
56+
margin-top: 1rem;
57+
}

src/pages/system-admin/sync-logs/sync-logs.component.tsx

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useMemo, useEffect } from 'react';
1+
import React, { useState, useMemo } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import {
44
DataTable,
@@ -16,16 +16,15 @@ import {
1616
Button,
1717
DatePicker,
1818
DatePickerInput,
19-
Tile,
2019
Pagination,
20+
Select,
21+
SelectItem,
2122
} from '@carbon/react';
2223
import {
2324
ErrorState,
24-
useLayoutType,
2525
usePagination,
2626
} from '@openmrs/esm-framework';
2727
import {
28-
Renew,
2928
Checkmark,
3029
Warning,
3130
Time,
@@ -38,8 +37,6 @@ import styles from './sync-logs.scss';
3837
const SyncLogsContent: React.FC = () => {
3938
const { t } = useTranslation();
4039
const { logs, isLoading, isError } = useSyncLogs();
41-
const isTablet = useLayoutType() === 'tablet';
42-
const responsiveSize = isTablet ? 'lg' : 'sm';
4340

4441
const [searchQuery, setSearchQuery] = useState('');
4542
const [selectedSyncType, setSelectedSyncType] = useState('');
@@ -51,6 +48,17 @@ const SyncLogsContent: React.FC = () => {
5148
const pageSizes = [10, 20, 30, 40, 50];
5249
const [currentPageSize, setPageSize] = useState(10);
5350

51+
// Extract unique sync task types for the filter dropdown
52+
const syncTaskTypes = useMemo(() => {
53+
const types = new Set<string>();
54+
logs.forEach((log) => {
55+
if (log.syncTaskType?.name) {
56+
types.add(log.syncTaskType.name);
57+
}
58+
});
59+
return Array.from(types).sort();
60+
}, [logs]);
61+
5462
const filteredLogs = useMemo(() => {
5563
return logs.filter((log) => {
5664
const matchesSearch =
@@ -91,8 +99,6 @@ const SyncLogsContent: React.FC = () => {
9199
return <Checkmark size={16} className={styles.statusSuccess} />;
92100
case 'failed':
93101
return <Warning size={16} className={styles.statusFailed} />;
94-
case 'in_progress':
95-
return <Renew size={16} className={styles.statusInProgress} />;
96102
default:
97103
return <Time size={16} className={styles.statusPending} />;
98104
}
@@ -133,13 +139,26 @@ const SyncLogsContent: React.FC = () => {
133139
[t]
134140
);
135141

142+
const getStatusClass = (status?: string) => {
143+
switch (status) {
144+
case 'success':
145+
return styles.statusSuccess;
146+
case 'failed':
147+
return styles.statusFailed;
148+
case 'in_progress':
149+
return styles.statusInProgress;
150+
default:
151+
return styles.statusPending;
152+
}
153+
};
154+
136155
const tableRows = useMemo(
137156
() =>
138157
paginatedList.map((log: SyncTaskLog, index: number) => ({
139158
id: log.uuid || String(index),
140159
syncTaskType: log.syncTaskType?.name || '-',
141160
status: (
142-
<div className={`${styles.statusIndicator} ${styles['status_' + log.status]}`}>
161+
<div className={`${styles.statusIndicator} ${getStatusClass(log.status)}`}>
143162
{getStatusIcon(log.status)}
144163
<span>{t(log.status || 'unknown', log.status || 'Unknown')}</span>
145164
</div>
@@ -176,13 +195,8 @@ const SyncLogsContent: React.FC = () => {
176195
</p>
177196
</div>
178197
) : (
179-
<DataTable
180-
rows={tableRows}
181-
headers={tableHeaders}
182-
size={isTablet ? 'lg' : 'sm'}
183-
useZebraStyles
184-
>
185-
{({ rows, headers, getTableProps, getHeaderProps }) => (
198+
<DataTable rows={tableRows} headers={tableHeaders}>
199+
{({ rows, headers, getTableProps, getHeaderProps, getRowProps }) => (
186200
<TableContainer className={styles.syncTable}>
187201
<TableToolbar>
188202
<TableToolbarContent className={styles.toolbarContent}>
@@ -191,6 +205,22 @@ const SyncLogsContent: React.FC = () => {
191205
onChange={(event) => setSearchQuery(event ? event.toString() : '')}
192206
placeholder={t('searchLogs', 'Search logs...')}
193207
/>
208+
<Select
209+
id="sync-task-type-filter"
210+
labelText=""
211+
defaultValue=""
212+
onChange={(event) => setSelectedSyncType(event.target.value)}
213+
className={styles.syncTypeFilter}
214+
>
215+
<SelectItem value="" text={t('allTaskTypes', 'All Task Types')}>
216+
{t('allTaskTypes', 'All Task Types')}
217+
</SelectItem>
218+
{syncTaskTypes.map((type) => (
219+
<SelectItem key={type} value={type} text={type}>
220+
{type}
221+
</SelectItem>
222+
))}
223+
</Select>
194224
<div className={styles.datePicker}>
195225
<DatePicker
196226
datePickerType="range"
@@ -238,28 +268,14 @@ const SyncLogsContent: React.FC = () => {
238268
</TableHead>
239269
<TableBody>
240270
{rows.map((row) => (
241-
<TableRow key={row.id}>
271+
<TableRow {...getRowProps({ row })}>
242272
{row.cells.map((cell) => (
243273
<TableCell key={cell.id}>{cell.value}</TableCell>
244274
))}
245275
</TableRow>
246276
))}
247277
</TableBody>
248278
</Table>
249-
{rows.length === 0 ? (
250-
<div className={styles.tileContainer}>
251-
<Tile className={styles.tile}>
252-
<div className={styles.tileContent}>
253-
<p className={styles.content}>
254-
{t('noLogsToDisplay', 'No logs to display')}
255-
</p>
256-
<p className={styles.helper}>
257-
{t('checkFilter', 'Check the filter above')}
258-
</p>
259-
</div>
260-
</Tile>
261-
</div>
262-
) : null}
263279
<Pagination
264280
forwardText="Next page"
265281
backwardText="Previous page"

0 commit comments

Comments
 (0)