From c3a1c1b4692e2bee56b0e0cb3a848d177ce480df Mon Sep 17 00:00:00 2001 From: mlogclub Date: Sat, 11 Apr 2026 14:27:18 +0800 Subject: [PATCH] feat: implement dynamic filter dropdown for conversation options --- web/app/(console)/conversations/page.tsx | 123 +++++++++++++++++++---- 1 file changed, 103 insertions(+), 20 deletions(-) diff --git a/web/app/(console)/conversations/page.tsx b/web/app/(console)/conversations/page.tsx index 809c048..d791d9a 100644 --- a/web/app/(console)/conversations/page.tsx +++ b/web/app/(console)/conversations/page.tsx @@ -4,6 +4,7 @@ import { ArrowRightLeftIcon, ChevronLeft, ChevronRight, + ChevronsUpDown, CircleUserRoundIcon, CircleXIcon, FilePlus2Icon, @@ -23,6 +24,8 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, + DropdownMenuRadioGroup, + DropdownMenuRadioItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { @@ -69,6 +72,38 @@ export default function ConversationsPage() { const [createTicketOpen, setCreateTicketOpen] = useState(false); const sidebarPanelRef = useRef(null); const infoPanelRef = useRef(null); + const filterContainerRef = useRef(null); + const filterMeasureRef = useRef(null); + const [showFilterDropdown, setShowFilterDropdown] = useState(false); + + useEffect(() => { + const container = filterContainerRef.current; + const measure = filterMeasureRef.current; + if (!container || !measure) { + return; + } + + const updateFilterMode = () => { + setShowFilterDropdown(measure.scrollWidth > container.clientWidth); + }; + + updateFilterMode(); + + const observer = new ResizeObserver(() => { + updateFilterMode(); + }); + + observer.observe(container); + observer.observe(measure); + + return () => { + observer.disconnect(); + }; + }, []); + + const currentFilterOption = + agentConversationFilterOptions.find((opt) => opt.value === conversationFilter) ?? + agentConversationFilterOptions[0]; useEffect(() => { void loadConversations().catch((error) => { toast.error(error instanceof Error ? error.message : "加载会话列表失败"); @@ -122,27 +157,75 @@ export default function ConversationsPage() { const renderConversationSidebar = (opts?: { onListAfterSelect?: () => void }) => (
- - setConversationFilter(value as AgentConversationFilterKey) - } - className="min-w-0 flex-1 gap-0" - > - - {agentConversationFilterOptions.map((opt) => ( - + {showFilterDropdown ? ( + + + } > - {opt.label} - - ))} - - + {currentFilterOption?.label ?? "筛选状态"} + + + + + setConversationFilter(value as AgentConversationFilterKey) + } + > + {agentConversationFilterOptions.map((opt) => ( + + {opt.label} + + ))} + + + + ) : ( + + setConversationFilter(value as AgentConversationFilterKey) + } + className="min-w-0 flex-1 gap-0" + > + + {agentConversationFilterOptions.map((opt) => ( + + {opt.label} + + ))} + + + )} + +