import { Folder, FolderPlus, Pencil, Trash2, X } from "lucide-react"; import { useId, useRef, useState, type RefObject } from "react"; import { Button } from "@/shared/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/shared/ui/dialog"; import { Input } from "@/shared/ui/input"; import type { AgentTopic } from "../api/client"; type TopicView = { kind: "list" | "create" } | { kind: "rename" | "delete"; topic: AgentTopic }; type Props = { open: boolean; initialMode: "create" | "manage"; onOpenChange: (open: boolean) => void; triggerRef: RefObject; topics: AgentTopic[]; onCreate: (name: string) => Promise; onRename: (id: string, name: string) => Promise; onDelete: (id: string) => Promise; }; export function AgentTopicDialog({ open, initialMode, onOpenChange, triggerRef, topics, onCreate, onRename, onDelete }: Props) { const [view, setView] = useState({ kind: initialMode === "create" ? "create" : "list" }); const [name, setName] = useState(""); const [busy, setBusy] = useState(false); const [error, setError] = useState(); const fieldId = useId(); const inputRef = useRef(null); const newTopicRef = useRef(null); const isForm = view.kind === "create" || view.kind === "rename"; const title = view.kind === "create" ? "新建主题" : view.kind === "rename" ? "重命名主题" : view.kind === "delete" ? "删除主题" : "管理主题"; const description = view.kind === "create" ? "将相关事件、问题和对话整理到同一主题。" : view.kind === "rename" ? "修改名称不会影响主题中的现有会话。" : view.kind === "delete" ? "仅删除分类,其中的会话会保留在未分类中。" : `当前项目共有 ${topics.length} 个主题,用于整理相关事件与问题。`; const changeView = (next: TopicView) => { setError(undefined); setName(next.kind === "rename" ? next.topic.name : ""); setView(next); }; const perform = async (action: () => Promise, done: () => void) => { setBusy(true); setError(undefined); try { await action(); done(); } catch (reason) { setError(reason instanceof Error ? reason.message : "主题操作失败,请重试"); } finally { setBusy(false); } }; const cancel = () => initialMode === "create" ? onOpenChange(false) : changeView({ kind: "list" }); const footerClass = "gap-2 px-6 pb-6 sm:gap-0"; return { if (!busy) onOpenChange(next); }}> { event.preventDefault(); (inputRef.current ?? newTopicRef.current)?.focus(); }} onCloseAutoFocus={(event) => { event.preventDefault(); triggerRef.current?.focus(); }}> {title} {description} {isForm ?
{ event.preventDefault(); if (!name.trim() || busy) return; void perform(() => view.kind === "rename" ? onRename(view.topic.id, name.trim()) : onCreate(name.trim()), () => view.kind === "create" ? onOpenChange(false) : changeView({ kind: "list" })); }}>
setName(event.target.value)} placeholder="例如:城南压力异常排查" />

名称最多 80 个字符。

{error ?

{error}

: null}
: view.kind === "delete" ? <>

确认删除“{view.topic.name}”?

{error ?

{error}

: null}
: <>
{topics.length === 0 ?

还没有主题,可以新建一个来整理对话。

: topics.map((topic) => (
))}
}
; }