fix(projects): raise page size to 250 and add page controls - #147
Conversation
The projects page only requested the first API page, so years with more than 50 projects hid the rest. Walk nextCursor until the full filtered list is loaded. Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
Allow the projects API to return up to 250 items per request so current Hackweek years fit in one fetch. Keep next/previous controls for any result set that still returns a next cursor. Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 561a443. Configure here.
D1 allows at most 100 bound parameters per query. listProjects loads members with IN (...), so page sizes above 100 failed. Chunk those lookups and cover the path with a 101-project list test. Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
Merge the project pagination work with the latest ballot-aware project list while preserving vote-category badges and page controls. Keep both worker regression cases and make their generated year IDs sort consistently once the suite reaches double-digit cases.
Keep page controls rendered when a later cursor returns no results so users can navigate back. Move focus to the loaded result start only after placeholder data is replaced, and announce loading, completed ranges, and empty pages through the paginator status.\n\nCover empty-page recovery and deferred page transitions to prevent stale placeholder focus regressions.
Clear pending post-pagination focus whenever filters, year changes, or debounced search reset the cursor. This prevents replacement query results from stealing focus from the control that superseded an in-flight page request. Add a race regression covering a kind filter change while the next page remains pending.
HazAT
left a comment
There was a problem hiding this comment.
One accessibility race still needs fixing before approval.
P2 — src/app/routes/ProjectsPage.tsx search input: paginationRequestPending is cleared only when the 300 ms debounced search calls resetPagination. If a pending page request resolves after the user starts typing but before that debounce fires, the pagination effect focuses the results region and steals focus from the search field mid-entry. Clear the pending page-focus flag synchronously in the search input change path (while keeping the debounced request), and cover the delayed-page/search-input race.
Nonblocking: pagination currently exposes both the global updating… status and paginator loading page… status, causing duplicate screen-reader announcements.
Conflict resolution and the full local verification pipeline otherwise pass.
|
Addressed the accessibility race in
Checks: |
The projects page stopped at the first API page, so years with more than 50 projects hid the rest. Raise the API max and client page size to 250, add previous/next controls when a next cursor exists, batch member lookups under D1's 100-parameter bind limit, and keep search focus when a pending page load is superseded. Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
Co-Authored-By: Trevor Elkins <trevor.elkins@sentry.io>
HazAT
left a comment
There was a problem hiding this comment.
JR’s follow-up fixes the remaining search-focus race by clearing pending pagination focus synchronously on input changes, and it removes the duplicate live announcement during paginated fetches.
Quick verification passed: 30 app route tests, 10 project worker tests, TypeScript, focused lint/format, and diff sanity checks. All 13 GitHub checks are green.

The projects page stopped at the first API page (
limitmax 50), so years with more than 50 projects hid the rest.This change raises the API max and client page size to 250 so a typical Hackweek year fits in one request. If a result set still has more pages, the UI shows previous/next controls from
nextCursor.Test plan
npm run test:appRequested by telkins.
--
View Junior Session [Sentry]