Skip to content

Commit 8b18bfd

Browse files
committed
use shared constants everywhere
1 parent 5694031 commit 8b18bfd

File tree

7 files changed

+63
-91
lines changed

7 files changed

+63
-91
lines changed

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/subflows/subflow-node.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { RepeatIcon, SplitIcon } from 'lucide-react'
33
import { Handle, type NodeProps, Position, useReactFlow } from 'reactflow'
44
import { Button, Trash } from '@/components/emcn'
55
import { cn } from '@/lib/core/utils/cn'
6+
import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
67
import { type DiffStatus, hasDiffStatus } from '@/lib/workflows/diff/types'
78
import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks'
89
import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
@@ -119,7 +120,7 @@ export const SubflowNodeComponent = memo(({ data, id }: NodeProps<SubflowNodeDat
119120
}
120121

121122
const getHandleStyle = () => {
122-
return { top: '20px', transform: 'translateY(-50%)' }
123+
return { top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`, transform: 'translateY(-50%)' }
123124
}
124125

125126
/**

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/workflow-block/workflow-block.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
import { useBlockVisual } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks'
2929
import {
3030
BLOCK_DIMENSIONS,
31+
HANDLE_POSITIONS,
3132
useBlockDimensions,
3233
} from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-dimensions'
3334
import { SELECTOR_TYPES_HYDRATION_REQUIRED, type SubBlockConfig } from '@/blocks/types'
@@ -716,7 +717,7 @@ export const WorkflowBlock = memo(function WorkflowBlock({
716717

717718
const getHandleStyle = (position: 'horizontal' | 'vertical') => {
718719
if (position === 'horizontal') {
719-
return { top: '20px', transform: 'translateY(-50%)' }
720+
return { top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`, transform: 'translateY(-50%)' }
720721
}
721722
return { left: '50%', transform: 'translateX(-50%)' }
722723
}
@@ -1030,7 +1031,9 @@ export const WorkflowBlock = memo(function WorkflowBlock({
10301031
{type === 'condition' && (
10311032
<>
10321033
{conditionRows.map((cond, condIndex) => {
1033-
const topOffset = 60 + condIndex * 29
1034+
const topOffset =
1035+
HANDLE_POSITIONS.CONDITION_START_Y +
1036+
condIndex * HANDLE_POSITIONS.CONDITION_ROW_HEIGHT
10341037
return (
10351038
<Handle
10361039
key={`handle-${cond.id}`}
@@ -1052,7 +1055,12 @@ export const WorkflowBlock = memo(function WorkflowBlock({
10521055
position={Position.Right}
10531056
id='error'
10541057
className={getHandleClasses('right', true)}
1055-
style={{ right: '-7px', top: 'auto', bottom: '17px', transform: 'translateY(50%)' }}
1058+
style={{
1059+
right: '-7px',
1060+
top: 'auto',
1061+
bottom: `${HANDLE_POSITIONS.ERROR_BOTTOM_OFFSET}px`,
1062+
transform: 'translateY(50%)',
1063+
}}
10561064
data-nodeid={id}
10571065
data-handleid='error'
10581066
isConnectableStart={true}
@@ -1083,7 +1091,12 @@ export const WorkflowBlock = memo(function WorkflowBlock({
10831091
position={Position.Right}
10841092
id='error'
10851093
className={getHandleClasses('right', true)}
1086-
style={{ right: '-7px', top: 'auto', bottom: '17px', transform: 'translateY(50%)' }}
1094+
style={{
1095+
right: '-7px',
1096+
top: 'auto',
1097+
bottom: `${HANDLE_POSITIONS.ERROR_BOTTOM_OFFSET}px`,
1098+
transform: 'translateY(50%)',
1099+
}}
10871100
data-nodeid={id}
10881101
data-handleid='error'
10891102
isConnectableStart={true}

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-block-dimensions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { useUpdateNodeInternals } from 'reactflow'
33
import { useWorkflowStore } from '@/stores/workflows/workflow/store'
44

55
// Re-export for backwards compatibility
6-
export { BLOCK_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions'
6+
export { BLOCK_DIMENSIONS, HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
77

88
interface BlockDimensions {
99
width: number

apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-block.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import { memo, useMemo } from 'react'
44
import { Handle, type NodeProps, Position } from 'reactflow'
5+
import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
56
import { getBlock } from '@/blocks/registry'
67

78
interface WorkflowPreviewBlockData {
@@ -62,7 +63,7 @@ function WorkflowPreviewBlockInner({ data }: NodeProps<WorkflowPreviewBlockData>
6263
className={horizontalHandles ? horizontalHandleClass : verticalHandleClass}
6364
style={
6465
horizontalHandles
65-
? { left: '-7px', top: '24px' }
66+
? { left: '-7px', top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px` }
6667
: { top: '-7px', left: '50%', transform: 'translateX(-50%)' }
6768
}
6869
/>
@@ -122,7 +123,7 @@ function WorkflowPreviewBlockInner({ data }: NodeProps<WorkflowPreviewBlockData>
122123
className={horizontalHandles ? horizontalHandleClass : verticalHandleClass}
123124
style={
124125
horizontalHandles
125-
? { right: '-7px', top: '24px' }
126+
? { right: '-7px', top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px` }
126127
: { bottom: '-7px', left: '50%', transform: 'translateX(-50%)' }
127128
}
128129
/>

apps/sim/app/workspace/[workspaceId]/w/components/workflow-preview/workflow-preview-subflow.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { memo } from 'react'
44
import { RepeatIcon, SplitIcon } from 'lucide-react'
55
import { Handle, type NodeProps, Position } from 'reactflow'
6+
import { HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
67

78
interface WorkflowPreviewSubflowData {
89
name: string
@@ -47,7 +48,11 @@ function WorkflowPreviewSubflowInner({ data }: NodeProps<WorkflowPreviewSubflowD
4748
position={Position.Left}
4849
id='target'
4950
className={handleClass}
50-
style={{ left: '-7px', top: '20px', transform: 'translateY(-50%)' }}
51+
style={{
52+
left: '-7px',
53+
top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`,
54+
transform: 'translateY(-50%)',
55+
}}
5156
/>
5257

5358
{/* Header - matches actual subflow header */}
@@ -81,7 +86,11 @@ function WorkflowPreviewSubflowInner({ data }: NodeProps<WorkflowPreviewSubflowD
8186
position={Position.Right}
8287
id={endHandleId}
8388
className={handleClass}
84-
style={{ right: '-7px', top: '20px', transform: 'translateY(-50%)' }}
89+
style={{
90+
right: '-7px',
91+
top: `${HANDLE_POSITIONS.DEFAULT_Y_OFFSET}px`,
92+
transform: 'translateY(-50%)',
93+
}}
8594
/>
8695
</div>
8796
)

apps/sim/lib/workflows/autolayout/core.ts

Lines changed: 11 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { createLogger } from '@/lib/logs/console/logger'
22
import {
3-
BLOCK_DIMENSIONS,
43
CONTAINER_LAYOUT_OPTIONS,
54
DEFAULT_LAYOUT_OPTIONS,
65
MAX_OVERLAP_ITERATIONS,
@@ -11,91 +10,54 @@ import {
1110
normalizePositions,
1211
prepareBlockMetrics,
1312
} from '@/lib/workflows/autolayout/utils'
13+
import { BLOCK_DIMENSIONS, HANDLE_POSITIONS } from '@/lib/workflows/blocks/block-dimensions'
1414
import type { BlockState } from '@/stores/workflows/workflow/types'
1515

1616
const logger = createLogger('AutoLayout:Core')
1717

18-
/** Handle names that indicate edges from subflow end */
1918
const SUBFLOW_END_HANDLES = new Set(['loop-end-source', 'parallel-end-source'])
20-
21-
/** Handle names that indicate edges from subflow start (inside the container) */
2219
const SUBFLOW_START_HANDLES = new Set(['loop-start-source', 'parallel-start-source'])
2320

24-
/** Default handle Y offset from block top (matches workflow-block.tsx top: '20px') */
25-
const DEFAULT_HANDLE_Y_OFFSET = 20
26-
27-
/** Error handle offset from block bottom (matches workflow-block.tsx bottom: '17px') */
28-
const ERROR_HANDLE_BOTTOM_OFFSET = 17
29-
30-
/** Condition handle starting Y offset (matches workflow-block.tsx: 60 + condIndex * 29) */
31-
const CONDITION_HANDLE_START_Y = 60
32-
const CONDITION_HANDLE_ROW_HEIGHT = 29
33-
34-
/**
35-
* Subflow start handle Y offset from subflow node top.
36-
* - Header height: 50px (from h-[calc(100%-50px)] on content area)
37-
* - Content div has position: relative
38-
* - Start pill at: absolute top-[16px] from content div
39-
* - Pill height: ~28px (py-[6px]=12px padding + ~16px text)
40-
* - Handle at top: '50%' within pill = 14px from pill top
41-
* Total: 50 + 16 + 14 = 80px from subflow node top
42-
*/
43-
const SUBFLOW_START_HANDLE_Y_OFFSET = 80
44-
4521
/**
4622
* Calculates the Y offset for a source handle based on block type and handle ID.
47-
* For condition blocks, each condition row has its own handle at different Y positions.
48-
* For error handles, the position is from the bottom of the block.
49-
* For subflow start handles, the position is based on the Start pill location.
50-
* For other blocks, handles are at a fixed offset from the top.
5123
*/
5224
function getSourceHandleYOffset(block: BlockState, sourceHandle?: string | null): number {
53-
// Error handles are positioned from the bottom of the block
5425
if (sourceHandle === 'error') {
5526
const blockHeight = block.height || BLOCK_DIMENSIONS.MIN_HEIGHT
56-
return blockHeight - ERROR_HANDLE_BOTTOM_OFFSET
27+
return blockHeight - HANDLE_POSITIONS.ERROR_BOTTOM_OFFSET
5728
}
5829

59-
// Subflow start handles are positioned at the Start pill inside the container
6030
if (sourceHandle && SUBFLOW_START_HANDLES.has(sourceHandle)) {
61-
return SUBFLOW_START_HANDLE_Y_OFFSET
31+
return HANDLE_POSITIONS.SUBFLOW_START_Y_OFFSET
6232
}
6333

64-
// Condition blocks have multiple handles at different Y positions
6534
if (block.type === 'condition' && sourceHandle?.startsWith('condition-')) {
66-
// Extract condition ID from handle (e.g., "condition-abc123" -> "abc123")
6735
const conditionId = sourceHandle.replace('condition-', '')
68-
69-
// Try to find the index by parsing the conditions subblock value
7036
try {
7137
const conditionsValue = block.subBlocks?.conditions?.value
7238
if (typeof conditionsValue === 'string' && conditionsValue) {
7339
const conditions = JSON.parse(conditionsValue) as Array<{ id?: string }>
7440
const conditionIndex = conditions.findIndex((c) => c.id === conditionId)
75-
7641
if (conditionIndex >= 0) {
77-
// Matches workflow-block.tsx: top: `${60 + condIndex * 29}px`
78-
return CONDITION_HANDLE_START_Y + conditionIndex * CONDITION_HANDLE_ROW_HEIGHT
42+
return (
43+
HANDLE_POSITIONS.CONDITION_START_Y +
44+
conditionIndex * HANDLE_POSITIONS.CONDITION_ROW_HEIGHT
45+
)
7946
}
8047
}
8148
} catch {
82-
// If parsing fails, fall back to default offset
49+
// Fall back to default offset
8350
}
8451
}
8552

86-
// Loop/parallel end handles and regular blocks use default offset
87-
return DEFAULT_HANDLE_Y_OFFSET
53+
return HANDLE_POSITIONS.DEFAULT_Y_OFFSET
8854
}
8955

9056
/**
9157
* Calculates the Y offset for a target handle based on block type and handle ID.
92-
* Most blocks have their target handle at DEFAULT_HANDLE_Y_OFFSET.
93-
* Subflow nodes (loop/parallel) have their target handle at the same position.
9458
*/
9559
function getTargetHandleYOffset(_block: BlockState, _targetHandle?: string | null): number {
96-
// All target handles are currently at the same position (20px from block top)
97-
// This function exists for future extensibility if target handles vary
98-
return DEFAULT_HANDLE_Y_OFFSET
60+
return HANDLE_POSITIONS.DEFAULT_Y_OFFSET
9961
}
10062

10163
/**
@@ -431,7 +393,7 @@ export function calculatePositions(
431393

432394
// If no predecessors found (shouldn't happen for layer > 0), use padding
433395
if (bestSourceHandleY < 0) {
434-
bestSourceHandleY = padding.y + DEFAULT_HANDLE_Y_OFFSET
396+
bestSourceHandleY = padding.y + HANDLE_POSITIONS.DEFAULT_Y_OFFSET
435397
}
436398

437399
// Calculate the target handle Y offset for this node

apps/sim/lib/workflows/blocks/block-dimensions.ts

Lines changed: 18 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,56 +2,42 @@
22
* Shared Block Dimension Constants
33
*
44
* Single source of truth for block dimensions used by:
5-
* - UI components (workflow-block, note-block)
5+
* - UI components (workflow-block, note-block, subflow-node)
66
* - Autolayout system
77
* - Node utilities
8-
*
9-
* IMPORTANT: These values must match the actual CSS dimensions in the UI.
10-
* Changing these values will affect both rendering and layout calculations.
118
*/
129

13-
/**
14-
* Block dimension constants for workflow blocks
15-
*/
1610
export const BLOCK_DIMENSIONS = {
17-
/** Fixed width for all workflow blocks (matches w-[250px] in workflow-block.tsx) */
1811
FIXED_WIDTH: 250,
19-
20-
/** Header height for blocks */
2112
HEADER_HEIGHT: 40,
22-
23-
/** Minimum height for blocks */
2413
MIN_HEIGHT: 100,
25-
26-
/** Padding around workflow block content (p-[8px] top + bottom = 16px) */
2714
WORKFLOW_CONTENT_PADDING: 16,
28-
29-
/** Height of each subblock row (14px text + 8px gap + padding) */
3015
WORKFLOW_ROW_HEIGHT: 29,
31-
32-
/** Padding around note block content */
3316
NOTE_CONTENT_PADDING: 14,
34-
35-
/** Minimum content height for note blocks */
3617
NOTE_MIN_CONTENT_HEIGHT: 20,
37-
38-
/** Base content height for note blocks */
3918
NOTE_BASE_CONTENT_HEIGHT: 60,
4019
} as const
4120

42-
/**
43-
* Container block dimension constants (loop, parallel, subflow)
44-
*/
4521
export const CONTAINER_DIMENSIONS = {
46-
/** Default width for container blocks */
4722
DEFAULT_WIDTH: 500,
48-
49-
/** Default height for container blocks */
5023
DEFAULT_HEIGHT: 300,
51-
52-
/** Minimum width for container blocks */
5324
MIN_WIDTH: 400,
54-
55-
/** Minimum height for container blocks */
5625
MIN_HEIGHT: 200,
26+
HEADER_HEIGHT: 50,
27+
} as const
28+
29+
/**
30+
* Handle position constants - must match CSS in workflow-block.tsx and subflow-node.tsx
31+
*/
32+
export const HANDLE_POSITIONS = {
33+
/** Default Y offset from block top for source/target handles */
34+
DEFAULT_Y_OFFSET: 20,
35+
/** Error handle offset from block bottom */
36+
ERROR_BOTTOM_OFFSET: 17,
37+
/** Condition handle starting Y offset */
38+
CONDITION_START_Y: 60,
39+
/** Height per condition row */
40+
CONDITION_ROW_HEIGHT: 29,
41+
/** Subflow start handle Y offset (header 50px + pill offset 16px + pill center 14px) */
42+
SUBFLOW_START_Y_OFFSET: 80,
5743
} as const

0 commit comments

Comments
 (0)