mirror of
https://github.com/mathuo/dockview
synced 2025-09-02 15:36:42 +00:00
feat: improve remove group events
This commit is contained in:
parent
6a1d2757f0
commit
f6bc266e1d
@ -1,7 +1,11 @@
|
|||||||
import { DockviewComponent } from '../../dockview/dockviewComponent';
|
import {
|
||||||
|
DockviewComponent,
|
||||||
|
IDockviewComponent,
|
||||||
|
} from '../../dockview/dockviewComponent';
|
||||||
import {
|
import {
|
||||||
GroupPanelPartInitParameters,
|
GroupPanelPartInitParameters,
|
||||||
IContentRenderer,
|
IContentRenderer,
|
||||||
|
ITabRenderer,
|
||||||
} from '../../groupview/types';
|
} from '../../groupview/types';
|
||||||
import { PanelUpdateEvent } from '../../panel/types';
|
import { PanelUpdateEvent } from '../../panel/types';
|
||||||
import { Orientation } from '../../splitview/core/splitview';
|
import { Orientation } from '../../splitview/core/splitview';
|
||||||
@ -12,6 +16,20 @@ import {
|
|||||||
GroupChangeEvent,
|
GroupChangeEvent,
|
||||||
GroupChangeKind,
|
GroupChangeKind,
|
||||||
} from '../../gridview/baseComponentGridview';
|
} from '../../gridview/baseComponentGridview';
|
||||||
|
import { CompositeDisposable } from '../../lifecycle';
|
||||||
|
import {
|
||||||
|
GroupPanelUpdateEvent,
|
||||||
|
GroupviewPanelState,
|
||||||
|
IGroupPanel,
|
||||||
|
IGroupPanelInitParameters,
|
||||||
|
} from '../../groupview/groupPanel';
|
||||||
|
import { IGroupPanelView } from '../../dockview/defaultGroupPanelView';
|
||||||
|
import {
|
||||||
|
DockviewPanelApi,
|
||||||
|
DockviewPanelApiImpl,
|
||||||
|
} from '../../api/groupPanelApi';
|
||||||
|
import { DefaultTab } from '../../dockview/components/tab/defaultTab';
|
||||||
|
|
||||||
class PanelContentPartTest implements IContentRenderer {
|
class PanelContentPartTest implements IContentRenderer {
|
||||||
element: HTMLElement = document.createElement('div');
|
element: HTMLElement = document.createElement('div');
|
||||||
|
|
||||||
@ -48,12 +66,106 @@ class PanelContentPartTest implements IContentRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestGroupPanelView implements IGroupPanelView {
|
||||||
|
readonly tab: ITabRenderer = new DefaultTab();
|
||||||
|
|
||||||
|
constructor(public readonly content: IContentRenderer) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
update(event: GroupPanelUpdateEvent): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(width: number, height: number): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
init(params: GroupPanelPartInitParameters): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
updateParentGroup(group: GroupviewPanel, isPanelVisible: boolean): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(): {} {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestGroupPanel implements IGroupPanel {
|
||||||
|
private _group: GroupviewPanel | undefined;
|
||||||
|
|
||||||
|
readonly view: IGroupPanelView;
|
||||||
|
readonly suppressClosable: boolean = false;
|
||||||
|
readonly api: DockviewPanelApi;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public readonly id: string,
|
||||||
|
public readonly title: string,
|
||||||
|
accessor: IDockviewComponent
|
||||||
|
) {
|
||||||
|
this.api = new DockviewPanelApiImpl(this, this._group);
|
||||||
|
this._group = new GroupviewPanel(accessor, id, {});
|
||||||
|
this.view = new TestGroupPanelView(
|
||||||
|
new PanelContentPartTest(id, 'component')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
get group(): GroupviewPanel | undefined {
|
||||||
|
return this._group;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateParentGroup(group: GroupviewPanel, isGroupActive: boolean): void {
|
||||||
|
this._group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
init(params: IGroupPanelInitParameters): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
layout(width: number, height: number): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
focus(): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
toJSON(): GroupviewPanelState {
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
title: this.title,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
update(event: GroupPanelUpdateEvent): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
dispose(): void {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
describe('dockviewComponent', () => {
|
describe('dockviewComponent', () => {
|
||||||
|
let root: HTMLElement;
|
||||||
let container: HTMLElement;
|
let container: HTMLElement;
|
||||||
let dockview: DockviewComponent;
|
let dockview: DockviewComponent;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
root = document.createElement('div'); // dockview container must have parent element
|
||||||
container = document.createElement('div');
|
container = document.createElement('div');
|
||||||
|
|
||||||
|
root.appendChild(container);
|
||||||
|
root.className = 'root';
|
||||||
|
container.className = 'container';
|
||||||
|
|
||||||
dockview = new DockviewComponent(container, {
|
dockview = new DockviewComponent(container, {
|
||||||
components: {
|
components: {
|
||||||
default: PanelContentPartTest,
|
default: PanelContentPartTest,
|
||||||
@ -155,7 +267,7 @@ describe('dockviewComponent', () => {
|
|||||||
|
|
||||||
dockview.removeGroup(panel2.group);
|
dockview.removeGroup(panel2.group);
|
||||||
|
|
||||||
expect(dockview.size).toBe(1);
|
expect(dockview.size).toBe(0);
|
||||||
expect(dockview.totalPanels).toBe(0);
|
expect(dockview.totalPanels).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -294,7 +406,7 @@ describe('dockviewComponent', () => {
|
|||||||
|
|
||||||
await panel2.api.close();
|
await panel2.api.close();
|
||||||
|
|
||||||
expect(dockview.size).toBe(1);
|
expect(dockview.size).toBe(0);
|
||||||
expect(dockview.totalPanels).toBe(0);
|
expect(dockview.totalPanels).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -838,4 +950,92 @@ describe('dockviewComponent', () => {
|
|||||||
expect(dockview.getGroupPanel('panel1')).toBeUndefined();
|
expect(dockview.getGroupPanel('panel1')).toBeUndefined();
|
||||||
expect(dockview.getGroupPanel('panel2')).toBeUndefined();
|
expect(dockview.getGroupPanel('panel2')).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('#1', () => {
|
||||||
|
dockview.layout(500, 500);
|
||||||
|
dockview.deserializer = {
|
||||||
|
fromJSON: (panelData: GroupviewPanelState): IGroupPanel => {
|
||||||
|
return new TestGroupPanel(
|
||||||
|
panelData.id,
|
||||||
|
panelData.title,
|
||||||
|
dockview
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const panel1 = dockview.addPanel({
|
||||||
|
id: 'panel1',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
const panel2 = dockview.addPanel({
|
||||||
|
id: 'panel2',
|
||||||
|
component: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
const panel3 = dockview.addPanel({
|
||||||
|
id: 'panel3',
|
||||||
|
component: 'default',
|
||||||
|
position: { referencePanel: 'panel2', direction: 'below' },
|
||||||
|
});
|
||||||
|
|
||||||
|
const removedGroups: GroupviewPanel[] = [];
|
||||||
|
const removedPanels: IGroupPanel[] = [];
|
||||||
|
|
||||||
|
const disposable = new CompositeDisposable(
|
||||||
|
dockview.onDidRemoveGroup((group) => {
|
||||||
|
removedGroups.push(group);
|
||||||
|
}),
|
||||||
|
dockview.onDidRemovePanel((panel) => {
|
||||||
|
removedPanels.push(panel);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
dockview.fromJSON({
|
||||||
|
grid: {
|
||||||
|
height: 500,
|
||||||
|
width: 500,
|
||||||
|
orientation: Orientation.HORIZONTAL,
|
||||||
|
root: {
|
||||||
|
type: 'branch',
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
type: 'leaf',
|
||||||
|
data: {
|
||||||
|
views: ['view_1', 'view_2'],
|
||||||
|
id: 'group_1',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'leaf',
|
||||||
|
data: { views: ['view_3'], id: 'group_2' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
panels: {
|
||||||
|
view_1: {
|
||||||
|
id: 'view_1',
|
||||||
|
title: 'view_1_title',
|
||||||
|
view: {},
|
||||||
|
},
|
||||||
|
view_2: {
|
||||||
|
id: 'view_2',
|
||||||
|
title: 'view_2_title',
|
||||||
|
view: {},
|
||||||
|
},
|
||||||
|
view_3: {
|
||||||
|
id: 'view_3',
|
||||||
|
title: 'view_3_title',
|
||||||
|
view: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
options: {},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(removedGroups.length).toBe(2);
|
||||||
|
expect(removedPanels.length).toBe(3);
|
||||||
|
|
||||||
|
disposable.dispose();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -71,6 +71,7 @@ export type DockviewComponentUpdateOptions = Pick<
|
|||||||
| 'tabComponents'
|
| 'tabComponents'
|
||||||
| 'frameworkTabComponents'
|
| 'frameworkTabComponents'
|
||||||
| 'showDndOverlay'
|
| 'showDndOverlay'
|
||||||
|
| 'watermarkFrameworkComponent'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export interface DockviewDropEvent extends GroupviewDropEvent {
|
export interface DockviewDropEvent extends GroupviewDropEvent {
|
||||||
@ -335,11 +336,14 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
|
|
||||||
fromJSON(data: SerializedDockview): void {
|
fromJSON(data: SerializedDockview): void {
|
||||||
|
const groups = Array.from(this._groups.values()).map((_) => _.value);
|
||||||
|
|
||||||
|
for (const group of groups) {
|
||||||
|
// remove the group will automatically remove the panels
|
||||||
|
this.removeGroup(group, true);
|
||||||
|
}
|
||||||
|
|
||||||
this.gridview.clear();
|
this.gridview.clear();
|
||||||
this.panels.forEach((panel) => {
|
|
||||||
panel.dispose();
|
|
||||||
});
|
|
||||||
this._groups.clear();
|
|
||||||
|
|
||||||
if (!this.deserializer) {
|
if (!this.deserializer) {
|
||||||
throw new Error('invalid deserializer');
|
throw new Error('invalid deserializer');
|
||||||
@ -438,7 +442,10 @@ export class DockviewComponent
|
|||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
removePanel(panel: IGroupPanel): void {
|
removePanel(
|
||||||
|
panel: IGroupPanel,
|
||||||
|
options: { removeEmptyGroup: boolean } = { removeEmptyGroup: true }
|
||||||
|
): void {
|
||||||
const group = panel.group;
|
const group = panel.group;
|
||||||
|
|
||||||
if (!group) {
|
if (!group) {
|
||||||
@ -449,7 +456,7 @@ export class DockviewComponent
|
|||||||
|
|
||||||
group.model.removePanel(panel);
|
group.model.removePanel(panel);
|
||||||
|
|
||||||
if (group.model.size === 0) {
|
if (group.model.size === 0 && options.removeEmptyGroup) {
|
||||||
this.removeGroup(group);
|
this.removeGroup(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,18 +511,14 @@ export class DockviewComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeGroup(group: GroupviewPanel): void {
|
removeGroup(group: GroupviewPanel, skipActive = false): void {
|
||||||
const panels = [...group.model.panels]; // reassign since group panels will mutate
|
const panels = [...group.model.panels]; // reassign since group panels will mutate
|
||||||
panels.forEach((panel) => {
|
|
||||||
this.removePanel(panel);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (this._groups.size === 1) {
|
for (const panel of panels) {
|
||||||
this._activeGroup = group;
|
this.removePanel(panel, { removeEmptyGroup: false });
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
super.removeGroup(group);
|
super.doRemoveGroup(group, { skipActive });
|
||||||
}
|
}
|
||||||
|
|
||||||
moveGroupOrPanel(
|
moveGroupOrPanel(
|
||||||
|
@ -167,6 +167,15 @@ export const DockviewReact = React.forwardRef(
|
|||||||
});
|
});
|
||||||
}, [props.components]);
|
}, [props.components]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!dockviewRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dockviewRef.current.updateOptions({
|
||||||
|
watermarkFrameworkComponent: props.watermarkComponent,
|
||||||
|
});
|
||||||
|
}, [props.watermarkComponent]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!dockviewRef.current) {
|
if (!dockviewRef.current) {
|
||||||
return;
|
return;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user