Merge pull request #422 from mathuo/360-investigate-opening-tabs-in-new-browser-window

test: add tests
This commit is contained in:
mathuo 2024-01-08 22:03:44 +00:00 committed by GitHub
commit b78a7a6207
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1339 additions and 1084 deletions

View File

@ -1,4 +1,8 @@
import { CompositeDisposable, MutableDisposable } from '../lifecycle';
import {
CompositeDisposable,
Disposable,
MutableDisposable,
} from '../lifecycle';
describe('lifecycle', () => {
test('mutable disposable', () => {
@ -64,4 +68,16 @@ describe('lifecycle', () => {
expect(cut.checkIsDisposed()).toBeTruthy();
});
test('Disposable.from(...)', () => {
const func = jest.fn();
const disposable = Disposable.from(func);
expect(func).not.toHaveBeenCalled();
disposable.dispose();
expect(func).toHaveBeenCalledTimes(1);
});
});

View File

@ -1,4 +1,4 @@
import { Position } from '../dnd/droptarget';
import { Position, positionToDirection } from '../dnd/droptarget';
import { DockviewComponent } from '../dockview/dockviewComponent';
import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel';
import { DockviewGroupLocation } from '../dockview/dockviewGroupPanelModel';
@ -6,9 +6,9 @@ import { Emitter, Event } from '../events';
import { GridviewPanelApi, GridviewPanelApiImpl } from './gridviewPanelApi';
export interface DockviewGroupPanelApi extends GridviewPanelApi {
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
readonly location: DockviewGroupLocation;
moveTo(options: { group: DockviewGroupPanel; position?: Position }): void;
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void;
maximize(): void;
isMaximized(): boolean;
exitMaximized(): void;
@ -24,10 +24,10 @@ const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized';
export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
private _group: DockviewGroupPanel | undefined;
readonly _onDidRenderPositionChange =
readonly _onDidLocationChange =
new Emitter<DockviewGroupPanelFloatingChangeEvent>();
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent> =
this._onDidRenderPositionChange.event;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent> =
this._onDidLocationChange.event;
get location(): DockviewGroupLocation {
if (!this._group) {
@ -39,19 +39,25 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
constructor(id: string, private readonly accessor: DockviewComponent) {
super(id);
this.addDisposables(this._onDidRenderPositionChange);
this.addDisposables(this._onDidLocationChange);
}
moveTo(options: { group: DockviewGroupPanel; position?: Position }): void {
moveTo(options: { group?: DockviewGroupPanel; position?: Position }): void {
if (!this._group) {
throw new Error(NOT_INITIALIZED_MESSAGE);
}
const group =
options.group ??
this.accessor.addGroup({
direction: positionToDirection(options.position ?? 'right'),
});
this.accessor.moveGroupOrPanel(
options.group,
group,
this._group.id,
undefined,
options.position ?? 'center'
options.group ? options.position ?? 'center' : 'center'
);
}
@ -60,6 +66,11 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
throw new Error(NOT_INITIALIZED_MESSAGE);
}
if (this.location !== 'grid') {
// only grid groups can be maximized
return;
}
this.accessor.maximizeGroup(this._group);
}

View File

@ -7,7 +7,7 @@ import {
import { directionToPosition, Droptarget, Position } from '../dnd/droptarget';
import { tail, sequenceEquals, remove } from '../array';
import { DockviewPanel, IDockviewPanel } from './dockviewPanel';
import { CompositeDisposable } from '../lifecycle';
import { CompositeDisposable, Disposable } from '../lifecycle';
import { Event, Emitter } from '../events';
import { Watermark } from './components/watermark/watermark';
import {
@ -58,7 +58,10 @@ import {
DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE,
DEFAULT_FLOATING_GROUP_POSITION,
} from '../constants';
import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlayRenderContainer';
import {
DockviewPanelRenderer,
OverlayRenderContainer,
} from '../overlayRenderContainer';
function getTheme(element: HTMLElement): string | undefined {
function toClassList(element: HTMLElement) {
@ -386,6 +389,17 @@ export class DockviewComponent
this.onDidActivePanelChange
)(() => {
this._bufferOnDidLayoutChange.fire();
}),
Disposable.from(() => {
// iterate over a copy of the array since .dispose() mutates the original array
for (const group of [...this._floatingGroups]) {
group.dispose();
}
// iterate over a copy of the array since .dispose() mutates the original array
for (const group of [...this._popoutGroups]) {
group.dispose();
}
})
);

View File

@ -283,7 +283,7 @@ export class DockviewGroupPanelModel
break;
}
this.groupPanel.api._onDidRenderPositionChange.fire({
this.groupPanel.api._onDidLocationChange.fire({
location: this.location,
});
}

View File

@ -13,6 +13,14 @@ export namespace Disposable {
// noop
},
};
export function from(func: () => void): IDisposable {
return {
dispose: () => {
func();
},
};
}
}
export class CompositeDisposable {

View File

@ -75,10 +75,7 @@ export class PopoutWindow extends CompositeDisposable {
this._window = { value: externalWindow, disposable };
const grievingParent = content.parentElement;
const cleanUp = () => {
grievingParent?.appendChild(content);
this._onDidClose.fire();
this._window = null;
};

View File

@ -399,6 +399,17 @@ From within a panel you may say
props.containerApi.addPopoutGroup(props.api.group);
```
To programatically move the popout group back into the main grid you can use the `moveTo` method in many ways, one of the following would suffice
```tsx
// option 1: add absolutely to the right-side of the grid
props.group.api.moveTo({position: 'right'});
// option 2: create a new group and move the contents of the popout group to it
const group = props.containerApi.addGroup();
props.group.api.moveTo({ group });
```
<MultiFrameworkContainer
height={600}
sandboxId="popoutgroup-dockview"

View File

@ -109,7 +109,7 @@ const Icon = (props: {
);
};
const groupControlsComponents = {
const groupControlsComponents: Record<string, React.FC> = {
panel_1: () => {
return <Icon icon="file_download" />;
},
@ -130,6 +130,10 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
: 'expand_content'
);
const [popoutIcon, setPopoutIcon] = React.useState<string>(
props.api.location === 'popout' ? 'close_fullscreen' : 'open_in_new'
);
React.useEffect(() => {
const disposable = props.containerApi.onDidMaxmizedGroupChange(() => {
setIcon(
@ -139,8 +143,17 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
);
});
const disposable2 = props.api.onDidLocationChange(() => {
setPopoutIcon(
props.api.location === 'popout'
? 'close_fullscreen'
: 'open_in_new'
);
});
return () => {
disposable.dispose();
disposable2.dispose();
};
}, [props.containerApi]);
@ -152,6 +165,14 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
}
};
const onClick2 = () => {
if (props.api.location !== 'popout') {
props.containerApi.addPopoutGroup(props.group);
} else {
props.api.moveTo({ position: 'right' });
}
};
return (
<div
className="group-control"
@ -165,6 +186,7 @@ const RightControls = (props: IDockviewHeaderActionsProps) => {
>
{props.isGroupActive && <Icon icon="star" />}
{Component && <Component />}
<Icon icon={popoutIcon} onClick={onClick2} />
<Icon icon={icon} onClick={onClick} />
</div>
);

View File

@ -259,7 +259,7 @@ const RightComponent = (props: IDockviewHeaderActionsProps) => {
);
React.useEffect(() => {
const disposable = props.group.api.onDidRenderPositionChange(
const disposable = props.group.api.onDidLocationChange(
(event) => {
setFloating(event.location === 'floating');
}

View File

@ -218,7 +218,7 @@ const RightComponent = (props: IDockviewHeaderActionsProps) => {
);
React.useEffect(() => {
const disposable = props.group.api.onDidRenderPositionChange(
const disposable = props.group.api.onDidLocationChange(
(event) => [setPopout(event.location === 'popout')]
);