feat: enhance fired events

This commit is contained in:
mathuo 2021-10-19 18:38:19 +01:00
parent 005d802a99
commit 0ef3df76f9
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
11 changed files with 235 additions and 138 deletions

View File

@ -12,11 +12,8 @@ import {
IWatermarkRenderer,
} from '../../groupview/types';
import { PanelUpdateEvent } from '../../panel/types';
import { fireEvent } from '@testing-library/dom';
import { LocalSelectionTransfer } from '../../dnd/dataTransfer';
import { Position } from '../../dnd/droptarget';
import { GroupviewPanel } from '../../groupview/groupviewPanel';
import { GroupOptions } from '../../groupview/groupview';
import { GroupChangeKind, GroupOptions } from '../../groupview/groupview';
import { DockviewPanelApi } from '../../api/groupPanelApi';
import {
DefaultGroupPanelView,
@ -222,6 +219,7 @@ describe('groupview', () => {
tabHeight: 30,
};
groupview = new GroupviewPanel(dockview, 'groupview-1', options);
groupview.initialize();
});
test('serialized layout shows active panel', () => {
@ -234,6 +232,7 @@ describe('groupview', () => {
panels: [panel1, panel2, panel3],
activePanel: panel2,
});
groupview2.initialize();
expect(groupview2.model.activePanel).toBe(panel2);
@ -248,6 +247,138 @@ describe('groupview', () => {
).toBeFalsy();
});
test('panel events are captured during de-serialization', () => {
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
const panel3 = new TestPanel('panel3', jest.fn() as any);
const groupview2 = new GroupviewPanel(dockview, 'groupview-2', {
tabHeight: 25,
panels: [panel1, panel2, panel3],
activePanel: panel2,
});
const events: Array<{
kind: GroupChangeKind;
}> = [];
const disposable = groupview2.model.onDidGroupChange((e) => {
events.push(e);
});
groupview2.initialize();
expect(events).toEqual([
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel1,
},
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel2,
},
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel3,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
panel: panel2,
},
]);
disposable.dispose();
});
test('panel events flow', () => {
let events: Array<{
kind: GroupChangeKind;
}> = [];
const disposable = groupview.model.onDidGroupChange((e) => {
events.push(e);
});
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
const panel3 = new TestPanel('panel3', jest.fn() as any);
expect(events.length).toBe(0);
groupview.model.openPanel(panel1);
expect(events).toEqual([
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel1,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
panel: panel1,
},
]);
events = [];
groupview.model.openPanel(panel2);
expect(events).toEqual([
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel2,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
panel: panel2,
},
]);
events = [];
groupview.model.openPanel(panel3);
expect(events).toEqual([
{
kind: GroupChangeKind.ADD_PANEL,
panel: panel3,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
panel: panel3,
},
]);
events = [];
groupview.model.removePanel(panel3);
expect(events).toEqual([
{
kind: GroupChangeKind.REMOVE_PANEL,
panel: panel3,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
panel: panel2,
},
]);
events = [];
groupview.model.removePanel(panel1);
expect(events).toEqual([
{
kind: GroupChangeKind.REMOVE_PANEL,
panel: panel1,
},
]);
events = [];
groupview.model.removePanel(panel2);
expect(events).toEqual([
{
kind: GroupChangeKind.REMOVE_PANEL,
panel: panel2,
},
{
kind: GroupChangeKind.PANEL_ACTIVE,
},
]);
events = [];
disposable.dispose();
});
test('moveToPrevious and moveToNext', () => {
const panel1 = new TestPanel('panel1', jest.fn() as any);
const panel2 = new TestPanel('panel2', jest.fn() as any);
@ -293,45 +424,4 @@ describe('groupview', () => {
);
expect(viewQuery).toBeTruthy();
});
// test('dnd', () => {
// const panel1 = new TestPanel('panel1', jest.fn() as any);
// const panel2 = new TestPanel('panel2', jest.fn() as any);
// groupview.model.openPanel(panel1);
// groupview.model.openPanel(panel2);
// const events: GroupDropEvent[] = [];
// groupview.model.onDrop((event) => {
// events.push(event);
// });
// const viewQuery = groupview.element.querySelectorAll(
// '.groupview > .tabs-and-actions-container > .tabs-container > .tab'
// );
// expect(viewQuery.length).toBe(2);
// LocalSelectionTransfer.getInstance().setData([], 'dockview-1');
// fireEvent.dragEnter(viewQuery[0]);
// let dropTarget = viewQuery[0].querySelector('.drop-target-dropzone');
// fireEvent.dragOver(dropTarget);
// fireEvent.drop(dropTarget);
// expect(events.length).toBe(1);
// expect(events[0].target).toBe(Position.Center);
// expect(events[0].index).toBe(0);
// fireEvent.dragEnter(viewQuery[1]);
// dropTarget = viewQuery[1].querySelector('.drop-target-dropzone');
// fireEvent.dragOver(dropTarget);
// fireEvent.drop(dropTarget);
// expect(events.length).toBe(2);
// expect(events[1].target).toBe(Position.Center);
// expect(events[1].index).toBe(1);
// });
});

