feat: add delete functionality for condition branches in node forms and improve edge filtering in workflow normalization
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Field, type WorkflowNodeRegistry } from "@flowgram.ai/free-layout-editor"
|
||||
import { PlusIcon } from "lucide-react"
|
||||
import { PlusIcon, XIcon } from "lucide-react"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import type { AIWorkflowNodeSpec } from "@/lib/api/admin"
|
||||
@@ -99,6 +99,9 @@ function ConditionNodeForm({ fallbackTitle }: { fallbackTitle: string }) {
|
||||
branches: ensureConditionBranches(nextBranches),
|
||||
})
|
||||
}
|
||||
const deleteBranch = (branchId: string) => {
|
||||
updateBranches(branches.filter((branch) => branch.id !== branchId))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="px-4 py-3">
|
||||
@@ -114,6 +117,19 @@ function ConditionNodeForm({ fallbackTitle }: { fallbackTitle: string }) {
|
||||
<span className="shrink-0 rounded-sm bg-[#e7e9f3] px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">
|
||||
{branch.default ? "else" : index === 0 ? "if" : "elseif"}
|
||||
</span>
|
||||
{branch.default ? null : (
|
||||
<button
|
||||
type="button"
|
||||
className="flex size-5 shrink-0 items-center justify-center rounded-sm text-muted-foreground transition-colors hover:bg-destructive/10 hover:text-destructive"
|
||||
aria-label={`删除条件 ${branch.name || branch.id}`}
|
||||
onClick={(event) => {
|
||||
event.stopPropagation()
|
||||
deleteBranch(branch.id)
|
||||
}}
|
||||
>
|
||||
<XIcon className="size-3.5" />
|
||||
</button>
|
||||
)}
|
||||
<span
|
||||
data-port-id={branch.id}
|
||||
data-port-type="output"
|
||||
|
||||
@@ -274,15 +274,17 @@ function ConditionBranchesEditor({
|
||||
className="h-8"
|
||||
onChange={(event) => onChange({ ...branch, name: event.target.value })}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 px-2 text-xs text-muted-foreground hover:text-destructive"
|
||||
onClick={() => onDelete(branch.id)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
{branch.default ? null : (
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-8 px-2 text-xs text-muted-foreground hover:text-destructive"
|
||||
onClick={() => onDelete(branch.id)}
|
||||
>
|
||||
删除
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="space-y-1.5">
|
||||
|
||||
@@ -241,18 +241,32 @@ export function deleteConditionBranch(
|
||||
return definition
|
||||
}
|
||||
const config = normalizeNodeConfig(node.data?.config)
|
||||
return updateWorkflowNodeData(definition, nodeId, {
|
||||
const nextDefinition = updateWorkflowNodeData(definition, nodeId, {
|
||||
...(node.data ?? {}),
|
||||
config: {
|
||||
...config,
|
||||
branches: (config.branches ?? []).filter((branch) => branch.id !== branchId),
|
||||
},
|
||||
})
|
||||
return {
|
||||
...nextDefinition,
|
||||
edges: nextDefinition.edges.filter((edge) => !(edge.sourceNodeID === nodeId && edge.sourcePortID === branchId)),
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeConditionPortsForFlowgram(
|
||||
definition: AIWorkflowDefinition
|
||||
): AIWorkflowDefinition {
|
||||
const branchIdsByNodeId = new Map<string, Set<string>>()
|
||||
for (const node of definition.nodes) {
|
||||
if (node.type !== "condition") {
|
||||
continue
|
||||
}
|
||||
const config = normalizeNodeConfig(node.data?.config)
|
||||
const branches = ensureConditionBranches(config.branches ?? [])
|
||||
branchIdsByNodeId.set(node.id, new Set(branches.map((branch) => branch.id)))
|
||||
}
|
||||
|
||||
return {
|
||||
...definition,
|
||||
nodes: definition.nodes.map((node) => {
|
||||
@@ -271,7 +285,13 @@ export function normalizeConditionPortsForFlowgram(
|
||||
},
|
||||
}
|
||||
}),
|
||||
edges: definition.edges.map((edge) => {
|
||||
edges: definition.edges.filter((edge) => {
|
||||
if (!edge.sourcePortID) {
|
||||
return true
|
||||
}
|
||||
const branchIds = branchIdsByNodeId.get(edge.sourceNodeID)
|
||||
return !branchIds || branchIds.has(edge.sourcePortID)
|
||||
}).map((edge) => {
|
||||
const source = definition.nodes.find((node) => node.id === edge.sourceNodeID)
|
||||
if (!source || source.type !== "condition" || edge.sourcePortID) {
|
||||
return edge
|
||||
|
||||
Reference in New Issue
Block a user