fix(web): add load-more pagination for Done column on issue board (#492)
* fix(web): add load-more pagination for Done column on issue board The Done column was capped at 50 issues with no way to load more. Track doneTotal in the TQ cache and add a useLoadMoreDoneIssues hook that fetches the next page and merges it into the unified issue cache. The Done column now shows a "Load more" button when there are additional items. - shared/types/api.ts: add doneTotal to ListIssuesResponse - core/issues/queries.ts: store doneTotal from the done-status response - core/issues/mutations.ts: add useLoadMoreDoneIssues hook, update create/delete mutations to maintain doneTotal - core/issues/ws-updaters.ts: maintain doneTotal on WS events - features/issues/components/board-column.tsx: accept optional footer - features/issues/components/board-view.tsx: render Load more button in Done column Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix(web): address review issues in done-column load-more 1. Fix total over-counting: loadMore no longer inflates total since the initial query already includes all done issues in total count. 2. Fix onIssueUpdated: maintain doneTotal when issue status changes to/from done via WS events. 3. Make doneTotal optional in ListIssuesResponse since it's a frontend-only field not returned by the backend API. All reads now use ?? 0 fallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a7afd4b959
commit
ec934f3a8b
7 changed files with 142 additions and 49 deletions
|
|
@ -1,6 +1,6 @@
|
|||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { useMemo, type ReactNode } from "react";
|
||||
import { EyeOff, MoreHorizontal, Plus } from "lucide-react";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
import { useDroppable } from "@dnd-kit/core";
|
||||
|
|
@ -23,10 +23,12 @@ export function BoardColumn({
|
|||
status,
|
||||
issueIds,
|
||||
issueMap,
|
||||
footer,
|
||||
}: {
|
||||
status: IssueStatus;
|
||||
issueIds: string[];
|
||||
issueMap: Map<string, Issue>;
|
||||
footer?: ReactNode;
|
||||
}) {
|
||||
const cfg = STATUS_CONFIG[status];
|
||||
const { setNodeRef, isOver } = useDroppable({ id: status });
|
||||
|
|
@ -106,6 +108,7 @@ export function BoardColumn({
|
|||
No issues
|
||||
</p>
|
||||
)}
|
||||
{footer}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ import {
|
|||
type DragOverEvent,
|
||||
} from "@dnd-kit/core";
|
||||
import { arrayMove } from "@dnd-kit/sortable";
|
||||
import { Eye, MoreHorizontal } from "lucide-react";
|
||||
import { Eye, Loader2, MoreHorizontal } from "lucide-react";
|
||||
import type { Issue, IssueStatus } from "@/shared/types";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { useLoadMoreDoneIssues } from "@core/issues/mutations";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuTrigger,
|
||||
|
|
@ -110,6 +111,7 @@ export function BoardView({
|
|||
}) {
|
||||
const sortBy = useViewStore((s) => s.sortBy);
|
||||
const sortDirection = useViewStore((s) => s.sortDirection);
|
||||
const { loadMore, hasMore, isLoading: loadingMore } = useLoadMoreDoneIssues();
|
||||
|
||||
// --- Drag state ---
|
||||
const [activeIssue, setActiveIssue] = useState<Issue | null>(null);
|
||||
|
|
@ -272,6 +274,21 @@ export function BoardView({
|
|||
status={status}
|
||||
issueIds={columns[status] ?? []}
|
||||
issueMap={issueMapRef.current}
|
||||
footer={
|
||||
status === "done" && hasMore ? (
|
||||
<button
|
||||
type="button"
|
||||
className="mt-1 flex w-full items-center justify-center gap-1.5 rounded-md py-2 text-xs text-muted-foreground hover:bg-accent/60 transition-colors disabled:opacity-50"
|
||||
onClick={loadMore}
|
||||
disabled={loadingMore}
|
||||
>
|
||||
{loadingMore ? (
|
||||
<Loader2 className="size-3 animate-spin" />
|
||||
) : null}
|
||||
{loadingMore ? "Loading..." : "Load more"}
|
||||
</button>
|
||||
) : undefined
|
||||
}
|
||||
/>
|
||||
))}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue