Merge pull request #194 from mathuo/191-dockview-watermark-fixes

feat: attach watermark seperately from groups
This commit is contained in:
mathuo 2023-02-25 18:36:55 +08:00 committed by GitHub
commit 417cdf875f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 142 additions and 62 deletions

View File

@ -7,7 +7,6 @@ import {
import { PanelUpdateEvent } from '../../panel/types';
import { Orientation } from '../../splitview/core/splitview';
import { ReactPanelDeserialzier } from '../../react/deserializer';
import { Position } from '../../dnd/droptarget';
import { GroupPanel } from '../../groupview/groupviewPanel';
import { CompositeDisposable } from '../../lifecycle';
import {
@ -459,7 +458,7 @@ describe('dockviewComponent', () => {
await panel2.api.close();
expect(dockview.size).toBe(1); // watermark
expect(dockview.size).toBe(0);
expect(dockview.totalPanels).toBe(0);
});
@ -1206,55 +1205,6 @@ describe('dockviewComponent', () => {
expect(dockview.totalPanels).toBe(0);
});
test('last group is retained for watermark', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
components: { default: PanelContentPartTest },
});
dockview.layout(500, 1000);
const panel1 = dockview.addPanel({
id: 'panel1',
component: 'default',
tabComponent: 'default',
});
expect(dockview.size).toBe(1);
expect(dockview.totalPanels).toBe(1);
const group = panel1.group;
dockview.removePanel(panel1);
expect(group.model.hasWatermark).toBeTruthy();
expect(dockview.size).toBe(1);
expect(dockview.totalPanels).toBe(0);
const panel2 = dockview.addPanel({
id: 'panel2',
component: 'default',
tabComponent: 'default',
});
expect(group.model.hasWatermark).toBeFalsy();
const panel3 = dockview.addPanel({
id: 'panel3',
component: 'default',
tabComponent: 'default',
});
expect(dockview.size).toBe(1);
expect(dockview.totalPanels).toBe(2);
panel2.api.close();
expect(group.model.hasWatermark).toBeFalsy();
panel3.api.close();
expect(group.model.hasWatermark).toBeTruthy();
});
test('panel is disposed of when removed', () => {
const container = document.createElement('div');
@ -2392,4 +2342,91 @@ describe('dockviewComponent', () => {
options: {},
});
});
test('that a empty component has no groups', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
components: {
default: PanelContentPartTest,
},
tabComponents: {
test_tab_id: PanelTabPartTest,
},
orientation: Orientation.HORIZONTAL,
});
dockview.deserializer = new ReactPanelDeserialzier(dockview);
expect(dockview.groups.length).toBe(0);
});
test('that deserializing an empty layout has zero groups and a watermark', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
components: {
default: PanelContentPartTest,
},
tabComponents: {
test_tab_id: PanelTabPartTest,
},
orientation: Orientation.HORIZONTAL,
});
dockview.deserializer = new ReactPanelDeserialzier(dockview);
expect(dockview.groups.length).toBe(0);
expect(
dockview.element.querySelectorAll('.dv-watermark-container').length
).toBe(1);
dockview.fromJSON({
grid: {
orientation: Orientation.HORIZONTAL,
root: {
type: 'branch',
data: [],
},
height: 100,
width: 100,
},
panels: {},
});
expect(dockview.groups.length).toBe(0);
expect(
dockview.element.querySelectorAll('.dv-watermark-container').length
).toBe(1);
});
test('empty', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
components: {
default: PanelContentPartTest,
},
tabComponents: {
test_tab_id: PanelTabPartTest,
},
orientation: Orientation.HORIZONTAL,
});
dockview.deserializer = new ReactPanelDeserialzier(dockview);
expect(JSON.parse(JSON.stringify(dockview.toJSON()))).toEqual({
grid: {
height: 0,
width: 0,
orientation: Orientation.HORIZONTAL,
root: {
data: [],
type: 'branch',
size: 0,
},
},
options: {},
panels: {},
});
});
});

View File

@ -1,3 +1,16 @@
.dv-dockview {
position: relative;
background-color: var(--dv-group-view-background-color);
.dv-watermark-container {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
}
.groupview {
&.active-group {
> .tabs-and-actions-container > .tabs-container > .tab {

View File

@ -131,6 +131,7 @@ export class DockviewComponent
private _deserializer: IPanelDeserializer | undefined;
private _api: DockviewApi;
private _options: Exclude<DockviewComponentOptions, 'orientation'>;
private watermark: IWatermarkRenderer | null = null;
private readonly _onDidDrop = new Emitter<DockviewDropEvent>();
readonly onDidDrop: Event<DockviewDropEvent> = this._onDidDrop.event;
@ -203,8 +204,16 @@ export class DockviewComponent
styles: options.styles,
});
this.element.classList.add('dv-dockview');
this.addDisposables(
this._onDidDrop,
Event.any(
this.onDidAddGroup,
this.onDidRemoveGroup
)(() => {
this.updateWatermark();
}),
Event.any(
this.onDidAddPanel,
this.onDidRemovePanel,
@ -288,6 +297,8 @@ export class DockviewComponent
);
this._api = new DockviewApi(this);
this.updateWatermark();
}
private orthogonalize(position: Position): GroupPanel {
@ -421,7 +432,7 @@ export class DockviewComponent
this.clear();
if (!this.deserializer) {
throw new Error('invalid deserializer');
throw new Error('no deserializer provided');
}
const { grid, panels, options, activeGroup } = data;
@ -429,8 +440,8 @@ export class DockviewComponent
this.tabHeight = options.tabHeight;
}
if (!this.deserializer) {
throw new Error('no deserializer provided');
if (grid.root.type !== 'branch' || !Array.isArray(grid.root.data)) {
throw new Error('root must be of type branch');
}
this.gridview.deserialize(grid, {
@ -610,13 +621,7 @@ export class DockviewComponent
panel.dispose();
const retainGroupForWatermark = this.size === 1;
if (
!retainGroupForWatermark &&
group.size === 0 &&
options.removeEmptyGroup
) {
if (group.size === 0 && options.removeEmptyGroup) {
this.removeGroup(group);
}
}
@ -635,7 +640,32 @@ export class DockviewComponent
);
}
addGroup(options: AddGroupOptions): GroupPanel {
private updateWatermark(): void {
if (this.groups.length === 0) {
if (!this.watermark) {
this.watermark = this.createWatermarkComponent();
this.watermark.init({
containerApi: new DockviewApi(this),
params: {},
title: '',
api: null as any,
});
const watermarkContainer = document.createElement('div');
watermarkContainer.className = 'dv-watermark-container';
watermarkContainer.appendChild(this.watermark.element);
this.element.appendChild(watermarkContainer);
}
} else if (this.watermark) {
this.watermark.element.parentElement!.remove();
this.watermark.dispose();
this.watermark = null;
}
}
addGroup(options?: AddGroupOptions): GroupPanel {
const group = this.createGroup();
if (options) {