Skip to content

Commit 7640fdf

Browse files
authored
feat(autolayout): add snap-to-grid support (#3031)
* feat(autolayout): add snap-to-grid support * fix(autolayout): recalculate dimensions after grid snapping * fix(autolayout): correct dimension calculation and propagate gridSize
1 parent bca355c commit 7640fdf

File tree

8 files changed

+93
-187
lines changed

8 files changed

+93
-187
lines changed

apps/sim/app/api/workflows/[id]/autolayout/route.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ const AutoLayoutRequestSchema = z.object({
3535
})
3636
.optional()
3737
.default({}),
38-
// Optional: if provided, use these blocks instead of loading from DB
39-
// This allows using blocks with live measurements from the UI
38+
gridSize: z.number().min(0).max(50).optional(),
4039
blocks: z.record(z.any()).optional(),
4140
edges: z.array(z.any()).optional(),
4241
loops: z.record(z.any()).optional(),
@@ -53,7 +52,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
5352
const { id: workflowId } = await params
5453

5554
try {
56-
// Get the session
5755
const session = await getSession()
5856
if (!session?.user?.id) {
5957
logger.warn(`[${requestId}] Unauthorized autolayout attempt for workflow ${workflowId}`)
@@ -62,15 +60,13 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
6260

6361
const userId = session.user.id
6462

65-
// Parse request body
6663
const body = await request.json()
6764
const layoutOptions = AutoLayoutRequestSchema.parse(body)
6865

6966
logger.info(`[${requestId}] Processing autolayout request for workflow ${workflowId}`, {
7067
userId,
7168
})
7269

73-
// Fetch the workflow to check ownership/access
7470
const accessContext = await getWorkflowAccessContext(workflowId, userId)
7571
const workflowData = accessContext?.workflow
7672

@@ -79,7 +75,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
7975
return NextResponse.json({ error: 'Workflow not found' }, { status: 404 })
8076
}
8177

82-
// Check if user has permission to update this workflow
8378
const canUpdate =
8479
accessContext?.isOwner ||
8580
(workflowData.workspaceId
@@ -94,8 +89,6 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
9489
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
9590
}
9691

97-
// Use provided blocks/edges if available (with live measurements from UI),
98-
// otherwise load from database
9992
let currentWorkflowData: NormalizedWorkflowData | null
10093

10194
if (layoutOptions.blocks && layoutOptions.edges) {
@@ -125,6 +118,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
125118
y: layoutOptions.padding?.y ?? DEFAULT_LAYOUT_PADDING.y,
126119
},
127120
alignment: layoutOptions.alignment,
121+
gridSize: layoutOptions.gridSize,
128122
}
129123

130124
const layoutResult = applyAutoLayout(

apps/sim/app/api/yaml/autolayout/route.ts

Lines changed: 0 additions & 108 deletions
This file was deleted.

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export function layoutContainers(
3434
: DEFAULT_CONTAINER_HORIZONTAL_SPACING,
3535
verticalSpacing: options.verticalSpacing ?? DEFAULT_VERTICAL_SPACING,
3636
padding: { x: CONTAINER_PADDING_X, y: CONTAINER_PADDING_Y },
37+
gridSize: options.gridSize,
3738
}
3839

3940
for (const [parentId, childIds] of children.entries()) {
@@ -56,18 +57,15 @@ export function layoutContainers(
5657
continue
5758
}
5859

59-
// Use the shared core layout function with container options
6060
const { nodes, dimensions } = layoutBlocksCore(childBlocks, childEdges, {
6161
isContainer: true,
6262
layoutOptions: containerOptions,
6363
})
6464

65-
// Apply positions back to blocks
6665
for (const node of nodes.values()) {
6766
blocks[node.id].position = node.position
6867
}
6968

70-
// Update container dimensions
7169
const calculatedWidth = dimensions.width
7270
const calculatedHeight = dimensions.height
7371

0 commit comments

Comments
 (0)