Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • fix subflow resize on drag, children deselected in subflow on drag

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel
Copy link

vercel bot commented Jan 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Review Updated (UTC)
docs Skipped Skipped Jan 11, 2026 7:27pm

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 11, 2026

Greptile Overview

Greptile Summary

This PR successfully fixes two related issues with subflow container behavior:

Key Improvements

1. Unified Container Dimension Calculation

  • Extracts calculateContainerDimensions as a single source of truth for container sizing
  • Bug fix: Old code omitted LEFT_PADDING in calculateLoopDimensions but included it during drag updates, causing dimension jumps
  • New implementation ensures consistent calculations across live drag updates and final dimension sync
  • Child positions are correctly interpreted as relative to content area, requiring LEFT_PADDING + maxRight + RIGHT_PADDING for total width

2. Parent-Child Selection Conflict Resolution

  • Replaces deferred selection mechanism with resolveParentChildSelectionConflicts function
  • Automatically deselects children when their parent container is selected
  • Applied in three critical locations: onNodesChange, onSelectionEnd, and onSelectionDragStart
  • Prevents the "wiggle" behavior during drag operations
  • Includes performance optimization: returns original array if no conflicts detected

3. Improved Paste/Duplicate Selection

  • Replaces selectNodesDeferred with pendingSelectionRef mechanism
  • Selection state properly synchronized with React Flow's controlled state
  • Applies parent-child conflict resolution to paste operations

Architecture

The changes follow a clean separation of concerns:

  • use-node-utilities.ts: Pure dimension calculation logic
  • workflow-canvas-helpers.ts: Selection conflict resolution utilities
  • workflow.tsx: Orchestration and state management

Issues Found

Minor race condition (low severity): Rapid successive paste operations could overwrite pending selections. See inline comment for details.

Confidence Score: 4/5

  • This PR is safe to merge with one minor theoretical race condition that is unlikely to manifest in normal usage
  • Score of 4 reflects solid implementation with proper architectural separation and bug fixes. The PR successfully addresses the stated issues (subflow resize during drag and parent-child selection conflicts). The unified dimension calculation fixes a real bug where containers would jump between different sizes during vs after drag. The parent-child conflict resolution is well-designed with performance optimizations. One point deducted for: (1) minor race condition with rapid successive pastes, and (2) lack of automated tests despite PR checklist indicating tests should be added/updated. The changes are backwards compatible and the manual testing approach is reasonable for UI interaction bugs.
  • Pay close attention to workflow.tsx around the pendingSelectionRef mechanism (lines 1954-1975) if rapid paste operations are part of your testing scenarios

Important Files Changed

File Analysis

Filename Score Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/use-node-utilities.ts 4/5 Extracts calculateContainerDimensions as unified function; fixes missing LEFT_PADDING in width calculation for consistency between drag and final resize
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-canvas-helpers.ts 5/5 Removes selectNodesDeferred, adds resolveParentChildSelectionConflicts to prevent parent-child selection conflicts; logic is sound with proper performance optimization
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx 3/5 Implements pendingSelectionRef mechanism for paste/duplicate operations, applies parent-child conflict resolution in multiple locations; has minor race condition risk with rapid successive pastes
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/hooks/index.ts 5/5 Updates exports to replace selectNodesDeferred with resolveParentChildSelectionConflicts and adds calculateContainerDimensions export

Sequence Diagram

sequenceDiagram
    participant User
    participant ReactFlow
    participant workflow.tsx
    participant useNodeUtilities
    participant helpers as workflow-canvas-helpers
    participant Store

    Note over User,Store: Subflow Container Resize During Drag

    User->>ReactFlow: Drag child node inside container
    ReactFlow->>workflow.tsx: onNodeDrag(nodeId, position)
    workflow.tsx->>workflow.tsx: updateContainerDimensionsDuringDrag()
    workflow.tsx->>useNodeUtilities: getBlockDimensions(childId)
    useNodeUtilities-->>workflow.tsx: {width, height}
    workflow.tsx->>useNodeUtilities: calculateContainerDimensions(childPositions)
    Note over useNodeUtilities: Single source of truth:<br/>LEFT_PADDING + maxRight + RIGHT_PADDING<br/>HEADER + TOP_PADDING + maxBottom + BOTTOM
    useNodeUtilities-->>workflow.tsx: {width, height}
    workflow.tsx->>workflow.tsx: setDisplayNodes (update container dimensions)
    ReactFlow-->>User: Visual feedback (container resizes live)

    User->>ReactFlow: Drop child node
    ReactFlow->>workflow.tsx: onNodeDragStop()
    workflow.tsx->>Store: collaborativeBatchUpdatePositions()
    Store->>workflow.tsx: blocks updated
    workflow.tsx->>useNodeUtilities: calculateLoopDimensions()
    useNodeUtilities->>useNodeUtilities: calculateContainerDimensions(childPositions)
    Note over useNodeUtilities: Same calculation as during drag<br/>ensures no dimension jump
    useNodeUtilities-->>workflow.tsx: {width, height}
    workflow.tsx->>Store: updateNodeDimensions()

    Note over User,Store: Parent-Child Selection Conflict Resolution

    User->>ReactFlow: Select parent container
    ReactFlow->>workflow.tsx: onNodesChange([{type: 'select'}])
    workflow.tsx->>workflow.tsx: applyNodeChanges()
    workflow.tsx->>helpers: resolveParentChildSelectionConflicts(nodes, blocks)
    Note over helpers: Check each selected node:<br/>if parent also selected → deselect child
    helpers-->>workflow.tsx: resolved nodes
    workflow.tsx->>workflow.tsx: setDisplayNodes()
    ReactFlow-->>User: Only parent selected (children deselected)

    Note over User,Store: Paste with Selection

    User->>workflow.tsx: Paste (Cmd+V)
    workflow.tsx->>workflow.tsx: pendingSelectionRef = new Set(pastedIds)
    workflow.tsx->>Store: collaborativeBatchAddBlocks()
    Store->>workflow.tsx: blocks updated
    Note over workflow.tsx: derivedNodes recomputes
    workflow.tsx->>workflow.tsx: useEffect [derivedNodes, blocks]
    workflow.tsx->>workflow.tsx: Check pendingSelectionRef
    workflow.tsx->>helpers: resolveParentChildSelectionConflicts(withSelection, blocks)
    helpers-->>workflow.tsx: resolved selection
    workflow.tsx->>workflow.tsx: setDisplayNodes() + clear pendingSelectionRef
    ReactFlow-->>User: Pasted nodes selected (respecting parent-child rules)
Loading

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

@waleedlatif1
Copy link
Collaborator Author

@greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@waleedlatif1 waleedlatif1 merged commit 4941b52 into staging Jan 11, 2026
6 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/resize branch January 12, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants