Skip to content

Conversation

@waleedlatif1
Copy link
Collaborator

Summary

  • Use panel-aware getViewportCenter from useCanvasViewport hook instead of naive rect.width/2 calculation
  • Blocks now paste/place at the true visible center accounting for sidebar, terminal, and side panel
  • Refactored getVisibleCanvasCenter to reuse getVisibleCanvasBounds (removed duplicate code)
  • Removed unused isInvitationsDisabled and handleContextInvite

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 27, 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 27, 2026 8:17pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 27, 2026

Greptile Overview

Greptile Summary

This PR fixes viewport center calculation for block paste and placement operations by using panel-aware bounds from the useCanvasViewport hook instead of naive rect.width/2 calculations.

Key Changes:

  • Replaced local getViewportCenter function with getViewportCenter() from useCanvasViewport hook that properly accounts for sidebar, terminal, and side panel overlays
  • Refactored getVisibleCanvasCenter in the hook to reuse getVisibleCanvasBounds, eliminating duplicate bounds calculation logic
  • Enhanced executePasteOperation to support pasting into subflows with proper validation (prevents triggers and nested subflows) and position clamping
  • Added smart offset handling in regenerateBlockIds - caps large viewport-based offsets to DEFAULT_DUPLICATE_OFFSET (180,20) for blocks remaining in existing subflows, since large offsets don't make sense for relative positions
  • Removed unused isInvitationsDisabled, handleContextInvite, and deleted entire server-utils.ts file as wrapper functions are no longer needed
  • Added comprehensive test coverage for the new regenerateBlockIds logic

Impact:
Blocks now paste/place at the true visible center of the canvas, improving UX when panels are open.

Confidence Score: 5/5

  • This PR is safe to merge - well-tested refactoring with clear improvements to viewport calculations
  • Score reflects comprehensive test coverage, clean refactoring that eliminates code duplication, proper validation logic for subflow pasting, and smart offset handling that accounts for different paste contexts. The changes are backward-compatible and improve user experience.
  • No files require special attention

Important Files Changed

Filename Overview
apps/sim/hooks/use-canvas-viewport.ts Refactored getVisibleCanvasCenter to reuse getVisibleCanvasBounds, eliminating duplicate logic. Clean refactoring with no issues.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx Replaced naive viewport center calculation with panel-aware getViewportCenter hook, removed unused code, added subflow paste support with proper validation.
apps/sim/stores/workflows/utils.ts Added smart offset handling for viewport-based vs duplicate offsets, improved parentId preservation logic for subflow children, removed unused code.

Sequence Diagram

sequenceDiagram
    participant User
    participant Workflow
    participant useCanvasViewport
    participant getVisibleCanvasBounds
    participant calculatePasteOffset
    participant executePasteOperation
    participant regenerateBlockIds

    User->>Workflow: Paste blocks (Cmd+V or Context Menu)
    Workflow->>useCanvasViewport: getViewportCenter()
    useCanvasViewport->>getVisibleCanvasBounds: Get visible bounds
    Note over getVisibleCanvasBounds: Accounts for sidebar, panel,<br/>and terminal overlays
    getVisibleCanvasBounds-->>useCanvasViewport: Returns visible bounds
    useCanvasViewport->>useCanvasViewport: Calculate center from bounds
    useCanvasViewport->>Workflow: screenToFlowPosition(center)
    useCanvasViewport-->>Workflow: Viewport center in flow coords
    
    Workflow->>calculatePasteOffset: Calculate offset
    Note over calculatePasteOffset: Calculate clipboard center<br/>from block positions
    calculatePasteOffset-->>Workflow: Paste offset
    
    Workflow->>executePasteOperation: Execute paste
    
    alt Pasting into subflow
        executePasteOperation->>executePasteOperation: Validate (no triggers/subflows)
        executePasteOperation->>executePasteOperation: Adjust positions to relative coords
        executePasteOperation->>executePasteOperation: Clamp to container bounds
        executePasteOperation->>executePasteOperation: Set parentId and extent
    end
    
    executePasteOperation->>regenerateBlockIds: Generate new IDs
    
    alt Block has parent in existing workflow
        Note over regenerateBlockIds: Cap large viewport offset to<br/>DEFAULT_DUPLICATE_OFFSET (180,20)
        regenerateBlockIds->>regenerateBlockIds: Use capped offset
        regenerateBlockIds->>regenerateBlockIds: Preserve parentId
    else Block has parent in paste set
        regenerateBlockIds->>regenerateBlockIds: Keep relative position
        regenerateBlockIds->>regenerateBlockIds: Remap parentId to new ID
    else Top-level block
        regenerateBlockIds->>regenerateBlockIds: Apply full viewport offset
    end
    
    regenerateBlockIds-->>executePasteOperation: New blocks with remapped IDs
    executePasteOperation->>Workflow: Add blocks to workflow
    Workflow-->>User: Blocks pasted at viewport center
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.

1 file reviewed, 1 comment

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.

No files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

@waleedlatif1 waleedlatif1 merged commit dddd0c8 into staging Jan 27, 2026
12 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/duplicate branch January 27, 2026 20:36
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