Skip to content

Bounties page renders every bounty on first paint after PR #983 dropped pagination #1027

@cleanjunc

Description

@cleanjunc

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

  1. Open /bounties on a network with several hundred completed bounties (or seed useIssues('completed,cancelled') with a large dataset locally).
  2. Open the browser performance panel, hard reload, and observe the long task and layout cost on first paint.
  3. 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:

  1. 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.
  2. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions