diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index 9aed10312..25bd1ea39 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -4716,6 +4716,61 @@ describe('dockviewComponent', () => { expect(dockview.panels.length).toBe(2); }); + test('remove all panels from popout group', async () => { + const container = document.createElement('div'); + + const dockview = new DockviewComponent({ + parentElement: 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', + position: { direction: 'right' }, + }); + + const panel3 = dockview.addPanel({ + id: 'panel_3', + component: 'default', + position: { referencePanel: panel2 }, + }); + + await dockview.addPopoutGroup(panel2.group); + + expect(panel1.group.api.location.type).toBe('grid'); + expect(panel2.group.api.location.type).toBe('popout'); + expect(panel3.group.api.location.type).toBe('popout'); + + expect(dockview.panels.length).toBe(3); + expect(dockview.groups.length).toBe(3); // includes one hidden group + + panel2.api.moveTo({ group: panel1.group, position: 'left' }); + expect(dockview.panels.length).toBe(3); + expect(dockview.groups.length).toBe(4); + + panel3.api.moveTo({ group: panel1.group, position: 'left' }); + expect(dockview.panels.length).toBe(3); + expect(dockview.groups.length).toBe(3); + }); + test('that can remove a popout group', 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 d1dc93f92..be0af1dba 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -1767,6 +1767,8 @@ export class DockviewComponent this._onDidRemoveGroup.fire(group); } + remove(this._popoutGroups, selectedGroup); + const removedGroup = selectedGroup.disposable.dispose(); if (!options?.skipPopoutReturn && removedGroup) { @@ -1922,6 +1924,47 @@ export class DockviewComponent } } + if (sourceGroup.api.location.type === 'popout') { + /** + * the source group is a popout group with a single panel + * + * 1. remove the panel from the group without triggering any events + * 2. remove the popout group + * 3. create a new group at the requested location and add that panel + */ + + const popoutGroup = this._popoutGroups.find( + (group) => group.popoutGroup === sourceGroup + )!; + + const removedPanel: IDockviewPanel | undefined = + this.movingLock(() => + popoutGroup.popoutGroup.model.removePanel( + popoutGroup.popoutGroup.panels[0], + { + skipSetActive: true, + skipSetActiveGroup: true, + } + ) + ); + + this.doRemoveGroup(sourceGroup, { skipActive: true }); + + const newGroup = this.createGroupAtLocation(targetLocation); + this.movingLock(() => + newGroup.model.openPanel(removedPanel!, { + skipSetActive: true, + }) + ); + this.doSetGroupAndPanelActive(newGroup); + + this._onDidMovePanel.fire({ + panel: this.getGroupPanel(sourceItemId)!, + from: sourceGroup, + }); + return; + } + // source group will become empty so delete the group const targetGroup = this.movingLock(() => this.doRemoveGroup(sourceGroup, {