diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx b/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx index 7f63fea38e..0ff9a86e9f 100644 --- a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx +++ b/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-card.tsx @@ -26,44 +26,6 @@ export function DeployedWorkflowCard({ const [showingDeployed, setShowingDeployed] = useState(true) const workflowToShow = showingDeployed ? deployedWorkflowState : currentWorkflowState const activeWorkflowId = useWorkflowRegistry((state) => state.activeWorkflowId) - - // Create sanitized workflow state - // const sanitizedWorkflowState = useMemo(() => { - // if (!workflowToShow) return null; - - // // Verify the workflow ID matches if metadata exists - // if (workflowToShow._metadata?.workflowId && - // workflowToShow._metadata.workflowId !== activeWorkflowId) { - // logger.warn('Workflow ID mismatch detected in card', { - // stateWorkflowId: workflowToShow._metadata.workflowId, - // activeWorkflowId, - // isDeployed: showingDeployed - // }); - // } - - // // Filter out invalid blocks and make deep clone to avoid reference issues - // const result = { - // blocks: Object.fromEntries( - // Object.entries(workflowToShow.blocks || {}) - // .filter(([_, block]) => block && block.type) // Filter out invalid blocks - // .map(([id, block]) => { - // // Deep clone the block to avoid any reference sharing - // const clonedBlock = structuredClone(block); - // return [id, clonedBlock]; - // }) - // ), - // edges: workflowToShow.edges ? structuredClone(workflowToShow.edges) : [], - // loops: workflowToShow.loops ? structuredClone(workflowToShow.loops) : {}, - // _metadata: { - // ...(workflowToShow._metadata || {}), - // workflowId: activeWorkflowId, - // viewType: showingDeployed ? 'deployed' : 'current', - // sanitizedAt: Date.now() - // } - // }; - - // return result; - // }, [workflowToShow, showingDeployed, activeWorkflowId]); // // Generate a unique key for the workflow preview const previewKey = useMemo(() => { diff --git a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx b/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx index 1ec70c9a39..fb05a5518d 100644 --- a/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx +++ b/apps/sim/app/w/[id]/components/control-bar/components/deployment-controls/components/deployed-workflow-modal.tsx @@ -62,90 +62,6 @@ export function DeployedWorkflowModal({ loops: state.loops, parallels: state.parallels, })) - - // Sanitize states to ensure no invalid blocks are passed to components - // const sanitizedCurrentState = useMemo(() => { - // if (!currentWorkflowState) return undefined; - - // const result = { - // blocks: Object.fromEntries( - // Object.entries(currentWorkflowState.blocks || {}) - // .filter(([_, block]) => block && block.type) - // .map(([id, block]) => { - // // Deep clone the block to avoid any reference sharing - // return [id, structuredClone(block)]; - // }) - // ), - // edges: currentWorkflowState.edges ? [...currentWorkflowState.edges] : [], - // loops: currentWorkflowState.loops ? {...currentWorkflowState.loops} : {}, - // _metadata: { - // workflowId: activeWorkflowId || undefined, - // type: 'current', - // timestamp: Date.now() - // } - // }; - - // return result; - // }, [currentWorkflowState, activeWorkflowId]); - - // const sanitizedDeployedState = useMemo(() => { - // if (!deployedWorkflowState) return { - // blocks: {}, - // edges: [], - // loops: {}, - // _metadata: { - // workflowId: activeWorkflowId || undefined, - // type: 'deployed-empty', - // timestamp: Date.now() - // } - // }; - - // const stateWorkflowId = deployedWorkflowState?._metadata?.workflowId; - // const stateMatch = stateWorkflowId === activeWorkflowId; - - // // Check if the deployed state belongs to the current workflow - // // This is a critical safety check to prevent showing the wrong workflow state - // if (stateWorkflowId && !stateMatch) { - // logger.error('Attempted to use deployed state from wrong workflow', { - // stateWorkflowId, - // activeWorkflowId, - // }); - - // // Return empty state to prevent showing wrong workflow data - // return { - // blocks: {}, - // edges: [], - // loops: {}, - // _metadata: { - // workflowId: activeWorkflowId || undefined, - // type: 'deployed-empty-mismatch', - // originalWorkflowId: stateWorkflowId, - // timestamp: Date.now() - // } - // }; - // } - - // const result = { - // blocks: Object.fromEntries( - // Object.entries(deployedWorkflowState.blocks || {}) - // .filter(([_, block]) => block && block.type) - // .map(([id, block]) => { - // // Deep clone the block to avoid any reference sharing - // return [id, structuredClone(block)]; - // }) - // ), - // edges: deployedWorkflowState.edges ? [...deployedWorkflowState.edges] : [], - // loops: deployedWorkflowState.loops ? {...deployedWorkflowState.loops} : {}, - // _metadata: { - // ...(deployedWorkflowState._metadata || {}), - // workflowId: deployedWorkflowState._metadata?.workflowId || activeWorkflowId || undefined, - // type: 'deployed-sanitized', - // sanitizedAt: Date.now() - // } - // }; - - // return result; - // }, [deployedWorkflowState, activeWorkflowId]); const handleRevert = () => { if (activeWorkflowId) { diff --git a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx b/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx index f954a04d13..0adcf93173 100644 --- a/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx +++ b/apps/sim/app/w/[id]/components/workflow-block/components/sub-block/sub-block.tsx @@ -218,13 +218,20 @@ export function SubBlock({ /> ) case 'webhook-config': + // For webhook config, we need to construct the value from multiple subblock values + const webhookValue = isPreview && subBlockValues ? { + webhookProvider: subBlockValues['webhookProvider']?.value, + webhookPath: subBlockValues['webhookPath']?.value, + providerConfig: subBlockValues['providerConfig']?.value, + } : previewValue + return ( ) case 'schedule-config': diff --git a/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx b/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx index 393c301eba..2ec26f026e 100644 --- a/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx +++ b/apps/sim/app/w/[id]/components/workflow-block/workflow-block.tsx @@ -200,15 +200,21 @@ export function WorkflowBlock({ id, data }: NodeProps) { let currentRow: SubBlockConfig[] = [] let currentRowWidth = 0 - // Get merged state for this block - const blocks = useWorkflowStore.getState().blocks - const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId || undefined - const isAdvancedMode = useWorkflowStore((state) => state.blocks[id]?.advancedMode ?? false) + // Get the appropriate state for conditional evaluation + let stateToUse: Record = {} - // If in preview mode with direct subBlockValues, use those instead of global state - const mergedState = data.isPreview && data.subBlockValues - ? { [blockId]: { subBlocks: data.subBlockValues } } - : mergeSubblockState(blocks, activeWorkflowId, blockId) + if (data.isPreview && data.subBlockValues) { + // In preview mode, use the preview values + stateToUse = data.subBlockValues + } else { + // In normal mode, use merged state + const blocks = useWorkflowStore.getState().blocks + const activeWorkflowId = useWorkflowRegistry.getState().activeWorkflowId || undefined + const mergedState = mergeSubblockState(blocks, activeWorkflowId, blockId)[blockId] + stateToUse = mergedState?.subBlocks || {} + } + + const isAdvancedMode = useWorkflowStore((state) => state.blocks[id]?.advancedMode ?? false) // Filter visible blocks and those that meet their conditions const visibleSubBlocks = subBlocks.filter((block) => { @@ -217,10 +223,10 @@ export function WorkflowBlock({ id, data }: NodeProps) { // If there's no condition, the block should be shown if (!block.condition) return true - // Get the values of the fields this block depends on from merged state - const fieldValue = mergedState?.subBlocks[block.condition.field]?.value + // Get the values of the fields this block depends on from the appropriate state + const fieldValue = stateToUse[block.condition.field]?.value const andFieldValue = block.condition.and - ? mergedState?.subBlocks[block.condition.and.field]?.value + ? stateToUse[block.condition.and.field]?.value : undefined // Check if the condition value is an array