From 5694031ef4823a3d5fca2bd65245b08fb4381e65 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 9 Dec 2025 15:55:08 -0800 Subject: [PATCH 1/3] fix(autolayout): align by handle --- apps/sim/lib/workflows/autolayout/core.ts | 209 ++++++++++++++++++---- 1 file changed, 178 insertions(+), 31 deletions(-) diff --git a/apps/sim/lib/workflows/autolayout/core.ts b/apps/sim/lib/workflows/autolayout/core.ts index 0131984756d..9a61804897b 100644 --- a/apps/sim/lib/workflows/autolayout/core.ts +++ b/apps/sim/lib/workflows/autolayout/core.ts @@ -1,5 +1,6 @@ import { createLogger } from '@/lib/logs/console/logger' import { + BLOCK_DIMENSIONS, CONTAINER_LAYOUT_OPTIONS, DEFAULT_LAYOUT_OPTIONS, MAX_OVERLAP_ITERATIONS, @@ -17,6 +18,86 @@ const logger = createLogger('AutoLayout:Core') /** Handle names that indicate edges from subflow end */ const SUBFLOW_END_HANDLES = new Set(['loop-end-source', 'parallel-end-source']) +/** Handle names that indicate edges from subflow start (inside the container) */ +const SUBFLOW_START_HANDLES = new Set(['loop-start-source', 'parallel-start-source']) + +/** Default handle Y offset from block top (matches workflow-block.tsx top: '20px') */ +const DEFAULT_HANDLE_Y_OFFSET = 20 + +/** Error handle offset from block bottom (matches workflow-block.tsx bottom: '17px') */ +const ERROR_HANDLE_BOTTOM_OFFSET = 17 + +/** Condition handle starting Y offset (matches workflow-block.tsx: 60 + condIndex * 29) */ +const CONDITION_HANDLE_START_Y = 60 +const CONDITION_HANDLE_ROW_HEIGHT = 29 + +/** + * Subflow start handle Y offset from subflow node top. + * - Header height: 50px (from h-[calc(100%-50px)] on content area) + * - Content div has position: relative + * - Start pill at: absolute top-[16px] from content div + * - Pill height: ~28px (py-[6px]=12px padding + ~16px text) + * - Handle at top: '50%' within pill = 14px from pill top + * Total: 50 + 16 + 14 = 80px from subflow node top + */ +const SUBFLOW_START_HANDLE_Y_OFFSET = 80 + +/** + * Calculates the Y offset for a source handle based on block type and handle ID. + * For condition blocks, each condition row has its own handle at different Y positions. + * For error handles, the position is from the bottom of the block. + * For subflow start handles, the position is based on the Start pill location. + * For other blocks, handles are at a fixed offset from the top. + */ +function getSourceHandleYOffset(block: BlockState, sourceHandle?: string | null): number { + // Error handles are positioned from the bottom of the block + if (sourceHandle === 'error') { + const blockHeight = block.height || BLOCK_DIMENSIONS.MIN_HEIGHT + return blockHeight - ERROR_HANDLE_BOTTOM_OFFSET + } + + // Subflow start handles are positioned at the Start pill inside the container + if (sourceHandle && SUBFLOW_START_HANDLES.has(sourceHandle)) { + return SUBFLOW_START_HANDLE_Y_OFFSET + } + + // Condition blocks have multiple handles at different Y positions + if (block.type === 'condition' && sourceHandle?.startsWith('condition-')) { + // Extract condition ID from handle (e.g., "condition-abc123" -> "abc123") + const conditionId = sourceHandle.replace('condition-', '') + + // Try to find the index by parsing the conditions subblock value + try { + const conditionsValue = block.subBlocks?.conditions?.value + if (typeof conditionsValue === 'string' && conditionsValue) { + const conditions = JSON.parse(conditionsValue) as Array<{ id?: string }> + const conditionIndex = conditions.findIndex((c) => c.id === conditionId) + + if (conditionIndex >= 0) { + // Matches workflow-block.tsx: top: `${60 + condIndex * 29}px` + return CONDITION_HANDLE_START_Y + conditionIndex * CONDITION_HANDLE_ROW_HEIGHT + } + } + } catch { + // If parsing fails, fall back to default offset + } + } + + // Loop/parallel end handles and regular blocks use default offset + return DEFAULT_HANDLE_Y_OFFSET +} + +/** + * Calculates the Y offset for a target handle based on block type and handle ID. + * Most blocks have their target handle at DEFAULT_HANDLE_Y_OFFSET. + * Subflow nodes (loop/parallel) have their target handle at the same position. + */ +function getTargetHandleYOffset(_block: BlockState, _targetHandle?: string | null): number { + // All target handles are currently at the same position (20px from block top) + // This function exists for future extensibility if target handles vary + return DEFAULT_HANDLE_Y_OFFSET +} + /** * Checks if an edge comes from a subflow end handle */ @@ -225,18 +306,36 @@ function resolveVerticalOverlaps(nodes: GraphNode[], verticalSpacing: number): v } } +/** + * Checks if a block is a container type (loop or parallel) + */ +function isContainerBlock(node: GraphNode): boolean { + return node.block.type === 'loop' || node.block.type === 'parallel' +} + +/** + * Extra vertical spacing after containers to prevent edge crossings with sibling blocks. + * This creates clearance for edges from container ends to route cleanly. + */ +const CONTAINER_VERTICAL_CLEARANCE = 120 + /** * Calculates positions for nodes organized by layer. * Uses cumulative width-based X positioning to properly handle containers of varying widths. + * Aligns blocks based on their connected predecessors to achieve handle-to-handle alignment. + * + * Handle alignment: Calculates actual source handle Y positions based on block type + * (condition blocks have handles at different heights for each branch). + * Target handles are also calculated per-block to ensure precise alignment. */ export function calculatePositions( layers: Map, + edges: Edge[], options: LayoutOptions = {} ): void { const horizontalSpacing = options.horizontalSpacing ?? DEFAULT_LAYOUT_OPTIONS.horizontalSpacing const verticalSpacing = options.verticalSpacing ?? DEFAULT_LAYOUT_OPTIONS.verticalSpacing const padding = options.padding ?? DEFAULT_LAYOUT_OPTIONS.padding - const alignment = options.alignment ?? DEFAULT_LAYOUT_OPTIONS.alignment const layerNumbers = Array.from(layers.keys()).sort((a, b) => a - b) @@ -257,41 +356,89 @@ export function calculatePositions( cumulativeX += layerWidths.get(layerNum)! + horizontalSpacing } - // Position nodes using cumulative X + // Build a flat map of all nodes for quick lookups + const allNodes = new Map() + for (const nodesInLayer of layers.values()) { + for (const node of nodesInLayer) { + allNodes.set(node.id, node) + } + } + + // Build incoming edges map for handle lookups + const incomingEdgesMap = new Map() + for (const edge of edges) { + if (!incomingEdgesMap.has(edge.target)) { + incomingEdgesMap.set(edge.target, []) + } + incomingEdgesMap.get(edge.target)!.push(edge) + } + + // Position nodes layer by layer, aligning with connected predecessors for (const layerNum of layerNumbers) { const nodesInLayer = layers.get(layerNum)! const xPosition = layerXPositions.get(layerNum)! - // Calculate total height for this layer - const totalHeight = nodesInLayer.reduce( - (sum, node, idx) => sum + node.metrics.height + (idx > 0 ? verticalSpacing : 0), - 0 - ) - - // Start Y based on alignment - let yOffset: number - switch (alignment) { - case 'start': - yOffset = padding.y - break - case 'center': - yOffset = Math.max(padding.y, 300 - totalHeight / 2) - break - case 'end': - yOffset = 600 - totalHeight - padding.y - break - default: - yOffset = padding.y - break + // Separate containers and non-containers + const containersInLayer = nodesInLayer.filter(isContainerBlock) + const nonContainersInLayer = nodesInLayer.filter((n) => !isContainerBlock(n)) + + // For the first layer (layer 0), position sequentially from padding.y + if (layerNum === 0) { + let yOffset = padding.y + + // Sort containers by height for visual balance + containersInLayer.sort((a, b) => b.metrics.height - a.metrics.height) + + for (const node of containersInLayer) { + node.position = { x: xPosition, y: yOffset } + yOffset += node.metrics.height + verticalSpacing + } + + if (containersInLayer.length > 0 && nonContainersInLayer.length > 0) { + yOffset += CONTAINER_VERTICAL_CLEARANCE + } + + // Sort non-containers by outgoing connections + nonContainersInLayer.sort((a, b) => b.outgoing.size - a.outgoing.size) + + for (const node of nonContainersInLayer) { + node.position = { x: xPosition, y: yOffset } + yOffset += node.metrics.height + verticalSpacing + } + continue } - // Position each node - for (const node of nodesInLayer) { - node.position = { - x: xPosition, - y: yOffset, + // For subsequent layers, align with connected predecessors (handle-to-handle) + for (const node of [...containersInLayer, ...nonContainersInLayer]) { + // Find the bottommost predecessor handle Y (highest value) and align to it + let bestSourceHandleY = -1 + let bestEdge: Edge | null = null + const incomingEdges = incomingEdgesMap.get(node.id) || [] + + for (const edge of incomingEdges) { + const predecessor = allNodes.get(edge.source) + if (predecessor) { + // Calculate actual source handle Y position based on block type and handle + const sourceHandleOffset = getSourceHandleYOffset(predecessor.block, edge.sourceHandle) + const sourceHandleY = predecessor.position.y + sourceHandleOffset + + if (sourceHandleY > bestSourceHandleY) { + bestSourceHandleY = sourceHandleY + bestEdge = edge + } + } } - yOffset += node.metrics.height + verticalSpacing + + // If no predecessors found (shouldn't happen for layer > 0), use padding + if (bestSourceHandleY < 0) { + bestSourceHandleY = padding.y + DEFAULT_HANDLE_Y_OFFSET + } + + // Calculate the target handle Y offset for this node + const targetHandleOffset = getTargetHandleYOffset(node.block, bestEdge?.targetHandle) + + // Position node so its target handle aligns with the source handle Y + node.position = { x: xPosition, y: bestSourceHandleY - targetHandleOffset } } } @@ -338,8 +485,8 @@ export function layoutBlocksCore( // 3. Group by layer const layers = groupByLayer(nodes) - // 4. Calculate positions - calculatePositions(layers, layoutOptions) + // 4. Calculate positions (pass edges for handle offset calculations) + calculatePositions(layers, edges, layoutOptions) // 5. Normalize positions const dimensions = normalizePositions(nodes, { isContainer: options.isContainer }) From 8b18bfd16ffdbac6d1ecf01ff8aeacc40c97f9a4 Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 9 Dec 2025 16:17:10 -0800 Subject: [PATCH 2/3] use shared constants everywhere --- .../components/subflows/subflow-node.tsx | 3 +- .../workflow-block/workflow-block.tsx | 21 +++++-- .../hooks/use-block-dimensions.ts | 2 +- .../workflow-preview-block.tsx | 5 +- .../workflow-preview-subflow.tsx | 13 +++- apps/sim/lib/workflows/autolayout/core.ts | 60 ++++--------------- .../lib/workflows/blocks/block-dimensions.ts | 50 ++++++---------- 7 files changed, 63 insertions(+), 91 deletions(-) diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx index 303b833265e..28970fd484f 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx @@ -3,6 +3,7 @@ import { RepeatIcon, SplitIcon } from 'lucide-react' import { Handle, type NodeProps, Position, useReactFlow } from 'reactflow' import { Button, Trash } from '@/components/emcn' import { cn } from '@/lib/core/utils/cn' +import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions' import { type DiffStatus, hasDiffStatus } from '@/lib/workflows/diff/types' import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks' import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow' @@ -119,7 +120,7 @@ export const SubflowNodeComponent = memo(({ data, id }: NodeProps { - return { top: '20px', transform: 'translateY(-50%)' } + return { top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`, transform: 'translateY(-50%)' } } /** diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx index bdd29fc9de2..7e6e2f4d97b 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx @@ -28,6 +28,7 @@ import { import { useBlockVisual } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks' import { BLOCK_DIMENSIONS, + HANDLE_POSITIONS, useBlockDimensions, } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-dimensions' import { SELECTOR_TYPES_HYDRATION_REQUIRED, type SubBlockConfig } from '@/blocks/types' @@ -716,7 +717,7 @@ export const WorkflowBlock = memo(function WorkflowBlock({ const getHandleStyle = (position: 'horizontal' | 'vertical') => { if (position === 'horizontal') { - return { top: '20px', transform: 'translateY(-50%)' } + return { top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`, transform: 'translateY(-50%)' } } return { left: '50%', transform: 'translateX(-50%)' } } @@ -1030,7 +1031,9 @@ export const WorkflowBlock = memo(function WorkflowBlock({ {type === 'condition' && ( <> {conditionRows.map((cond, condIndex) => { - const topOffset = 60 + condIndex * 29 + const topOffset = + HANDLE_POSITIONS.CONDITION_START_Y + + condIndex * HANDLE_POSITIONS.CONDITION_ROW_HEIGHT return ( className={horizontalHandles ? horizontalHandleClass : verticalHandleClass} style={ horizontalHandles - ? { left: '-7px', top: '24px' } + ? { left: '-7px', top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px` } : { top: '-7px', left: '50%', transform: 'translateX(-50%)' } } /> @@ -122,7 +123,7 @@ function WorkflowPreviewBlockInner({ data }: NodeProps className={horizontalHandles ? horizontalHandleClass : verticalHandleClass} style={ horizontalHandles - ? { right: '-7px', top: '24px' } + ? { right: '-7px', top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px` } : { bottom: '-7px', left: '50%', transform: 'translateX(-50%)' } } /> diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-subflow.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-subflow.tsx index d58d04b5df4..56059ff80a1 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-subflow.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-subflow.tsx @@ -3,6 +3,7 @@ import { memo } from 'react' import { RepeatIcon, SplitIcon } from 'lucide-react' import { Handle, type NodeProps, Position } from 'reactflow' +import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions' interface WorkflowPreviewSubflowData { name: string @@ -47,7 +48,11 @@ function WorkflowPreviewSubflowInner({ data }: NodeProps {/* Header - matches actual subflow header */} @@ -81,7 +86,11 @@ function WorkflowPreviewSubflowInner({ data }: NodeProps ) diff --git a/apps/sim/lib/workflows/autolayout/core.ts b/apps/sim/lib/workflows/autolayout/core.ts index 9a61804897b..745b4865ef5 100644 --- a/apps/sim/lib/workflows/autolayout/core.ts +++ b/apps/sim/lib/workflows/autolayout/core.ts @@ -1,6 +1,5 @@ import { createLogger } from '@/lib/logs/console/logger' import { - BLOCK_DIMENSIONS, CONTAINER_LAYOUT_OPTIONS, DEFAULT_LAYOUT_OPTIONS, MAX_OVERLAP_ITERATIONS, @@ -11,91 +10,54 @@ import { normalizePositions, prepareBlockMetrics, } from '@/lib/workflows/autolayout/utils' +import { BLOCK_DIMENSIONS, HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions' import type { BlockState } from '@/stores/workflows/workflow/types' const logger = createLogger('AutoLayout:Core') -/** Handle names that indicate edges from subflow end */ const SUBFLOW_END_HANDLES = new Set(['loop-end-source', 'parallel-end-source']) - -/** Handle names that indicate edges from subflow start (inside the container) */ const SUBFLOW_START_HANDLES = new Set(['loop-start-source', 'parallel-start-source']) -/** Default handle Y offset from block top (matches workflow-block.tsx top: '20px') */ -const DEFAULT_HANDLE_Y_OFFSET = 20 - -/** Error handle offset from block bottom (matches workflow-block.tsx bottom: '17px') */ -const ERROR_HANDLE_BOTTOM_OFFSET = 17 - -/** Condition handle starting Y offset (matches workflow-block.tsx: 60 + condIndex * 29) */ -const CONDITION_HANDLE_START_Y = 60 -const CONDITION_HANDLE_ROW_HEIGHT = 29 - -/** - * Subflow start handle Y offset from subflow node top. - * - Header height: 50px (from h-[calc(100%-50px)] on content area) - * - Content div has position: relative - * - Start pill at: absolute top-[16px] from content div - * - Pill height: ~28px (py-[6px]=12px padding + ~16px text) - * - Handle at top: '50%' within pill = 14px from pill top - * Total: 50 + 16 + 14 = 80px from subflow node top - */ -const SUBFLOW_START_HANDLE_Y_OFFSET = 80 - /** * Calculates the Y offset for a source handle based on block type and handle ID. - * For condition blocks, each condition row has its own handle at different Y positions. - * For error handles, the position is from the bottom of the block. - * For subflow start handles, the position is based on the Start pill location. - * For other blocks, handles are at a fixed offset from the top. */ function getSourceHandleYOffset(block: BlockState, sourceHandle?: string | null): number { - // Error handles are positioned from the bottom of the block if (sourceHandle === 'error') { const blockHeight = block.height || BLOCK_DIMENSIONS.MIN_HEIGHT - return blockHeight - ERROR_HANDLE_BOTTOM_OFFSET + return blockHeight - HANDLE_POSITIONS.ERROR_BOTTOM_OFFSET } - // Subflow start handles are positioned at the Start pill inside the container if (sourceHandle && SUBFLOW_START_HANDLES.has(sourceHandle)) { - return SUBFLOW_START_HANDLE_Y_OFFSET + return HANDLE_POSITIONS.SUBFLOW_START_Y_OFFSET } - // Condition blocks have multiple handles at different Y positions if (block.type === 'condition' && sourceHandle?.startsWith('condition-')) { - // Extract condition ID from handle (e.g., "condition-abc123" -> "abc123") const conditionId = sourceHandle.replace('condition-', '') - - // Try to find the index by parsing the conditions subblock value try { const conditionsValue = block.subBlocks?.conditions?.value if (typeof conditionsValue === 'string' && conditionsValue) { const conditions = JSON.parse(conditionsValue) as Array<{ id?: string }> const conditionIndex = conditions.findIndex((c) => c.id === conditionId) - if (conditionIndex >= 0) { - // Matches workflow-block.tsx: top: `${60 + condIndex * 29}px` - return CONDITION_HANDLE_START_Y + conditionIndex * CONDITION_HANDLE_ROW_HEIGHT + return ( + HANDLE_POSITIONS.CONDITION_START_Y + + conditionIndex * HANDLE_POSITIONS.CONDITION_ROW_HEIGHT + ) } } } catch { - // If parsing fails, fall back to default offset + // Fall back to default offset } } - // Loop/parallel end handles and regular blocks use default offset - return DEFAULT_HANDLE_Y_OFFSET + return HANDLE_POSITIONS.DEFAULT_Y_OFFSET } /** * Calculates the Y offset for a target handle based on block type and handle ID. - * Most blocks have their target handle at DEFAULT_HANDLE_Y_OFFSET. - * Subflow nodes (loop/parallel) have their target handle at the same position. */ function getTargetHandleYOffset(_block: BlockState, _targetHandle?: string | null): number { - // All target handles are currently at the same position (20px from block top) - // This function exists for future extensibility if target handles vary - return DEFAULT_HANDLE_Y_OFFSET + return HANDLE_POSITIONS.DEFAULT_Y_OFFSET } /** @@ -431,7 +393,7 @@ export function calculatePositions( // If no predecessors found (shouldn't happen for layer > 0), use padding if (bestSourceHandleY < 0) { - bestSourceHandleY = padding.y + DEFAULT_HANDLE_Y_OFFSET + bestSourceHandleY = padding.y + HANDLE_POSITIONS.DEFAULT_Y_OFFSET } // Calculate the target handle Y offset for this node diff --git a/apps/sim/lib/workflows/blocks/block-dimensions.ts b/apps/sim/lib/workflows/blocks/block-dimensions.ts index cff175dc30b..d311f0dc0fd 100644 --- a/apps/sim/lib/workflows/blocks/block-dimensions.ts +++ b/apps/sim/lib/workflows/blocks/block-dimensions.ts @@ -2,56 +2,42 @@ * Shared Block Dimension Constants * * Single source of truth for block dimensions used by: - * - UI components (workflow-block, note-block) + * - UI components (workflow-block, note-block, subflow-node) * - Autolayout system * - Node utilities - * - * IMPORTANT: These values must match the actual CSS dimensions in the UI. - * Changing these values will affect both rendering and layout calculations. */ -/** - * Block dimension constants for workflow blocks - */ export const BLOCK_DIMENSIONS = { - /** Fixed width for all workflow blocks (matches w-[250px] in workflow-block.tsx) */ FIXED_WIDTH: 250, - - /** Header height for blocks */ HEADER_HEIGHT: 40, - - /** Minimum height for blocks */ MIN_HEIGHT: 100, - - /** Padding around workflow block content (p-[8px] top + bottom = 16px) */ WORKFLOW_CONTENT_PADDING: 16, - - /** Height of each subblock row (14px text + 8px gap + padding) */ WORKFLOW_ROW_HEIGHT: 29, - - /** Padding around note block content */ NOTE_CONTENT_PADDING: 14, - - /** Minimum content height for note blocks */ NOTE_MIN_CONTENT_HEIGHT: 20, - - /** Base content height for note blocks */ NOTE_BASE_CONTENT_HEIGHT: 60, } as const -/** - * Container block dimension constants (loop, parallel, subflow) - */ export const CONTAINER_DIMENSIONS = { - /** Default width for container blocks */ DEFAULT_WIDTH: 500, - - /** Default height for container blocks */ DEFAULT_HEIGHT: 300, - - /** Minimum width for container blocks */ MIN_WIDTH: 400, - - /** Minimum height for container blocks */ MIN_HEIGHT: 200, + HEADER_HEIGHT: 50, +} as const + +/** + * Handle position constants - must match CSS in workflow-block.tsx and subflow-node.tsx + */ +export const HANDLE_POSITIONS = { + /** Default Y offset from block top for source/target handles */ + DEFAULT_Y_OFFSET: 20, + /** Error handle offset from block bottom */ + ERROR_BOTTOM_OFFSET: 17, + /** Condition handle starting Y offset */ + CONDITION_START_Y: 60, + /** Height per condition row */ + CONDITION_ROW_HEIGHT: 29, + /** Subflow start handle Y offset (header 50px + pill offset 16px + pill center 14px) */ + SUBFLOW_START_Y_OFFSET: 80, } as const From 699bdefa8006d89a65697c1188c9f4f40263bc5d Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Tue, 9 Dec 2025 16:21:26 -0800 Subject: [PATCH 3/3] cleanup --- apps/sim/lib/workflows/autolayout/constants.ts | 2 -- apps/sim/lib/workflows/autolayout/containers.ts | 4 ---- apps/sim/lib/workflows/autolayout/targeted.ts | 1 - apps/sim/lib/workflows/autolayout/types.ts | 1 - apps/sim/lib/workflows/autolayout/utils.ts | 2 -- 5 files changed, 10 deletions(-) diff --git a/apps/sim/lib/workflows/autolayout/constants.ts b/apps/sim/lib/workflows/autolayout/constants.ts index c932ede0a03..7616fb09447 100644 --- a/apps/sim/lib/workflows/autolayout/constants.ts +++ b/apps/sim/lib/workflows/autolayout/constants.ts @@ -75,7 +75,6 @@ export const DEFAULT_LAYOUT_OPTIONS = { horizontalSpacing: DEFAULT_HORIZONTAL_SPACING, verticalSpacing: DEFAULT_VERTICAL_SPACING, padding: DEFAULT_LAYOUT_PADDING, - alignment: 'center' as const, } /** @@ -90,5 +89,4 @@ export const CONTAINER_LAYOUT_OPTIONS = { horizontalSpacing: DEFAULT_CONTAINER_HORIZONTAL_SPACING, verticalSpacing: DEFAULT_VERTICAL_SPACING, padding: { x: CONTAINER_PADDING_X, y: CONTAINER_PADDING_Y }, - alignment: 'center' as const, } diff --git a/apps/sim/lib/workflows/autolayout/containers.ts b/apps/sim/lib/workflows/autolayout/containers.ts index 53cfd0c0bcb..cdd79fcadc4 100644 --- a/apps/sim/lib/workflows/autolayout/containers.ts +++ b/apps/sim/lib/workflows/autolayout/containers.ts @@ -28,16 +28,12 @@ export function layoutContainers( ): void { const { children } = getBlocksByParent(blocks) - // Build container-specific layout options - // If horizontalSpacing provided, reduce by 15% for tighter container layout - // Otherwise use the default container spacing (400) const containerOptions: LayoutOptions = { horizontalSpacing: options.horizontalSpacing ? options.horizontalSpacing * 0.85 : DEFAULT_CONTAINER_HORIZONTAL_SPACING, verticalSpacing: options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING, padding: { x: CONTAINER_PADDING_X, y: CONTAINER_PADDING_Y }, - alignment: options.alignment, } for (const [parentId, childIds] of children.entries()) { diff --git a/apps/sim/lib/workflows/autolayout/targeted.ts b/apps/sim/lib/workflows/autolayout/targeted.ts index 97cb9e0715a..f4b741bd8f5 100644 --- a/apps/sim/lib/workflows/autolayout/targeted.ts +++ b/apps/sim/lib/workflows/autolayout/targeted.ts @@ -228,7 +228,6 @@ function computeLayoutPositions( layoutOptions: { horizontalSpacing: isContainer ? horizontalSpacing * 0.85 : horizontalSpacing, verticalSpacing, - alignment: 'center', }, subflowDepths, }) diff --git a/apps/sim/lib/workflows/autolayout/types.ts b/apps/sim/lib/workflows/autolayout/types.ts index ed763ae5717..a20c35715aa 100644 --- a/apps/sim/lib/workflows/autolayout/types.ts +++ b/apps/sim/lib/workflows/autolayout/types.ts @@ -4,7 +4,6 @@ export interface LayoutOptions { horizontalSpacing?: number verticalSpacing?: number padding?: { x: number; y: number } - alignment?: 'start' | 'center' | 'end' } export interface LayoutResult { diff --git a/apps/sim/lib/workflows/autolayout/utils.ts b/apps/sim/lib/workflows/autolayout/utils.ts index 7c63edc81a4..45ddc614a4f 100644 --- a/apps/sim/lib/workflows/autolayout/utils.ts +++ b/apps/sim/lib/workflows/autolayout/utils.ts @@ -329,7 +329,6 @@ export type LayoutFunction = ( horizontalSpacing?: number verticalSpacing?: number padding?: { x: number; y: number } - alignment?: 'start' | 'center' | 'end' } subflowDepths?: Map } @@ -418,7 +417,6 @@ export function prepareContainerDimensions( layoutOptions: { horizontalSpacing: horizontalSpacing * 0.85, verticalSpacing, - alignment: 'center', }, })