View File

@ -1,6 +1,6 @@
import { ReactPart } from '../../react/react';
import * as React from 'react';
import { render, screen } from '@testing-library/react';
import { render, screen, act } from '@testing-library/react';
interface TestInterface {
valueA: string;
@ -23,12 +23,16 @@ describe('react', () => {
expect(screen.getByTestId('valueA').textContent).toBe('stringA');
expect(screen.getByTestId('valueB').textContent).toBe('42');
act(() => {
api.update({ valueB: '32' });
});
expect(screen.getByTestId('valueA').textContent).toBe('stringA');
expect(screen.getByTestId('valueB').textContent).toBe('32');
act(() => {
api.update({ valueA: 'anotherStringA', valueB: '22' });
});
expect(screen.getByTestId('valueA').textContent).toBe(
'anotherStringA'

View File

@ -3,43 +3,45 @@ import { FunctionOrValue } from '../types';
import { PanelApiImpl, PanelApi } from './panelApi';
export interface GridConstraintChangeEvent {
minimumWidth?: number;
minimumHeight?: number;
maximumWidth?: number;
maximumHeight?: number;
readonly minimumWidth?: number;
readonly minimumHeight?: number;
readonly maximumWidth?: number;
readonly maximumHeight?: number;
}
interface GridConstraintChangeEvent2 {
minimumWidth?: FunctionOrValue<number>;
minimumHeight?: FunctionOrValue<number>;
maximumWidth?: FunctionOrValue<number>;
maximumHeight?: FunctionOrValue<number>;
readonly minimumWidth?: FunctionOrValue<number>;
readonly minimumHeight?: FunctionOrValue<number>;
readonly maximumWidth?: FunctionOrValue<number>;
readonly maximumHeight?: FunctionOrValue<number>;
}
export interface SizeEvent {
width?: number;
height?: number;
readonly width?: number;
readonly height?: number;
}
export interface GridviewPanelApi extends PanelApi {
onDidConstraintsChange: Event<GridConstraintChangeEvent>;
readonly onDidConstraintsChange: Event<GridConstraintChangeEvent>;
setConstraints(value: GridConstraintChangeEvent2): void;
setSize(event: SizeEvent): void;
}
export class GridviewPanelApiImpl
extends PanelApiImpl
implements GridviewPanelApi {
readonly _onDidConstraintsChangeInternal = new Emitter<GridConstraintChangeEvent2>();
readonly onDidConstraintsChangeInternal: Event<GridConstraintChangeEvent2> = this
._onDidConstraintsChangeInternal.event;
implements GridviewPanelApi
{
readonly _onDidConstraintsChangeInternal =
new Emitter<GridConstraintChangeEvent2>();
readonly onDidConstraintsChangeInternal: Event<GridConstraintChangeEvent2> =
this._onDidConstraintsChangeInternal.event;
//
readonly _onDidConstraintsChange = new Emitter<GridConstraintChangeEvent>({
replay: true,
});
readonly onDidConstraintsChange: Event<GridConstraintChangeEvent> = this
._onDidConstraintsChange.event;
readonly onDidConstraintsChange: Event<GridConstraintChangeEvent> =
this._onDidConstraintsChange.event;
//
readonly _onDidSizeChange = new Emitter<SizeEvent>();

View File

@ -4,11 +4,11 @@ import { IGroupPanel } from '../groupview/groupPanel';
import { GroupviewPanel } from '../groupview/groupviewPanel';
export interface TitleEvent {
title: string;
readonly title: string;
}
export interface SuppressClosableEvent {
suppressClosable: boolean;
readonly suppressClosable: boolean;
}
/*
@ -21,7 +21,7 @@ export interface DockviewPanelApi
readonly isGroupActive: boolean;
readonly title: string;
readonly suppressClosable: boolean;
onDidDirtyChange: Event<boolean>;
readonly onDidDirtyChange: Event<boolean>;
close: () => Promise<boolean>;
interceptOnCloseAction(interceptor: () => Promise<boolean>): void;
setTitle(title: string): void;
@ -29,17 +29,14 @@ export interface DockviewPanelApi
export class DockviewPanelApiImpl
extends GridviewPanelApiImpl
implements DockviewPanelApi {
implements DockviewPanelApi
{
private _group: GroupviewPanel | undefined;
private _interceptor: undefined | (() => Promise<boolean>);
readonly _onDidDirtyChange = new Emitter<boolean>();
readonly onDidDirtyChange = this._onDidDirtyChange.event;
// readonly _onDidGroupPanelVisibleChange = new Emitter<VisibilityEvent>({
// replay: true,
// });
// readonly onDidGroupPanelVisibleChange: Event<VisibilityEvent> = this
// ._onDidGroupPanelVisibleChange.event;
readonly _onDidTitleChange = new Emitter<TitleEvent>();
readonly onDidTitleChange = this._onDidTitleChange.event;
@ -49,10 +46,6 @@ export class DockviewPanelApiImpl
readonly _suppressClosableChanged = new Emitter<SuppressClosableEvent>();
readonly suppressClosableChanged = this._suppressClosableChanged.event;
// get isGroupVisible() {
// return this._isGroupVisible;
// }
get tryClose(): undefined | (() => Promise<boolean>) {
return this._interceptor;
}
@ -81,13 +74,7 @@ export class DockviewPanelApiImpl
super(panel.id);
this._group = group;
this.addDisposables(
// this._onDidGroupPanelVisibleChange,
this._onDidDirtyChange
// this.onDidGroupPanelVisibleChange((event) => {
// this._isGroupVisible = event.isVisible;
// })
);
this.addDisposables(this._onDidDirtyChange);
}
public setTitle(title: string) {

View File

@ -21,29 +21,29 @@ export interface State {
}
export interface FocusEvent {
isFocused: boolean;
readonly isFocused: boolean;
}
export interface PanelDimensionChangeEvent {
width: number;
height: number;
readonly width: number;
readonly height: number;
}
export interface VisibilityEvent {
isVisible: boolean;
readonly isVisible: boolean;
}
export interface ActiveEvent {
isActive: boolean;
readonly isActive: boolean;
}
export interface PanelApi {
// events
onDidDimensionsChange: Event<PanelDimensionChangeEvent>;
onDidStateChange: Event<void>;
onDidFocusChange: Event<FocusEvent>;
onDidVisibilityChange: Event<VisibilityEvent>;
onDidActiveChange: Event<ActiveEvent>;
onFocusEvent: Event<void>;
readonly onDidDimensionsChange: Event<PanelDimensionChangeEvent>;
readonly onDidStateChange: Event<void>;
readonly onDidFocusChange: Event<FocusEvent>;
readonly onDidVisibilityChange: Event<VisibilityEvent>;
readonly onDidActiveChange: Event<ActiveEvent>;
readonly onFocusEvent: Event<void>;
//
setVisible(isVisible: boolean): void;
setActive(): void;
@ -92,11 +92,10 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
readonly _onDidStateChange = new Emitter<void>();
readonly onDidStateChange: Event<void> = this._onDidStateChange.event;
//
readonly _onDidPanelDimensionChange = new Emitter<PanelDimensionChangeEvent>(
{
readonly _onDidPanelDimensionChange =
new Emitter<PanelDimensionChangeEvent>({
replay: true,
}
);
});
readonly onDidDimensionsChange = this._onDidPanelDimensionChange.event;
//
readonly _onDidChangeFocus = new Emitter<FocusEvent>({
@ -110,19 +109,19 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
readonly _onDidVisibilityChange = new Emitter<VisibilityEvent>({
replay: true,
});
readonly onDidVisibilityChange: Event<VisibilityEvent> = this
._onDidVisibilityChange.event;
readonly onDidVisibilityChange: Event<VisibilityEvent> =
this._onDidVisibilityChange.event;
//
readonly _onVisibilityChange = new Emitter<VisibilityEvent>();
readonly onVisibilityChange: Event<VisibilityEvent> = this
._onVisibilityChange.event;
readonly onVisibilityChange: Event<VisibilityEvent> =
this._onVisibilityChange.event;
//
readonly _onDidActiveChange = new Emitter<ActiveEvent>({
replay: true,
});
readonly onDidActiveChange: Event<ActiveEvent> = this._onDidActiveChange
.event;
readonly onDidActiveChange: Event<ActiveEvent> =
this._onDidActiveChange.event;
//
readonly _onActiveChange = new Emitter<void>();
readonly onActiveChange: Event<void> = this._onActiveChange.event;

View File

@ -3,25 +3,26 @@ import { PaneviewPanel } from '../paneview/paneviewPanel';
import { SplitviewPanelApi, SplitviewPanelApiImpl } from './splitviewPanelApi';
export interface ExpansionEvent {
isExpanded: boolean;
readonly isExpanded: boolean;
}
export interface PaneviewPanelApi extends SplitviewPanelApi {
onDidExpansionChange: Event<ExpansionEvent>;
readonly isExpanded: boolean;
readonly onDidExpansionChange: Event<ExpansionEvent>;
readonly onMouseEnter: Event<MouseEvent>;
readonly onMouseLeave: Event<MouseEvent>;
setExpanded(isExpanded: boolean): void;
readonly isExpanded: boolean;
}
export class PaneviewPanelApiImpl
extends SplitviewPanelApiImpl
implements PaneviewPanelApi {
implements PaneviewPanelApi
{
readonly _onDidExpansionChange = new Emitter<ExpansionEvent>({
replay: true,
});
readonly onDidExpansionChange: Event<ExpansionEvent> = this
._onDidExpansionChange.event;
readonly onDidExpansionChange: Event<ExpansionEvent> =
this._onDidExpansionChange.event;
readonly _onMouseEnter = new Emitter<MouseEvent>({});
readonly onMouseEnter: Event<MouseEvent> = this._onMouseEnter.event;

View File

@ -4,43 +4,45 @@ import { FunctionOrValue } from '../types';
import { PanelApiImpl, PanelApi } from './panelApi';
interface PanelConstraintChangeEvent2 {
minimumSize?: FunctionOrValue<number>;
maximumSize?: FunctionOrValue<number>;
readonly minimumSize?: FunctionOrValue<number>;
readonly maximumSize?: FunctionOrValue<number>;
}
export interface PanelConstraintChangeEvent {
minimumSize?: number;
maximumSize?: number;
readonly minimumSize?: number;
readonly maximumSize?: number;
}
export interface PanelSizeEvent {
size: number;
readonly size: number;
}
export interface SplitviewPanelApi extends PanelApi {
onDidConstraintsChange: Event<PanelConstraintChangeEvent>;
readonly onDidConstraintsChange: Event<PanelConstraintChangeEvent>;
setConstraints(value: PanelConstraintChangeEvent2): void;
setSize(event: PanelSizeEvent): void;
}
export class SplitviewPanelApiImpl
extends PanelApiImpl
implements SplitviewPanelApi, IDisposable {
readonly _onDidConstraintsChangeInternal = new Emitter<PanelConstraintChangeEvent2>();
readonly onDidConstraintsChangeInternal: Event<PanelConstraintChangeEvent2> = this
._onDidConstraintsChangeInternal.event;
implements SplitviewPanelApi, IDisposable
{
readonly _onDidConstraintsChangeInternal =
new Emitter<PanelConstraintChangeEvent2>();
readonly onDidConstraintsChangeInternal: Event<PanelConstraintChangeEvent2> =
this._onDidConstraintsChangeInternal.event;
//
readonly _onDidConstraintsChange = new Emitter<PanelConstraintChangeEvent>({
replay: true,
});
readonly onDidConstraintsChange: Event<PanelConstraintChangeEvent> = this
._onDidConstraintsChange.event;
readonly onDidConstraintsChange: Event<PanelConstraintChangeEvent> =
this._onDidConstraintsChange.event;
//
readonly _onDidSizeChange = new Emitter<PanelSizeEvent>();
readonly onDidSizeChange: Event<PanelSizeEvent> = this._onDidSizeChange
.event;
readonly onDidSizeChange: Event<PanelSizeEvent> =
this._onDidSizeChange.event;
//
constructor(id: string) {

View File

@ -625,10 +625,6 @@ export class DockviewComponent
const view = new GroupviewPanel(this, id, options);
if (typeof this.options.tabHeight === 'number') {
view.model.tabHeight = this.options.tabHeight;
}
if (!this._groups.has(view.id)) {
const disposable = new CompositeDisposable(
view.model.onMove((event) => {
@ -643,6 +639,14 @@ export class DockviewComponent
this._groups.set(view.id, { value: view, disposable });
}
// TODO: must be called after the above listeners have been setup,
// not an ideal pattern
view.initialize();
if (typeof this.options.tabHeight === 'number') {
view.model.tabHeight = this.options.tabHeight;
}
return view;
}

View File

@ -552,7 +552,7 @@ export class Groupview extends CompositeDisposable implements IGroupview {
}
if (this._activePanel && this.panels.length === 0) {
this._activePanel = undefined;
this.doSetActivePanel(undefined);
}
this.updateContainer();
@ -601,20 +601,24 @@ export class Groupview extends CompositeDisposable implements IGroupview {
this.updateMru(panel);
this.panels.splice(index, 0, panel);
this._onDidGroupChange.fire({ kind: GroupChangeKind.ADD_PANEL });
this._onDidGroupChange.fire({ kind: GroupChangeKind.ADD_PANEL, panel });
}
private doSetActivePanel(panel: IGroupPanel) {
private doSetActivePanel(panel: IGroupPanel | undefined) {
this._activePanel = panel;
this.tabsContainer.setActivePanel(panel);
// this.contentContainer.openPanel(panel.content);
if (panel) {
this.tabsContainer.setActivePanel(panel);
panel.layout(this._width, this._height);
this.updateMru(panel);
}
this._onDidGroupChange.fire({ kind: GroupChangeKind.PANEL_ACTIVE });
this._onDidGroupChange.fire({
kind: GroupChangeKind.PANEL_ACTIVE,
panel,
});
}
private updateMru(panel: IGroupPanel) {

View File

@ -35,6 +35,9 @@ export class GroupviewPanel extends GridviewPanel {
super(id, 'groupview_default', new GridviewPanelApiImpl(id));
this._model = new Groupview(this.element, accessor, id, options, this);
}
initialize() {
this.model.initialize();
}

View File

@ -28,6 +28,7 @@ export {
PanelDimensionChangeEvent,
VisibilityEvent,
ActiveEvent,
PanelApi,
} from './api/panelApi';
export {
SizeEvent,