import van from "vanjs-core"; import type { AppController } from "../../app/app-controller"; import "./project-panel.css"; const { button, div, form, h1, input, label, p, span } = van.tags; export function ProjectPanel(controller: AppController): HTMLElement { const selection = controller.selection.val; if (selection.kind === "project-create") return ProjectForm("新建项目", "创建项目", "", "", (name, root) => controller.createProject(name, root), ); if (!("projectId" in selection)) return div(); const project = controller.projects.val.find( (item) => item.id === selection.projectId, ); if (!project) return div({ class: "project-panel" }, p("项目不存在")); if (selection.kind === "project-rename") return ProjectForm( "重命名项目", "保存", project.name, project.workspaceRoot, (name) => controller.renameProject(project.id, name), true, ); if (selection.kind === "project-delete") return div( { class: "project-panel" }, span({ class: "project-icon danger" }, "×"), h1("删除项目?"), p("将删除应用内的项目记录,以及该项目下的对话、消息和运行记录。"), div( { class: "delete-summary" }, p("项目", span(project.name)), p("项目对话", span(`${project.conversationCount} 条`)), p("本地工作目录", span("不会删除、移动或写入")), ), div( { class: "form-actions" }, button( { class: "secondary", onclick: () => controller.startProjectTask(project.id), }, "取消", ), button( { class: "danger-button", onclick: () => void controller.deleteProject(project.id), }, "确认删除", ), ), ); return div( { class: "project-welcome" }, span({ class: "project-icon" }, "▣"), h1(project.name), p(project.workspaceRoot), !project.workspaceAvailable ? p( { class: "project-unavailable" }, "项目目录当前不可用。历史对话仍可查看,但无法开始新任务。", ) : p("开始一段新的项目对话,第一条消息发送后才会创建会话。"), ); } function ProjectForm( title: string, submitLabel: string, initialName: string, initialRoot: string, submit: (name: string, root: string) => Promise, rename = false, ): HTMLElement { const name = van.state(initialName); const root = van.state(initialRoot); return form( { class: "project-panel", onsubmit: (event: Event) => { event.preventDefault(); void submit(name.val, root.val); }, }, span({ class: "project-icon" }, "▣"), h1(title), p( rename ? "修改侧栏中显示的项目名称。" : "选择一个已存在、可读写的本地文件夹作为项目目录。", ), label( "项目名称", input({ value: name, maxlength: 80, autofocus: true, oninput: (event: Event) => (name.val = (event.target as HTMLInputElement).value), }), ), rename ? null : label( "本地目录(绝对路径)", input({ value: root, placeholder: "/Users/你的名字/Projects/项目名", oninput: (event: Event) => (root.val = (event.target as HTMLInputElement).value), }), ), div( { class: "form-actions" }, button( { class: "primary", type: "submit", disabled: () => !name.val.trim() || (!rename && !root.val.trim()), }, submitLabel, ), ), ); }