diff --git a/ui/src/components/IssuesList.tsx b/ui/src/components/IssuesList.tsx index 9ebf80e0..ef0362d5 100644 --- a/ui/src/components/IssuesList.tsx +++ b/ui/src/components/IssuesList.tsx @@ -17,7 +17,7 @@ import { Input } from "@/components/ui/input"; import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover"; import { Checkbox } from "@/components/ui/checkbox"; import { Collapsible, CollapsibleTrigger, CollapsibleContent } from "@/components/ui/collapsible"; -import { CircleDot, Plus, Filter, ArrowUpDown, Layers, Check, X, ChevronRight, List, Columns3, User, Search } from "lucide-react"; +import { CircleDot, Plus, Filter, ArrowUpDown, Layers, Check, X, ChevronRight, List, Columns3, User, Search, ArrowDown } from "lucide-react"; import { KanbanBoard } from "./KanbanBoard"; import type { Issue } from "@paperclipai/shared"; @@ -218,6 +218,24 @@ export function IssuesList({ const activeFilterCount = countActiveFilters(viewState); + const [showScrollBottom, setShowScrollBottom] = useState(false); + useEffect(() => { + const el = document.getElementById("main-content"); + if (!el) return; + const check = () => { + const distanceFromBottom = el.scrollHeight - el.scrollTop - el.clientHeight; + setShowScrollBottom(distanceFromBottom > 300); + }; + check(); + el.addEventListener("scroll", check, { passive: true }); + return () => el.removeEventListener("scroll", check); + }, [filtered.length]); + + const scrollToBottom = useCallback(() => { + const el = document.getElementById("main-content"); + if (el) el.scrollTo({ top: el.scrollHeight, behavior: "smooth" }); + }, []); + const groupedContent = useMemo(() => { if (viewState.groupBy === "none") { return [{ key: "__all", label: null as string | null, items: filtered }]; @@ -706,6 +724,15 @@ export function IssuesList({ )) )} + {showScrollBottom && ( + + )} ); }