diff --git a/src/components/run/RunsTable.tsx b/src/components/run/RunsTable.tsx index 922332146..091a6c447 100644 --- a/src/components/run/RunsTable.tsx +++ b/src/components/run/RunsTable.tsx @@ -70,6 +70,13 @@ interface RunsTableProps { runningRecordingName: string; } +interface PaginationState { + [robotMetaId: string]: { + page: number; + rowsPerPage: number; + }; +} + export const RunsTable: React.FC = ({ currentInterpretationLog, abortRunHandler, @@ -79,6 +86,8 @@ export const RunsTable: React.FC = ({ const { t } = useTranslation(); const navigate = useNavigate(); + const [accordionPage, setAccordionPage] = useState(0); + const [accordionsPerPage, setAccordionsPerPage] = useState(10); const [accordionSortConfigs, setAccordionSortConfigs] = useState({}); const handleSort = useCallback((columnId: keyof Data, robotMetaId: string) => { @@ -107,27 +116,62 @@ export const RunsTable: React.FC = ({ [t] ); - const [page, setPage] = useState(0); - const [rowsPerPage, setRowsPerPage] = useState(10); const [rows, setRows] = useState([]); const [searchTerm, setSearchTerm] = useState(''); const [isLoading, setIsLoading] = useState(true); + const [paginationStates, setPaginationStates] = useState({}); + const { notify, rerenderRuns, setRerenderRuns } = useGlobalInfoStore(); const handleAccordionChange = useCallback((robotMetaId: string, isExpanded: boolean) => { navigate(isExpanded ? `/runs/${robotMetaId}` : '/runs'); }, [navigate]); - const handleChangePage = useCallback((event: unknown, newPage: number) => { - setPage(newPage); + const handleAccordionPageChange = useCallback((event: unknown, newPage: number) => { + setAccordionPage(newPage); + }, []); + + const handleAccordionsPerPageChange = useCallback((event: React.ChangeEvent) => { + setAccordionsPerPage(+event.target.value); + setAccordionPage(0); + }, []); + + const handleChangePage = useCallback((robotMetaId: string, newPage: number) => { + setPaginationStates(prev => ({ + ...prev, + [robotMetaId]: { + ...prev[robotMetaId], + page: newPage + } + })); }, []); - const handleChangeRowsPerPage = useCallback((event: React.ChangeEvent) => { - setRowsPerPage(+event.target.value); - setPage(0); + const handleChangeRowsPerPage = useCallback((robotMetaId: string, newRowsPerPage: number) => { + setPaginationStates(prev => ({ + ...prev, + [robotMetaId]: { + page: 0, // Reset to first page when changing rows per page + rowsPerPage: newRowsPerPage + } + })); }, []); + const getPaginationState = useCallback((robotMetaId: string) => { + const defaultState = { page: 0, rowsPerPage: 10 }; + + if (!paginationStates[robotMetaId]) { + setTimeout(() => { + setPaginationStates(prev => ({ + ...prev, + [robotMetaId]: defaultState + })); + }, 0); + return defaultState; + } + return paginationStates[robotMetaId]; + }, [paginationStates]); + const debouncedSearch = useCallback((fn: Function, delay: number) => { let timeoutId: NodeJS.Timeout; return (...args: any[]) => { @@ -139,7 +183,14 @@ export const RunsTable: React.FC = ({ const handleSearchChange = useCallback((event: React.ChangeEvent) => { const debouncedSetSearch = debouncedSearch((value: string) => { setSearchTerm(value); - setPage(0); + setAccordionPage(0); + setPaginationStates(prev => { + const reset = Object.keys(prev).reduce((acc, robotId) => ({ + ...acc, + [robotId]: { ...prev[robotId], page: 0 } + }), {}); + return reset; + }); }, 300); debouncedSetSearch(event.target.value); }, [debouncedSearch]); @@ -219,6 +270,7 @@ export const RunsTable: React.FC = ({ }; const renderTableRows = useCallback((data: Data[], robotMetaId: string) => { + const { page, rowsPerPage } = getPaginationState(robotMetaId); const start = page * rowsPerPage; const end = start + rowsPerPage; @@ -251,7 +303,7 @@ export const RunsTable: React.FC = ({ runningRecordingName={runningRecordingName} /> )); - }, [page, rowsPerPage, runId, runningRecordingName, currentInterpretationLog, abortRunHandler, handleDelete, accordionSortConfigs]); + }, [paginationStates, runId, runningRecordingName, currentInterpretationLog, abortRunHandler, handleDelete, accordionSortConfigs]); const renderSortIcon = useCallback((column: Column, robotMetaId: string) => { const sortConfig = accordionSortConfigs[robotMetaId]; @@ -305,82 +357,99 @@ export const RunsTable: React.FC = ({ - {Object.entries(groupedRows).map(([robotMetaId, data]) => ( - handleAccordionChange(robotMetaId, isExpanded)} - TransitionProps={{ unmountOnExit: true }} // Optimize accordion rendering - > - }> - {data[data.length - 1].name} - - - - - - - {translatedColumns.map((column) => ( - { - if (column.id === 'startedAt' || column.id === 'finishedAt') { - handleSort(column.id, robotMetaId); - } - }} - > - ( + handleAccordionChange(robotMetaId, isExpanded)} + TransitionProps={{ unmountOnExit: true }} // Optimize accordion rendering + > + }> + {data[data.length - 1].name} + + +
+ + + + {translatedColumns.map((column) => ( + { + if (column.id === 'startedAt' || column.id === 'finishedAt') { + handleSort(column.id, robotMetaId); + } + }} > - - {column.label} - + - {renderSortIcon(column, robotMetaId)} + {column.label} + + {renderSortIcon(column, robotMetaId)} + - - - - ))} - - - - {renderTableRows(data, robotMetaId)} - -
-
-
- ))} + + + ))} + + + + {renderTableRows(data, robotMetaId)} + + + + handleChangePage(robotMetaId, newPage)} + onRowsPerPageChange={(event) => + handleChangeRowsPerPage(robotMetaId, +event.target.value) + } + rowsPerPageOptions={[10, 25, 50, 100]} + /> + + + ))}