Skip to content

Commit 9a6c687

Browse files
committed
fix(subflow): resizing live update
1 parent 08bc112 commit 9a6c687

File tree

1 file changed

+85
-1
lines changed
  • apps/sim/app/workspace/[workspaceId]/w/[workflowId]

1 file changed

+85
-1
lines changed

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

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { useShallow } from 'zustand/react/shallow'
1818
import type { OAuthConnectEventDetail } from '@/lib/copilot/tools/client/other/oauth-request-access'
1919
import { createLogger } from '@/lib/logs/console/logger'
2020
import type { OAuthProvider } from '@/lib/oauth'
21+
import { BLOCK_DIMENSIONS, CONTAINER_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions'
2122
import { TriggerUtils } from '@/lib/workflows/triggers/triggers'
2223
import { useWorkspacePermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
2324
import {
@@ -1501,6 +1502,77 @@ const WorkflowContent = React.memo(() => {
15011502
// Only sync non-position changes (like selection) to store if needed
15021503
}, [])
15031504

1505+
/**
1506+
* Updates container dimensions in displayNodes during drag.
1507+
* This allows live resizing of containers as their children are dragged.
1508+
*/
1509+
const updateContainerDimensionsDuringDrag = useCallback(
1510+
(draggedNodeId: string, draggedNodePosition: { x: number; y: number }) => {
1511+
const parentId = blocks[draggedNodeId]?.data?.parentId
1512+
if (!parentId) return
1513+
1514+
setDisplayNodes((currentNodes) => {
1515+
// Find all children of this container from current displayNodes
1516+
const childNodes = currentNodes.filter((n) => n.parentId === parentId)
1517+
if (childNodes.length === 0) return currentNodes
1518+
1519+
// Calculate dimensions using current positions from displayNodes
1520+
// Match padding values from use-node-utilities.ts calculateLoopDimensions
1521+
const headerHeight = 50
1522+
const leftPadding = 16
1523+
const rightPadding = 80
1524+
const topPadding = 16
1525+
const bottomPadding = 16
1526+
const minWidth = CONTAINER_DIMENSIONS.DEFAULT_WIDTH
1527+
const minHeight = CONTAINER_DIMENSIONS.DEFAULT_HEIGHT
1528+
1529+
let maxRight = 0
1530+
let maxBottom = 0
1531+
1532+
childNodes.forEach((node) => {
1533+
// Use the dragged node's live position, others from displayNodes
1534+
const nodePosition = node.id === draggedNodeId ? draggedNodePosition : node.position
1535+
1536+
// Get dimensions - use block store for height estimates
1537+
const blockData = blocks[node.id]
1538+
const nodeWidth = BLOCK_DIMENSIONS.FIXED_WIDTH
1539+
const nodeHeight = blockData?.height || node.height || BLOCK_DIMENSIONS.MIN_HEIGHT
1540+
1541+
const rightEdge = nodePosition.x + nodeWidth
1542+
const bottomEdge = nodePosition.y + nodeHeight
1543+
1544+
maxRight = Math.max(maxRight, rightEdge)
1545+
maxBottom = Math.max(maxBottom, bottomEdge)
1546+
})
1547+
1548+
const newWidth = Math.max(minWidth, leftPadding + maxRight + rightPadding)
1549+
const newHeight = Math.max(minHeight, headerHeight + topPadding + maxBottom + bottomPadding)
1550+
1551+
// Update the container node's dimensions in displayNodes
1552+
return currentNodes.map((node) => {
1553+
if (node.id === parentId) {
1554+
const currentWidth = node.data?.width || CONTAINER_DIMENSIONS.DEFAULT_WIDTH
1555+
const currentHeight = node.data?.height || CONTAINER_DIMENSIONS.DEFAULT_HEIGHT
1556+
1557+
// Only update if dimensions changed
1558+
if (newWidth !== currentWidth || newHeight !== currentHeight) {
1559+
return {
1560+
...node,
1561+
data: {
1562+
...node.data,
1563+
width: newWidth,
1564+
height: newHeight,
1565+
},
1566+
}
1567+
}
1568+
}
1569+
return node
1570+
})
1571+
})
1572+
},
1573+
[blocks]
1574+
)
1575+
15041576
/**
15051577
* Effect to resize loops when nodes change (add/remove/position change).
15061578
* Runs on structural changes only - not during drag (position-only changes).
@@ -1681,6 +1753,11 @@ const WorkflowContent = React.memo(() => {
16811753
// Get the current parent ID of the node being dragged
16821754
const currentParentId = blocks[node.id]?.data?.parentId || null
16831755

1756+
// If the node is inside a container, update container dimensions during drag
1757+
if (currentParentId) {
1758+
updateContainerDimensionsDuringDrag(node.id, node.position)
1759+
}
1760+
16841761
// Check if this is a starter block - starter blocks should never be in containers
16851762
const isStarterBlock = node.data?.type === 'starter'
16861763
if (isStarterBlock) {
@@ -1812,7 +1889,14 @@ const WorkflowContent = React.memo(() => {
18121889
}
18131890
}
18141891
},
1815-
[getNodes, potentialParentId, blocks, getNodeAbsolutePosition, getNodeDepth]
1892+
[
1893+
getNodes,
1894+
potentialParentId,
1895+
blocks,
1896+
getNodeAbsolutePosition,
1897+
getNodeDepth,
1898+
updateContainerDimensionsDuringDrag,
1899+
]
18161900
)
18171901

18181902
/** Captures initial parent ID and position when drag starts. */

0 commit comments

Comments
 (0)