Skip to content

feat(billing): Paginate invoice comparison admin UI#116647

Draft
armcknight wants to merge 2 commits into
masterfrom
andrewmcknight/reveng-131-paginate-invoice-comparison
Draft

feat(billing): Paginate invoice comparison admin UI#116647
armcknight wants to merge 2 commits into
masterfrom
andrewmcknight/reveng-131-paginate-invoice-comparison

Conversation

@armcknight
Copy link
Copy Markdown
Member

@armcknight armcknight commented Jun 1, 2026

Summary

REVENG-131. Paginates the /_admin/cells/$region/invoice-comparison/ page so operators can navigate past the first 200 rows.

  • Both tables (both-sides comparison + one-sided unmatched debug) get their own paginator. The two paginators are independent: paging through rows doesn't move you in unmatched, and vice versa.
  • Page numbers live in URL search params (rows_page, unmatched_page) so refresh and share-links keep their position.
  • Running a new comparison resets both paginators to page 1 — the new window's result set is unrelated to the previous one's page numbers.
  • Drops the inline "showing top N" notes from the panel headers; replaces them with a paginator row showing start–end of total · page X of Y plus prev/next.

Consumes the new summary.{rows,unmatched}_{page,page_size,total_pages} contract from getsentry#20496 — that PR needs to land first.

image

Test plan

  • With getsentry#20496 deployed locally and make seed-invoice-comparison run, load /_admin/cells/<region>/invoice-comparison/, click Run, and confirm both tables show page 1 of 2 by default (page_size=200, 250 rows each)
  • Click Next on the rows paginator — URL updates with ?rows_page=2, rows change, unmatched paginator stays on page 1
  • Click Next on the unmatched paginator — URL updates with ?unmatched_page=2, unmatched rows change, rows table stays on page 2
  • Refresh — both paginators stay on page 2
  • Change the date window and click Run — both paginators reset to page 1 (URL ?rows_page=1&unmatched_page=1)
  • Empty window (e.g. start = end = now) — paginator row shows "No rows" rather than a broken Prev/Next pair
  • Manually visit ?rows_page=99 — backend clamps to last page, frontend shows that page with Next disabled

🤖 Generated with Claude Code

Adds page navigation to `/_admin/cells/$region/invoice-comparison/`. Each
of the page's two tables (the both-sides comparison list and the
one-sided unmatched debug list) gets its own paginator backed by URL
search params (`rows_page` / `unmatched_page`) so refresh and
shareable URLs preserve position. Running a new comparison resets both
pages to 1.

Consumes the new `summary.{rows,unmatched}_{page,page_size,total_pages}`
contract from getsentry#20496.

REVENG-131.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear-code
Copy link
Copy Markdown

linear-code Bot commented Jun 1, 2026

REVENG-131

@github-actions github-actions Bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jun 1, 2026
@armcknight armcknight marked this pull request as draft June 1, 2026 22:47
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 1, 2026

📊 Type Coverage Diff

Metric Before After Delta
Coverage 93.59% 93.59% ±0%
Typed 133,329 133,366 🟢 +37
Untyped 9,135 9,136 🔴 +1
🔍 1 new type safety issue introduced

Type assertions (as) (1 new)

File Line Detail
static/gsAdmin/views/invoiceComparison.tsx 141 as readonly number[]PAGE_SIZE_OPTIONS as readonly number[]

This is informational only and does not block the PR.

Copy link
Copy Markdown
Contributor

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit a4defb0. Configure here.

align-items: center;
padding: 8px 12px;
border-bottom: 1px solid ${p => p.theme.tokens.border.primary};
`;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New styled component replaces core layout primitives

Low Severity

The newly added PaginatorRow is a styled('div') using flex layout (display: flex, justify-content: space-between, align-items: center) plus padding and border-bottom — all of which map directly to existing Flex component props. Per static/AGENTS.md, core components like Flex and Container are preferred over new styled() calls. Since space.md = 8px and space.lg = 12px, the styling maps exactly to <Flex justify="between" align="center" padding="md lg" borderBottom="primary">.

Fix in Cursor Fix in Web

Triggered by project rule: Frontend guidelines

Reviewed by Cursor Bugbot for commit a4defb0. Configure here.

…omparison

Two fixes + one feature:

- Move `start` / `end` from local state into URL search params. Previously
  a refresh wiped the in-memory `submitted` value, which disabled the
  query and reset the page to the empty input form — and the same gap
  made `?rows_page=99` URLs render nothing. The window is now reread
  from the URL on mount and the query fires whenever start+end are
  present.

- After every response, if the server clamped the requested page (e.g.
  asked for page 99 against a 2-page result), replace the URL with the
  clamped value so refresh converges on the real page rather than
  re-requesting the bad one.

- Add a "Results per page" dropdown with 25 / 50 / 100 / 250 options.
  Selection persists in the URL as `page_size` and is applied to both
  tables (sent as `rows_page_size` and `unmatched_page_size` on the
  request). Default is 50. Changing the value resets both paginators
  to page 1 — the previous offset doesn't map cleanly to the resized list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant