Skip to content

fix(workflow): show Remove from Subflow for unconnected blocks pasted into subflows#4971

Merged
waleedlatif1 merged 1 commit into
stagingfrom
fix/remove-from-subflow-context-menu
Jun 11, 2026
Merged

fix(workflow): show Remove from Subflow for unconnected blocks pasted into subflows#4971
waleedlatif1 merged 1 commit into
stagingfrom
fix/remove-from-subflow-context-menu

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Blocks copy-pasted into a loop/parallel have parentId set but no incoming edges yet, so the context menu's positional-trigger heuristic (no incoming edges = trigger) misclassified them as triggers and hid "Remove from Subflow"
  • Added isPositionalTriggerBlock helper — blocks nested inside a subflow are never classified as positional triggers regardless of edges
  • The hover action-bar was unaffected (it only checks parentId), which is why it showed the button while the right-click menu didn't

Type of Change

  • Bug fix

Testing

Added unit tests for the helper, including a regression case for a pasted, unconnected block inside a loop. All canvas utils tests pass; typecheck clean.

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)

… into subflows

A block copy-pasted into a loop/parallel has parentId set but no incoming
edges yet, so the context menu's positional-trigger heuristic (no incoming
edges = trigger) classified it as a trigger and hid Remove from Subflow.
Blocks nested inside a subflow can never be entry points, so they are now
excluded from positional-trigger classification.
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 11, 2026 6:02pm

Request Review

@cursor

cursor Bot commented Jun 11, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Small UI classification fix in the workflow canvas context menu with dedicated unit tests; no auth, API, or execution path changes.

Overview
Fixes the block right-click context menu mislabeling blocks pasted into loop/parallel subflows as positional triggers when they have no incoming edges yet, which hid Remove from Subflow (canRemoveFromSubflow requires !hasTriggerBlock).

Introduces isPositionalTriggerBlock: a top-level block with no incoming edges counts as a positional trigger; any block with parentId is never treated as one. workflow.tsx passes that helper into BlockMenu instead of inline edge counting. Unit tests cover nested/unconnected and regression paste-into-loop cases.

Reviewed by Cursor Bugbot for commit e8a8cd3. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit e8a8cd3. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a bug where the "Remove from Subflow" context menu option was hidden for blocks that were copy-pasted into a loop or parallel subflow. Pasted blocks have parentId set immediately but no incoming edges yet, so the old inline heuristic (edges.filter(e => e.target === id).length === 0) classified them as positional triggers and suppressed the option.

  • Extracts the trigger-classification heuristic into a named helper isPositionalTriggerBlock in workflow-canvas-helpers.ts, which short-circuits to false whenever the block has a parentId (i.e., is nested in a subflow).
  • Replaces the inline edge-count expression in workflow.tsx with a call to the new helper.
  • Adds a focused unit-test suite with six cases, including the explicit regression scenario (pasted, unconnected block inside a loop).

Confidence Score: 5/5

Safe to merge — the change is a well-scoped extraction of an existing inline expression into a named, tested helper with a clear correctness invariant.

The fix is minimal and focused: one new pure helper, one call-site substitution, and six unit tests including a regression case. The parentId guard is the correct property to check — it is set synchronously when a block is pasted into a subflow, before any edges are created, which is exactly the scenario that was broken. No existing behavior is altered for top-level blocks, and the BlockInfo type already carries parentId, so the type contract is satisfied at the call site.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-canvas-helpers.ts Adds isPositionalTriggerBlock helper — logic is correct, well-documented, and properly guards against the parentId case before checking edges.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/workflow-canvas-helpers.test.ts New test file covers all key cases for isPositionalTriggerBlock, including the regression scenario for a pasted, unconnected block inside a loop.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx Replaces a one-off inline edge-count expression with a call to the new isPositionalTriggerBlock helper — minimal, correct change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Right-click block in canvas] --> B{contextMenuBlocks.length === 1?}
    B -- No --> C[isPositionalTrigger = false]
    B -- Yes --> D[isPositionalTriggerBlock called with block + edges]
    D --> E{block defined?}
    E -- No --> F[return false]
    E -- Yes --> G{block.parentId set?}
    G -- Yes: nested in subflow --> H[return false — never a trigger]
    G -- No: top-level --> I{any edge targets this block?}
    I -- Yes --> J[return false — has incoming connection]
    I -- No --> K[return true — positional trigger]
    H --> L{Show Remove from Subflow?}
    J --> L
    K --> L
    C --> L
    L -- isPositionalTrigger=true --> M[Hide Remove from Subflow]
    L -- isPositionalTrigger=false --> N[Show Remove from Subflow if parentId is set]
Loading

Reviews (2): Last reviewed commit: "fix(workflow): show Remove from Subflow ..." | Re-trigger Greptile

@waleedlatif1 waleedlatif1 merged commit d41f0a0 into staging Jun 11, 2026
15 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/remove-from-subflow-context-menu branch June 11, 2026 18:17
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.

1 participant