feat(agent-sidebar): 「智能体」区支持收起/展开
标题栏改为可折叠头(chevron 切换),收起后仅留标题栏并隐藏来源下拉/搜索/列表, 下方「最近的对话」占满剩余空间;收起状态持久化到 localStorage。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
8cc2650e98
commit
e906a911b2
1 file changed
+50
-8
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Bot,
|
Bot,
|
||||||
|
ChevronDown,
|
||||||
Download,
|
Download,
|
||||||
FileJson,
|
FileJson,
|
||||||
FileText,
|
FileText,
|
||||||
@@ -127,6 +128,18 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [searchInput]);
|
}, [searchInput]);
|
||||||
|
|
||||||
|
// 「智能体」区可收起(持久化);收起后只留标题栏,下方「最近的对话」占满剩余空间。
|
||||||
|
const [agentsCollapsed, setAgentsCollapsed] = useState(
|
||||||
|
() =>
|
||||||
|
typeof window !== "undefined" &&
|
||||||
|
localStorage.getItem("agent-chat-sidebar:agents-collapsed") === "true",
|
||||||
|
);
|
||||||
|
const toggleAgents = () =>
|
||||||
|
setAgentsCollapsed((v) => {
|
||||||
|
localStorage.setItem("agent-chat-sidebar:agents-collapsed", String(!v));
|
||||||
|
return !v;
|
||||||
|
});
|
||||||
|
|
||||||
// 若所选广场被管理员删除,回退到「我的」,避免指向不存在的广场。
|
// 若所选广场被管理员删除,回退到「我的」,避免指向不存在的广场。
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (
|
if (
|
||||||
@@ -151,7 +164,32 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
return (
|
return (
|
||||||
// 配色与 AgentModuleSidebar 一致:浅色白底,深蓝主题半透明深蓝玻璃面板。
|
// 配色与 AgentModuleSidebar 一致:浅色白底,深蓝主题半透明深蓝玻璃面板。
|
||||||
<aside className="flex h-full w-(--sidebar-width) shrink-0 flex-col overflow-hidden border-r border-border/70 bg-white text-foreground backdrop-blur-md dark:border-[#2b8ffe]/45 dark:bg-[#032650]/80">
|
<aside className="flex h-full w-(--sidebar-width) shrink-0 flex-col overflow-hidden border-r border-border/70 bg-white text-foreground backdrop-blur-md dark:border-[#2b8ffe]/45 dark:bg-[#032650]/80">
|
||||||
{/* 顶部:作用域下拉(我的 / 各广场)+ 智能体名称模糊搜索 */}
|
{/* 智能体(上半,可收起)。展开时:标题栏 + 来源下拉/名称搜索 + 列表;
|
||||||
|
收起时只留标题栏,下方「最近的对话」占满剩余空间。 */}
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex flex-col",
|
||||||
|
agentsCollapsed ? "shrink-0" : "min-h-0 flex-[3]",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={toggleAgents}
|
||||||
|
className="text-foreground/80 hover:bg-accent/40 flex shrink-0 items-center justify-between border-b border-border/60 px-3 py-2.5 text-[12px] font-semibold transition-colors select-none"
|
||||||
|
title={agentsCollapsed ? "展开智能体" : "收起智能体"}
|
||||||
|
>
|
||||||
|
<span>智能体</span>
|
||||||
|
<ChevronDown
|
||||||
|
className={cn(
|
||||||
|
"text-muted-foreground size-4 shrink-0 transition-transform duration-200",
|
||||||
|
agentsCollapsed && "-rotate-90",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
{!agentsCollapsed && (
|
||||||
|
<>
|
||||||
|
{/* 来源下拉(我的 / 各广场)+ 智能体名称模糊搜索 */}
|
||||||
<div className="shrink-0 space-y-2 border-b border-border/60 px-3 py-2.5">
|
<div className="shrink-0 space-y-2 border-b border-border/60 px-3 py-2.5">
|
||||||
<Select value={scope} onValueChange={setScope}>
|
<Select value={scope} onValueChange={setScope}>
|
||||||
<SelectTrigger className="h-9 w-full text-sm" title="切换智能体来源">
|
<SelectTrigger className="h-9 w-full text-sm" title="切换智能体来源">
|
||||||
@@ -189,11 +227,8 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 智能体列表(上半,独立滚动) */}
|
{/* 智能体列表(独立滚动) */}
|
||||||
<div className="flex min-h-0 flex-[3] flex-col overflow-y-auto px-2 py-3">
|
<div className="flex min-h-0 flex-1 flex-col overflow-y-auto px-2 py-3">
|
||||||
<h2 className="mb-1 px-3 py-1 text-[11px] font-semibold tracking-[0.04em] text-muted-foreground/80 select-none">
|
|
||||||
智能体
|
|
||||||
</h2>
|
|
||||||
{isLoading && agents.length === 0 ? (
|
{isLoading && agents.length === 0 ? (
|
||||||
<div className="text-muted-foreground flex h-24 items-center justify-center gap-2 text-xs">
|
<div className="text-muted-foreground flex h-24 items-center justify-center gap-2 text-xs">
|
||||||
<Loader2 className="size-3.5 animate-spin" />
|
<Loader2 className="size-3.5 animate-spin" />
|
||||||
@@ -201,7 +236,11 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
</div>
|
</div>
|
||||||
) : agents.length === 0 ? (
|
) : agents.length === 0 ? (
|
||||||
<p className="px-3 py-1.5 text-xs text-muted-foreground/70">
|
<p className="px-3 py-1.5 text-xs text-muted-foreground/70">
|
||||||
{search ? "未找到匹配的智能体" : isMine ? "暂无智能体" : "该广场暂无智能体"}
|
{search
|
||||||
|
? "未找到匹配的智能体"
|
||||||
|
: isMine
|
||||||
|
? "暂无智能体"
|
||||||
|
: "该广场暂无智能体"}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : (
|
||||||
<div
|
<div
|
||||||
@@ -258,7 +297,7 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
{total > agents.length && (
|
{total > agents.length && (
|
||||||
<Link
|
<Link
|
||||||
href={`${routeBase}/agents`}
|
href={`${routeBase}/agents`}
|
||||||
className="text-muted-foreground hover:text-foreground mt-0.5 rounded-lg px-3 py-1.5 text-center text-xs transition-colors hover:bg-accent/50"
|
className="text-muted-foreground hover:text-foreground hover:bg-accent/50 mt-0.5 rounded-lg px-3 py-1.5 text-center text-xs transition-colors"
|
||||||
>
|
>
|
||||||
共 {total} 个,查看全部 →
|
共 {total} 个,查看全部 →
|
||||||
</Link>
|
</Link>
|
||||||
@@ -266,6 +305,9 @@ export function AgentChatSidebar({ activeAgentId }: { activeAgentId?: string })
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* 最近的对话(下半,独立滚动)—— 参考首页通用问答左栏 */}
|
{/* 最近的对话(下半,独立滚动)—— 参考首页通用问答左栏 */}
|
||||||
<RecentChatsPane activeAgentId={activeAgentId} />
|
<RecentChatsPane activeAgentId={activeAgentId} />
|
||||||
|
|||||||
Reference in new issue
Block a user