diff --git a/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx b/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx new file mode 100644 index 00000000..b1e71d7e --- /dev/null +++ b/frontend-web/src/components/workspace/agents/agent-module-settings-dialog.tsx @@ -0,0 +1,174 @@ +"use client"; + +import { Bot, Loader2 } from "lucide-react"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { toast } from "sonner"; +import { Select } from "tdesign-react"; + +import { Button } from "@/components/ui/button"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { useAgents } from "@/core/agents"; +import type { Agent } from "@/core/agents"; +import { + useAgentModuleConfig, + useUpdateAgentModuleConfig, +} from "@/core/system-settings/hooks"; +import { useTags } from "@/core/tags"; +import { desensitize } from "@/lib/desensitize"; + +/** + * 模块(zzJC / zzXD)类型配置弹窗(需求 0616 #3/#4,admin)。 + * + * 单选一个「类型」(agent 标签,TDesign 下拉框)→ 下方实时预览该类型下的智能体(名称+描述)→ + * 确认后写入后端(``/api/system-settings/agent-modules/{key}``,单选即存单元素列表), + * 该模块左栏据此只展示选中类型的智能体。 + */ +export function AgentModuleSettingsDialog({ + open, + onOpenChange, + moduleKey, + moduleTitle, +}: { + open: boolean; + onOpenChange: (open: boolean) => void; + moduleKey: string; + moduleTitle: string; +}) { + const { data: tags = [] } = useTags("agent"); + const { agents } = useAgents(); + const { data: config } = useAgentModuleConfig(moduleKey); + const { mutate: save, isPending } = useUpdateAgentModuleConfig(moduleKey); + + const [selectedTagId, setSelectedTagId] = useState(); + // Radix Dialog(modal) 把 body 设为 pointer-events:none,TDesign 浮层默认挂到 body 上 + // 会点不动 —— 用 attach 把下拉浮层挂到弹窗内部容器(pointer-events 正常)。 + const selectWrapRef = useRef(null); + + // 每次打开同步当前已保存配置(取首个,单选语义)。 + useEffect(() => { + if (open) setSelectedTagId(config?.tag_ids?.[0]); + }, [open, config?.tag_ids]); + + const tagOptions = useMemo( + () => tags.map((t) => ({ label: t.name, value: t.id })), + [tags], + ); + + // 选中类型下的智能体(含名称 + 描述)。 + const previewAgents = useMemo(() => { + if (!selectedTagId) return []; + return agents.filter((agent) => + (agent.tags ?? []).some((t) => t.id === selectedTagId), + ); + }, [agents, selectedTagId]); + + const handleConfirm = () => { + save(selectedTagId ? [selectedTagId] : [], { + onSuccess: () => { + toast.success(`已更新「${moduleTitle}」展示的类型`); + onOpenChange(false); + }, + onError: (err) => + toast.error(err instanceof Error ? err.message : "保存失败,请重试"), + }); + }; + + return ( + + + + {moduleTitle} · 类型配置 + + 选择该模块左栏展示的智能体类型(标签);下方预览该类型下的智能体。 + + + +
+
+
+ 选择类型 +
+ {tags.length === 0 ? ( +

+ 暂无智能体标签,请先到「标签管理」创建。 +

+ ) : ( +
+