refactor(workflow): simplify edge configuration

This commit is contained in:
Xin Wang
2026-08-03 15:17:01 +08:00
parent dd40bfb90a
commit 8064bb7152
10 changed files with 53 additions and 205 deletions

View File

@@ -3,10 +3,7 @@
import type { Edge } from "@xyflow/react";
import {
Braces,
CircleCheck,
CircleX,
GitBranch,
MessageSquareText,
Plus,
Trash2,
} from "lucide-react";
@@ -38,14 +35,11 @@ export function EdgeSettingsPanel({
sourceType?: string;
isOnlyOutgoing: boolean;
hasOtherDefaultPath: boolean;
onChange: (patch: WorkflowEdgeData) => void;
onChange: (patch: Partial<WorkflowEdgeData>) => void;
}) {
const data = (edge.data ?? { mode: "always", priority: 10 }) as WorkflowEdgeData;
const [mode, setMode] = useState(data.mode ?? "always");
const [priority, setPriority] = useState(data.priority ?? 10);
const [label, setLabel] = useState(data.label ?? "");
const [condition, setCondition] = useState(data.condition ?? "");
const [transitionSpeech, setTransitionSpeech] = useState(data.transitionSpeech ?? "");
const [combinator, setCombinator] = useState<"and" | "or">(
data.expression?.combinator ?? "and",
);
@@ -57,33 +51,22 @@ export function EdgeSettingsPanel({
const publish = ({
nextMode = mode,
nextPriority = priority,
nextLabel = label,
nextCondition = condition,
nextTransitionSpeech = transitionSpeech,
nextCombinator = combinator,
nextRules = rules,
}: {
nextMode?: WorkflowEdgeData["mode"];
nextPriority?: number;
nextLabel?: string;
nextCondition?: string;
nextTransitionSpeech?: string;
nextCombinator?: "and" | "or";
nextRules?: ExpressionRule[];
}) =>
onChange({
mode: nextMode,
priority: nextPriority,
label: nextLabel.trim() ? nextLabel : undefined,
condition: nextMode === "llm" ? nextCondition : undefined,
expression:
nextMode === "expression"
? { combinator: nextCombinator, rules: nextRules }
: undefined,
transitionSpeech: nextTransitionSpeech.trim()
? nextTransitionSpeech
: undefined,
});
const setRule = (index: number, patch: Partial<ExpressionRule>) => {
@@ -94,24 +77,6 @@ export function EdgeSettingsPanel({
publish({ nextRules });
};
const applyActionResultPreset = (status: "ok" | "error") => {
const nextRules: ExpressionRule[] = [
{
variable: "system__last_action_status",
operator: "eq",
value: status,
},
];
setMode("expression");
setCombinator("and");
setRules(nextRules);
publish({
nextMode: "expression",
nextCombinator: "and",
nextRules,
});
};
const parseValue = (value: string): unknown => {
if (value === "true") return true;
if (value === "false") return false;
@@ -159,82 +124,13 @@ export function EdgeSettingsPanel({
Agent
</span>
)}
{sourceType === "action" && (
<div className="rounded-xl border border-hairline bg-canvas-soft p-3">
<div className="mb-2 text-xs text-muted-foreground">
Action
</div>
<div className="flex flex-wrap gap-2">
<Button
type="button"
size="sm"
variant="outline"
className="gap-1.5"
onClick={() => applyActionResultPreset("ok")}
>
<CircleCheck size={14} />
</Button>
<Button
type="button"
size="sm"
variant="outline"
className="gap-1.5"
onClick={() => applyActionResultPreset("error")}
>
<CircleX size={14} />
</Button>
</div>
</div>
)}
{mode !== "always" && (
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground">
</div>
<Input
type="number"
value={priority}
onChange={(event) => {
const nextPriority = Number(event.target.value) || 0;
setPriority(nextPriority);
publish({ nextPriority });
}}
className="border-hairline-strong bg-background text-foreground"
/>
<span className="mt-1.5 block text-xs text-muted-foreground">
</span>
</label>
)}
</SectionCard>
<SectionCard
icon={<Braces size={15} />}
title="触发条件"
description="配置画布标签以及这条连接被命中的条件"
description="配置这条连接被命中的条件"
>
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground">
</div>
<Input
value={label}
maxLength={64}
placeholder="例如:用户想转人工"
onChange={(event) => {
const nextLabel = event.target.value;
setLabel(nextLabel);
publish({ nextLabel });
}}
className="border-hairline-strong bg-background text-foreground placeholder:text-muted-soft"
/>
<span className="mt-1.5 block text-xs text-muted-foreground">
{label.length}/64
</span>
</label>
{mode === "llm" && (
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground">
@@ -376,32 +272,6 @@ export function EdgeSettingsPanel({
</p>
)}
</SectionCard>
<SectionCard
icon={<MessageSquareText size={15} />}
title="过渡语"
description="命中连接后、进入下一节点前播放的固定内容"
>
<label className="block">
<div className="mb-1.5 text-sm font-medium text-foreground">
</div>
<Textarea
rows={3}
value={transitionSpeech}
placeholder="例如:好的,正在为你转接。"
onChange={(event) => {
const nextTransitionSpeech = event.target.value;
setTransitionSpeech(nextTransitionSpeech);
publish({ nextTransitionSpeech });
}}
className="field-sizing-fixed min-h-24 resize-y border-hairline-strong bg-background text-sm text-foreground placeholder:text-muted-soft"
/>
<span className="mt-1.5 block text-xs text-muted-foreground">
使 TTS
</span>
</label>
</SectionCard>
</div>
);
}