Merge pull request #28 from mathuo/20-enhance-public-api

20 enhance public api
This commit is contained in:
mathuo 2022-03-11 21:37:08 +00:00 committed by GitHub
commit b43a4b9d06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 38 additions and 100 deletions

View File

@ -30,7 +30,7 @@ export const ControlCenter = () => {
const panel = api.getPanel(id); const panel = api.getPanel(id);
if (panel) { if (panel) {
api.setActivePanel(panel); panel.api.setActive();
return; return;
} }
api.addPanel({ api.addPanel({
@ -76,10 +76,8 @@ export const ControlCenter = () => {
const onLoad = async () => { const onLoad = async () => {
const api = registry.get<DockviewApi>('dockview'); const api = registry.get<DockviewApi>('dockview');
const didClose = await api.closeAllGroups(); api.closeAllGroups();
if (!didClose) {
return;
}
const data = localStorage.getItem('layout'); const data = localStorage.getItem('layout');
if (data) { if (data) {
const jsonData = JSON.parse(data); const jsonData = JSON.parse(data);
@ -102,7 +100,7 @@ export const ControlCenter = () => {
const settingsPanel = api.getPanel('settings'); const settingsPanel = api.getPanel('settings');
if (settingsPanel) { if (settingsPanel) {
api.setActivePanel(settingsPanel); settingsPanel.api.setActive();
return; return;
} }
@ -124,7 +122,7 @@ export const ControlCenter = () => {
const onFocusPanel = () => { const onFocusPanel = () => {
const api = registry.get<DockviewApi>('dockview'); const api = registry.get<DockviewApi>('dockview');
const panel = api.getPanel('split_panel'); const panel = api.getPanel('split_panel');
api.setActivePanel(panel); panel.api.setActive();
}; };
return ( return (

View File

@ -145,13 +145,6 @@ const components: PanelCollection<IDockviewPanelProps> = {
}) })
); );
props.api.interceptOnCloseAction(() => {
if (confirm('close?')) {
return Promise.resolve(true);
}
return Promise.resolve(false);
});
return () => { return () => {
disposable.dispose(); disposable.dispose();
}; };

View File

@ -6,7 +6,7 @@ export const WelcomePanel = (props: IDockviewPanelProps) => {
const onAddSplitview = (event: React.MouseEvent<HTMLDivElement>) => { const onAddSplitview = (event: React.MouseEvent<HTMLDivElement>) => {
const splitviewPanel = props.containerApi.getPanel('splitview'); const splitviewPanel = props.containerApi.getPanel('splitview');
if (splitviewPanel) { if (splitviewPanel) {
props.containerApi.setActivePanel(splitviewPanel); splitviewPanel.api.setActive();
return; return;
} }
@ -20,7 +20,7 @@ export const WelcomePanel = (props: IDockviewPanelProps) => {
const onAddGridview = (event: React.MouseEvent<HTMLDivElement>) => { const onAddGridview = (event: React.MouseEvent<HTMLDivElement>) => {
const splitviewPanel = props.containerApi.getPanel('gridview'); const splitviewPanel = props.containerApi.getPanel('gridview');
if (splitviewPanel) { if (splitviewPanel) {
props.containerApi.setActivePanel(splitviewPanel); splitviewPanel.api.setActive();
return; return;
} }

View File

@ -1,3 +1,4 @@
import { DockviewComponent } from '../..';
import { DockviewApi } from '../../api/component.api'; import { DockviewApi } from '../../api/component.api';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
@ -6,8 +7,12 @@ describe('dockviewGroupPanel', () => {
const dockviewApiMock = jest.fn<DockviewApi, []>(() => { const dockviewApiMock = jest.fn<DockviewApi, []>(() => {
return {} as any; return {} as any;
}); });
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const api = new dockviewApiMock(); const api = new dockviewApiMock();
const cut = new DockviewGroupPanel('fake-id', api); const accessor = new accessorMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api);
let latestTitle: string | undefined = undefined; let latestTitle: string | undefined = undefined;
@ -32,8 +37,13 @@ describe('dockviewGroupPanel', () => {
const dockviewApiMock = jest.fn<DockviewApi, []>(() => { const dockviewApiMock = jest.fn<DockviewApi, []>(() => {
return {} as any; return {} as any;
}); });
const accessorMock = jest.fn<DockviewComponent, []>(() => {
return {} as any;
});
const api = new dockviewApiMock(); const api = new dockviewApiMock();
const cut = new DockviewGroupPanel('fake-id', api); const accessor = new accessorMock();
const cut = new DockviewGroupPanel('fake-id', accessor, api);
let latestSuppressClosable: boolean | undefined = undefined; let latestSuppressClosable: boolean | undefined = undefined;

View File

@ -396,10 +396,6 @@ export class DockviewApi implements CommonApi {
return this.component.getGroupPanel(id); return this.component.getGroupPanel(id);
} }
setActivePanel(panel: IGroupPanel): void {
this.component.setActivePanel(panel);
}
layout(width: number, height: number, force = false): void { layout(width: number, height: number, force = false): void {
this.component.layout(width, height, force); this.component.layout(width, height, force);
} }
@ -408,10 +404,6 @@ export class DockviewApi implements CommonApi {
return this.component.addPanel(options); return this.component.addPanel(options);
} }
removePanel(panel: IGroupPanel): void {
this.component.removePanel(panel);
}
addEmptyGroup(options?: AddGroupOptions): void { addEmptyGroup(options?: AddGroupOptions): void {
this.component.addEmptyGroup(options); this.component.addEmptyGroup(options);
} }
@ -424,7 +416,7 @@ export class DockviewApi implements CommonApi {
this.component.moveToPrevious(options); this.component.moveToPrevious(options);
} }
closeAllGroups(): Promise<boolean> { closeAllGroups(): void {
return this.component.closeAllGroups(); return this.component.closeAllGroups();
} }

View File

@ -21,8 +21,7 @@ export interface DockviewPanelApi
readonly isGroupActive: boolean; readonly isGroupActive: boolean;
readonly title: string; readonly title: string;
readonly suppressClosable: boolean; readonly suppressClosable: boolean;
close: () => Promise<boolean>; close(): void;
interceptOnCloseAction(interceptor: () => Promise<boolean>): void;
setTitle(title: string): void; setTitle(title: string): void;
} }
@ -31,7 +30,6 @@ export class DockviewPanelApiImpl
implements DockviewPanelApi implements DockviewPanelApi
{ {
private _group: GroupviewPanel | undefined; private _group: GroupviewPanel | undefined;
private _interceptor: undefined | (() => Promise<boolean>);
readonly _onDidTitleChange = new Emitter<TitleEvent>(); readonly _onDidTitleChange = new Emitter<TitleEvent>();
readonly onDidTitleChange = this._onDidTitleChange.event; readonly onDidTitleChange = this._onDidTitleChange.event;
@ -42,10 +40,6 @@ export class DockviewPanelApiImpl
readonly _suppressClosableChanged = new Emitter<SuppressClosableEvent>(); readonly _suppressClosableChanged = new Emitter<SuppressClosableEvent>();
readonly suppressClosableChanged = this._suppressClosableChanged.event; readonly suppressClosableChanged = this._suppressClosableChanged.event;
get tryClose(): undefined | (() => Promise<boolean>) {
return this._interceptor;
}
get title() { get title() {
return this.panel.title; return this.panel.title;
} }
@ -81,14 +75,10 @@ export class DockviewPanelApiImpl
this._onDidTitleChange.fire({ title }); this._onDidTitleChange.fire({ title });
} }
public close(): Promise<boolean> { public close(): void {
if (!this.group) { if (!this.group) {
throw new Error(`panel ${this.id} has no group`); throw new Error(`panel ${this.id} has no group`);
} }
return this.group.model.closePanel(this.panel); return this.group.model.closePanel(this.panel);
} }
public interceptOnCloseAction(interceptor: () => Promise<boolean>) {
this._interceptor = interceptor;
}
} }

View File

@ -103,7 +103,7 @@ export interface IDockviewComponent extends IBaseGrid<GroupviewPanel> {
// lifecycle // lifecycle
addEmptyGroup(options?: AddGroupOptions): void; addEmptyGroup(options?: AddGroupOptions): void;
closeAllGroups: () => Promise<boolean>; closeAllGroups(): void;
// events // events
onTabInteractionEvent: Event<LayoutMouseEvent>; onTabInteractionEvent: Event<LayoutMouseEvent>;
onTabContextMenu: Event<TabContextMenuEvent>; onTabContextMenu: Event<TabContextMenuEvent>;
@ -400,16 +400,12 @@ export class DockviewComponent
this._onGridEvent.fire({ kind: GroupChangeKind.LAYOUT_FROM_JSON }); this._onGridEvent.fire({ kind: GroupChangeKind.LAYOUT_FROM_JSON });
} }
async closeAllGroups(): Promise<boolean> { closeAllGroups(): void {
for (const entry of this._groups.entries()) { for (const entry of this._groups.entries()) {
const [_, group] = entry; const [_, group] = entry;
const didCloseAll = await group.value.model.closeAllPanels(); group.value.model.closeAllPanels();
if (!didCloseAll) {
return false;
}
} }
return true;
} }
fireMouseEvent(event: LayoutMouseEvent): void { fireMouseEvent(event: LayoutMouseEvent): void {
@ -733,6 +729,7 @@ export class DockviewComponent
const panel: IGroupPanel = new DockviewGroupPanel( const panel: IGroupPanel = new DockviewGroupPanel(
options.id, options.id,
this,
this._api this._api
); );
panel.init({ panel.init({

View File

@ -11,6 +11,7 @@ import { GroupviewPanel } from '../groupview/groupviewPanel';
import { CompositeDisposable, MutableDisposable } from '../lifecycle'; import { CompositeDisposable, MutableDisposable } from '../lifecycle';
import { Parameters } from '../panel/types'; import { Parameters } from '../panel/types';
import { IGroupPanelView } from './defaultGroupPanelView'; import { IGroupPanelView } from './defaultGroupPanelView';
import { DockviewComponent } from './dockviewComponent';
export class DockviewGroupPanel export class DockviewGroupPanel
extends CompositeDisposable extends CompositeDisposable
@ -45,6 +46,7 @@ export class DockviewGroupPanel
constructor( constructor(
public readonly id: string, public readonly id: string,
accessor: DockviewComponent,
private readonly containerApi: DockviewApi private readonly containerApi: DockviewApi
) { ) {
super(); super();
@ -55,7 +57,7 @@ export class DockviewGroupPanel
this.addDisposables( this.addDisposables(
this.api.onActiveChange(() => { this.api.onActiveChange(() => {
this.containerApi.setActivePanel(this); accessor.setActivePanel(this);
}), }),
this.api.onDidTitleChange((event) => { this.api.onDidTitleChange((event) => {
const title = event.title; const title = event.title;
@ -82,14 +84,6 @@ export class DockviewGroupPanel
this.api._onFocusEvent.fire(); this.api._onFocusEvent.fire();
} }
public close(): Promise<boolean> {
if (this.api.tryClose) {
return this.api.tryClose();
}
return Promise.resolve(true);
}
public toJSON(): GroupviewPanelState { public toJSON(): GroupviewPanelState {
return <GroupviewPanelState>{ return <GroupviewPanelState>{
id: this.id, id: this.id,

View File

@ -29,7 +29,6 @@ export interface IGroupPanel extends IDisposable, IPanel {
readonly title: string; readonly title: string;
readonly suppressClosable: boolean; readonly suppressClosable: boolean;
updateParentGroup(group: GroupviewPanel, isGroupActive: boolean): void; updateParentGroup(group: GroupviewPanel, isGroupActive: boolean): void;
close?(): Promise<boolean>;
init(params: IGroupPanelInitParameters): void; init(params: IGroupPanelInitParameters): void;
toJSON(): GroupviewPanelState; toJSON(): GroupviewPanelState;
update(event: GroupPanelUpdateEvent): void; update(event: GroupPanelUpdateEvent): void;

View File

@ -88,8 +88,8 @@ export interface IGroupview extends IDisposable, IGridPanelView {
panel: IGroupPanel, panel: IGroupPanel,
options?: { index?: number; skipFocus?: boolean } options?: { index?: number; skipFocus?: boolean }
): void; ): void;
closePanel(panel: IGroupPanel): Promise<boolean>; closePanel(panel: IGroupPanel): void;
closeAllPanels(): Promise<boolean>; closeAllPanels(): void;
containsPanel(panel: IGroupPanel): boolean; containsPanel(panel: IGroupPanel): boolean;
removePanel: (panelOrId: IGroupPanel | string) => IGroupPanel; removePanel: (panelOrId: IGroupPanel | string) => IGroupPanel;
// events // events
@ -393,57 +393,21 @@ export class Groupview extends CompositeDisposable implements IGroupview {
return this._removePanel(panelToRemove); return this._removePanel(panelToRemove);
} }
public async closeAllPanels() { public closeAllPanels() {
const index = this._activePanel
? this.panels.indexOf(this._activePanel)
: -1;
if (this._activePanel && index > -1) {
if (this.panels.indexOf(this._activePanel) < 0) {
console.warn('active panel not tracked');
}
const canClose =
!this._activePanel?.close || (await this._activePanel.close());
if (!canClose) {
return false;
}
}
for (let i = 0; i < this.panels.length; i++) {
if (i === index) {
continue;
}
const panel = this.panels[i];
this.openPanel(panel);
if (panel.close) {
const canClose = await panel.close();
if (!canClose) {
return false;
}
}
}
if (this.panels.length > 0) { if (this.panels.length > 0) {
// take a copy since we will be edting the array as we iterate through // take a copy since we will be edting the array as we iterate through
const arrPanelCpy = [...this.panels]; const arrPanelCpy = [...this.panels];
await Promise.all(arrPanelCpy.map((p) => this.doClose(p))); for (const panel of arrPanelCpy) {
this.doClose(panel);
}
} else { } else {
this.accessor.removeGroup(this.parent); this.accessor.removeGroup(this.parent);
} }
return true;
} }
public closePanel = async (panel: IGroupPanel) => { public closePanel(panel: IGroupPanel): void {
if (panel.close && !(await panel.close())) {
return false;
}
this.doClose(panel); this.doClose(panel);
return true; }
};
private doClose(panel: IGroupPanel) { private doClose(panel: IGroupPanel) {
this.accessor.removePanel(panel); this.accessor.removePanel(panel);

View File

@ -38,6 +38,7 @@ export class ReactPanelDeserialzier implements IPanelDeserializer {
const panel = new DockviewGroupPanel( const panel = new DockviewGroupPanel(
panelId, panelId,
this.layout,
new DockviewApi(this.layout) new DockviewApi(this.layout)
); );