feat: add pagination for runs
This commit is contained in:
@@ -86,6 +86,8 @@ export const RunsTable: React.FC<RunsTableProps> = ({
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const [accordionPage, setAccordionPage] = useState(0);
|
||||
const [accordionsPerPage, setAccordionsPerPage] = useState(10);
|
||||
const [accordionSortConfigs, setAccordionSortConfigs] = useState<AccordionSortConfig>({});
|
||||
|
||||
const handleSort = useCallback((columnId: keyof Data, robotMetaId: string) => {
|
||||
@@ -114,8 +116,6 @@ export const RunsTable: React.FC<RunsTableProps> = ({
|
||||
[t]
|
||||
);
|
||||
|
||||
// const [page, setPage] = useState(0);
|
||||
// const [rowsPerPage, setRowsPerPage] = useState(10);
|
||||
const [rows, setRows] = useState<Data[]>([]);
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
@@ -128,6 +128,15 @@ export const RunsTable: React.FC<RunsTableProps> = ({
|
||||
navigate(isExpanded ? `/runs/${robotMetaId}` : '/runs');
|
||||
}, [navigate]);
|
||||
|
||||
const handleAccordionPageChange = useCallback((event: unknown, newPage: number) => {
|
||||
setAccordionPage(newPage);
|
||||
}, []);
|
||||
|
||||
const handleAccordionsPerPageChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setAccordionsPerPage(+event.target.value);
|
||||
setAccordionPage(0);
|
||||
}, []);
|
||||
|
||||
const handleChangePage = useCallback((robotMetaId: string, newPage: number) => {
|
||||
setPaginationStates(prev => ({
|
||||
...prev,
|
||||
@@ -174,6 +183,7 @@ export const RunsTable: React.FC<RunsTableProps> = ({
|
||||
const handleSearchChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const debouncedSetSearch = debouncedSearch((value: string) => {
|
||||
setSearchTerm(value);
|
||||
setAccordionPage(0);
|
||||
setPaginationStates(prev => {
|
||||
const reset = Object.keys(prev).reduce((acc, robotId) => ({
|
||||
...acc,
|
||||
@@ -347,86 +357,101 @@ export const RunsTable: React.FC<RunsTableProps> = ({
|
||||
</Box>
|
||||
|
||||
<TableContainer component={Paper} sx={{ width: '100%', overflow: 'hidden' }}>
|
||||
{Object.entries(groupedRows).map(([robotMetaId, data]) => (
|
||||
<Accordion
|
||||
key={robotMetaId}
|
||||
onChange={(event, isExpanded) => handleAccordionChange(robotMetaId, isExpanded)}
|
||||
TransitionProps={{ unmountOnExit: true }} // Optimize accordion rendering
|
||||
>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">{data[data.length - 1].name}</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Table stickyHeader aria-label="sticky table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
{translatedColumns.map((column) => (
|
||||
<TableCell
|
||||
key={column.id}
|
||||
align={column.align}
|
||||
style={{
|
||||
minWidth: column.minWidth,
|
||||
cursor: column.id === 'startedAt' || column.id === 'finishedAt' ? 'pointer' : 'default'
|
||||
}}
|
||||
onClick={() => {
|
||||
if (column.id === 'startedAt' || column.id === 'finishedAt') {
|
||||
handleSort(column.id, robotMetaId);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
(column.id === 'startedAt' || column.id === 'finishedAt')
|
||||
? t('runstable.sort_tooltip')
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
'&:hover': {
|
||||
'& .sort-icon': {
|
||||
opacity: 1
|
||||
}
|
||||
{Object.entries(groupedRows)
|
||||
.slice(
|
||||
accordionPage * accordionsPerPage,
|
||||
accordionPage * accordionsPerPage + accordionsPerPage
|
||||
)
|
||||
.map(([robotMetaId, data]) => (
|
||||
<Accordion
|
||||
key={robotMetaId}
|
||||
onChange={(event, isExpanded) => handleAccordionChange(robotMetaId, isExpanded)}
|
||||
TransitionProps={{ unmountOnExit: true }} // Optimize accordion rendering
|
||||
>
|
||||
<AccordionSummary expandIcon={<ExpandMoreIcon />}>
|
||||
<Typography variant="h6">{data[data.length - 1].name}</Typography>
|
||||
</AccordionSummary>
|
||||
<AccordionDetails>
|
||||
<Table stickyHeader aria-label="sticky table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell />
|
||||
{translatedColumns.map((column) => (
|
||||
<TableCell
|
||||
key={column.id}
|
||||
align={column.align}
|
||||
style={{
|
||||
minWidth: column.minWidth,
|
||||
cursor: column.id === 'startedAt' || column.id === 'finishedAt' ? 'pointer' : 'default'
|
||||
}}
|
||||
onClick={() => {
|
||||
if (column.id === 'startedAt' || column.id === 'finishedAt') {
|
||||
handleSort(column.id, robotMetaId);
|
||||
}
|
||||
}}>
|
||||
{column.label}
|
||||
<Box className="sort-icon" sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
opacity: accordionSortConfigs[robotMetaId]?.field === column.id ? 1 : 0.3,
|
||||
transition: 'opacity 0.2s'
|
||||
}}
|
||||
>
|
||||
<Tooltip
|
||||
title={
|
||||
(column.id === 'startedAt' || column.id === 'finishedAt')
|
||||
? t('runstable.sort_tooltip')
|
||||
: ''
|
||||
}
|
||||
>
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 1,
|
||||
'&:hover': {
|
||||
'& .sort-icon': {
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
}}>
|
||||
{renderSortIcon(column, robotMetaId)}
|
||||
{column.label}
|
||||
<Box className="sort-icon" sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
opacity: accordionSortConfigs[robotMetaId]?.field === column.id ? 1 : 0.3,
|
||||
transition: 'opacity 0.2s'
|
||||
}}>
|
||||
{renderSortIcon(column, robotMetaId)}
|
||||
</Box>
|
||||
</Box>
|
||||
</Box>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{renderTableRows(data, robotMetaId)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
))}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{renderTableRows(data, robotMetaId)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
<TablePagination
|
||||
component="div"
|
||||
count={data.length}
|
||||
rowsPerPage={getPaginationState(robotMetaId).rowsPerPage}
|
||||
page={getPaginationState(robotMetaId).page}
|
||||
onPageChange={(_, newPage) => handleChangePage(robotMetaId, newPage)}
|
||||
onRowsPerPageChange={(event) =>
|
||||
handleChangeRowsPerPage(robotMetaId, +event.target.value)
|
||||
}
|
||||
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||
/>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
))}
|
||||
<TablePagination
|
||||
component="div"
|
||||
count={data.length}
|
||||
rowsPerPage={getPaginationState(robotMetaId).rowsPerPage}
|
||||
page={getPaginationState(robotMetaId).page}
|
||||
onPageChange={(_, newPage) => handleChangePage(robotMetaId, newPage)}
|
||||
onRowsPerPageChange={(event) =>
|
||||
handleChangeRowsPerPage(robotMetaId, +event.target.value)
|
||||
}
|
||||
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||
/>
|
||||
</AccordionDetails>
|
||||
</Accordion>
|
||||
))}
|
||||
</TableContainer>
|
||||
|
||||
<TablePagination
|
||||
component="div"
|
||||
count={Object.keys(groupedRows).length}
|
||||
page={accordionPage}
|
||||
rowsPerPage={accordionsPerPage}
|
||||
onPageChange={handleAccordionPageChange}
|
||||
onRowsPerPageChange={handleAccordionsPerPageChange}
|
||||
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user