feat: addPanel positional index

This commit is contained in:
mathuo 2024-11-03 14:38:10 +00:00
parent ca6f46ac8e
commit 291e76afdb
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
7 changed files with 142 additions and 18 deletions

View File

@ -5378,6 +5378,101 @@ describe('dockviewComponent', () => {
});
describe('addPanel', () => {
test('that can add panel to index with referencePanel', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
createComponent(options) {
switch (options.name) {
case 'default':
return new PanelContentPartTest(
options.id,
options.name
);
default:
throw new Error(`unsupported`);
}
},
});
const api = new DockviewApi(dockview);
dockview.layout(1000, 1000);
const panel1 = api.addPanel({
id: 'panel_1',
component: 'default',
});
const panel2 = api.addPanel({
id: 'panel_2',
component: 'default',
position: {
referencePanel: panel1,
},
});
const panel3 = api.addPanel({
id: 'panel_3',
component: 'default',
position: {
referencePanel: panel1,
index: 1,
},
});
expect(panel1.api.group.panels).toEqual([panel1, panel3, panel2]);
});
test('that can add panel to index with referenceGroup', () => {
const container = document.createElement('div');
const dockview = new DockviewComponent(container, {
createComponent(options) {
switch (options.name) {
case 'default':
return new PanelContentPartTest(
options.id,
options.name
);
default:
throw new Error(`unsupported`);
}
},
});
const api = new DockviewApi(dockview);
dockview.layout(1000, 1000);
const panel1 = api.addPanel({
id: 'panel_1',
component: 'default',
});
const panel2 = api.addPanel({
id: 'panel_2',
component: 'default',
position: {
referencePanel: panel1,
index: 1,
},
});
const panel3 = api.addPanel({
id: 'panel_3',
component: 'default',
position: {
referenceGroup: panel1.api.group,
index: 1,
},
});
expect(panel1.api.group.panels).toEqual([panel1, panel3, panel2]);
panel1.api.moveTo({ index: 1 });
expect(panel1.api.group.panels).toEqual([panel3, panel1, panel2]);
});
test('that can add panel', () => {
const container = document.createElement('div');

View File

@ -9,6 +9,15 @@ import { Emitter, Event } from '../events';
import { MutableDisposable } from '../lifecycle';
import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi';
export interface DockviewGroupMoveParams {
group?: DockviewGroupPanel;
position?: Position;
/**
* The index to place the panel within a group, only applicable if the placement is within an existing group
*/
index?: number;
}
export interface DockviewGroupPanelApi extends GridviewPanelApi {
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly onDidActivePanelChange: Event<DockviewGroupChangeEvent>;
@ -17,7 +26,7 @@ export interface DockviewGroupPanelApi extends GridviewPanelApi {
* If you require the Window object
*/
getWindow(): Window;
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void;
moveTo(options: DockviewGroupMoveParams): void;
maximize(): void;
isMaximized(): boolean;
exitMaximized(): void;
@ -28,7 +37,8 @@ export interface DockviewGroupPanelFloatingChangeEvent {
readonly location: DockviewGroupLocation;
}
const NOT_INITIALIZED_MESSAGE = 'dockview: DockviewGroupPanelApiImpl not initialized';
const NOT_INITIALIZED_MESSAGE =
'dockview: DockviewGroupPanelApiImpl not initialized';
export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
private readonly _mutableDisposable = new MutableDisposable();
@ -74,7 +84,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
: window;
}
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void {
moveTo(options: DockviewGroupMoveParams): void {
if (!this._group) {
throw new Error(NOT_INITIALIZED_MESSAGE);
}
@ -93,6 +103,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
position: options.group
? options.position ?? 'center'
: 'center',
index: options.index,
},
});
}

View File

@ -4,9 +4,11 @@ import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
import { CompositeDisposable, MutableDisposable } from '../lifecycle';
import { DockviewPanel } from '../dockview/dockviewPanel';
import { DockviewComponent } from '../dockview/dockviewComponent';
import { Position } from '../dnd/droptarget';
import { DockviewPanelRenderer } from '../overlay/overlayRenderContainer';
import { DockviewGroupPanelFloatingChangeEvent } from './dockviewGroupPanelApi';
import {
DockviewGroupMoveParams,
DockviewGroupPanelFloatingChangeEvent,
} from './dockviewGroupPanelApi';
import { DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel';
export interface TitleEvent {
@ -25,6 +27,8 @@ export interface GroupChangedEvent {
// empty
}
export type DockviewPanelMoveParams = DockviewGroupMoveParams;
export interface DockviewPanelApi
extends Omit<
GridviewPanelApi,
@ -50,11 +54,7 @@ export interface DockviewPanelApi
close(): void;
setTitle(title: string): void;
setRenderer(renderer: DockviewPanelRenderer): void;
moveTo(options: {
group: DockviewGroupPanel;
position?: Position;
index?: number;
}): void;
moveTo(options: DockviewPanelMoveParams): void;
maximize(): void;
isMaximized(): boolean;
exitMaximized(): void;
@ -160,16 +160,14 @@ export class DockviewPanelApiImpl
return this.group.api.getWindow();
}
moveTo(options: {
group: DockviewGroupPanel;
position?: Position;
index?: number;
}): void {
moveTo(options: DockviewPanelMoveParams): void {
this.accessor.moveGroupOrPanel({
from: { groupId: this._group.id, panelId: this.panel.id },
to: {
group: options.group,
position: options.position ?? 'center',
group: options.group ?? this._group,
position: options.group
? options.position ?? 'center'
: 'center',
index: options.index,
},
});

View File

@ -1387,12 +1387,15 @@ export class DockviewComponent
height: options.initialHeight,
};
let index: number | undefined;
if (options.position) {
if (isPanelOptionsWithPanel(options.position)) {
const referencePanel =
typeof options.position.referencePanel === 'string'
? this.getGroupPanel(options.position.referencePanel)
: options.position.referencePanel;
index = options.position.index;
if (!referencePanel) {
throw new Error(
@ -1407,6 +1410,7 @@ export class DockviewComponent
? this._groups.get(options.position.referenceGroup)
?.value
: options.position.referenceGroup;
index = options.position.index;
if (!referenceGroup) {
throw new Error(
@ -1422,6 +1426,7 @@ export class DockviewComponent
group.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
if (!options.inactive) {
@ -1468,6 +1473,7 @@ export class DockviewComponent
group.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
} else if (
referenceGroup.api.location.type === 'floating' ||
@ -1477,6 +1483,7 @@ export class DockviewComponent
referenceGroup.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
referenceGroup.api.setSize({
@ -1505,6 +1512,7 @@ export class DockviewComponent
group.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
if (!options.inactive) {
@ -1532,6 +1540,7 @@ export class DockviewComponent
group.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
} else {
const group = this.createGroupAtLocation(
@ -1544,6 +1553,7 @@ export class DockviewComponent
group.model.openPanel(panel, {
skipSetActive: options.inactive,
skipSetGroupActive: options.inactive,
index,
});
if (!options.inactive) {

View File

@ -326,7 +326,7 @@ export class DockviewGroupPanelModel
private readonly _api: DockviewApi;
get element(): HTMLElement {
throw new Error('not supported');
throw new Error('dockview: not supported');
}
get activePanel(): IDockviewPanel | undefined {

View File

@ -159,11 +159,19 @@ export interface PanelOptions<P extends object = Parameters> {
type RelativePanel = {
direction?: Direction;
referencePanel: string | IDockviewPanel;
/**
* The index to place the panel within a group, only applicable if the placement is within an existing group
*/
index?: number;
};
type RelativeGroup = {
direction?: Direction;
referenceGroup: string | DockviewGroupPanel;
/**
* The index to place the panel within a group, only applicable if the placement is within an existing group
*/
index?: number;
};
type AbsolutePosition = {

View File

@ -100,6 +100,7 @@ export {
TitleEvent,
RendererChangedEvent,
DockviewPanelApi,
DockviewPanelMoveParams,
} from './api/dockviewPanelApi';
export {
PanelSizeEvent,
@ -110,6 +111,7 @@ export { ExpansionEvent, PaneviewPanelApi } from './api/paneviewPanelApi';
export {
DockviewGroupPanelApi,
DockviewGroupPanelFloatingChangeEvent,
DockviewGroupMoveParams,
} from './api/dockviewGroupPanelApi';
export {
CommonApi,