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