Convert Group Nodes to Subgraph (#4972)

* fix: Convert groupNodes to Subgraph Properly

* fix: Use correct positioning with requestAnimationFrame when groupnodes are converted to Subgraph
This commit is contained in:
Johnpaul Chiwetelu
2025-08-19 04:58:56 +01:00
committed by GitHub
parent 30d48f2356
commit 7d2d006c07
4 changed files with 42 additions and 10 deletions

View File

@@ -0,0 +1,8 @@
/**
* Constants for group node type prefixes and separators
*
* v1 Prefix + Separator: workflow/
* v2 Prefix + Separator: workflow> (ComfyUI_frontend v1.2.63)
*/
export const PREFIX = 'workflow'
export const SEPARATOR = '>'

View File

@@ -1,3 +1,4 @@
import { PREFIX, SEPARATOR } from '@/constants/groupNodeConstants'
import { t } from '@/i18n'
import { type NodeId } from '@/lib/litegraph/src/LGraphNode'
import {
@@ -35,11 +36,6 @@ type GroupNodeWorkflowData = {
nodes: ComfyNode[]
}
// v1 Prefix + Separator: workflow/
// v2 Prefix + Separator: workflow> (ComfyUI_frontend v1.2.63)
const PREFIX = 'workflow'
const SEPARATOR = '>'
const Workflow = {
InUse: {
Free: 0,

View File

@@ -1,3 +1,4 @@
import { PREFIX, SEPARATOR } from '@/constants/groupNodeConstants'
import {
type LGraphNode,
type LGraphNodeConstructor,
@@ -13,8 +14,6 @@ import { GroupNodeConfig, GroupNodeHandler } from './groupNode'
import './groupNodeManage.css'
const ORDER: symbol = Symbol()
const PREFIX = 'workflow'
const SEPARATOR = '>'
// @ts-expect-error fixme ts strict error
function merge(target, source) {

View File

@@ -1,5 +1,6 @@
import { toString } from 'es-toolkit/compat'
import { PREFIX, SEPARATOR } from '@/constants/groupNodeConstants'
import { LinkConnector } from '@/lib/litegraph/src/canvas/LinkConnector'
import { CanvasPointer } from './CanvasPointer'
@@ -8102,7 +8103,6 @@ export class LGraphCanvas
| IContextMenuValue<(typeof LiteGraph.VALID_SHAPES)[number]>
| null
)[]
if (node.getMenuOptions) {
options = node.getMenuOptions(this)
} else {
@@ -8110,9 +8110,38 @@ export class LGraphCanvas
{
content: 'Convert to Subgraph 🆕',
callback: () => {
if (!this.selectedItems.size)
// find groupnodes, degroup and select children
if (this.selectedItems.size) {
let hasGroups = false
for (const item of this.selectedItems) {
const node = item as LGraphNode
const isGroup =
typeof node.type === 'string' &&
node.type.startsWith(`${PREFIX}${SEPARATOR}`)
if (isGroup && node.convertToNodes) {
hasGroups = true
const nodes = node.convertToNodes()
requestAnimationFrame(() => {
this.selectItems(nodes, true)
if (!this.selectedItems.size)
throw new Error('Convert to Subgraph: Nothing selected.')
this._graph.convertToSubgraph(this.selectedItems)
})
return
}
}
// If no groups were found, continue normally
if (!hasGroups) {
if (!this.selectedItems.size)
throw new Error('Convert to Subgraph: Nothing selected.')
this._graph.convertToSubgraph(this.selectedItems)
}
} else {
throw new Error('Convert to Subgraph: Nothing selected.')
this._graph.convertToSubgraph(this.selectedItems)
}
}
},
{