Description
src/components/issues/IssuesList.tsx lost its pagination state and <TablePagination> block in PR #983 ("right sidebar with filter portal, donut, and top hunters", merged May 8). The diff for that PR removed:
- TablePagination,
- const [rowsPerPage, setRowsPerPage] = useState(...)
- const [page, setPage] = useState(0);
- const start = page * rowsPerPage;
- return sortedIssues.slice(start, start + rowsPerPage);
- }, [sortedIssues, page, rowsPerPage]);
- <TablePagination ... />
No virtualization, infinite scroll, or other windowing strategy replaced it. Both render paths now hand the entire sortedIssues array straight to the renderer:
viewMode === 'cards' ? (
<Grid container spacing={2}>
{sortedIssues.map((issue) => (
<Grid item xs={12} sm={6} md={4} key={issue.id}>
<BountyCard ... />
</Grid>
))}
</Grid>
) : (
<DataTable<IssueBounty, SortKey>
columns={columns}
rows={sortedIssues}
...
/>
)
src/components/issues/IssuesList.tsx:1162-1207
IssuesPage feeds this list with the union of three useIssues queries ('active', 'registered', 'completed,cancelled') merged into a single allIssues array (src/pages/IssuesPage.tsx:33-51). Once completed accumulates a few hundred bounties, every entry materializes a BountyCard (cards view) or a <TableRow> (list view) on first paint.
Steps to Reproduce
- Open
/bounties on a network with several hundred completed bounties (or seed useIssues('completed,cancelled') with a large dataset locally).
- Open the browser performance panel, hard reload, and observe the long task and layout cost on first paint.
- Scroll the page and notice the paint area extending over every card or row instead of the viewport.
Expected Behavior
First paint shows a windowed slice of bounties (10 rows in list view or 12 cards in card view, matching the constants already declared in src/components/issues/issuesViewMode.ts), with prev/next pagination below the list.
Actual Behavior
- Multi-second layout work when the page first opens on desktop, longer on phones.
- Scroll feels jerky because the browser repaints every card, not just the visible window.
- The constants
ISSUES_DEFAULT_LIST_ROWS = 10 and ISSUES_DEFAULT_CARD_ROWS = 12 in src/components/issues/issuesViewMode.ts still exist, but their only remaining reference is the loading skeleton on IssuesList.tsx:777. The skeleton accurately previews 10 rows, then the real content blows past that.
Environment
- Browser: any
- OS: any
- Branch:
test
- Affected component:
src/components/issues/IssuesList.tsx
- Affected page:
/bounties. The local IssuesList defined inline in WatchlistPage.tsx:3842 already paginates and is not affected.
Additional Context
Two adjacent cleanups drop out of the same change:
- The shared
TablePagination already used by MinerPRsTable, MinerRepositoriesTable, and MinerOpenDiscoveryIssuesByRepo lives at src/components/miners/TablePagination.tsx despite containing no miner-specific code. Promoting it to src/components/common/TablePagination.tsx matches where every other shared table primitive lives and removes the cross-domain reach that adopting it on IssuesList would otherwise add.
- Filter, search, sort, and view changes need to drop the user back to page 0. Wiring this through
useEffect causes a one-frame render where the clamped stale page shows before the effect commits. A useState-tracked previous-key with a setState-during-render bail-out lets React discard the stale render before commit, so the flash never reaches the user.
Related
Description
src/components/issues/IssuesList.tsxlost its pagination state and<TablePagination>block in PR #983 ("right sidebar with filter portal, donut, and top hunters", merged May 8). The diff for that PR removed:No virtualization, infinite scroll, or other windowing strategy replaced it. Both render paths now hand the entire
sortedIssuesarray straight to the renderer:src/components/issues/IssuesList.tsx:1162-1207IssuesPagefeeds this list with the union of threeuseIssuesqueries ('active','registered','completed,cancelled') merged into a singleallIssuesarray (src/pages/IssuesPage.tsx:33-51). Oncecompletedaccumulates a few hundred bounties, every entry materializes aBountyCard(cards view) or a<TableRow>(list view) on first paint.Steps to Reproduce
/bountieson a network with several hundred completed bounties (or seeduseIssues('completed,cancelled')with a large dataset locally).Expected Behavior
First paint shows a windowed slice of bounties (10 rows in list view or 12 cards in card view, matching the constants already declared in
src/components/issues/issuesViewMode.ts), with prev/next pagination below the list.Actual Behavior
ISSUES_DEFAULT_LIST_ROWS = 10andISSUES_DEFAULT_CARD_ROWS = 12insrc/components/issues/issuesViewMode.tsstill exist, but their only remaining reference is the loading skeleton onIssuesList.tsx:777. The skeleton accurately previews 10 rows, then the real content blows past that.Environment
testsrc/components/issues/IssuesList.tsx/bounties. The localIssuesListdefined inline inWatchlistPage.tsx:3842already paginates and is not affected.Additional Context
Two adjacent cleanups drop out of the same change:
TablePaginationalready used byMinerPRsTable,MinerRepositoriesTable, andMinerOpenDiscoveryIssuesByRepolives atsrc/components/miners/TablePagination.tsxdespite containing no miner-specific code. Promoting it tosrc/components/common/TablePagination.tsxmatches where every other shared table primitive lives and removes the cross-domain reach that adopting it onIssuesListwould otherwise add.useEffectcauses a one-frame render where the clamped stale page shows before the effect commits. AuseState-tracked previous-key with a setState-during-render bail-out lets React discard the stale render before commit, so the flash never reaches the user.Related
useIssuesfan-out from issue [Bug] Bounties page fires three useIssues queries and shows partial data while two of them are still loading #978 but does not touch pagination.MinersList,TopMinersTable, andWatchlistPage.IssuesListis not in its diff.