feat(designer-v2): Multi-node selection, hotkey improvements#9231
Open
rllyy97 wants to merge 24 commits into
Open
feat(designer-v2): Multi-node selection, hotkey improvements#9231rllyy97 wants to merge 24 commits into
rllyy97 wants to merge 24 commits into
Conversation
…p-in-scope Implement first-pass multi-selection in the DesignerV2 workflow editor: - Shift-click toggles nodes in a selection set (OperationCardNode, ScopeCardNode). - Box/marquee selection re-enabled in DesignerReactFlow (selectionOnDrag, SelectionMode.Partial, panOnDrag mouse buttons), filtered to operation/scope nodes. - panelSlice tracks canonical selectedNodeIds; reconciles to selectedNodeId (1) and alternateSelectedNode (2, side-by-side) for the existing single/dual panels. - New MultiSelectPanel (>2 selected) lists nodes with a batch Delete action. - Wrap-in-scope actions (Scope, Condition) shown when selected nodes are on the same graph level and contiguous/connected, via canWrapSelectedNodes contiguity analysis. - New deleteOperations batch thunk, wrapSelectedNodesInScope thunk, and wrapNodesInScope workflow reducer for graph restructuring + runAfter rewiring. Adds unit tests for the multiselect contiguity utils and panelSlice selection reducers. Switch/Agent wrap types are intentionally deferred for this first pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
🤖 AI PR Validation ReportPR Review ResultsThank you for your submission! Here's detailed feedback on your PR title and body compliance:✅ PR Title
✅ Commit Type
|
| Section | Status | Recommendation |
|---|---|---|
| Title | ✅ | |
| Commit Type | ✅ | |
| Risk Level | Update to High |
|
| What & Why | ✅ | |
| Impact of Change | Mention broader UI/workflow surface area | |
| Test Plan | ✅ | |
| Contributors | ✅ | Optional add credit |
| Screenshots/Videos | ✅ |
The PR passes review, but I advise raising the risk level from Medium to High based on the breadth and impact of the changes. Please update the PR body accordingly if you want the submitted risk to match the diff.
Last updated: Fri, 05 Jun 2026 05:04:32 GMT
Contributor
There was a problem hiding this comment.
Pull request overview
Adds first-pass multi-node selection support to DesignerV2, including a new multi-select details panel, batch delete, and “wrap in scope/condition” operations that restructure the workflow graph.
Changes:
- Introduces canonical multi-selection state in the panel slice (
selectedNodeIds) with reconciliation back to existing 1-node / 2-node panel behavior. - Re-enables ReactFlow box selection and wires selection events + shift-click toggling into Redux selection state.
- Adds multi-select utilities + tests, plus new wrap-in-scope thunk/reducer and batch delete thunk.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| Localize/lang/strings.json | Adds new localized strings for multi-select panel and wrap actions. |
| libs/designer-v2/src/lib/ui/panel/panelRoot.tsx | Routes Operation panel rendering to MultiSelectPanel when >2 nodes are selected. |
| libs/designer-v2/src/lib/ui/panel/multiSelectPanel/multiSelectPanel.tsx | New multi-select panel UI with selected list, wrap actions, and batch delete. |
| libs/designer-v2/src/lib/ui/panel/multiSelectPanel/multiSelectPanel.styles.ts | Fluent v9 makeStyles styling for MultiSelectPanel. |
| libs/designer-v2/src/lib/ui/DesignerReactFlow.tsx | Re-enables marquee selection and syncs selection changes into Redux. |
| libs/designer-v2/src/lib/ui/CustomNodes/ScopeCardNode.tsx | Adds shift-click toggling and multi-select highlighting for scope nodes. |
| libs/designer-v2/src/lib/ui/CustomNodes/OperationCardNode.tsx | Adds shift-click toggling and multi-select highlighting for operation nodes. |
| libs/designer-v2/src/lib/ui/CustomNodes/components/card/actionCard.tsx | Forwards MouseEvent through onClick to enable shift-click detection upstream. |
| libs/designer-v2/src/lib/core/utils/multiselect.ts | Adds utilities to validate same-graph contiguous chain selection for wrap eligibility. |
| libs/designer-v2/src/lib/core/utils/test/multiselect.spec.ts | Adds unit tests for multiselect chain/graph eligibility logic. |
| libs/designer-v2/src/lib/core/state/workflow/workflowSlice.ts | Adds workflow reducer to wrap selected nodes into a new scope/condition container. |
| libs/designer-v2/src/lib/core/state/panel/panelTypes.ts | Adds selectedNodeIds to operation panel state. |
| libs/designer-v2/src/lib/core/state/panel/panelSlice.ts | Adds set/toggle selection reducers and reconciliation to existing panel selection model. |
| libs/designer-v2/src/lib/core/state/panel/panelSelectors.ts | Adds selectors for selectedNodeIds, multi-select membership, and wrap eligibility. |
| libs/designer-v2/src/lib/core/state/panel/test/panelSlice.multiselect.spec.ts | Adds tests validating selection reconciliation behavior for 0/1/2/>2 selections. |
| libs/designer-v2/src/lib/core/actions/bjsworkflow/wrapInScope.ts | Adds thunk to create a new scope/condition and move selected nodes inside it. |
| libs/designer-v2/src/lib/core/actions/bjsworkflow/delete.ts | Adds batch delete thunk for deleting multiple selected nodes. |
Contributor
|
📊 Coverage check completed. See workflow run for details. |
…+drag The multi-select feature swapped left-click drag from panning to marquee selection, which regressed the default canvas pan gesture. Restore panOnDrag to all buttons (left/middle/right) and gate the selection box behind the Shift key via react-flow's selectionKeyCode, matching react-flow defaults. Drop Shift from multiSelectionKeyCode so it no longer conflicts with the shift-click node toggle. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Commit box/marquee selection only on release instead of continuously during drag, so the panel no longer re-renders while dragging. - Gate the multi-select Delete action behind a confirmation dialog instead of deleting immediately. - Verified wrap-in-Condition nests the selected nodes in the true block. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When wrapping selected nodes in a Condition, the first moved node is now chained off the subgraph header (Condition-actions-#subgraph) so ELK lays it out inside the 'true' branch (below the header) instead of beside the true/false branch labels. Adds a reducer regression test covering the header->first-node edge for both Condition and Scope wraps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The delete confirmation dialog now lists each selected action (icon + display name) so users can see exactly what will be removed before confirming. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…i-copy, selection box styling - Add right-click bulk context menu (Delete/Copy N actions) when right-clicking a node that is part of a multi-selection - Extract a shared redux-driven MultiSelectDeleteModal (rendered at Designer level) so the delete confirmation with action list works from both the multi-select panel and the canvas context menu - Add copyOperations thunk that writes a multi-node clipboard payload; handle isMultiNode paste (reverse, sequential) in dropzone and EdgeContextualMenu - Style the selection box: 8px border-radius + 8px padding Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ine box styling Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ion race - Add Delete/Backspace, Ctrl+D (duplicate), and Ctrl+A (select all) hotkeys - Ctrl/Meta-click behaves like Shift-click for multi-select - Ctrl+A includes triggers via useAllSelectableNodeIds - Fix marquee selection randomly committing no nodes by committing from whichever of onSelectionEnd/onSelectionChange fires last, with empty-guard and dedupe to avoid echo loops - Guard multi-select panel against Escape clearing selection on delete dialog Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replaces the bespoke header in MultiSelectPanelBody with the shared PanelHeader component so the multi-select drawer matches the chrome of every other panel. Adds a customIcon prop on PanelHeader and renders a primary-background count badge in its place. Overflow (...) button now hides automatically when headerItems is empty. PanelContainer customContent path lets the multi-select panel reuse the same Drawer infrastructure (mountNode, resize, position) instead of a one-off Drawer. Also folds in the shift-click-to-deselect fix (stopPropagation on modifier-key clicks in OperationCardNode and ScopeCardNode so React Flow's own shift-select logic doesn't clobber our toggle reducer), removes the FocusTrapZone wrapper that was swallowing canvas clicks while the panel was open, and keeps the existing delete-modal Escape guard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The msla-panel-layout div needs the msla-panel-border-selected class to render the panel chrome (background + border) — without it the multi-select content floats over the canvas with no visible drawer frame. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…vents Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add Ctrl+C/X canvas-level hotkeys for copy/cut operations - Convert paste option to split button (inline paste + parallel submenu) - Fix panel width: 480px single/multi-select, 680px dual-view - Fix NodeDetailsPanel overrideWidth initialization - Fix chevron click closing edge menu via stopPropagation
- Switch Drawer from type='inline' to type='overlay' so panel floats over canvas - Add PanelViewportShift component that detects when selected node is behind panel - Animate canvas translation (300ms) to keep selected node visible - Reverse the shift when panel closes - Re-apply Ctrl+C hotkey for copy, split button paste, panel width fixes
ccastrotrejo
approved these changes
Jun 4, 2026
…com/Azure/LogicAppsUX into rllyy97/designer-v2-multi-selection
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.
Commit Type
Risk Level
Changes are specific to DesignerV2, and are utilizing mostly existing pre-exisisting workflow modification functions.
What & Why
Adds multi-node selection capabilities to the designer-v2 canvas, enabling users to select multiple workflow actions and perform batch operations on them.
Key features:
Impact of Change
selectedNodeIdsin panel slice), new selectors (useIsNodeInMultiSelection,useSelectedNodeIds), new thunks (copyOperations,cutOperations,wrapSelectedNodesInScope), and new utility module (multiselect.ts).useMemoensures React Flow node stamping is efficient. No new dependencies added.Test Plan
pnpm run start)New test files:
panelSlice.multiselect.spec.ts— Redux multi-select state management (toggle, set, clear, single-select clears multi)wrapNodesInScope.spec.ts— Wrap-in-scope reducer logic (re-parenting, runAfter rewiring)multiselect.spec.ts— Contiguity validation, wrappable node filtering, scope type utilitiesContributors
Screenshots/Videos