refactor: improve public api

This commit is contained in:
mathuo 2023-02-12 22:34:00 +07:00
parent 716424d972
commit 01816a1d8b
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
13 changed files with 94 additions and 37 deletions

View File

@ -13,6 +13,7 @@ describe('groupPanelApi', () => {
const accessor: Partial<DockviewComponent> = { const accessor: Partial<DockviewComponent> = {
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
const groupViewPanel = new GroupPanel( const groupViewPanel = new GroupPanel(
<DockviewComponent>accessor, <DockviewComponent>accessor,
@ -50,6 +51,7 @@ describe('groupPanelApi', () => {
const accessor: Partial<DockviewComponent> = { const accessor: Partial<DockviewComponent> = {
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
const groupViewPanel = new GroupPanel( const groupViewPanel = new GroupPanel(
<DockviewComponent>accessor, <DockviewComponent>accessor,

View File

@ -1,3 +1,4 @@
import { GridviewPanelApiImpl } from '../../api/gridviewPanelApi';
import { GridviewComponent } from '../../gridview/gridviewComponent'; import { GridviewComponent } from '../../gridview/gridviewComponent';
import { GridviewPanel } from '../../gridview/gridviewPanel'; import { GridviewPanel } from '../../gridview/gridviewPanel';
import { CompositeDisposable } from '../../lifecycle'; import { CompositeDisposable } from '../../lifecycle';
@ -6,7 +7,9 @@ import { Orientation } from '../../splitview/core/splitview';
class TestGridview extends GridviewPanel { class TestGridview extends GridviewPanel {
constructor(id: string, componentName: string) { constructor(id: string, componentName: string) {
super(id, componentName); super(id, componentName, new GridviewPanelApiImpl(id));
this.api.initialize(this);
this.element.id = id; this.element.id = id;
} }
@ -65,7 +68,7 @@ describe('gridview', () => {
expect(gridview.size).toBe(1); expect(gridview.size).toBe(1);
const panel1 = gridview.getPanel('panel1'); const panel1 = gridview.getPanel('panel1')!;
gridview.removePanel(panel1); gridview.removePanel(panel1);
@ -101,9 +104,9 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel1 = gridview.getPanel('panel1'); const panel1 = gridview.getPanel('panel1')!;
const panel2 = gridview.getPanel('panel2'); const panel2 = gridview.getPanel('panel2')!;
const panel3 = gridview.getPanel('panel3'); const panel3 = gridview.getPanel('panel3')!;
expect(panel1.api.isActive).toBeFalsy(); expect(panel1.api.isActive).toBeFalsy();
expect(panel2.api.isActive).toBeFalsy(); expect(panel2.api.isActive).toBeFalsy();
@ -192,9 +195,9 @@ describe('gridview', () => {
}); });
gridview.layout(800, 400, true); gridview.layout(800, 400, true);
const panel1 = gridview.getPanel('panel_1'); const panel1 = gridview.getPanel('panel_1')!;
const panel2 = gridview.getPanel('panel_2'); const panel2 = gridview.getPanel('panel_2')!;
const panel3 = gridview.getPanel('panel_3'); const panel3 = gridview.getPanel('panel_3')!;
expect(panel1?.api.isVisible).toBeTruthy(); expect(panel1?.api.isVisible).toBeTruthy();
expect(panel1?.api.id).toBe('panel_1'); expect(panel1?.api.id).toBe('panel_1');
@ -330,7 +333,7 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel1 = gridview.getPanel('panel_1'); const panel1 = gridview.getPanel('panel_1')!;
expect(events).toEqual([ expect(events).toEqual([
{ {
@ -349,7 +352,7 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel2 = gridview.getPanel('panel_2'); const panel2 = gridview.getPanel('panel_2')!;
expect(events).toEqual([ expect(events).toEqual([
{ {
@ -368,7 +371,7 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel3 = gridview.getPanel('panel_3'); const panel3 = gridview.getPanel('panel_3')!;
expect(events).toEqual([ expect(events).toEqual([
{ {
@ -1685,8 +1688,8 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel1 = gridview.getPanel('panel1'); const panel1 = gridview.getPanel('panel1')!;
const panel2 = gridview.getPanel('panel2'); const panel2 = gridview.getPanel('panel2')!;
const panel1Spy = jest.spyOn(panel1, 'dispose'); const panel1Spy = jest.spyOn(panel1, 'dispose');
const panel2Spy = jest.spyOn(panel2, 'dispose'); const panel2Spy = jest.spyOn(panel2, 'dispose');
@ -1714,8 +1717,8 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel1 = gridview.getPanel('panel1'); const panel1 = gridview.getPanel('panel1')!;
const panel2 = gridview.getPanel('panel2'); const panel2 = gridview.getPanel('panel2')!;
const panel1Spy = jest.spyOn(panel1, 'dispose'); const panel1Spy = jest.spyOn(panel1, 'dispose');
const panel2Spy = jest.spyOn(panel2, 'dispose'); const panel2Spy = jest.spyOn(panel2, 'dispose');
@ -1743,8 +1746,8 @@ describe('gridview', () => {
component: 'default', component: 'default',
}); });
const panel1 = gridview.getPanel('panel1'); const panel1 = gridview.getPanel('panel1')!;
const panel2 = gridview.getPanel('panel2'); const panel2 = gridview.getPanel('panel2')!;
const panel1Spy = jest.spyOn(panel1, 'dispose'); const panel1Spy = jest.spyOn(panel1, 'dispose');
const panel2Spy = jest.spyOn(panel2, 'dispose'); const panel2Spy = jest.spyOn(panel2, 'dispose');

View File

@ -7,6 +7,7 @@ describe('gridviewPanel', () => {
return { return {
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
} as any; } as any;
}); });

View File

@ -15,6 +15,7 @@ describe('tabsContainer', () => {
return { return {
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
}); });
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => { const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
@ -34,7 +35,7 @@ describe('tabsContainer', () => {
const accessor = new accessorMock() as DockviewComponent; const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel; const groupPanel = new groupPanelMock() as GroupPanel;
const cut = new TabsContainer(accessor, groupPanel, {}); const cut = new TabsContainer(accessor, groupPanel);
const emptySpace = cut.element const emptySpace = cut.element
.getElementsByClassName('void-container') .getElementsByClassName('void-container')
@ -67,6 +68,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid', id: 'testcomponentid',
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
}); });
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => { const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
@ -88,7 +90,7 @@ describe('tabsContainer', () => {
const accessor = new accessorMock() as DockviewComponent; const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel; const groupPanel = new groupPanelMock() as GroupPanel;
const cut = new TabsContainer(accessor, groupPanel, {}); const cut = new TabsContainer(accessor, groupPanel);
const emptySpace = cut.element const emptySpace = cut.element
.getElementsByClassName('void-container') .getElementsByClassName('void-container')
@ -132,6 +134,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid', id: 'testcomponentid',
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
}); });
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => { const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
@ -153,7 +156,7 @@ describe('tabsContainer', () => {
const accessor = new accessorMock() as DockviewComponent; const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel; const groupPanel = new groupPanelMock() as GroupPanel;
const cut = new TabsContainer(accessor, groupPanel, {}); const cut = new TabsContainer(accessor, groupPanel);
cut.openPanel(new TestPanel('panel1', jest.fn() as any)); cut.openPanel(new TestPanel('panel1', jest.fn() as any));
cut.openPanel(new TestPanel('panel2', jest.fn() as any)); cut.openPanel(new TestPanel('panel2', jest.fn() as any));
@ -194,6 +197,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid', id: 'testcomponentid',
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
}); });
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => { const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
@ -215,7 +219,7 @@ describe('tabsContainer', () => {
const accessor = new accessorMock() as DockviewComponent; const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel; const groupPanel = new groupPanelMock() as GroupPanel;
const cut = new TabsContainer(accessor, groupPanel, {}); const cut = new TabsContainer(accessor, groupPanel);
cut.openPanel(new TestPanel('panel1', jest.fn() as any)); cut.openPanel(new TestPanel('panel1', jest.fn() as any));
cut.openPanel(new TestPanel('panel2', jest.fn() as any)); cut.openPanel(new TestPanel('panel2', jest.fn() as any));
@ -256,6 +260,7 @@ describe('tabsContainer', () => {
id: 'testcomponentid', id: 'testcomponentid',
onDidAddPanel: jest.fn(), onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(), onDidRemovePanel: jest.fn(),
options: {},
}; };
}); });
const groupviewMock = jest.fn<Partial<Groupview>, []>(() => { const groupviewMock = jest.fn<Partial<Groupview>, []>(() => {
@ -276,7 +281,7 @@ describe('tabsContainer', () => {
const accessor = new accessorMock() as DockviewComponent; const accessor = new accessorMock() as DockviewComponent;
const groupPanel = new groupPanelMock() as GroupPanel; const groupPanel = new groupPanelMock() as GroupPanel;
const cut = new TabsContainer(accessor, groupPanel, {}); const cut = new TabsContainer(accessor, groupPanel);
cut.openPanel(new TestPanel('panel1', jest.fn() as any)); cut.openPanel(new TestPanel('panel1', jest.fn() as any));
cut.openPanel(new TestPanel('panel2', jest.fn() as any)); cut.openPanel(new TestPanel('panel2', jest.fn() as any));

View File

@ -1,4 +1,7 @@
import { Emitter, Event } from '../events'; import { Emitter, Event } from '../events';
import { GridviewPanel } from '../gridview/gridviewPanel';
import { MutableDisposable } from '../lifecycle';
import { IPanel } from '../panel/types';
import { FunctionOrValue } from '../types'; import { FunctionOrValue } from '../types';
import { PanelApiImpl, PanelApi } from './panelApi'; import { PanelApiImpl, PanelApi } from './panelApi';
@ -48,7 +51,7 @@ export class GridviewPanelApiImpl
readonly onDidSizeChange: Event<SizeEvent> = this._onDidSizeChange.event; readonly onDidSizeChange: Event<SizeEvent> = this._onDidSizeChange.event;
// //
constructor(id: string) { constructor(id: string, panel?: IPanel) {
super(id); super(id);
this.addDisposables( this.addDisposables(
@ -56,6 +59,10 @@ export class GridviewPanelApiImpl
this._onDidConstraintsChange, this._onDidConstraintsChange,
this._onDidSizeChange this._onDidSizeChange
); );
if (panel) {
this.initialize(panel);
}
} }
public setConstraints(value: GridConstraintChangeEvent) { public setConstraints(value: GridConstraintChangeEvent) {

View File

@ -71,6 +71,9 @@ export class DockviewPanelApiImpl
constructor(private panel: IDockviewPanel, group: GroupPanel) { constructor(private panel: IDockviewPanel, group: GroupPanel) {
super(panel.id); super(panel.id);
this.initialize(panel);
this._group = group; this._group = group;
this.addDisposables( this.addDisposables(

View File

@ -1,5 +1,7 @@
import { Emitter, Event } from '../events'; import { Emitter, Event } from '../events';
import { CompositeDisposable } from '../lifecycle'; import { BasePanelView } from '../gridview/basePanelView';
import { CompositeDisposable, MutableDisposable } from '../lifecycle';
import { IPanel, Parameters } from '../panel/types';
export interface FocusEvent { export interface FocusEvent {
readonly isFocused: boolean; readonly isFocused: boolean;
@ -25,6 +27,7 @@ export interface PanelApi {
readonly onDidActiveChange: Event<ActiveEvent>; readonly onDidActiveChange: Event<ActiveEvent>;
setVisible(isVisible: boolean): void; setVisible(isVisible: boolean): void;
setActive(): void; setActive(): void;
updateParameters(parameters: Parameters): void;
/** /**
* The id of the panel that would have been assigned when the panel was created * The id of the panel that would have been assigned when the panel was created
*/ */
@ -54,13 +57,18 @@ export interface PanelApi {
/** /**
* A core api implementation that should be used across all panel-like objects * A core api implementation that should be used across all panel-like objects
*/ */
export class PanelApiImpl extends CompositeDisposable implements PanelApi { export abstract class PanelApiImpl
extends CompositeDisposable
implements PanelApi
{
private _isFocused = false; private _isFocused = false;
private _isActive = false; private _isActive = false;
private _isVisible = true; private _isVisible = true;
private _width = 0; private _width = 0;
private _height = 0; private _height = 0;
private readonly panelUpdatesDisposable = new MutableDisposable();
readonly _onDidDimensionChange = new Emitter<PanelDimensionChangeEvent>({ readonly _onDidDimensionChange = new Emitter<PanelDimensionChangeEvent>({
replay: true, replay: true,
}); });
@ -94,6 +102,10 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
readonly _onActiveChange = new Emitter<void>(); readonly _onActiveChange = new Emitter<void>();
readonly onActiveChange: Event<void> = this._onActiveChange.event; readonly onActiveChange: Event<void> = this._onActiveChange.event;
// //
readonly _onUpdateParameters = new Emitter<Parameters>();
readonly onUpdateParameters: Event<Parameters> =
this._onUpdateParameters.event;
//
get isFocused() { get isFocused() {
return this._isFocused; return this._isFocused;
@ -118,6 +130,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
super(); super();
this.addDisposables( this.addDisposables(
this.panelUpdatesDisposable,
this._onDidDimensionChange, this._onDidDimensionChange,
this._onDidChangeFocus, this._onDidChangeFocus,
this._onDidVisibilityChange, this._onDidVisibilityChange,
@ -125,6 +138,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this._onFocusEvent, this._onFocusEvent,
this._onActiveChange, this._onActiveChange,
this._onVisibilityChange, this._onVisibilityChange,
this._onUpdateParameters,
this.onDidFocusChange((event) => { this.onDidFocusChange((event) => {
this._isFocused = event.isFocused; this._isFocused = event.isFocused;
}), }),
@ -141,6 +155,18 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
); );
} }
public initialize(panel: IPanel): void {
this.panelUpdatesDisposable.value = this._onUpdateParameters.event(
(parameters) => {
panel.update({
params: {
params: parameters,
},
});
}
);
}
setVisible(isVisible: boolean) { setVisible(isVisible: boolean) {
this._onVisibilityChange.fire({ isVisible }); this._onVisibilityChange.fire({ isVisible });
} }
@ -149,6 +175,10 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this._onActiveChange.fire(); this._onActiveChange.fire();
} }
updateParameters(parameters: Parameters): void {
this._onUpdateParameters.fire(parameters);
}
dispose() { dispose() {
super.dispose(); super.dispose();
} }

View File

@ -43,7 +43,7 @@ import {
GroupPanelViewState, GroupPanelViewState,
GroupviewDropEvent, GroupviewDropEvent,
} from '../groupview/groupview'; } from '../groupview/groupview';
import { GroupPanel } from '../groupview/groupviewPanel'; import { GroupPanel, IGroupviewPanel } from '../groupview/groupviewPanel';
import { DefaultGroupPanelView } from './defaultGroupPanelView'; import { DefaultGroupPanelView } from './defaultGroupPanelView';
import { getPanelData } from '../dnd/dataTransfer'; import { getPanelData } from '../dnd/dataTransfer';
@ -107,7 +107,7 @@ export interface IDockviewComponent extends IBaseGrid<GroupPanel> {
getGroupPanel: (id: string) => IDockviewPanel | undefined; getGroupPanel: (id: string) => IDockviewPanel | undefined;
createWatermarkComponent(): IWatermarkRenderer; createWatermarkComponent(): IWatermarkRenderer;
// lifecycle // lifecycle
addGroup(options?: AddGroupOptions): GroupPanel; addGroup(options?: AddGroupOptions): IGroupviewPanel;
closeAllGroups(): void; closeAllGroups(): void;
// events // events
moveToNext(options?: MovementOptions): void; moveToNext(options?: MovementOptions): void;

View File

@ -6,7 +6,7 @@ import {
PanelInitParameters, PanelInitParameters,
IPanel, IPanel,
} from '../panel/types'; } from '../panel/types';
import { PanelApiImpl } from '../api/panelApi'; import { PanelApi, PanelApiImpl } from '../api/panelApi';
export interface BasePanelViewState { export interface BasePanelViewState {
id: string; id: string;
@ -14,7 +14,7 @@ export interface BasePanelViewState {
params?: Record<string, any>; params?: Record<string, any>;
} }
export interface BasePanelViewExported<T extends PanelApiImpl> { export interface BasePanelViewExported<T extends PanelApi> {
readonly id: string; readonly id: string;
readonly api: T; readonly api: T;
readonly width: number; readonly width: number;

View File

@ -9,7 +9,10 @@ import {
BasePanelViewExported, BasePanelViewExported,
BasePanelViewState, BasePanelViewState,
} from './basePanelView'; } from './basePanelView';
import { GridviewPanelApiImpl } from '../api/gridviewPanelApi'; import {
GridviewPanelApi,
GridviewPanelApiImpl,
} from '../api/gridviewPanelApi';
import { LayoutPriority } from '../splitview/core/splitview'; import { LayoutPriority } from '../splitview/core/splitview';
import { Emitter, Event } from '../events'; import { Emitter, Event } from '../events';
import { IViewSize } from './gridview'; import { IViewSize } from './gridview';
@ -26,7 +29,7 @@ export interface GridviewInitParameters extends PanelInitParameters {
} }
export interface IGridviewPanel export interface IGridviewPanel
extends BasePanelViewExported<GridviewPanelApiImpl> { extends BasePanelViewExported<GridviewPanelApi> {
readonly minimumWidth: number; readonly minimumWidth: number;
readonly maximumWidth: number; readonly maximumWidth: number;
readonly minimumHeight: number; readonly minimumHeight: number;
@ -123,13 +126,11 @@ export abstract class GridviewPanel
return this.api.isActive; return this.api.isActive;
} }
constructor( constructor(id: string, component: string, api: GridviewPanelApiImpl) {
id: string,
component: string,
api = new GridviewPanelApiImpl(id)
) {
super(id, component, api); super(id, component, api);
this.api.initialize(this); // TODO: required to by-pass 'super before this' requirement
this.addDisposables( this.addDisposables(
this._onDidChange, this._onDidChange,
this.api.onVisibilityChange((event) => { this.api.onVisibilityChange((event) => {

View File

@ -164,6 +164,8 @@ export abstract class PaneviewPanel
) { ) {
super(id, component, new PaneviewPanelApiImpl(id)); super(id, component, new PaneviewPanelApiImpl(id));
this.api.pane = this; // TODO cannot use 'this' before 'super' this.api.pane = this; // TODO cannot use 'this' before 'super'
this.api.initialize(this);
this._isExpanded = isExpanded; this._isExpanded = isExpanded;
this._headerVisible = isHeaderVisible; this._headerVisible = isHeaderVisible;

View File

@ -1,4 +1,5 @@
import { GridviewApi } from '../../api/component.api'; import { GridviewApi } from '../../api/component.api';
import { GridviewPanelApiImpl } from '../../api/gridviewPanelApi';
import { import {
GridviewPanel, GridviewPanel,
GridviewInitParameters, GridviewInitParameters,
@ -14,7 +15,7 @@ export class ReactGridPanelView extends GridviewPanel {
private readonly reactComponent: React.FunctionComponent<IGridviewPanelProps>, private readonly reactComponent: React.FunctionComponent<IGridviewPanelProps>,
private readonly reactPortalStore: ReactPortalStore private readonly reactPortalStore: ReactPortalStore
) { ) {
super(id, component); super(id, component, new GridviewPanelApiImpl(id));
} }
getComponent(): IFrameworkPart { getComponent(): IFrameworkPart {

View File

@ -85,6 +85,8 @@ export abstract class SplitviewPanel
constructor(id: string, componentName: string) { constructor(id: string, componentName: string) {
super(id, componentName, new SplitviewPanelApiImpl(id)); super(id, componentName, new SplitviewPanelApiImpl(id));
this.api.initialize(this);
this.addDisposables( this.addDisposables(
this._onDidChange, this._onDidChange,
this.api.onVisibilityChange((event) => { this.api.onVisibilityChange((event) => {