mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 17:10:06 +00:00
fix: stabilize nested subgraph promoted widget resolution (#9282)
## Summary Fix multiple issues with promoted widget resolution in nested subgraphs, ensuring correct value propagation, slot matching, and rendering for deeply nested promoted widgets. ## Changes - **What**: Stabilize nested subgraph promoted widget resolution chain - Use deep source keys for promoted widget values in Vue rendering mode - Resolve effective widget options from the source widget instead of the promoted view - Stabilize slot resolution for nested promoted widgets - Preserve combo value rendering for promoted subgraph widgets - Prevent subgraph definition deletion while other nodes still reference the same type - Clean up unused exported resolution types ## Review Focus - `resolveConcretePromotedWidget.ts` — new recursive resolution logic for deeply nested promoted widgets - `useGraphNodeManager.ts` — option extraction now uses `effectiveWidget` for promoted widgets - `SubgraphNode.ts` — unpack no longer force-deletes definitions referenced by other nodes ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-9282-fix-stabilize-nested-subgraph-promoted-widget-resolution-3146d73d365081208a4fe931bb7569cf) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
@@ -184,6 +184,8 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
for (const widget of widgets) {
|
||||
if (!shouldRenderAsVue(widget)) continue
|
||||
|
||||
const isPromotedView = !!widget.nodeId
|
||||
|
||||
const vueComponent =
|
||||
getComponent(widget.type) ||
|
||||
(widget.isDOMWidget ? WidgetDOM : WidgetLegacy)
|
||||
@@ -191,9 +193,12 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
const { slotMetadata } = widget
|
||||
|
||||
// Get metadata from store (registered during BaseWidget.setNodeId)
|
||||
const bareWidgetId = stripGraphPrefix(widget.nodeId ?? nodeId)
|
||||
const bareWidgetId = stripGraphPrefix(
|
||||
widget.storeNodeId ?? widget.nodeId ?? nodeId
|
||||
)
|
||||
const storeWidgetName = widget.storeName ?? widget.name
|
||||
const widgetState = graphId
|
||||
? widgetValueStore.getWidget(graphId, bareWidgetId, widget.name)
|
||||
? widgetValueStore.getWidget(graphId, bareWidgetId, storeWidgetName)
|
||||
: undefined
|
||||
|
||||
// Get value from store (falls back to undefined if not registered)
|
||||
@@ -205,7 +210,6 @@ const processedWidgets = computed((): ProcessedWidget[] => {
|
||||
? { ...storeOptions, disabled: true }
|
||||
: storeOptions
|
||||
|
||||
const isPromotedView = !!widget.nodeId
|
||||
const borderStyle =
|
||||
graphId &&
|
||||
!isPromotedView &&
|
||||
|
||||
@@ -96,6 +96,38 @@ describe('resolveWidgetFromHostNode', () => {
|
||||
expect(resolved).toEqual({ node: innerNode, widget: innerWidget })
|
||||
})
|
||||
|
||||
it('resolves nested promoted widget chain to deepest interior widget', () => {
|
||||
const innerWidget = createWidget('inner_text')
|
||||
const innerNode = createHostNode([innerWidget])
|
||||
|
||||
const middleNode = createHostNode([], {
|
||||
isSubgraphNode: true,
|
||||
innerNodesById: { '100': innerNode }
|
||||
})
|
||||
const middlePromotedWidget = {
|
||||
...createPromotedWidget('inner_text', '100', 'inner_text'),
|
||||
node: middleNode
|
||||
} as TestPromotedWidget & { node: LGraphNode }
|
||||
middleNode.widgets = [middlePromotedWidget]
|
||||
|
||||
const outerPromotedWidget = createPromotedWidget(
|
||||
'outer_text',
|
||||
'42',
|
||||
'inner_text'
|
||||
)
|
||||
const hostNode = createHostNode([outerPromotedWidget], {
|
||||
isSubgraphNode: true,
|
||||
innerNodesById: { '42': middleNode }
|
||||
})
|
||||
|
||||
const resolved = resolveWidgetFromHostNode(
|
||||
hostNode,
|
||||
outerPromotedWidget.name
|
||||
)
|
||||
|
||||
expect(resolved).toEqual({ node: innerNode, widget: innerWidget })
|
||||
})
|
||||
|
||||
it('returns undefined when promoted interior node is missing', () => {
|
||||
const promotedWidget = createPromotedWidget(
|
||||
'promoted_text',
|
||||
|
||||
Reference in New Issue
Block a user