bug: fixup popout group flows

This commit is contained in:
mathuo 2024-12-21 13:07:18 +00:00
parent 703418e27f
commit 7515b9b05d
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
3 changed files with 198 additions and 12 deletions

View File

@ -21,6 +21,7 @@ import { DockviewApi } from '../../api/component.api';
import { DockviewDndOverlayEvent } from '../../dockview/options';
import { SizeEvent } from '../../api/gridviewPanelApi';
import { setupMockWindow } from '../__mocks__/mockWindow';
import { exhaustMicrotaskQueue } from '../__test_utils__/utils';
class PanelContentPartTest implements IContentRenderer {
element: HTMLElement = document.createElement('div');
@ -4867,6 +4868,155 @@ describe('dockviewComponent', () => {
);
});
test('basic', async () => {
jest.useRealTimers();
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, 1000);
dockview.fromJSON({
activeGroup: 'group-1',
grid: {
root: {
type: 'branch',
data: [
{
type: 'leaf',
data: {
views: ['panel1'],
id: 'group-1',
activeView: 'panel1',
},
size: 1000,
},
],
size: 1000,
},
height: 1000,
width: 1000,
orientation: Orientation.VERTICAL,
},
popoutGroups: [
{
data: {
views: ['panel2'],
id: 'group-2',
activeView: 'panel2',
},
position: null,
},
],
panels: {
panel1: {
id: 'panel1',
contentComponent: 'default',
title: 'panel1',
},
panel2: {
id: 'panel2',
contentComponent: 'default',
title: 'panel2',
},
},
});
await new Promise((resolve) => setTimeout(resolve, 0));
const panel2 = dockview.api.getPanel('panel2');
const windowObject =
panel2?.api.location.type === 'popout'
? panel2?.api.location.getWindow()
: undefined;
expect(windowObject).toBeTruthy();
windowObject!.close();
});
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');
@ -5116,7 +5266,7 @@ describe('dockviewComponent', () => {
mockWindow.close();
expect(panel1.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('grid');
expect(panel2.group.api.location.type).toBe('floating');
expect(panel3.group.api.location.type).toBe('grid');
dockview.clear();

View File

@ -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,

View File

@ -252,6 +252,7 @@ export type AddPanelOptions<P extends object = Parameters> = {
inactive?: boolean;
initialWidth?: number;
initialHeight?: number;
popout?: boolean;
} & Partial<AddPanelOptionsUnion> &
Partial<Contraints>;