feat: adjust to make group non-optional

This commit is contained in:
mathuo 2022-05-02 17:47:49 +01:00
parent 05f8ab8f8b
commit a6b0250b86
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
10 changed files with 99 additions and 63 deletions

View File

@ -619,7 +619,7 @@ describe('dockviewComponent', () => {
data: {
views: ['panel2', 'panel3'],
id: 'group-2',
activeView: 'panel2',
activeView: 'panel3',
},
size: 500,
},

View File

@ -1,19 +1,26 @@
import { DockviewComponent } from '../..';
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewApi } from '../../api/component.api';
import { IGroupPanelView } from '../../dockview/defaultGroupPanelView';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { GroupviewPanel } from '../../groupview/groupviewPanel';
describe('dockviewGroupPanel', () => {
test('update title', () => {
const dockviewApiMock = jest.fn<DockviewApi, []>(() => {
return {} as any;
return {
onDidActiveChange: jest.fn(),
} as any;
});
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupviewPanel, []>(() => {
return {} as any;
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api);
const group = new groupMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api, group);
let latestTitle: string | undefined = undefined;
@ -41,10 +48,14 @@ describe('dockviewGroupPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupviewPanel, []>(() => {
return {} as any;
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api);
const cut = new DockviewGroupPanel('fake-id', accessor, api, group);
let latestSuppressClosable: boolean | undefined = undefined;
@ -77,10 +88,14 @@ describe('dockviewGroupPanel', () => {
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const groupMock = jest.fn<GroupviewPanel, []>(() => {
return {} as any;
});
const api = new dockviewApiMock();
const accessor = new accessorMock();
const group = new groupMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api);
const cut = new DockviewGroupPanel('fake-id', accessor, api, group);
const viewMock = jest.fn<IGroupPanelView, []>(() => {
return {

View File

@ -17,7 +17,7 @@ export interface SuppressClosableEvent {
* because it belongs to a groupview
*/
export interface DockviewPanelApi extends Omit<GridviewPanelApi, 'setVisible'> {
readonly group: GroupviewPanel | undefined;
readonly group: GroupviewPanel;
readonly isGroupActive: boolean;
readonly title: string;
readonly suppressClosable: boolean;
@ -29,7 +29,7 @@ export class DockviewPanelApiImpl
extends GridviewPanelApiImpl
implements DockviewPanelApi
{
private _group: GroupviewPanel | undefined;
private _group: GroupviewPanel;
readonly _onDidTitleChange = new Emitter<TitleEvent>();
readonly onDidTitleChange = this._onDidTitleChange.event;
@ -60,7 +60,7 @@ export class DockviewPanelApiImpl
return !!this.group?.isActive;
}
set group(value: GroupviewPanel | undefined) {
set group(value: GroupviewPanel) {
const isOldGroupActive = this.isGroupActive;
this._group = value;
@ -78,13 +78,13 @@ export class DockviewPanelApiImpl
}
}
get group(): GroupviewPanel | undefined {
get group(): GroupviewPanel {
return this._group;
}
constructor(private panel: IGroupPanel, group: GroupviewPanel | undefined) {
constructor(private panel: IGroupPanel, group: GroupviewPanel) {
super(panel.id);
this.group = group;
this._group = group;
this.addDisposables(
this.disposable,

View File

@ -5,17 +5,21 @@ import {
} from '../gridview/gridview';
import { GroupviewPanelState, IGroupPanel } from '../groupview/groupPanel';
import { GroupPanelViewState } from '../groupview/groupview';
import { GroupviewPanel } from '../groupview/groupviewPanel';
import { DockviewComponent } from './dockviewComponent';
export interface IPanelDeserializer {
fromJSON(panelData: GroupviewPanelState): IGroupPanel;
fromJSON(
panelData: GroupviewPanelState,
group: GroupviewPanel
): IGroupPanel;
}
export class DefaultDeserializer implements IViewDeserializer {
constructor(
private readonly layout: DockviewComponent,
private panelDeserializer: {
createPanel: (id: string) => IGroupPanel;
createPanel: (id: string, group: GroupviewPanel) => IGroupPanel;
}
) {}
@ -24,29 +28,26 @@ export class DefaultDeserializer implements IViewDeserializer {
const children = data.views;
const active = data.activeView;
const panels: IGroupPanel[] = [];
for (const child of children) {
const panel = this.panelDeserializer.createPanel(child);
panels.push(panel);
}
return this.layout.createGroup({
panels,
activePanel: panels.find((p) => p.id === active),
const group = this.layout.createGroup({
id: data.id,
locked: !!data.locked,
headerHidden: !!data.headerHidden,
});
for (const child of children) {
const panel = this.panelDeserializer.createPanel(child, group);
const isActive = typeof active === 'string' && active === panel.id;
group.model.openPanel(panel, {
skipSetActive: !isActive,
});
}
if (!group.activePanel && group.panels.length > 0) {
group.model.openPanel(group.panels[group.panels.length - 1]);
}
return group;
}
}
/**
* isGroup
*
*
* panel.group.locked = true
* panel.group.header.hiddden = true
*
*/

View File

@ -263,9 +263,6 @@ export class DockviewComponent
}
setActivePanel(panel: IGroupPanel): void {
if (!panel.group) {
throw new Error(`Panel ${panel.id} has no associated group`);
}
this.doSetGroupActive(panel.group);
panel.group.model.openPanel(panel);
}
@ -367,9 +364,9 @@ export class DockviewComponent
this.gridview.deserialize(
grid,
new DefaultDeserializer(this, {
createPanel: (id) => {
createPanel: (id, group) => {
const panelData = panels[id];
return this.deserializer!.fromJSON(panelData);
return this.deserializer!.fromJSON(panelData, group);
},
})
);
@ -411,8 +408,6 @@ export class DockviewComponent
throw new Error(`panel with id ${options.id} already exists`);
}
const panel = this.createPanel(options);
let referenceGroup: GroupviewPanel | undefined;
if (options.position?.referencePanel) {
@ -431,9 +426,12 @@ export class DockviewComponent
referenceGroup = this.activeGroup;
}
let panel: IGroupPanel
if (referenceGroup) {
const target = toTarget(options.position?.direction || 'within');
if (target === Position.Center) {
panel = this.createPanel(options, referenceGroup)
referenceGroup.model.openPanel(panel);
} else {
const location = getGridLocation(referenceGroup.element);
@ -442,10 +440,14 @@ export class DockviewComponent
location,
target
);
this.addPanelToNewGroup(panel, relativeLocation);
const group = this.createGroupAtLocation(relativeLocation);
panel = this.createPanel(options, group)
group.model.openPanel(panel);
}
} else {
this.addPanelToNewGroup(panel);
const group = this.createGroupAtLocation();
panel = this.createPanel(options, group);
group.model.openPanel(panel);
}
return panel;
@ -622,7 +624,8 @@ export class DockviewComponent
target
);
this.addPanelToNewGroup(groupItem, dropLocation);
const group = this.createGroupAtLocation( dropLocation);
group.model.openPanel(groupItem);
}
}
}
@ -710,13 +713,13 @@ export class DockviewComponent
return view;
}
private createPanel(options: AddPanelOptions): IGroupPanel {
private createPanel(options: AddPanelOptions, group: GroupviewPanel): IGroupPanel {
const view = new DefaultGroupPanelView({
content: this.createContentComponent(options.id, options.component),
tab: this.createTabComponent(options.id, options.tabComponent),
});
const panel = new DockviewGroupPanel(options.id, this, this._api);
const panel = new DockviewGroupPanel(options.id, this, this._api, group);
panel.init({
view,
title: options.title || options.id,
@ -754,14 +757,12 @@ export class DockviewComponent
);
}
private addPanelToNewGroup(
panel: IGroupPanel,
private createGroupAtLocation(
location: number[] = [0]
): void {
): GroupviewPanel {
const group = this.createGroup();
this.doAddGroup(group, location);
group.model.openPanel(panel);
return group
}
private findGroup(panel: IGroupPanel): GroupviewPanel | undefined {

View File

@ -19,7 +19,7 @@ export class DockviewGroupPanel
private readonly mutableDisposable = new MutableDisposable();
readonly api: DockviewPanelApiImpl;
private _group: GroupviewPanel | undefined;
private _group: GroupviewPanel;
private _params?: Parameters;
private _view?: IGroupPanelView;
@ -39,7 +39,7 @@ export class DockviewGroupPanel
return this._suppressClosable;
}
get group(): GroupviewPanel | undefined {
get group(): GroupviewPanel {
return this._group;
}
@ -50,11 +50,13 @@ export class DockviewGroupPanel
constructor(
public readonly id: string,
accessor: DockviewComponent,
private readonly containerApi: DockviewApi
private readonly containerApi: DockviewApi,
group: GroupviewPanel
) {
super();
this._suppressClosable = false;
this._title = '';
this._group = group;
this.api = new DockviewPanelApiImpl(this, this._group);
@ -169,7 +171,7 @@ export class DockviewGroupPanel
// the obtain the correct dimensions of the content panel we must deduct the tab height
this.api._onDidPanelDimensionChange.fire({
width,
height: height - (this.group?.model.header.height || 0),
height: height - (this.group.model.header.height || 0),
});
this.view?.layout(width, height);

View File

@ -24,7 +24,7 @@ export type GroupPanelUpdateEvent = PanelUpdateEvent<{
export interface IGroupPanel extends IDisposable, IPanel {
readonly view?: IGroupPanelView;
readonly group?: GroupviewPanel;
readonly group: GroupviewPanel;
readonly api: DockviewPanelApi;
readonly title: string;
readonly suppressClosable: boolean;

View File

@ -394,7 +394,11 @@ export class Groupview extends CompositeDisposable implements IGroupview {
public openPanel(
panel: IGroupPanel,
options: { index?: number; skipFocus?: boolean } = {}
options: {
index?: number;
skipFocus?: boolean;
skipSetActive?: boolean;
} = {}
) {
if (
typeof options.index !== 'number' ||
@ -403,18 +407,22 @@ export class Groupview extends CompositeDisposable implements IGroupview {
options.index = this.panels.length;
}
const skipSetActive = !!options.skipSetActive;
// ensure the group is updated before we fire any events
panel.updateParentGroup(this.parent, true);
if (this._activePanel === panel) {
if (!skipSetActive && this._activePanel === panel) {
this.accessor.doSetGroupActive(this.parent);
return;
}
this.doAddPanel(panel, options.index);
if (!skipSetActive) {
this.doSetActivePanel(panel);
this.accessor.doSetGroupActive(this.parent, !!options.skipFocus);
}
this.updateContainer();
}

View File

@ -4,7 +4,7 @@ import {
GridviewPanelApi,
GridviewPanelApiImpl,
} from '../api/gridviewPanelApi';
import { Groupview, GroupOptions, IGroupview } from './groupview';
import { Groupview, GroupOptions, IHeader } from './groupview';
import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel';
import { IGroupPanel } from './groupPanel';
@ -65,6 +65,10 @@ export class GroupviewPanel extends GridviewPanel implements IGroupviewPanel {
this._model.locked = value;
}
get header(): IHeader {
return this._model.header;
}
constructor(
accessor: IDockviewComponent,
id: string,

View File

@ -6,11 +6,15 @@ import { createComponent } from '../panel/componentFactory';
import { DockviewApi } from '../api/component.api';
import { DefaultTab } from '../dockview/components/tab/defaultTab';
import { DefaultGroupPanelView } from '../dockview/defaultGroupPanelView';
import { GroupviewPanel } from '../groupview/groupviewPanel';
export class ReactPanelDeserialzier implements IPanelDeserializer {
constructor(private readonly layout: DockviewComponent) {}
public fromJSON(panelData: GroupviewPanelState): IGroupPanel {
public fromJSON(
panelData: GroupviewPanelState,
group: GroupviewPanel
): IGroupPanel {
const panelId = panelData.id;
const params = panelData.params;
const title = panelData.title;
@ -39,7 +43,8 @@ export class ReactPanelDeserialzier implements IPanelDeserializer {
const panel = new DockviewGroupPanel(
panelId,
this.layout,
new DockviewApi(this.layout)
new DockviewApi(this.layout),
group
);
panel.init({