From 9d6667241b3bbefd3f5a034e4de493c997997c27 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sat, 21 Dec 2024 13:07:18 +0000 Subject: [PATCH] bug: fixup popout group flows --- .../dockview/dockviewComponent.spec.ts | 66 +++++++++++++++++++ .../src/dockview/dockviewComponent.ts | 57 ++++++++++++---- .../dockview-core/src/dockview/options.ts | 1 + 3 files changed, 113 insertions(+), 11 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index c646ca0a5..7b2ad3869 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -4867,6 +4867,72 @@ describe('dockviewComponent', () => { ); }); + test('grid -> floating -> popout -> popout closed', async () => { + const container = document.createElement('div'); + + window.open = () => setupMockWindow(); + + const dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + dockview.layout(1000, 500); + + const panel1 = dockview.addPanel({ + id: 'panel_1', + component: 'default', + }); + + const panel2 = dockview.addPanel({ + id: 'panel_2', + component: 'default', + }); + + const panel3 = dockview.addPanel({ + id: 'panel_3', + component: 'default', + position: { direction: 'right' }, + }); + + expect(panel1.api.location.type).toBe('grid'); + expect(panel2.api.location.type).toBe('grid'); + expect(panel3.api.location.type).toBe('grid'); + + dockview.addFloatingGroup(panel2); + + expect(panel1.api.location.type).toBe('grid'); + expect(panel2.api.location.type).toBe('floating'); + expect(panel3.api.location.type).toBe('grid'); + + await dockview.addPopoutGroup(panel2); + + expect(panel1.api.location.type).toBe('grid'); + expect(panel2.api.location.type).toBe('popout'); + expect(panel3.api.location.type).toBe('grid'); + + const windowObject = + panel2.api.location.type === 'popout' + ? panel2.api.location.getWindow() + : undefined; + expect(windowObject).toBeTruthy(); + + windowObject!.close(); + + expect(panel1.api.location.type).toBe('grid'); + expect(panel2.api.location.type).toBe('floating'); + expect(panel3.api.location.type).toBe('grid'); + }); + test('move popout group of 1 panel inside grid', async () => { const container = document.createElement('div'); diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index cf7823d9f..9d49df053 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -706,6 +706,8 @@ export class DockviewComponent _window.window!.innerHeight ); + let floatingBox: AnchoredBox | undefined; + if (!options?.overridePopoutGroup && isGroupAddedToDom) { if (itemToPopout instanceof DockviewPanel) { this.movingLock(() => { @@ -727,7 +729,15 @@ export class DockviewComponent break; case 'floating': case 'popout': + floatingBox = this._floatingGroups + .find( + (value) => + value.group.api.id === + itemToPopout.api.id + ) + ?.overlay.toJSON(); this.removeGroup(referenceGroup); + break; } } @@ -825,20 +835,29 @@ export class DockviewComponent }); } } else if (this.getPanel(group.id)) { - this.doRemoveGroup(group, { - skipDispose: true, - skipActive: true, - skipPopoutReturn: true, - }); - const removedGroup = group; - removedGroup.model.renderContainer = - this.overlayRenderContainer; - removedGroup.model.location = { type: 'grid' }; - returnedGroup = removedGroup; + if (floatingBox) { + this.addFloatingGroup(removedGroup, { + height: floatingBox.height, + width: floatingBox.width, + position: floatingBox, + }); + } else { + this.doRemoveGroup(removedGroup, { + skipDispose: true, + skipActive: true, + skipPopoutReturn: true, + }); - this.doAddGroup(removedGroup, [0]); + removedGroup.model.renderContainer = + this.overlayRenderContainer; + removedGroup.model.location = { type: 'grid' }; + returnedGroup = removedGroup; + this.movingLock(() => { + this.doAddGroup(removedGroup, [0]); + }); + } this.doSetGroupAndPanelActive(removedGroup); } }) @@ -1477,6 +1496,22 @@ export class DockviewComponent ); } + if (options.popout) { + const group = this.createGroup(); + this._onDidAddGroup.fire(group); + + this.addPopoutGroup(group); + + const panel = this.createPanel(options, group); + + group.model.openPanel(panel, { + skipSetActive: options.inactive, + skipSetGroupActive: options.inactive, + }); + + return panel; + } + const initial = { width: options.initialWidth, height: options.initialHeight, diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 3e87923a2..d21418730 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -252,6 +252,7 @@ export type AddPanelOptions
= {
inactive?: boolean;
initialWidth?: number;
initialHeight?: number;
+ popout?: boolean;
} & Partial