From d4ab8f8fb18ae3916c214d81878fbadb0b1a6639 Mon Sep 17 00:00:00 2001 From: Lucio Lelii Date: Tue, 29 Sep 2026 21:18:37 +0200 Subject: [PATCH] fix(nodes): preserve open settings after replacement --- .../shared/nodes/generic-node/generic-node.spec.ts | 11 +++++++++++ src/app/shared/nodes/generic-node/generic-node.ts | 14 ++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/app/shared/nodes/generic-node/generic-node.spec.ts b/src/app/shared/nodes/generic-node/generic-node.spec.ts index 22a1966..3f947e2 100644 --- a/src/app/shared/nodes/generic-node/generic-node.spec.ts +++ b/src/app/shared/nodes/generic-node/generic-node.spec.ts @@ -109,6 +109,17 @@ describe('GenericNodeComponent', () => { expect(fixture.nativeElement.querySelector('.llm-modal-backdrop')).not.toBeNull(); }); + it('restores open settings after a structural edit replaces the node', () => { + component.toggleNodeSettings(); + expect(component.data.data.__nodeSettingsOpen).toBe(true); + + // Replacement creates a new Angular component, whose local state starts closed. + component.nodeSettingsOpen = false; + (component as any).restorePersistedNodeSettingsState(); + + expect(component.nodeSettingsOpen).toBe(true); + }); + describe('clearing an optional number', () => { /** Opens the modal editor on a numeric path, as clicking the pen does. */ function openNumericEditor(path: string, current: unknown) { diff --git a/src/app/shared/nodes/generic-node/generic-node.ts b/src/app/shared/nodes/generic-node/generic-node.ts index 13d0b7d..acb53a0 100644 --- a/src/app/shared/nodes/generic-node/generic-node.ts +++ b/src/app/shared/nodes/generic-node/generic-node.ts @@ -337,6 +337,7 @@ export class GenericNodeComponent implements OnDestroy { this.refreshValidationState(); this.refreshParameterFields(); + this.restorePersistedNodeSettingsState(); this.restorePersistedFocusState(); void this.loadSchemaContext(); } @@ -374,6 +375,7 @@ export class GenericNodeComponent implements OnDestroy { event?.preventDefault(); event?.stopPropagation(); this.nodeSettingsOpen = !this.nodeSettingsOpen; + this.syncPersistedNodeSettingsState(); this.cdr.markForCheck(); } @@ -839,6 +841,18 @@ export class GenericNodeComponent implements OnDestroy { ?? (typeof mostSevereValue === 'string' ? mostSevereValue : null); } + /** A structural edit replaces the Rete node, so keep this UI-only state with its data. */ + private restorePersistedNodeSettingsState() { + const nodeData = this.data?.data as Record | undefined; + this.nodeSettingsOpen = nodeData?.['__nodeSettingsOpen'] === true; + } + + private syncPersistedNodeSettingsState() { + const nodeData = this.data?.data as Record | undefined; + if (!nodeData) return; + nodeData['__nodeSettingsOpen'] = this.nodeSettingsOpen; + } + private ensureBlockConfiguration(): Record { if (!this.data?.data) { this.data.data = {};