feat(canvas): added the ability to lock blocks#3102
Merged
waleedlatif1 merged 34 commits intostagingfrom Feb 4, 2026
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Resolved conflicts: - Removed addBlock from store (now using batchAddBlocks) - Updated lock tests to use test helper addBlock function - Kept both staging's optimization tests and lock feature tests Co-Authored-By: Claude Opus 4.5 <[email protected]>
When duplicating a block that's inside a locked loop/parallel, the duplicate is now placed outside the container since nothing should be added to a locked container. Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Server-side workflow duplication now sets locked: false for all blocks - regenerateWorkflowStateIds also unlocks blocks for templates - Client-side regenerateBlockIds already handled this (for paste/import) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Contributor
Greptile OverviewGreptile SummaryThis PR implements a comprehensive block locking feature that prevents editing, deletion, and movement of workflow blocks. The implementation includes:
The lock feature cascades to children when locking loop/parallel containers, and provides clear user notifications when operations are blocked due to lock status. Confidence Score: 4/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant User
participant UI as Workflow UI
participant Store as Workflow Store
participant Hook as Collaborative Hook
participant Socket as Socket Server
participant DB as Database
Note over User,DB: Lock/Unlock Block Flow
User->>UI: Right-click block(s) → Lock
UI->>Hook: collaborativeBatchToggleLocked(blockIds)
Hook->>Store: batchToggleLocked(blockIds)
Note over Store: Collect blocks + children<br/>(if loop/parallel)
Note over Store: Determine target: !firstBlock.locked
Store->>Store: Update locked state for all blocks
Hook->>Hook: Record undo/redo operation
Hook->>Socket: Emit BATCH_TOGGLE_LOCKED operation
Socket->>DB: Update workflow_blocks.locked
Socket-->>Hook: Broadcast to collaborators
Hook->>Store: Apply remote lock changes
Note over User,DB: Protection Enforcement
User->>UI: Try to delete locked block
UI->>UI: filterProtectedBlocks()
alt All blocks protected
UI->>User: Show notification: Cannot delete locked blocks
else Some protected
UI->>User: Show notification: Skipped N protected blocks
UI->>Hook: collaborativeBatchRemoveBlocks(deletableIds)
end
User->>UI: Try to drag locked block
Note over UI: draggable={!isBlockProtected(id)}
UI-->>User: Drag prevented (React Flow)
User->>UI: Try to connect to locked block
UI->>UI: isEdgeProtected(connection)
UI->>User: Show notification: Cannot connect to locked blocks
User->>UI: Try to rename locked block
UI->>Hook: collaborativeUpdateBlockName()
Hook->>Hook: Check if block.locked || parent.locked
Hook->>User: Show notification: Cannot rename locked blocks
Note over User,DB: Duplicate with Locked Parent
User->>UI: Duplicate block inside locked loop
UI->>Store: duplicateBlock(blockId)
Store->>Store: Check if parent.locked
Note over Store: Place outside container<br/>Remove parentId
Store->>Store: Create unlocked duplicate
Store->>UI: New block outside locked container
|
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx
Outdated
Show resolved
Hide resolved
...sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/editor.tsx
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
Outdated
Show resolved
Hide resolved
- Fix toggle enabled using first toggleable block, not first block - Delete button now checks isParentLocked - Lock button now has disabled state - Editor lock icon distinguishes block vs parent lock state Co-Authored-By: Claude Opus 4.5 <[email protected]>
- Editor: can't unlock block if parent container is locked - Action bar: can't unlock block if parent container is locked - Shows "Parent container is locked" tooltip in both cases Co-Authored-By: Claude Opus 4.5 <[email protected]>
Block Menu, Editor, Action Bar now all have identical behavior: - Enable/Disable: disabled when locked OR parent locked - Flip Handles: disabled when locked OR parent locked - Delete: disabled when locked OR parent locked - Remove from Subflow: disabled when locked OR parent locked - Lock: always available for admins - Unlock: disabled when parent is locked (unlock parent first) Co-Authored-By: Claude Opus 4.5 <[email protected]>
Same pattern as lock: must enable parent container first before enabling children inside it. Co-Authored-By: Claude Opus 4.5 <[email protected]>
Added documentation for the lock/unlock block feature (admin only). Note: Image placeholder added, pending actual screenshot. Co-Authored-By: Claude Opus 4.5 <[email protected]>
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/block-menu/block-menu.tsx
Show resolved
Hide resolved
Paste creates new blocks, doesn't modify selected ones. Changed from disableEdit (includes lock state) to !userCanEdit (permission only), matching the Duplicate action behavior. Co-Authored-By: Claude Opus 4.5 <[email protected]>
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
Outdated
Show resolved
Hide resolved
Based on audit findings, adds lock validation to multiple operations: 1. BATCH_TOGGLE_HANDLES - now skips locked/protected blocks at: - Store layer (batchToggleHandles) - Collaborative hook (collaborativeBatchToggleBlockHandles) - Server socket handler 2. BATCH_ADD_BLOCKS - server now filters blocks being added to locked parent containers 3. BATCH_UPDATE_PARENT - server now: - Skips protected blocks (locked or inside locked container) - Prevents moving blocks into locked containers All validations use consistent isProtected() helper that checks both direct lock and parent container lock. Co-Authored-By: Claude Opus 4.5 <[email protected]>
contextMenuBlocks already has locked and isParentLocked properties computed in use-canvas-context-menu.ts, so there's no need to look up blocks again via hasProtectedBlocks. Co-Authored-By: Claude Opus 4.5 <[email protected]>
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/utils/block-protection-utils.ts
Outdated
Show resolved
Hide resolved
- Resolved merge conflict in editor.tsx (kept lock checking logic) - Removed unused hasProtectedBlocks function from block-protection-utils.ts Co-Authored-By: Claude Opus 4.5 <[email protected]>
Defense-in-depth: although the UI disables rename for locked blocks, the collaborative layer and server now also validate locks. - collaborativeUpdateBlockName: checks if block is locked or inside locked container before attempting rename - UPDATE_NAME server handler: checks lock status and parent lock before performing database update Co-Authored-By: Claude Opus 4.5 <[email protected]>
Collaborator
Author
|
@greptile |
Defense-in-depth: adds lock checks to server-side handlers that were previously relying only on client-side validation. Edge operations (ADD, REMOVE, BATCH_ADD, BATCH_REMOVE): - Check if source or target blocks are protected before modifying edges Subblock updates: - Check if parent block is protected before updating subblock values Co-Authored-By: Claude Opus 4.5 <[email protected]>
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx
Show resolved
Hide resolved
…ent tooltip
- Fixed edge operations to fetch parent blocks before checking lock status
- Previously, isBlockProtected checked if parent was locked, but the parent
wasn't in blocksById because only source/target blocks were fetched
- Now fetches parent blocks for all four edge operations: ADD, REMOVE,
BATCH_ADD_EDGES, BATCH_REMOVE_EDGES
- Fixed tooltip inconsistency: changed "Run previous blocks first" to
"Run upstream blocks first" in action-bar to match workflow.tsx
Co-Authored-By: Claude Opus 4.5 <[email protected]>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/action-bar/action-bar.tsx
Show resolved
Hide resolved
apps/sim/app/workspace/[workspaceId]/w/[workflowId]/workflow.tsx
Outdated
Show resolved
Hide resolved
- Added lock check to duplicate button in action bar to prevent duplicating locked blocks (consistent with other edit operations) - Removed ineffective early return in onNodeDragStart since the `draggable` property on nodes already prevents dragging protected blocks - the early return was misleading as it couldn't actually stop a drag operation Co-Authored-By: Claude Opus 4.5 <[email protected]>
Changed duplicate menu item to use disableEdit (which includes lock check) instead of !userCanEdit for consistency with action bar and other edit operations. Co-Authored-By: Claude Opus 4.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Type of Change
Testing
Tested manually
Checklist