From c32b54f588db79a501db456e6075a337dee8ed26 Mon Sep 17 00:00:00 2001 From: Dries Augustyns Date: Wed, 11 Mar 2026 15:30:00 +0100 Subject: [PATCH] fix: Prevent switching if nodes are attached to multi-branch --- apps/web/src/pages/workflows/[id].tsx | 96 ++++++++++++++++++++++----- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/apps/web/src/pages/workflows/[id].tsx b/apps/web/src/pages/workflows/[id].tsx index b380f7f..14b2f95 100644 --- a/apps/web/src/pages/workflows/[id].tsx +++ b/apps/web/src/pages/workflows/[id].tsx @@ -301,9 +301,7 @@ export default function WorkflowEditorPage() { const branch = (config as any).branches?.find((b: any) => b.id === id); return branch?.name || id; }); - errors.push( - `"${step.name}" condition step is missing connections for: ${branchNames.join(', ')}`, - ); + errors.push(`"${step.name}" condition step is missing connections for: ${branchNames.join(', ')}`); } else { errors.push(`"${step.name}" condition step must have both YES and NO branches connected`); } @@ -1871,6 +1869,56 @@ function EditStepDialog({step, workflowId, open, onOpenChange, onSuccess}: EditS const [conditionMode, setConditionMode] = useState<'binary' | 'multi'>(() => { return config?.mode === 'multi' ? 'multi' : 'binary'; }); + + // Helper to check if switching from multi to binary is safe + const hasMultiBranchConnections = () => { + if (step.type !== 'CONDITION') return false; + if (config?.mode !== 'multi') return false; + + const transitions = (step as any).outgoingTransitions || []; + // Check if any transition has a branch that's not 'yes' or 'no' (multi-branch specific) + return transitions.some((t: any) => { + const condition = t.condition; + if (condition && typeof condition === 'object' && 'branch' in condition) { + const branch = condition.branch as string; + // Multi-branch specific branches (not the simple if/else branches) + return branch !== 'yes' && branch !== 'no'; + } + return false; + }); + }; + + // Helper to check if switching from binary to multi is safe + const hasBinaryConnections = () => { + if (step.type !== 'CONDITION') return false; + if (config?.mode === 'multi') return false; + + const transitions = (step as any).outgoingTransitions || []; + // Check if any transition has 'yes' or 'no' branches (binary-specific) + return transitions.some((t: any) => { + const condition = t.condition; + if (condition && typeof condition === 'object' && 'branch' in condition) { + const branch = condition.branch as string; + return branch === 'yes' || branch === 'no'; + } + return false; + }); + }; + + // Safe mode change handler + const handleModeChange = (newMode: 'binary' | 'multi') => { + // If switching from multi to binary, check for multi-branch connections + if (conditionMode === 'multi' && newMode === 'binary' && hasMultiBranchConnections()) { + // Don't allow the switch - user needs to disconnect branches first + return; + } + // If switching from binary to multi, check for binary connections + if (conditionMode === 'binary' && newMode === 'multi' && hasBinaryConnections()) { + // Don't allow the switch - user needs to disconnect branches first + return; + } + setConditionMode(newMode); + }; const [conditionField, setConditionField] = useState(() => { if (!config?.field) return ''; // Handle case where field is an object like {field: 'email', type: 'string'} (legacy format) @@ -2402,22 +2450,28 @@ function EditStepDialog({step, workflowId, open, onOpenChange, onSuccess}: EditS