fix: preserve expanded node mode on boolean toggles
This commit is contained in:
parent
5a8d44d644
commit
0c64850b7d
|
|
@ -12,6 +12,7 @@ export type HFNodeData = FlowNode & {
|
|||
__needsServerCreate?: boolean;
|
||||
__createdOnServer?: boolean;
|
||||
__isCreatingOnServer?: boolean;
|
||||
__focusOpen?: boolean;
|
||||
__updateBlockError?: string | null;
|
||||
__containerValidationErrors?: unknown[];
|
||||
__containerAssignmentError?: string | null;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,26 @@ describe('ContainerNodeComponent', () => {
|
|||
expect(component.richContentFields.map((field) => field.path)).toContain('prompt');
|
||||
});
|
||||
|
||||
it('restores and syncs persisted expanded-mode state', () => {
|
||||
component.data = {
|
||||
data: {
|
||||
__focusOpen: true,
|
||||
specificConfiguration: {},
|
||||
inputs: [],
|
||||
outputs: []
|
||||
}
|
||||
};
|
||||
|
||||
(component as any).restorePersistedFocusState();
|
||||
|
||||
expect(component.focusOpen).toBe(true);
|
||||
expect(component.data.data.__focusOpen).toBe(true);
|
||||
|
||||
component.toggleFocus();
|
||||
expect(component.focusOpen).toBe(false);
|
||||
expect(component.data.data.__focusOpen).toBe(false);
|
||||
});
|
||||
|
||||
it('loads retriever-backed options for nested LLM descriptor fields', async () => {
|
||||
const schema = {
|
||||
type: 'object',
|
||||
|
|
|
|||
|
|
@ -131,6 +131,7 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.restorePersistedFocusState();
|
||||
void this.loadSchemaContext();
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +176,7 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
private setFocusOpen(value: boolean) {
|
||||
if (this.focusOpen === value) return;
|
||||
this.focusOpen = value;
|
||||
this.syncPersistedFocusState();
|
||||
if (value) {
|
||||
this.attachHostToModalLayer();
|
||||
this.applyPageScrollLock();
|
||||
|
|
@ -185,6 +187,18 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
private restorePersistedFocusState() {
|
||||
const nodeData = this.data?.data as Record<string, unknown> | undefined;
|
||||
if (nodeData?.['__focusOpen'] !== true) return;
|
||||
this.setFocusOpen(true);
|
||||
}
|
||||
|
||||
private syncPersistedFocusState() {
|
||||
const nodeData = this.data?.data as Record<string, unknown> | undefined;
|
||||
if (!nodeData) return;
|
||||
nodeData['__focusOpen'] = this.focusOpen;
|
||||
}
|
||||
|
||||
private applyPageScrollLock() {
|
||||
if (this.pageScrollLocked) return;
|
||||
const body = document.body;
|
||||
|
|
@ -1063,7 +1077,8 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
if (typeof replaceNode === 'function') {
|
||||
await replaceNode({
|
||||
...createdContainer,
|
||||
position: (current['position'] as { x: number; y: number } | undefined) ?? createdContainer.position
|
||||
position: (current['position'] as { x: number; y: number } | undefined) ?? createdContainer.position,
|
||||
__focusOpen: current['__focusOpen'] === true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,4 +75,18 @@ describe('GenericNodeComponent', () => {
|
|||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('restores and syncs persisted expanded-mode state', () => {
|
||||
const nodeData = component.data.data as Record<string, unknown>;
|
||||
nodeData['__focusOpen'] = true;
|
||||
|
||||
(component as any).restorePersistedFocusState();
|
||||
|
||||
expect(component.focusOpen).toBe(true);
|
||||
expect(nodeData['__focusOpen']).toBe(true);
|
||||
|
||||
component.toggleFocus();
|
||||
expect(component.focusOpen).toBe(false);
|
||||
expect(nodeData['__focusOpen']).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -242,6 +242,7 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
|
||||
this.refreshValidationState();
|
||||
this.refreshParameterFields();
|
||||
this.restorePersistedFocusState();
|
||||
void this.loadSchemaContext();
|
||||
}
|
||||
|
||||
|
|
@ -290,6 +291,7 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
private setFocusOpen(value: boolean) {
|
||||
if (this.focusOpen === value) return;
|
||||
this.focusOpen = value;
|
||||
this.syncPersistedFocusState();
|
||||
if (value) {
|
||||
this.attachHostToModalLayer();
|
||||
this.applyPageScrollLock();
|
||||
|
|
@ -300,6 +302,18 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
private restorePersistedFocusState() {
|
||||
const nodeData = this.data?.data as Record<string, unknown> | undefined;
|
||||
if (nodeData?.['__focusOpen'] !== true) return;
|
||||
this.setFocusOpen(true);
|
||||
}
|
||||
|
||||
private syncPersistedFocusState() {
|
||||
const nodeData = this.data?.data as Record<string, unknown> | undefined;
|
||||
if (!nodeData) return;
|
||||
nodeData['__focusOpen'] = this.focusOpen;
|
||||
}
|
||||
|
||||
private applyPageScrollLock() {
|
||||
if (this.pageScrollLocked) return;
|
||||
const body = document.body;
|
||||
|
|
@ -1868,7 +1882,8 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
if (typeof replaceNode === 'function') {
|
||||
void replaceNode({
|
||||
...createdBlock,
|
||||
position: (current['position'] as { x: number; y: number } | undefined) ?? createdBlock.position
|
||||
position: (current['position'] as { x: number; y: number } | undefined) ?? createdBlock.position,
|
||||
__focusOpen: current['__focusOpen'] === true
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,6 +409,7 @@ export async function addBlockToEditor(
|
|||
};
|
||||
const replaceWithCreatedNode = async (createdBlock: FlowNode) => {
|
||||
if (!editor.getNode(node.id)) return;
|
||||
const createdBlockData = createdBlock as FlowNode & Record<string, unknown>;
|
||||
const previousConnections = editor.getConnections()
|
||||
.filter((connection) => connection.source === node.id || connection.target === node.id)
|
||||
.map((connection) => ({
|
||||
|
|
@ -422,7 +423,11 @@ export async function addBlockToEditor(
|
|||
const replacementNode = await addBlockToEditor(
|
||||
editor,
|
||||
area,
|
||||
{ ...createdBlock, position: currentPosition },
|
||||
{
|
||||
...createdBlockData,
|
||||
position: currentPosition,
|
||||
__focusOpen: node.data?.['__focusOpen'] === true || createdBlockData['__focusOpen'] === true
|
||||
} as FlowNode & Record<string, unknown>,
|
||||
currentPosition,
|
||||
resolvedRuntime
|
||||
);
|
||||
|
|
@ -493,6 +498,7 @@ export async function addBlockToEditor(
|
|||
__needsServerCreate: sourceData['nodeFamily'] === 'container' ? false : true,
|
||||
__createdOnServer: false,
|
||||
__isCreatingOnServer: false,
|
||||
__focusOpen: false,
|
||||
__updateBlockError: null
|
||||
} as FlowNode & Record<string, unknown>;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue