diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts index d2eeb965e2..73cec39ce1 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils.ts @@ -986,9 +986,15 @@ export const applyAutoLayoutSmooth = ( options: LayoutOptions & { animationDuration?: number isSidebarCollapsed?: boolean + onComplete?: (finalPositions: Map) => void } = {} ): void => { - const { animationDuration = 500, isSidebarCollapsed = false, ...layoutOptions } = options + const { + animationDuration = 500, + isSidebarCollapsed = false, + onComplete, + ...layoutOptions + } = options if (!layoutOptions.handleOrientation || layoutOptions.handleOrientation === 'auto') { layoutOptions.handleOrientation = detectHandleOrientation(blocks) @@ -1066,13 +1072,18 @@ export const applyAutoLayoutSmooth = ( if (progress < 1) { requestAnimationFrame(animate) } else { - await resizeLoopNodes() + resizeLoopNodes() const padding = isSidebarCollapsed ? 0.35 : 0.55 - await fitView({ + fitView({ padding, duration: 400, }) + + // Call completion callback with final positions + if (onComplete) { + onComplete(allPositions) + } } } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx index 72606e7f03..d60663083c 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx @@ -231,6 +231,25 @@ const WorkflowContent = React.memo(() => { [getNodes] ) + // Helper function to get orientation config + const getOrientationConfig = useCallback((orientation: string) => { + return orientation === 'vertical' + ? { + // Vertical handles: optimize for top-to-bottom flow + horizontalSpacing: 400, + verticalSpacing: 300, + startX: 200, + startY: 200, + } + : { + // Horizontal handles: optimize for left-to-right flow + horizontalSpacing: 600, + verticalSpacing: 200, + startX: 150, + startY: 300, + } + }, []) + // Auto-layout handler const handleAutoLayout = useCallback(() => { if (Object.keys(blocks).length === 0) return @@ -238,31 +257,13 @@ const WorkflowContent = React.memo(() => { // Detect the predominant handle orientation in the workflow const detectedOrientation = detectHandleOrientation(blocks) - // Optimize spacing based on handle orientation - const orientationConfig = useMemo( - () => - detectedOrientation === 'vertical' - ? { - // Vertical handles: optimize for top-to-bottom flow - horizontalSpacing: 400, - verticalSpacing: 300, - startX: 200, - startY: 200, - } - : { - // Horizontal handles: optimize for left-to-right flow - horizontalSpacing: 600, - verticalSpacing: 200, - startX: 150, - startY: 300, - }, - [detectedOrientation] - ) + // Get spacing configuration based on handle orientation + const orientationConfig = getOrientationConfig(detectedOrientation) applyAutoLayoutSmooth( blocks, edges, - collaborativeUpdateBlockPosition, + storeUpdateBlockPosition, fitView, resizeLoopNodesWrapper, { @@ -271,6 +272,12 @@ const WorkflowContent = React.memo(() => { animationDuration: 500, // Smooth 500ms animation isSidebarCollapsed, handleOrientation: detectedOrientation, // Explicitly set the detected orientation + onComplete: (finalPositions) => { + // Emit collaborative updates for final positions after animation completes + finalPositions.forEach((position, blockId) => { + collaborativeUpdateBlockPosition(blockId, position) + }) + }, } ) @@ -286,10 +293,12 @@ const WorkflowContent = React.memo(() => { }, [ blocks, edges, + storeUpdateBlockPosition, collaborativeUpdateBlockPosition, fitView, isSidebarCollapsed, resizeLoopNodesWrapper, + getOrientationConfig, ]) const debouncedAutoLayout = useCallback(() => {