feat(workflow): edit node names in drawer header

This commit is contained in:
Xin Wang
2026-08-03 10:52:25 +08:00
parent cff591aa13
commit 2e84de0798
5 changed files with 48 additions and 45 deletions

View File

@@ -90,9 +90,15 @@ export function AssistantIdentity({ assistantId }: { assistantId: string | null
export function EditableTitle({
value,
onChange,
placeholder = "未命名助手",
editLabel = "助手名称",
variant = "page",
}: {
value: string;
onChange: (value: string) => void;
placeholder?: string;
editLabel?: string;
variant?: "page" | "panel";
}) {
const [editing, setEditing] = useState(false);
const [draft, setDraft] = useState(value);
@@ -134,7 +140,12 @@ export function EditableTitle({
setEditing(false);
}
}}
className="font-display display-sm w-[min(60vw,420px)] border-b border-primary bg-transparent text-ink outline-none"
aria-label={`修改${editLabel}`}
className={
variant === "panel"
? "min-w-0 flex-1 border-b border-primary bg-transparent px-3 py-1.5 text-sm font-medium text-foreground outline-none"
: "font-display display-sm w-[min(60vw,420px)] border-b border-primary bg-transparent text-ink outline-none"
}
/>
);
}
@@ -143,14 +154,24 @@ export function EditableTitle({
<button
type="button"
onClick={startEdit}
title="点击修改助手名称"
className="group -mx-2 flex min-w-0 items-center gap-2 rounded-lg px-2 py-1 text-left transition-colors hover:bg-surface-strong"
title={`点击修改${editLabel}`}
className={
variant === "panel"
? "group flex min-w-0 items-center gap-2 rounded-lg px-3 py-1.5 text-left transition-colors hover:bg-surface-strong"
: "group -mx-2 flex min-w-0 items-center gap-2 rounded-lg px-2 py-1 text-left transition-colors hover:bg-surface-strong"
}
>
<span className="font-display display-sm truncate text-ink">
{value || "未命名助手"}
<span
className={
variant === "panel"
? "truncate text-sm font-medium text-foreground"
: "font-display display-sm truncate text-ink"
}
>
{value || placeholder}
</span>
<Pencil
size={16}
size={variant === "panel" ? 14 : 16}
className="shrink-0 text-muted-soft opacity-0 transition-opacity group-hover:opacity-100"
/>
</button>

View File

@@ -25,6 +25,7 @@ import {
useState,
} from "react";
import { EditableTitle } from "@/components/assistant-editor/editor-controls";
import { Button } from "@/components/ui/button";
import {
Tooltip,
@@ -680,7 +681,22 @@ export function WorkflowCanvas({
? "工作流设置"
: editingEdge
? "编辑连接条件"
: `编辑${editingSpec?.displayName ?? "节点"}`
: editingNode && editingSpec
? (
<EditableTitle
value={
(editingNode.data as WorkflowNodeData).name ??
""
}
placeholder={editingSpec.displayName}
editLabel="节点名称"
variant="panel"
onChange={(name) =>
updateNodeData(editingNode.id, { name })
}
/>
)
: "编辑节点"
}
closeLabel={
dynamicVariablesOpen
@@ -719,7 +735,7 @@ export function WorkflowCanvas({
/>
) : editingNode && editingSpec ? (
<NodeSettingsPanel
key={editingNode.id}
key={`${editingNode.id}:${(editingNode.data as WorkflowNodeData).name ?? ""}`}
panel
spec={editingSpec}
data={editingNode.data as WorkflowNodeData}

View File

@@ -9,7 +9,7 @@ export function WorkflowSidePanel({
onClose,
children,
}: {
title?: string;
title?: ReactNode;
closeLabel?: string;
onClose?: () => void;
children: ReactNode;
@@ -27,7 +27,7 @@ export function WorkflowSidePanel({
>
<X size={16} />
</button>
<h2 className="min-w-0 truncate text-sm font-medium text-foreground">
<h2 className="min-w-0 flex-1 truncate text-sm font-medium text-foreground">
{title}
</h2>
</div>

View File

@@ -7,7 +7,6 @@ import {
MessageSquareText,
Settings2,
Sparkles,
Tag,
Wrench,
} from "lucide-react";
@@ -15,7 +14,6 @@ import { KnowledgeRetrievalConfigDialog } from "@/components/editor/knowledge-re
import { SectionCard } from "@/components/editor/section-card";
import { VisionConfigSection } from "@/components/editor/vision-config-section";
import { TurnConfigEditor } from "@/components/turn-config-editor";
import { Input } from "@/components/ui/input";
import { Switch } from "@/components/ui/switch";
import { Textarea } from "@/components/ui/textarea";
import type { KnowledgeRetrievalConfig } from "@/lib/api";
@@ -102,21 +100,6 @@ export function AgentNodePanel({
return (
<div className="space-y-3">
<SectionCard
icon={<Tag size={15} />}
title="节点信息"
description="节点在画布上显示的名称"
>
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground"></div>
<Input
value={draft.name ?? ""}
onChange={(event) => set("name", event.target.value)}
className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
/>
</label>
</SectionCard>
<SectionCard
icon={<Settings2 size={15} />}
title="配置范围"

View File

@@ -1,6 +1,6 @@
"use client";
import { Flag, PhoneForwarded, Tag } from "lucide-react";
import { Flag, PhoneForwarded } from "lucide-react";
import { useState } from "react";
import { SectionCard } from "@/components/editor/section-card";
@@ -297,23 +297,6 @@ function WorkflowNodePanelForm({
}) {
return (
<div className="space-y-3">
<SectionCard
icon={<Tag size={15} />}
title="节点信息"
description="节点在画布上显示的名称"
>
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground">
</div>
<Input
value={draft.name ?? ""}
onChange={(event) => set("name", event.target.value)}
className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
/>
</label>
</SectionCard>
{spec.type === "action" && (
<ActionNodePanel
draft={draft}