Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions apps/web/__tests__/unit/cap-pagination.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, expect, it } from "vitest";
import { getPaginationItems } from "../../lib/pagination-items";

describe("CapPagination getPaginationItems (#3566)", () => {
it("returns single page when totalPages <= 1", () => {
expect(getPaginationItems(1, 0)).toEqual([1]);
expect(getPaginationItems(1, 1)).toEqual([1]);
});

it("returns all pages for small page counts without ellipses (totalPages <= 5)", () => {
expect(getPaginationItems(1, 4)).toEqual([1, 2, 3, 4]);
expect(getPaginationItems(2, 4)).toEqual([1, 2, 3, 4]);
expect(getPaginationItems(3, 4)).toEqual([1, 2, 3, 4]);
expect(getPaginationItems(4, 4)).toEqual([1, 2, 3, 4]);
expect(getPaginationItems(3, 5)).toEqual([1, 2, 3, 4, 5]);
});

it("always links first and last page with ellipses for large page counts", () => {
// Viewing start

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.

P2 Test comments break repository rules

The new Viewing start, Viewing middle, and Viewing end comments repeat the page positions already shown by the assertions. AGENTS.md explicitly bans comments that merely narrate the code. Remove these comments or split the groups into named tests. This repository requirement must be satisfied before merging.

Context Used: AGENTS.md (source)

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/__tests__/unit/cap-pagination.test.ts
Line: 19

Comment:
**Test comments break repository rules**

The new `Viewing start`, `Viewing middle`, and `Viewing end` comments repeat the page positions already shown by the assertions. `AGENTS.md` explicitly bans comments that merely narrate the code. Remove these comments or split the groups into named tests. This repository requirement must be satisfied before merging.

**Context Used:** AGENTS.md ([source](https://github.com/capsoftware/cap/blob/main/AGENTS.md))

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

expect(getPaginationItems(1, 10)).toEqual([1, 2, "ellipsis", 10]);
expect(getPaginationItems(2, 10)).toEqual([1, 2, 3, "ellipsis", 10]);
expect(getPaginationItems(3, 10)).toEqual([1, 2, 3, 4, "ellipsis", 10]);

// Viewing middle
expect(getPaginationItems(5, 10)).toEqual([1, "ellipsis", 4, 5, 6, "ellipsis", 10]);

// Viewing end
expect(getPaginationItems(8, 10)).toEqual([1, "ellipsis", 7, 8, 9, 10]);
expect(getPaginationItems(9, 10)).toEqual([1, "ellipsis", 8, 9, 10]);
expect(getPaginationItems(10, 10)).toEqual([1, "ellipsis", 9, 10]);
});

it("inserts bridging page number instead of ellipsis when difference is 2", () => {
expect(getPaginationItems(3, 6)).toEqual([1, 2, 3, 4, 5, 6]);
});
});
62 changes: 27 additions & 35 deletions apps/web/app/(org)/dashboard/caps/components/CapPagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {
PaginationNext,
PaginationPrevious,
} from "@cap/ui";
import { getPaginationItems } from "@/lib/pagination-items";

export { getPaginationItems };

interface CapPaginationProps {
currentPage: number;
Expand All @@ -19,6 +22,8 @@ export const CapPagination: React.FC<CapPaginationProps> = ({
totalPages,
hrefForPage = (page) => `/dashboard/caps?page=${page}`,
}) => {
const items = getPaginationItems(currentPage, totalPages);

return (
<Pagination>
<PaginationContent>
Expand All @@ -30,46 +35,33 @@ export const CapPagination: React.FC<CapPaginationProps> = ({
/>
</PaginationItem>
)}
<PaginationItem>
<PaginationLink
className="h-10 min-w-10"
href={hrefForPage(1)}
isActive={currentPage === 1}
>
1
</PaginationLink>
</PaginationItem>
{currentPage !== 1 && (
<PaginationItem>
<PaginationLink
className="h-10 min-w-10"
href={hrefForPage(currentPage)}
isActive={true}
>
{currentPage}
</PaginationLink>
</PaginationItem>
{items.map((item, index) =>
item === "ellipsis" ? (
<PaginationEllipsis key={`ellipsis-${index}`} />
) : (
<PaginationItem key={item}>
<PaginationLink
className={
item === currentPage
? "h-10 min-w-10"
: "h-10 min-w-10 hover:bg-gray-3"
Comment on lines +38 to +47

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.

P2 Page links exceed phone width

CapPagination now renders all five numbered links when totalPages is 5, but the row cannot wrap. On a 320px-wide phone, those links, gaps, and Next exceed the dashboard's padded width and can leave links clipped. The old first-page row had only two numbered links. Add a narrow-screen layout so the extra links stay within view.

Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/app/(org)/dashboard/caps/components/CapPagination.tsx
Line: 38-47

Comment:
**Page links exceed phone width**

`CapPagination` now renders all five numbered links when `totalPages` is 5, but the row cannot wrap. On a 320px-wide phone, those links, gaps, and `Next` exceed the dashboard's padded width and can leave links clipped. The old first-page row had only two numbered links. Add a narrow-screen layout so the extra links stay within view.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

}
href={hrefForPage(item)}
isActive={item === currentPage}
>
{item}
</PaginationLink>
</PaginationItem>
),
)}
{totalPages > currentPage + 1 && (
{currentPage < totalPages && (
<PaginationItem>
<PaginationLink
className="h-10 min-w-10 hover:bg-gray-3"
<PaginationNext
className="h-10 bg-transparent hover:bg-gray-4"
href={hrefForPage(currentPage + 1)}
isActive={false}
>
{currentPage + 1}
</PaginationLink>
/>
</PaginationItem>
)}
{currentPage > 2 && <PaginationEllipsis />}
<PaginationItem>
<PaginationNext
className="h-10 bg-transparent hover:bg-gray-4"
href={hrefForPage(
currentPage === totalPages ? currentPage : currentPage + 1,
)}
/>
</PaginationItem>
</PaginationContent>
</Pagination>
);
Expand Down
36 changes: 36 additions & 0 deletions apps/web/lib/pagination-items.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export function getPaginationItems(
currentPage: number,
totalPages: number,
): (number | "ellipsis")[] {
if (totalPages <= 1) return [1];

if (totalPages <= 5) {
return Array.from({ length: totalPages }, (_, i) => i + 1);
}

const pages = new Set<number>();
pages.add(1);
pages.add(totalPages);
pages.add(currentPage);
if (currentPage > 1) pages.add(currentPage - 1);
if (currentPage < totalPages) pages.add(currentPage + 1);

const sorted = Array.from(pages).sort((a, b) => a - b);
const items: (number | "ellipsis")[] = [];

for (let i = 0; i < sorted.length; i++) {
const current = sorted[i];
items.push(current);

Check failure on line 23 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

Argument of type 'number | undefined' is not assignable to parameter of type 'number | "ellipsis"'.

if (i < sorted.length - 1) {
const next = sorted[i + 1];
if (next - current === 2) {

Check failure on line 27 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

'current' is possibly 'undefined'.

Check failure on line 27 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

'next' is possibly 'undefined'.
items.push(current + 1);

Check failure on line 28 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

'current' is possibly 'undefined'.
} else if (next - current > 2) {

Check failure on line 29 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

'current' is possibly 'undefined'.

Check failure on line 29 in apps/web/lib/pagination-items.ts

View workflow job for this annotation

GitHub Actions / Typecheck

'next' is possibly 'undefined'.
items.push("ellipsis");
}
}
}

return items;
}
Loading