mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
fix(site): use page count in usePaginatedQuery overshoot fallback (#30572)
Enables oxlint's `erasing-op` rule and fixes the one violation it found, an operator precedence bug in `usePaginatedQuery`. When the requested page reports a count of 0, the hook refetches page 1 to compute where to clamp. `Math.ceil(firstPageResult?.count ?? 0 / limit)` parsed as `count ?? (0 / limit)`, so it used the record count as the page count and left the user on the overshot page. The fix adds parentheses, and a regression test covers it (the test fails without the fix). <details> <summary>Context and findings</summary> Part of evaluating oxlint's `correctness` category. Turning on the whole category reported 1152 diagnostics across 24 rules, so rules are being enabled one at a time instead, which keeps the explicit allowlist model in `.oxlintrc.jsonc`. `erasing-op` had a single hit, and it was a real bug. Validation: `pnpm run lint` (Biome, oxlint, types, circular deps, React Compiler, knip) and the full unit suite. </details> _Generated by Coder Agents on behalf of @jeremyruppel._
This commit is contained in:
@@ -109,6 +109,7 @@
|
||||
"require-yield": "error",
|
||||
"rules-of-hooks": "error",
|
||||
"refs": "error",
|
||||
"erasing-op": "error",
|
||||
|
||||
// --- security ---
|
||||
"jsx-no-target-blank": "error",
|
||||
|
||||
@@ -228,6 +228,21 @@ describe(usePaginatedQuery.name, () => {
|
||||
await waitFor(() => expect(result.current.currentPage).toBe(1));
|
||||
});
|
||||
|
||||
it("No custom callback: uses the first page's count when an overshot page reports a count of 0", async () => {
|
||||
const mockQueryFn = vi.fn(({ pageNumber }: { pageNumber: number }) =>
|
||||
Promise.resolve({ data: [], count: pageNumber === 1 ? 100 : 0 }),
|
||||
);
|
||||
const { result } = await render(
|
||||
{
|
||||
queryKey: ({ pageNumber }) => ["overshoot", pageNumber],
|
||||
queryFn: mockQueryFn,
|
||||
},
|
||||
"/?page=35",
|
||||
);
|
||||
|
||||
await waitFor(() => expect(result.current.currentPage).toBe(4));
|
||||
});
|
||||
|
||||
it("With custom callback: Calls callback and does not update search params automatically", async () => {
|
||||
const testControl = new URLSearchParams({
|
||||
page: "1000",
|
||||
|
||||
@@ -232,7 +232,7 @@ export function usePaginatedQuery<
|
||||
const firstPageOptions = getQueryOptionsFromPage(1);
|
||||
try {
|
||||
const firstPageResult = await queryClient.fetchQuery(firstPageOptions);
|
||||
const rounded = Math.ceil(firstPageResult?.count ?? 0 / limit);
|
||||
const rounded = Math.ceil((firstPageResult?.count ?? 0) / limit);
|
||||
fixedTotalPages = Math.max(rounded, 1);
|
||||
} catch {
|
||||
fixedTotalPages = 1;
|
||||
|
||||
Reference in New Issue
Block a user