mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
improvement(subflow): resize vertical height estimate (#2428)
* improvement(node-dims): share constants for node padding * fix vertical height estimation
This commit is contained in:
committed by
GitHub
parent
9a6c68789d
commit
8775e76c32
@@ -252,23 +252,12 @@ export function useNodeUtilities(blocks: Record<string, any>) {
|
||||
*/
|
||||
const calculateLoopDimensions = useCallback(
|
||||
(nodeId: string): { width: number; height: number } => {
|
||||
const minWidth = CONTAINER_DIMENSIONS.DEFAULT_WIDTH
|
||||
const minHeight = CONTAINER_DIMENSIONS.DEFAULT_HEIGHT
|
||||
|
||||
// Match styling in subflow-node.tsx:
|
||||
// - Header section: 50px total height
|
||||
// - Content area: px-[16px] pb-[0px] pt-[16px] pr-[70px]
|
||||
// Left padding: 16px, Right padding: 64px, Top padding: 16px, Bottom padding: -6px (reduced by additional 6px from 0 to achieve 14px total reduction from original 8px)
|
||||
// - Children are positioned relative to the content area (after header, inside padding)
|
||||
const headerHeight = 50
|
||||
const leftPadding = 16
|
||||
const rightPadding = 80
|
||||
const topPadding = 16
|
||||
const bottomPadding = 16
|
||||
|
||||
const childNodes = getNodes().filter((node) => node.parentId === nodeId)
|
||||
if (childNodes.length === 0) {
|
||||
return { width: minWidth, height: minHeight }
|
||||
return {
|
||||
width: CONTAINER_DIMENSIONS.DEFAULT_WIDTH,
|
||||
height: CONTAINER_DIMENSIONS.DEFAULT_HEIGHT,
|
||||
}
|
||||
}
|
||||
|
||||
let maxRight = 0
|
||||
@@ -276,21 +265,21 @@ export function useNodeUtilities(blocks: Record<string, any>) {
|
||||
|
||||
childNodes.forEach((node) => {
|
||||
const { width: nodeWidth, height: nodeHeight } = getBlockDimensions(node.id)
|
||||
|
||||
// Child positions are relative to content area's inner top-left (inside padding)
|
||||
// Calculate the rightmost and bottommost edges of children
|
||||
const rightEdge = node.position.x + nodeWidth
|
||||
const bottomEdge = node.position.y + nodeHeight
|
||||
|
||||
maxRight = Math.max(maxRight, rightEdge)
|
||||
maxBottom = Math.max(maxBottom, bottomEdge)
|
||||
maxRight = Math.max(maxRight, node.position.x + nodeWidth)
|
||||
maxBottom = Math.max(maxBottom, node.position.y + nodeHeight)
|
||||
})
|
||||
|
||||
// Container dimensions = header + padding + children bounds + padding
|
||||
// Width: left padding + max child right edge + right padding (64px)
|
||||
const width = Math.max(minWidth, leftPadding + maxRight + rightPadding)
|
||||
// Height: header + top padding + max child bottom edge + bottom padding (8px)
|
||||
const height = Math.max(minHeight, headerHeight + topPadding + maxBottom + bottomPadding)
|
||||
const width = Math.max(
|
||||
CONTAINER_DIMENSIONS.DEFAULT_WIDTH,
|
||||
CONTAINER_DIMENSIONS.LEFT_PADDING + maxRight + CONTAINER_DIMENSIONS.RIGHT_PADDING
|
||||
)
|
||||
const height = Math.max(
|
||||
CONTAINER_DIMENSIONS.DEFAULT_HEIGHT,
|
||||
CONTAINER_DIMENSIONS.HEADER_HEIGHT +
|
||||
CONTAINER_DIMENSIONS.TOP_PADDING +
|
||||
maxBottom +
|
||||
CONTAINER_DIMENSIONS.BOTTOM_PADDING
|
||||
)
|
||||
|
||||
return { width, height }
|
||||
},
|
||||
|
||||
@@ -18,7 +18,7 @@ import { useShallow } from 'zustand/react/shallow'
|
||||
import type { OAuthConnectEventDetail } from '@/lib/copilot/tools/client/other/oauth-request-access'
|
||||
import { createLogger } from '@/lib/logs/console/logger'
|
||||
import type { OAuthProvider } from '@/lib/oauth'
|
||||
import { BLOCK_DIMENSIONS, CONTAINER_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions'
|
||||
import { CONTAINER_DIMENSIONS } from '@/lib/workflows/blocks/block-dimensions'
|
||||
import { TriggerUtils } from '@/lib/workflows/triggers/triggers'
|
||||
import { useWorkspacePermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
|
||||
import {
|
||||
@@ -177,6 +177,7 @@ const WorkflowContent = React.memo(() => {
|
||||
resizeLoopNodes,
|
||||
updateNodeParent: updateNodeParentUtil,
|
||||
getNodeAnchorPosition,
|
||||
getBlockDimensions,
|
||||
} = useNodeUtilities(blocks)
|
||||
|
||||
/** Triggers immediate subflow resize without delays. */
|
||||
@@ -1512,43 +1513,32 @@ const WorkflowContent = React.memo(() => {
|
||||
if (!parentId) return
|
||||
|
||||
setDisplayNodes((currentNodes) => {
|
||||
// Find all children of this container from current displayNodes
|
||||
const childNodes = currentNodes.filter((n) => n.parentId === parentId)
|
||||
if (childNodes.length === 0) return currentNodes
|
||||
|
||||
// Calculate dimensions using current positions from displayNodes
|
||||
// Match padding values from use-node-utilities.ts calculateLoopDimensions
|
||||
const headerHeight = 50
|
||||
const leftPadding = 16
|
||||
const rightPadding = 80
|
||||
const topPadding = 16
|
||||
const bottomPadding = 16
|
||||
const minWidth = CONTAINER_DIMENSIONS.DEFAULT_WIDTH
|
||||
const minHeight = CONTAINER_DIMENSIONS.DEFAULT_HEIGHT
|
||||
|
||||
let maxRight = 0
|
||||
let maxBottom = 0
|
||||
|
||||
childNodes.forEach((node) => {
|
||||
// Use the dragged node's live position, others from displayNodes
|
||||
const nodePosition = node.id === draggedNodeId ? draggedNodePosition : node.position
|
||||
const { width: nodeWidth, height: nodeHeight } = getBlockDimensions(node.id)
|
||||
|
||||
// Get dimensions - use block store for height estimates
|
||||
const blockData = blocks[node.id]
|
||||
const nodeWidth = BLOCK_DIMENSIONS.FIXED_WIDTH
|
||||
const nodeHeight = blockData?.height || node.height || BLOCK_DIMENSIONS.MIN_HEIGHT
|
||||
|
||||
const rightEdge = nodePosition.x + nodeWidth
|
||||
const bottomEdge = nodePosition.y + nodeHeight
|
||||
|
||||
maxRight = Math.max(maxRight, rightEdge)
|
||||
maxBottom = Math.max(maxBottom, bottomEdge)
|
||||
maxRight = Math.max(maxRight, nodePosition.x + nodeWidth)
|
||||
maxBottom = Math.max(maxBottom, nodePosition.y + nodeHeight)
|
||||
})
|
||||
|
||||
const newWidth = Math.max(minWidth, leftPadding + maxRight + rightPadding)
|
||||
const newHeight = Math.max(minHeight, headerHeight + topPadding + maxBottom + bottomPadding)
|
||||
const newWidth = Math.max(
|
||||
CONTAINER_DIMENSIONS.DEFAULT_WIDTH,
|
||||
CONTAINER_DIMENSIONS.LEFT_PADDING + maxRight + CONTAINER_DIMENSIONS.RIGHT_PADDING
|
||||
)
|
||||
const newHeight = Math.max(
|
||||
CONTAINER_DIMENSIONS.DEFAULT_HEIGHT,
|
||||
CONTAINER_DIMENSIONS.HEADER_HEIGHT +
|
||||
CONTAINER_DIMENSIONS.TOP_PADDING +
|
||||
maxBottom +
|
||||
CONTAINER_DIMENSIONS.BOTTOM_PADDING
|
||||
)
|
||||
|
||||
// Update the container node's dimensions in displayNodes
|
||||
return currentNodes.map((node) => {
|
||||
if (node.id === parentId) {
|
||||
const currentWidth = node.data?.width || CONTAINER_DIMENSIONS.DEFAULT_WIDTH
|
||||
@@ -1570,7 +1560,7 @@ const WorkflowContent = React.memo(() => {
|
||||
})
|
||||
})
|
||||
},
|
||||
[blocks]
|
||||
[blocks, getBlockDimensions]
|
||||
)
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,6 +24,10 @@ export const CONTAINER_DIMENSIONS = {
|
||||
MIN_WIDTH: 400,
|
||||
MIN_HEIGHT: 200,
|
||||
HEADER_HEIGHT: 50,
|
||||
LEFT_PADDING: 16,
|
||||
RIGHT_PADDING: 80,
|
||||
TOP_PADDING: 16,
|
||||
BOTTOM_PADDING: 16,
|
||||
} as const
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user