From 1cc5823f37173bd686a46c660f2b6e5e5e0de26e Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Tue, 27 Jan 2026 21:24:09 +0800 Subject: [PATCH] fix: preserve subgraph widget overrides when pruning invalid entries --- .../advancedWidgetOverridesStore.test.ts | 43 +++++++++++++++++-- .../workspace/advancedWidgetOverridesStore.ts | 10 ++--- 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/src/stores/workspace/advancedWidgetOverridesStore.test.ts b/src/stores/workspace/advancedWidgetOverridesStore.test.ts index f1e9bb672..ca28898ab 100644 --- a/src/stores/workspace/advancedWidgetOverridesStore.test.ts +++ b/src/stores/workspace/advancedWidgetOverridesStore.test.ts @@ -2,7 +2,7 @@ import { createPinia, setActivePinia } from 'pinia' import { nextTick } from 'vue' import { beforeEach, describe, expect, it, vi } from 'vitest' -import type { LGraphNode } from '@/lib/litegraph/src/litegraph' +import type { LGraphNode, Subgraph } from '@/lib/litegraph/src/litegraph' import type { IWidgetOptions } from '@/lib/litegraph/src/types/widgets' import { useAdvancedWidgetOverridesStore } from '@/stores/workspace/advancedWidgetOverridesStore' @@ -22,7 +22,8 @@ vi.mock('@/scripts/app', () => ({ vi.mock('@/platform/workflow/management/stores/workflowStore', () => ({ useWorkflowStore: () => ({ activeWorkflow: { path: 'test-workflow' }, - nodeToNodeLocatorId: (node: { id: number }) => `node-${node.id}` + nodeToNodeLocatorId: (node: { id: number; locatorId?: string }) => + node.locatorId ?? `node-${node.id}` }) })) @@ -34,9 +35,10 @@ vi.mock('@/renderer/core/canvas/canvasStore', () => ({ function makeNode( id: number, - widgets: Array<{ name: string; options?: IWidgetOptions }> + widgets: Array<{ name: string; options?: IWidgetOptions }>, + locatorId?: string ) { - return { id, widgets } as Partial as LGraphNode + return { id, widgets, locatorId } as unknown as LGraphNode } describe('useAdvancedWidgetOverridesStore', () => { @@ -185,4 +187,37 @@ describe('useAdvancedWidgetOverridesStore', () => { advanced: true }) }) + + it('pruneInvalidOverrides preserves overrides for nodes inside subgraphs', () => { + const store = useAdvancedWidgetOverridesStore() + + const innerNode = makeNode(1, [{ name: 'cfg' }], 'node-subgraph-10:node-1') + store.setAdvanced(innerNode, 'cfg', true) + + const subgraph = { nodes: [innerNode] } as unknown as Subgraph + const subgraphNode = { + id: 10, + widgets: [], + subgraph, + isSubgraphNode: () => true + } as unknown as LGraphNode + + mockGraph.nodes = [subgraphNode] + store.pruneInvalidOverrides() + + expect(store.isOverridden(innerNode, 'cfg')).toBe(true) + + const stored = mockGraph.extra.advancedWidgetOverrides as { + overrides: Array<{ + nodeLocatorId: string + widgetName: string + advanced: boolean + }> + } + expect(stored.overrides).toContainEqual({ + nodeLocatorId: 'node-subgraph-10:node-1', + widgetName: 'cfg', + advanced: true + }) + }) }) diff --git a/src/stores/workspace/advancedWidgetOverridesStore.ts b/src/stores/workspace/advancedWidgetOverridesStore.ts index cfc3cfeb7..54fa214fd 100644 --- a/src/stores/workspace/advancedWidgetOverridesStore.ts +++ b/src/stores/workspace/advancedWidgetOverridesStore.ts @@ -7,6 +7,7 @@ import { useWorkflowStore } from '@/platform/workflow/management/stores/workflow import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { app } from '@/scripts/app' import type { NodeLocatorId } from '@/types/nodeIdentification' +import { forEachNode } from '@/utils/graphTraversalUtil' interface AdvancedWidgetOverrideEntry { nodeLocatorId: NodeLocatorId @@ -197,15 +198,12 @@ export const useAdvancedWidgetOverridesStore = defineStore( if (!graph) return const validKeys = new Set() - for (const node of graph.nodes ?? []) { + forEachNode(graph, (node) => { for (const widget of node.widgets ?? []) { - const key = getOverrideKey( - getNodeLocatorId(node as LGraphNode), - widget.name - ) + const key = getOverrideKey(getNodeLocatorId(node), widget.name) validKeys.add(key) } - } + }) const next = new Map() for (const [key, advanced] of overrides.value) {