fix: move selected groups when dragging nodes in vueNodes mode#7306
fix: move selected groups when dragging nodes in vueNodes mode#7306christian-byrne merged 1 commit intomainfrom
Conversation
📝 WalkthroughWalkthroughAdds support for dragging LGraphGroup items alongside nodes in the node drag handler. Implementation tracks selected groups and applies delta-based movement to groups during drag operations, with cleanup on drag end. Existing per-node movement logic remains unchanged. Changes
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 12/10/2025, 02:29:23 AM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🎭 Playwright Test Results❌ Some tests failed ⏰ Completed at: 12/10/2025, 03:15:53 AM UTC 📈 Summary
📊 Test Reports by Browser
🎉 Click on the links above to view detailed test results for each browser configuration. |
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 3.22 MB (baseline 3.22 MB) • ⚪ 0 BMain entry bundles and manifests
Status: 3 added / 3 removed Graph Workspace — 988 kB (baseline 988 kB) • 🔴 +602 BGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 6.54 kB (baseline 6.54 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 1 added / 1 removed Panels & Settings — 298 kB (baseline 298 kB) • ⚪ 0 BConfiguration panels, inspectors, and settings screens
Status: 6 added / 6 removed UI Components — 178 kB (baseline 178 kB) • ⚪ 0 BReusable component library chunks
Status: 6 added / 6 removed Data & Services — 12.5 kB (baseline 12.5 kB) • ⚪ 0 BStores, services, APIs, and repositories
Status: 2 added / 2 removed Utilities & Hooks — 3.18 kB (baseline 3.18 kB) • ⚪ 0 BHelpers, composables, and utility bundles
Status: 1 added / 1 removed Vendor & Third-Party — 8.56 MB (baseline 8.56 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Other — 3.81 MB (baseline 3.81 MB) • ⚪ 0 BBundles that do not match a named category
Status: 17 added / 17 removed |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts(6 hunks)
🧰 Additional context used
📓 Path-based instructions (6)
src/**/*.{vue,ts}
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.{vue,ts}: Leverage VueUse functions for performance-enhancing styles
Implement proper error handling
Use vue-i18n in composition API for any string literals. Place new translation entries in src/locales/en/main.json
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
src/**/*.ts
📄 CodeRabbit inference engine (.github/copilot-instructions.md)
src/**/*.ts: Use es-toolkit for utility functions
Use TypeScript for type safetyMinimize the surface area (exported values) of each module and composable
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
src/**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (src/CLAUDE.md)
src/**/*.{ts,tsx,vue}: Sanitize HTML with DOMPurify to prevent XSS attacks
Avoid using @ts-expect-error; use proper TypeScript types instead
Use es-toolkit for utility functions instead of other utility libraries
Implement proper TypeScript types throughout the codebase
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
src/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (src/CLAUDE.md)
Follow Vue 3 composition API style guide
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
**/*.{ts,tsx,js,jsx,vue,json}
📄 CodeRabbit inference engine (AGENTS.md)
Code style: Use 2-space indentation, single quotes, no trailing semicolons, and 80-character line width (see
.prettierrc)
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
**/*.{ts,tsx,vue}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,vue}: Imports must be sorted and grouped by plugin; runpnpm formatbefore committing
Use TypeScript for type safety; never useanytype - use proper TypeScript types
Never useas anytype assertions; fix the underlying type issue instead
Use es-toolkit for utility functions
Write code that is expressive and self-documenting; avoid comments unless absolutely necessary; do not add or retain redundant comments
Keep functions short and functional
Minimize nesting in code (e.g., deeply nestediforforstatements); apply the Arrow Anti-Pattern principle
Avoid mutable state; prefer immutability and assignment at point of declaration
Favor pure functions, especially testable ones
Files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
🧠 Learnings (6)
📚 Learning: 2025-12-04T21:43:49.363Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7137
File: src/components/rightSidePanel/parameters/TabParameters.vue:10-0
Timestamp: 2025-12-04T21:43:49.363Z
Learning: Vue 3.5+ supports reactive props destructure in <script setup>. Destructuring props directly (e.g., `const { nodes } = defineProps<{ nodes: LGraphNode[] }>()`) maintains reactivity through compiler transformation. This is the recommended modern approach and does not require using `props.x` or `toRef`/`toRefs`.
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
📚 Learning: 2025-11-24T19:47:45.616Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: src/components/CLAUDE.md:0-0
Timestamp: 2025-11-24T19:47:45.616Z
Learning: Applies to src/components/**/*.vue : Use ref/reactive for state management in Vue 3 Composition API
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
📚 Learning: 2025-12-09T20:22:23.581Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T20:22:23.581Z
Learning: Applies to **/*.vue : Use `ref` for reactive state in Vue Composition API components
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.vue : Utilize ref and reactive for reactive state
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
📚 Learning: 2025-11-24T19:47:02.860Z
Learnt from: CR
Repo: Comfy-Org/ComfyUI_frontend PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-24T19:47:02.860Z
Learning: Applies to src/**/*.{vue,ts} : Leverage VueUse functions for performance-enhancing styles
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
📚 Learning: 2025-12-09T03:39:54.501Z
Learnt from: DrJKL
Repo: Comfy-Org/ComfyUI_frontend PR: 7169
File: src/platform/remote/comfyui/jobs/jobTypes.ts:1-107
Timestamp: 2025-12-09T03:39:54.501Z
Learning: In the ComfyUI_frontend project, Zod is on v3.x. Do not suggest Zod v4 standalone validators (z.uuid, z.ulid, z.cuid2, z.nanoid) until an upgrade to Zod 4 is performed. When reviewing TypeScript files (e.g., src/platform/remote/comfyui/jobs/jobTypes.ts) validate against Zod 3 capabilities and avoid introducing v4-specific features; flag any proposal to upgrade or incorporate v4-only validators and propose staying with compatible 3.x patterns.
Applied to files:
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts
🧬 Code graph analysis (1)
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts (2)
src/renderer/core/canvas/canvasStore.ts (1)
useCanvasStore(24-152)src/utils/litegraphUtil.ts (1)
isLGraphGroup(58-60)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: test
- GitHub Check: setup
- GitHub Check: lint-and-format
- GitHub Check: collect
🔇 Additional comments (5)
src/renderer/extensions/vueNodes/layout/useNodeDrag.ts (5)
4-4: LGTM! Imports are properly typed.The added imports for
LGraphGrouptype andisLGraphGrouphelper are appropriate for implementing group movement. AddingselectedItemsto the store refs enables access to selected groups.Also applies to: 17-17, 24-24
42-44: LGTM! State variables are properly typed and positioned.The
lastCanvasDeltaandselectedGroupsvariables follow the existing pattern for drag state management and are appropriately typed.
76-78: LGTM! Group capture is clean and type-safe.The logic correctly filters selected groups using the
isLGraphGrouptype guard and properly initializes the frame delta tracking.
1-242: Well-structured implementation that integrates cleanly with existing code.The implementation follows Vue 3 composition API best practices and coding guidelines:
- Proper TypeScript typing throughout
- No use of
anyor type assertions- Clean integration with existing drag logic
- Appropriate use of VueUse utilities
- Self-documenting code with helpful comments
The frame-based delta approach for group movement is well-reasoned and should align with LiteGraph's behavior as intended.
140-154: Frame-based delta movement for groups is implemented correctly.The third parameter
truetogroup.move()is correct—it skips moving child items, preventing unwanted recursive movement during group drag operations. Themove()method is safe and performs simple position updates without throwing exceptions, so error handling is unnecessary.
| selectedGroups = null | ||
| lastCanvasDelta = null |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n src/renderer/extensions/vueNodes/layout/useNodeDrag.ts | sed -n '150,230p'Repository: Comfy-Org/ComfyUI_frontend
Length of output: 3163
🏁 Script executed:
rg -n 'selectedGroups' src/renderer/extensions/vueNodes/layout/useNodeDrag.ts -B 3 -A 3Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1411
🏁 Script executed:
rg -n 'class.*Group|interface.*Group|type.*Group' src/renderer/extensions/vueNodes/layout/ --type=ts | head -20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 193
🏁 Script executed:
rg -n 'group\.move\|group\.position' src/renderer/extensions/vueNodes/layout/useNodeDrag.ts -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
rg -n 'applySnapToPosition|shouldSnap|snapToGrid' src/renderer/extensions/vueNodes/layout/useNodeDrag.ts -B 2 -A 2Repository: Comfy-Org/ComfyUI_frontend
Length of output: 951
🏁 Script executed:
rg -n 'snap.*grid|grid.*size|GRID' src/renderer/extensions/vueNodes/ --type=ts -i | head -15Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1989
🏁 Script executed:
find . -name 'LGraphGroup*' -o -name '*litegraph*' | grep -E '\.(ts|js)$' | head -10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 491
🏁 Script executed:
cat src/lib/litegraph/src/LGraphGroup.ts | head -100Repository: Comfy-Org/ComfyUI_frontend
Length of output: 2631
🏁 Script executed:
rg -n 'snapToGrid' src/lib/litegraph/src/litegraph.ts -B 3 -A 10 | head -50Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
rg -n 'snapToGrid' src/renderer/extensions/vueNodes/ --type=ts -B 2 -A 5Repository: Comfy-Org/ComfyUI_frontend
Length of output: 919
🏁 Script executed:
rg -n 'move\(' src/lib/litegraph/src/LGraphGroup.ts -B 3 -A 10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 670
🏁 Script executed:
rg -n 'snapToGrid|snap.*[Gg]roup' src/lib/litegraph/src/ --type=ts -B 2 -A 3Repository: Comfy-Org/ComfyUI_frontend
Length of output: 9444
🏁 Script executed:
cat src/tests-ui/tests/litegraph/core/LGraphGroup.test.ts 2>/dev/null | head -150Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
rg -n 'getAllNestedItems' src/lib/litegraph/src/ --type=ts -B 2 -A 8Repository: Comfy-Org/ComfyUI_frontend
Length of output: 4096
🏁 Script executed:
sed -n '1151,1160p' src/lib/litegraph/src/LGraph.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 339
🏁 Script executed:
rg -n 'function getAllNestedItems|export.*getAllNestedItems' src/lib/litegraph/src/ --type=tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 150
🏁 Script executed:
rg -n 'addRecursively' src/lib/litegraph/src/utils/collections.ts -B 3 -A 15Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1001
🏁 Script executed:
cat src/lib/litegraph/src/utils/collections.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 3221
🏁 Script executed:
cat src/tests-ui/tests/litegraph/core/LGraphGroup.test.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 155
🏁 Script executed:
rg -n 'snapToGrid|snap.*grid' src/tests-ui/tests/litegraph/ --type=ts -B 2 -A 4Repository: Comfy-Org/ComfyUI_frontend
Length of output: 139
🏁 Script executed:
rg -n 'LGraph.*snapToGrid|graph\.snapToGrid' src/renderer/extensions/vueNodes/ --type=tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
sed -n '1,50p' src/renderer/extensions/vueNodes/layout/useNodeDrag.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2104
🏁 Script executed:
rg -n 'LGraph\|graph\.' src/renderer/extensions/vueNodes/layout/useNodeDrag.ts | head -20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
rg -n 'snap.*comment|TODO|FIXME|XXX' src/renderer/extensions/vueNodes/layout/useNodeDrag.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 52
🏁 Script executed:
rg -n 'group.move|applySnapToPosition' src/renderer/extensions/vueNodes/layout/useNodeDrag.ts -B 3 -A 3Repository: Comfy-Org/ComfyUI_frontend
Length of output: 1204
🏁 Script executed:
sed -n '140,160p' src/renderer/extensions/vueNodes/layout/useNodeDrag.tsRepository: Comfy-Org/ComfyUI_frontend
Length of output: 794
Groups are not snapped to grid at drag end, unlike nodes.
While nodes receive snap-to-grid treatment in endDrag (lines 160-217), selected groups are only moved during drag via group.move() and are never snapped at drag completion. This creates an asymmetry in behavior. Both LGraphGroup and LGraphNode implement the snapToGrid interface, and the applySnapToPosition utility is available, so groups should also be snapped when shouldSnap(event) is true. Currently, the snap logic only executes when nodeId is present, which excludes the group snapping path.
DrJKL
left a comment
There was a problem hiding this comment.
Would this be a good time to handle Reroutes too?
DrJKL
left a comment
There was a problem hiding this comment.
Approving because this is better, but I feel like there should be a way to handle all the Positionables together.
## Summary Captures selected groups at drag start and moves them using frame delta to match LiteGraph's behavior. Litegraph doesn't have this issue. ## Screenshots (if applicable) ### Before https://github.com/user-attachments/assets/0e4ff907-376e-438b-aa89-106c146a8ac1 ### After https://github.com/user-attachments/assets/d954da99-3468-4bd8-9e1a-835e1a90a3bd ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7306-fix-move-selected-groups-when-dragging-nodes-in-vueNodes-mode-2c56d73d3650816a83efd11bbc36262e) by [Unito](https://www.unito.io)
… vueNodes mode (#7505) Backport of #7306 to `core/1.34` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7505-backport-core-1-34-fix-move-selected-groups-when-dragging-nodes-in-vueNodes-mode-2ca6d73d365081e2af2fd6a5e9599941) by [Unito](https://www.unito.io) Co-authored-by: Terry Jia <terryjia88@gmail.com>
…-Org#7306) ## Summary Captures selected groups at drag start and moves them using frame delta to match LiteGraph's behavior. Litegraph doesn't have this issue. ## Screenshots (if applicable) ### Before https://github.com/user-attachments/assets/0e4ff907-376e-438b-aa89-106c146a8ac1 ### After https://github.com/user-attachments/assets/d954da99-3468-4bd8-9e1a-835e1a90a3bd ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7306-fix-move-selected-groups-when-dragging-nodes-in-vueNodes-mode-2c56d73d3650816a83efd11bbc36262e) by [Unito](https://www.unito.io)
## Summary Captures selected groups at drag start and moves them using frame delta to match LiteGraph's behavior. Litegraph doesn't have this issue. ## Screenshots (if applicable) ### Before https://github.com/user-attachments/assets/0e4ff907-376e-438b-aa89-106c146a8ac1 ### After https://github.com/user-attachments/assets/d954da99-3468-4bd8-9e1a-835e1a90a3bd ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7306-fix-move-selected-groups-when-dragging-nodes-in-vueNodes-mode-2c56d73d3650816a83efd11bbc36262e) by [Unito](https://www.unito.io)
Summary
Captures selected groups at drag start and moves them using frame delta to match LiteGraph's behavior.
Litegraph doesn't have this issue.
Screenshots (if applicable)
Before
2025-12-09.21-25-05.mp4
After
2025-12-09.21-24-02.mp4
┆Issue is synchronized with this Notion page by Unito