From 8a05aede4cb16b0bdde8c64f5ec57c219d49a0d4 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:21:57 +0000 Subject: [PATCH 1/9] chore(release): publish v2.0.0 --- lerna.json | 2 +- packages/dockview-angular/package.json | 4 ++-- packages/dockview-core/package.json | 2 +- packages/dockview-react/package.json | 4 ++-- packages/dockview-vue/package.json | 4 ++-- packages/dockview/package.json | 4 ++-- packages/docs/package.json | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lerna.json b/lerna.json index 0db0b74b9..c1fe88e6a 100644 --- a/lerna.json +++ b/lerna.json @@ -2,7 +2,7 @@ "packages": [ "packages/*" ], - "version": "1.17.2", + "version": "2.0.0", "npmClient": "yarn", "command": { "publish": { diff --git a/packages/dockview-angular/package.json b/packages/dockview-angular/package.json index 71411409b..cebda7271 100644 --- a/packages/dockview-angular/package.json +++ b/packages/dockview-angular/package.json @@ -1,6 +1,6 @@ { "name": "dockview-angular", - "version": "1.17.2", + "version": "2.0.0", "description": "Zero dependency layout manager supporting tabs, grids and splitviews", "keywords": [ "splitview", @@ -54,6 +54,6 @@ "test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage" }, "dependencies": { - "dockview-core": "^1.17.2" + "dockview-core": "^2.0.0" } } diff --git a/packages/dockview-core/package.json b/packages/dockview-core/package.json index b63be23e7..01e63a421 100644 --- a/packages/dockview-core/package.json +++ b/packages/dockview-core/package.json @@ -1,6 +1,6 @@ { "name": "dockview-core", - "version": "1.17.2", + "version": "2.0.0", "description": "Zero dependency layout manager supporting tabs, grids and splitviews", "keywords": [ "splitview", diff --git a/packages/dockview-react/package.json b/packages/dockview-react/package.json index 5a8508a94..c0051e41f 100644 --- a/packages/dockview-react/package.json +++ b/packages/dockview-react/package.json @@ -1,6 +1,6 @@ { "name": "dockview-react", - "version": "1.17.2", + "version": "2.0.0", "description": "Zero dependency layout manager supporting tabs, grids and splitviews", "keywords": [ "splitview", @@ -54,6 +54,6 @@ "test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview-react --coverage" }, "dependencies": { - "dockview": "^1.17.2" + "dockview": "^2.0.0" } } diff --git a/packages/dockview-vue/package.json b/packages/dockview-vue/package.json index 6fbef7925..d5f23fd8a 100644 --- a/packages/dockview-vue/package.json +++ b/packages/dockview-vue/package.json @@ -1,6 +1,6 @@ { "name": "dockview-vue", - "version": "1.17.2", + "version": "2.0.0", "description": "Zero dependency layout manager supporting tabs, grids and splitviews", "keywords": [ "splitview", @@ -52,6 +52,6 @@ "test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview-vue --coverage" }, "dependencies": { - "dockview-core": "^1.17.2" + "dockview-core": "^2.0.0" } } diff --git a/packages/dockview/package.json b/packages/dockview/package.json index 89fd9e985..a7016f392 100644 --- a/packages/dockview/package.json +++ b/packages/dockview/package.json @@ -1,6 +1,6 @@ { "name": "dockview", - "version": "1.17.2", + "version": "2.0.0", "description": "Zero dependency layout manager supporting tabs, grids and splitviews", "keywords": [ "splitview", @@ -54,6 +54,6 @@ "test:cov": "cross-env ../../node_modules/.bin/jest --selectProjects dockview --coverage" }, "dependencies": { - "dockview-core": "^1.17.2" + "dockview-core": "^2.0.0" } } diff --git a/packages/docs/package.json b/packages/docs/package.json index 209c9c0a0..25f23a5df 100644 --- a/packages/docs/package.json +++ b/packages/docs/package.json @@ -1,6 +1,6 @@ { "name": "dockview-docs", - "version": "1.17.2", + "version": "2.0.0", "private": true, "scripts": { "build": "npm run build-templates && docusaurus build", @@ -38,7 +38,7 @@ "ag-grid-react": "^31.0.2", "axios": "^1.6.3", "clsx": "^2.1.0", - "dockview": "^1.17.2", + "dockview": "^2.0.0", "prism-react-renderer": "^2.3.1", "react-dnd": "^16.0.1", "react-laag": "^2.0.5", From 1a9ee8c34edd8ac882f0455969074caef92beb5d Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sun, 3 Nov 2024 19:23:16 +0000 Subject: [PATCH 2/9] chore: v2.0.0 docs --- .../docs/blog/2024-11-03-dockview-2.0.0.md | 32 ++ packages/docs/docs/core/panels/add.mdx | 22 +- packages/docs/src/generated/api.output.json | 384 +++++++++++------- 3 files changed, 297 insertions(+), 141 deletions(-) create mode 100644 packages/docs/blog/2024-11-03-dockview-2.0.0.md diff --git a/packages/docs/blog/2024-11-03-dockview-2.0.0.md b/packages/docs/blog/2024-11-03-dockview-2.0.0.md new file mode 100644 index 000000000..3cc856412 --- /dev/null +++ b/packages/docs/blog/2024-11-03-dockview-2.0.0.md @@ -0,0 +1,32 @@ +--- +slug: dockview-2.0.0-release +title: Dockview 2.0.0 +tags: [release] +--- + +# Release Notes + +This major version bump is due to breaking changes related to classnames. + +Please reference docs @ [dockview.dev](https://dockview.dev). + +## 🚀 Features + +- Add panel within group at specific index [#751](https://github.com/mathuo/dockview/pull/751) + +## 🛠 Miscs + +- Set drag event dataTransfer object to empty string [#738](https://github.com/mathuo/dockview/pull/738) +- General code cleanup / housekeeping [#740](https://github.com/mathuo/dockview/pull/740) [#746](https://github.com/mathuo/dockview/pull/746) +- Bug: Popout window initial sizing [#737](https://github.com/mathuo/dockview/pull/737) [#727](https://github.com/mathuo/dockview/pull/727) +- Bug: Close popout window on unload (refresh) [#731](https://github.com/mathuo/dockview/pull/731) +- Bug: Preserve Vue3 inject/provide context [#673](https://github.com/mathuo/dockview/pull/673) +- Bug: Fix Contraints [#744](https://github.com/mathuo/dockview/pull/744) +- Bug: Fix popout window issues [#748](https://github.com/mathuo/dockview/pull/748) + +## 🔥 Breaking changes + +- Prefix all classnames with `-dv-*` [#688](https://github.com/mathuo/dockview/pull/688) +- Remove depreciated methods [#742](https://github.com/mathuo/dockview/pull/742) + + diff --git a/packages/docs/docs/core/panels/add.mdx b/packages/docs/docs/core/panels/add.mdx index b964cdc05..cb151eb6e 100644 --- a/packages/docs/docs/core/panels/add.mdx +++ b/packages/docs/docs/core/panels/add.mdx @@ -115,6 +115,15 @@ api.addPanel({ direction: 'above' } }); + +api.addPanel({ + id: 'panel_4', + component: 'default', + position: { + referencePanel: panel2, + index: 2 // optionally specify which index to add the panel at + } +}); ``` #### Relative to another Group @@ -129,7 +138,9 @@ const panel2: IDockviewPanel = api.addPanel({ } }); -const panel = api.addPanel({ + + +api.addPanel({ id: 'panel_2', component: 'default', position: { @@ -137,6 +148,15 @@ const panel = api.addPanel({ direction: 'left' } }); + +api.addPanel({ + id: 'panel_3', + component: 'default', + position: { + referenceGroup: panel2.group, + index: 2 // optionally specify which index to add the panel at + } +}); ``` #### Relative to the container diff --git a/packages/docs/src/generated/api.output.json b/packages/docs/src/generated/api.output.json index 4f2f51762..d7024baab 100644 --- a/packages/docs/src/generated/api.output.json +++ b/packages/docs/src/generated/api.output.json @@ -5155,7 +5155,7 @@ }, { "name": "addPopoutGroup", - "code": "(itemToPopout: DockviewPanel | DockviewGroupPanel, options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box, skipRemoveGroup?: boolean }): Promise", + "code": "(itemToPopout: DockviewPanel | DockviewGroupPanel, options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box }): Promise", "kind": "method", "signature": [ { @@ -5184,12 +5184,12 @@ }, { "name": "options", - "code": "options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box, skipRemoveGroup?: boolean }", + "code": "options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box }", "type": { "type": "reflection", "value": { "name": "__type", - "code": "{ onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box, skipRemoveGroup?: boolean }", + "code": "{ onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box }", "kind": "typeLiteral", "properties": [ { @@ -5361,18 +5361,6 @@ "flags": { "isOptional": true } - }, - { - "name": "skipRemoveGroup", - "code": "boolean", - "kind": "property", - "type": { - "type": "intrinsic", - "value": "boolean" - }, - "flags": { - "isOptional": true - } } ] } @@ -5391,7 +5379,7 @@ } ] }, - "code": "(itemToPopout: DockviewPanel | DockviewGroupPanel, options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box, skipRemoveGroup?: boolean }): Promise", + "code": "(itemToPopout: DockviewPanel | DockviewGroupPanel, options?: { onDidOpen?: (event: { id: string, window: Window }): void, onWillClose?: (event: { id: string, window: Window }): void, overridePopoutGroup?: DockviewGroupPanel, popoutUrl?: string, position?: Box }): Promise", "kind": "callSignature" } ] @@ -7337,6 +7325,78 @@ } } }, + { + "name": "__maximumHeight", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__maximumHeight", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__maximumWidth", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__maximumWidth", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__minimumHeight", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__minimumHeight", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__minimumWidth", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__minimumWidth", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, { "name": "addDisposables", "code": "(args: IDisposable[]): void", @@ -14662,6 +14722,78 @@ } } }, + { + "name": "__maximumHeight", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__maximumHeight", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__maximumWidth", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__maximumWidth", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__minimumHeight", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__minimumHeight", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, + { + "name": "__minimumWidth", + "code": "(): number", + "kind": "method", + "signature": [ + { + "name": "__minimumWidth", + "typeParameters": [], + "parameters": [], + "returnType": { + "type": "intrinsic", + "value": "number" + }, + "code": "(): number", + "kind": "callSignature" + } + ] + }, { "name": "addDisposables", "code": "(args: IDisposable[]): void", @@ -23422,6 +23554,79 @@ ], "extends": [] }, + "DockviewGroupMoveParams": { + "kind": "interface", + "name": "DockviewGroupMoveParams", + "children": [ + { + "name": "group", + "code": "DockviewGroupPanel", + "kind": "property", + "type": { + "type": "reference", + "value": "DockviewGroupPanel", + "source": "dockview-core" + }, + "flags": { + "isOptional": true + } + }, + { + "name": "index", + "code": "number", + "kind": "property", + "type": { + "type": "intrinsic", + "value": "number" + }, + "flags": { + "isOptional": true + }, + "comment": { + "summary": [ + { + "kind": "text", + "text": "The index to place the panel within a group, only applicable if the placement is within an existing group" + } + ] + } + }, + { + "name": "position", + "code": "'bottom' | 'right' | 'top' | 'left' | 'center'", + "kind": "property", + "type": { + "type": "or", + "values": [ + { + "type": "literal", + "value": "bottom" + }, + { + "type": "literal", + "value": "right" + }, + { + "type": "literal", + "value": "top" + }, + { + "type": "literal", + "value": "left" + }, + { + "type": "literal", + "value": "center" + } + ] + }, + "flags": { + "isOptional": true + } + } + ], + "extends": [] + }, "DockviewGroupPanelApi": { "kind": "interface", "name": "DockviewGroupPanelApi", @@ -23898,7 +24103,7 @@ }, { "name": "moveTo", - "code": "(options: { group?: DockviewGroupPanel, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }): void", + "code": "(options: DockviewGroupMoveParams): void", "kind": "method", "signature": [ { @@ -23907,62 +24112,11 @@ "parameters": [ { "name": "options", - "code": "options: { group?: DockviewGroupPanel, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }", + "code": "options: DockviewGroupMoveParams", "type": { - "type": "reflection", - "value": { - "name": "__type", - "code": "{ group?: DockviewGroupPanel, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }", - "kind": "typeLiteral", - "properties": [ - { - "name": "group", - "code": "DockviewGroupPanel", - "kind": "property", - "type": { - "type": "reference", - "value": "DockviewGroupPanel", - "source": "dockview-core" - }, - "flags": { - "isOptional": true - } - }, - { - "name": "position", - "code": "'right' | 'bottom' | 'top' | 'left' | 'center'", - "kind": "property", - "type": { - "type": "or", - "values": [ - { - "type": "literal", - "value": "right" - }, - { - "type": "literal", - "value": "bottom" - }, - { - "type": "literal", - "value": "top" - }, - { - "type": "literal", - "value": "left" - }, - { - "type": "literal", - "value": "center" - } - ] - }, - "flags": { - "isOptional": true - } - } - ] - } + "type": "reference", + "value": "DockviewGroupMoveParams", + "source": "dockview-core" }, "kind": "parameter" } @@ -23971,7 +24125,7 @@ "type": "intrinsic", "value": "void" }, - "code": "(options: { group?: DockviewGroupPanel, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }): void", + "code": "(options: DockviewGroupMoveParams): void", "kind": "callSignature" } ] @@ -25016,7 +25170,7 @@ }, { "name": "moveTo", - "code": "(options: { group: DockviewGroupPanel, index?: number, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }): void", + "code": "(options: DockviewGroupMoveParams): void", "kind": "method", "signature": [ { @@ -25025,72 +25179,11 @@ "parameters": [ { "name": "options", - "code": "options: { group: DockviewGroupPanel, index?: number, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }", + "code": "options: DockviewGroupMoveParams", "type": { - "type": "reflection", - "value": { - "name": "__type", - "code": "{ group: DockviewGroupPanel, index?: number, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }", - "kind": "typeLiteral", - "properties": [ - { - "name": "group", - "code": "DockviewGroupPanel", - "kind": "property", - "type": { - "type": "reference", - "value": "DockviewGroupPanel", - "source": "dockview-core" - }, - "flags": {} - }, - { - "name": "index", - "code": "number", - "kind": "property", - "type": { - "type": "intrinsic", - "value": "number" - }, - "flags": { - "isOptional": true - } - }, - { - "name": "position", - "code": "'right' | 'bottom' | 'top' | 'left' | 'center'", - "kind": "property", - "type": { - "type": "or", - "values": [ - { - "type": "literal", - "value": "right" - }, - { - "type": "literal", - "value": "bottom" - }, - { - "type": "literal", - "value": "top" - }, - { - "type": "literal", - "value": "left" - }, - { - "type": "literal", - "value": "center" - } - ] - }, - "flags": { - "isOptional": true - } - } - ] - } + "type": "reference", + "value": "DockviewGroupMoveParams", + "source": "dockview-core" }, "kind": "parameter" } @@ -25099,7 +25192,7 @@ "type": "intrinsic", "value": "void" }, - "code": "(options: { group: DockviewGroupPanel, index?: number, position?: 'right' | 'bottom' | 'top' | 'left' | 'center' }): void", + "code": "(options: DockviewGroupMoveParams): void", "kind": "callSignature" } ] @@ -41519,6 +41612,17 @@ }, "kind": "typeAlias" }, + "DockviewPanelMoveParams": { + "name": "DockviewPanelMoveParams", + "code": "DockviewGroupMoveParams", + "typeParameters": [], + "type": { + "type": "reference", + "value": "DockviewGroupMoveParams", + "source": "dockview-core" + }, + "kind": "typeAlias" + }, "DockviewPanelRenderer": { "name": "DockviewPanelRenderer", "code": "'always' | 'onlyWhenVisible'", From c9e90168a4f551265073caaa4e354afd02bde228 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Mon, 4 Nov 2024 20:28:27 +0000 Subject: [PATCH 3/9] bug: fix setVisible on floating groups --- .../src/dockview/dockviewComponent.ts | 25 +++++++++++++++++++ .../dockview-core/src/overlay/overlay.scss | 4 +++ packages/dockview-core/src/overlay/overlay.ts | 17 +++++++++++++ 3 files changed, 46 insertions(+) diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 27e95fc52..78eed98c2 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -538,6 +538,31 @@ export class DockviewComponent this.updateWatermark(); } + override setVisible(panel: DockviewGroupPanel, visible: boolean): void { + switch (panel.api.location.type) { + case 'grid': + super.setVisible(panel, visible); + break; + case 'floating': + const item = this.floatingGroups.find( + (floatingGroup) => floatingGroup.group === panel + ); + + if (item) { + item.overlay.setVisible(visible); + panel.api._onDidVisibilityChange.fire({ + isVisible: visible, + }); + } + break; + case 'popout': + console.warn( + 'dockview: You cannot hide a group that is in a popout window' + ); + break; + } + } + addPopoutGroup( itemToPopout: DockviewPanel | DockviewGroupPanel, options?: { diff --git a/packages/dockview-core/src/overlay/overlay.scss b/packages/dockview-core/src/overlay/overlay.scss index 89788e032..fa88193c7 100644 --- a/packages/dockview-core/src/overlay/overlay.scss +++ b/packages/dockview-core/src/overlay/overlay.scss @@ -34,6 +34,10 @@ border: 1px solid var(--dv-tab-divider-color); box-shadow: var(--dv-floating-box-shadow); + &.dv-hidden { + display: none; + } + &.dv-resize-container-dragging { opacity: 0.5; } diff --git a/packages/dockview-core/src/overlay/overlay.ts b/packages/dockview-core/src/overlay/overlay.ts index b34fb9296..36fd00d96 100644 --- a/packages/dockview-core/src/overlay/overlay.ts +++ b/packages/dockview-core/src/overlay/overlay.ts @@ -59,6 +59,8 @@ export class Overlay extends CompositeDisposable { private verticalAlignment: 'top' | 'bottom' | undefined; private horiziontalAlignment: 'left' | 'right' | undefined; + private _isVisible: boolean; + set minimumInViewportWidth(value: number | undefined) { this.options.minimumInViewportWidth = value; } @@ -71,6 +73,10 @@ export class Overlay extends CompositeDisposable { return this._element; } + get isVisible(): boolean { + return this._isVisible; + } + constructor( private readonly options: AnchoredBox & { container: HTMLElement; @@ -84,6 +90,7 @@ export class Overlay extends CompositeDisposable { this.addDisposables(this._onDidChange, this._onDidChangeEnd); this._element.className = 'dv-resize-container'; + this._isVisible = true; this.setupResize('top'); this.setupResize('bottom'); @@ -110,6 +117,16 @@ export class Overlay extends CompositeDisposable { arialLevelTracker.push(this._element); } + setVisible(isVisible: boolean): void { + if (isVisible === this.isVisible) { + return; + } + + this._isVisible = isVisible; + + toggleClass(this.element, 'dv-hidden', !this.isVisible); + } + bringToFront(): void { arialLevelTracker.push(this._element); } From fe39c475a2d5ab0236f460ad72ee956245364804 Mon Sep 17 00:00:00 2001 From: Jafar Akhondali Date: Thu, 7 Nov 2024 17:23:01 +0100 Subject: [PATCH 4/9] Block malicious looking requests to prevent path traversal attacks. --- packages/docs/web-server/index.mjs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/docs/web-server/index.mjs b/packages/docs/web-server/index.mjs index 8cbd23434..7e1abd54f 100644 --- a/packages/docs/web-server/index.mjs +++ b/packages/docs/web-server/index.mjs @@ -35,5 +35,10 @@ function write(res, file) { http.createServer((req, res) => { const route = req.url.split('/').slice(1); + if (route.includes('..')) { + res.writeHead(403); + res.end(''); + return; + } write(res, route); }).listen(PORT, HOST); From 986132c602ffb687aeb8bf01065c26b187b4961c Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Thu, 7 Nov 2024 18:58:25 +0000 Subject: [PATCH 5/9] feat: tab container empty space not focusable --- .../src/dockview/components/titlebar/voidContainer.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/dockview-core/src/dockview/components/titlebar/voidContainer.ts b/packages/dockview-core/src/dockview/components/titlebar/voidContainer.ts index 284b780a4..6e9ea0c47 100644 --- a/packages/dockview-core/src/dockview/components/titlebar/voidContainer.ts +++ b/packages/dockview-core/src/dockview/components/titlebar/voidContainer.ts @@ -36,7 +36,6 @@ export class VoidContainer extends CompositeDisposable { this._element = document.createElement('div'); this._element.className = 'dv-void-container'; - this._element.tabIndex = 0; this._element.draggable = true; this.addDisposables( From 02d0ad8634de7f5314c41a8560ca8df30bd5947e Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sun, 10 Nov 2024 10:58:21 +0000 Subject: [PATCH 6/9] test: add tests --- .../dockview/dockviewComponent.spec.ts | 533 ++++++++++++------ 1 file changed, 345 insertions(+), 188 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index 72faaebe6..66f4f023e 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -5354,169 +5354,378 @@ describe('dockviewComponent', () => { }); }); - test('that setVisible toggles visiblity', () => { - const container = document.createElement('div'); + describe('panel visibility', () => { + test('that setVisible toggles visiblity', () => { + 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); + 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); + dockview.layout(1000, 1000); - const panel1 = api.addPanel({ - id: 'panel1', - component: 'default', - }); - const panel2 = api.addPanel({ - id: 'panel2', - component: 'default', - position: { referencePanel: panel1, direction: 'within' }, + const panel1 = api.addPanel({ + id: 'panel1', + component: 'default', + }); + const panel2 = api.addPanel({ + id: 'panel2', + component: 'default', + position: { referencePanel: panel1, direction: 'within' }, + }); + + const panel3 = api.addPanel({ + id: 'panel3', + component: 'default', + position: { referencePanel: panel1, direction: 'right' }, + }); + + const panel4 = api.addPanel({ + id: 'panel4', + component: 'default', + position: { referencePanel: panel3, direction: 'within' }, + }); + + expect(api.groups.length).toBe(2); + expect(panel1.group).toBe(panel2.group); + expect(panel3.group).toBe(panel4.group); + + expect(panel1.group.api.isVisible).toBeTruthy(); + expect(panel2.group.api.isVisible).toBeTruthy(); + expect(panel3.group.api.isVisible).toBeTruthy(); + expect(panel4.group.api.isVisible).toBeTruthy(); + + expect(panel1.api.isVisible).toBeFalsy(); + expect(panel2.api.isVisible).toBeTruthy(); + expect(panel3.api.isVisible).toBeFalsy(); + expect(panel4.api.isVisible).toBeTruthy(); + + // case #1 + panel1.group.api.setVisible(false); + + expect(panel1.group.api.isVisible).toBeFalsy(); + expect(panel2.group.api.isVisible).toBeFalsy(); + expect(panel3.group.api.isVisible).toBeTruthy(); + expect(panel4.group.api.isVisible).toBeTruthy(); + + expect(panel1.api.isVisible).toBeFalsy(); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel3.api.isVisible).toBeFalsy(); + expect(panel4.api.isVisible).toBeTruthy(); + + // case #2 + + panel3.group.api.setVisible(false); + + expect(panel1.group.api.isVisible).toBeFalsy(); + expect(panel2.group.api.isVisible).toBeFalsy(); + expect(panel3.group.api.isVisible).toBeFalsy(); + expect(panel4.group.api.isVisible).toBeFalsy(); + + expect(panel1.api.isVisible).toBeFalsy(); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel3.api.isVisible).toBeFalsy(); + expect(panel4.api.isVisible).toBeFalsy(); + + // case #2 + + panel3.group.api.setVisible(true); + + expect(panel1.group.api.isVisible).toBeFalsy(); + expect(panel2.group.api.isVisible).toBeFalsy(); + expect(panel3.group.api.isVisible).toBeTruthy(); + expect(panel4.group.api.isVisible).toBeTruthy(); + + expect(panel1.api.isVisible).toBeFalsy(); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel3.api.isVisible).toBeFalsy(); + expect(panel4.api.isVisible).toBeTruthy(); + + // case #2 + + panel1.group.api.setVisible(true); + + expect(panel1.group.api.isVisible).toBeTruthy(); + expect(panel2.group.api.isVisible).toBeTruthy(); + expect(panel3.group.api.isVisible).toBeTruthy(); + expect(panel4.group.api.isVisible).toBeTruthy(); + + expect(panel1.api.isVisible).toBeFalsy(); + expect(panel2.api.isVisible).toBeTruthy(); + expect(panel3.api.isVisible).toBeFalsy(); + expect(panel4.api.isVisible).toBeTruthy(); }); - const panel3 = api.addPanel({ - id: 'panel3', - component: 'default', - position: { referencePanel: panel1, direction: 'right' }, + test('setVisible #1', () => { + 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: 'panel1', + component: 'default', + }); + const panel2 = api.addPanel({ + id: 'panel2', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + const panel3 = api.addPanel({ + id: 'panel3', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + expect(api.groups.length).toBe(3); + + panel1.group.api.setVisible(false); + panel2.group.api.setVisible(false); + panel3.group.api.setVisible(false); + + expect(panel1.group.api.isVisible).toBeFalsy(); + expect(panel2.group.api.isVisible).toBeFalsy(); + expect(panel3.group.api.isVisible).toBeFalsy(); + + panel1.group.api.setVisible(true); + + expect(panel1.group.api.isVisible).toBeTruthy(); + expect(panel2.group.api.isVisible).toBeFalsy(); + expect(panel3.group.api.isVisible).toBeFalsy(); }); - const panel4 = api.addPanel({ - id: 'panel4', - component: 'default', - position: { referencePanel: panel3, direction: 'within' }, + test('that watermark appears when all views are not visible', () => { + jest.useFakeTimers(); + 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: { + direction: 'right', + }, + }); + + let query = queryByTestId(container, 'watermark-component'); + expect(query).toBeFalsy(); + + panel1.group.api.setVisible(false); + jest.runAllTicks(); // visibility events check fires on microtask-queue + query = queryByTestId(container, 'watermark-component'); + expect(query).toBeFalsy(); + + panel2.group.api.setVisible(false); + jest.runAllTicks(); // visibility events check fires on microtask-queue + query = queryByTestId(container, 'watermark-component'); + expect(query).toBeTruthy(); + + panel1.group.api.setVisible(true); + jest.runAllTicks(); // visibility events check fires on microtask-queue + query = queryByTestId(container, 'watermark-component'); + expect(query).toBeFalsy(); }); - expect(api.groups.length).toBe(2); - expect(panel1.group).toBe(panel2.group); - expect(panel3.group).toBe(panel4.group); + test('setVisible on floating group', () => { + const container = document.createElement('div'); - expect(panel1.group.api.isVisible).toBeTruthy(); - expect(panel2.group.api.isVisible).toBeTruthy(); - expect(panel3.group.api.isVisible).toBeTruthy(); - expect(panel4.group.api.isVisible).toBeTruthy(); + 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); - expect(panel1.api.isVisible).toBeFalsy(); - expect(panel2.api.isVisible).toBeTruthy(); - expect(panel3.api.isVisible).toBeFalsy(); - expect(panel4.api.isVisible).toBeTruthy(); + dockview.layout(1000, 1000); - // case #1 - panel1.group.api.setVisible(false); + const panel1 = api.addPanel({ + id: 'panel1', + component: 'default', + }); + const panel2 = api.addPanel({ + id: 'panel2', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); - expect(panel1.group.api.isVisible).toBeFalsy(); - expect(panel2.group.api.isVisible).toBeFalsy(); - expect(panel3.group.api.isVisible).toBeTruthy(); - expect(panel4.group.api.isVisible).toBeTruthy(); + const panel3 = api.addPanel({ + id: 'panel3', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); - expect(panel1.api.isVisible).toBeFalsy(); - expect(panel2.api.isVisible).toBeFalsy(); - expect(panel3.api.isVisible).toBeFalsy(); - expect(panel4.api.isVisible).toBeTruthy(); + api.addFloatingGroup(panel2); + expect(panel2.api.location.type).toBe('floating'); - // case #2 + panel2.api.group.setVisible(false); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel2.api.group.api.isVisible).toBeFalsy(); - panel3.group.api.setVisible(false); + panel2.api.group.setVisible(true); + expect(panel2.api.isVisible).toBeTruthy(); + expect(panel2.api.group.api.isVisible).toBeTruthy(); - expect(panel1.group.api.isVisible).toBeFalsy(); - expect(panel2.group.api.isVisible).toBeFalsy(); - expect(panel3.group.api.isVisible).toBeFalsy(); - expect(panel4.group.api.isVisible).toBeFalsy(); + panel2.api.group.setVisible(false); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel2.api.group.api.isVisible).toBeFalsy(); - expect(panel1.api.isVisible).toBeFalsy(); - expect(panel2.api.isVisible).toBeFalsy(); - expect(panel3.api.isVisible).toBeFalsy(); - expect(panel4.api.isVisible).toBeFalsy(); + panel2.api.group.api.moveTo({ + group: panel1.group, + position: 'left', + }); + expect(api.groups.length).toBe(3); + expect(panel2.api.isVisible).toBeFalsy(); + expect(panel2.api.group.api.isVisible).toBeFalsy(); - // case #2 - - panel3.group.api.setVisible(true); - - expect(panel1.group.api.isVisible).toBeFalsy(); - expect(panel2.group.api.isVisible).toBeFalsy(); - expect(panel3.group.api.isVisible).toBeTruthy(); - expect(panel4.group.api.isVisible).toBeTruthy(); - - expect(panel1.api.isVisible).toBeFalsy(); - expect(panel2.api.isVisible).toBeFalsy(); - expect(panel3.api.isVisible).toBeFalsy(); - expect(panel4.api.isVisible).toBeTruthy(); - - // case #2 - - panel1.group.api.setVisible(true); - - expect(panel1.group.api.isVisible).toBeTruthy(); - expect(panel2.group.api.isVisible).toBeTruthy(); - expect(panel3.group.api.isVisible).toBeTruthy(); - expect(panel4.group.api.isVisible).toBeTruthy(); - - expect(panel1.api.isVisible).toBeFalsy(); - expect(panel2.api.isVisible).toBeTruthy(); - expect(panel3.api.isVisible).toBeFalsy(); - expect(panel4.api.isVisible).toBeTruthy(); - }); - - test('setVisible #1', () => { - 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: 'panel1', - component: 'default', - }); - const panel2 = api.addPanel({ - id: 'panel2', - component: 'default', - position: { referencePanel: panel1, direction: 'below' }, + panel2.api.group.setVisible(true); + expect(panel2.api.isVisible).toBeTruthy(); + expect(panel2.api.group.api.isVisible).toBeTruthy(); }); - const panel3 = api.addPanel({ - id: 'panel3', - component: 'default', - position: { referencePanel: panel1, direction: 'below' }, + test('setVisible on popout group should have no effect', async () => { + window.open = () => setupMockWindow(); + + 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: 'panel1', + component: 'default', + }); + const panel2 = api.addPanel({ + id: 'panel2', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + const panel3 = api.addPanel({ + id: 'panel3', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + await api.addPopoutGroup(panel2); + expect(panel2.api.location.type).toBe('popout'); + + expect(panel2.api.group.api.isVisible).toBeTruthy(); + panel2.api.group.api.setVisible(false); + expect(panel2.api.group.api.isVisible).toBeTruthy(); }); - expect(api.groups.length).toBe(3); + test('opening a popout group from a group that is non visible should automatically make it visible', async () => { + window.open = () => setupMockWindow(); - panel1.group.api.setVisible(false); - panel2.group.api.setVisible(false); - panel3.group.api.setVisible(false); + const container = document.createElement('div'); - expect(panel1.group.api.isVisible).toBeFalsy(); - expect(panel2.group.api.isVisible).toBeFalsy(); - expect(panel3.group.api.isVisible).toBeFalsy(); + 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); - panel1.group.api.setVisible(true); + dockview.layout(1000, 1000); - expect(panel1.group.api.isVisible).toBeTruthy(); - expect(panel2.group.api.isVisible).toBeFalsy(); - expect(panel3.group.api.isVisible).toBeFalsy(); + const panel1 = api.addPanel({ + id: 'panel1', + component: 'default', + }); + const panel2 = api.addPanel({ + id: 'panel2', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + const panel3 = api.addPanel({ + id: 'panel3', + component: 'default', + position: { referencePanel: panel1, direction: 'below' }, + }); + + panel2.api.group.api.setVisible(false); + + await api.addPopoutGroup(panel2); + expect(panel2.api.location.type).toBe('popout'); + expect(panel2.api.group.api.isVisible).toBeTruthy(); + }); }); describe('addPanel', () => { @@ -5939,58 +6148,6 @@ describe('dockviewComponent', () => { expect(api.groups.length).toBe(3); }); - test('that watermark appears when all views are not visible', () => { - jest.useFakeTimers(); - 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: { - direction: 'right', - }, - }); - - let query = queryByTestId(container, 'watermark-component'); - expect(query).toBeFalsy(); - - panel1.group.api.setVisible(false); - jest.runAllTicks(); // visibility events check fires on microtask-queue - query = queryByTestId(container, 'watermark-component'); - expect(query).toBeFalsy(); - - panel2.group.api.setVisible(false); - jest.runAllTicks(); // visibility events check fires on microtask-queue - query = queryByTestId(container, 'watermark-component'); - expect(query).toBeTruthy(); - - panel1.group.api.setVisible(true); - jest.runAllTicks(); // visibility events check fires on microtask-queue - query = queryByTestId(container, 'watermark-component'); - expect(query).toBeFalsy(); - }); - describe('updateOptions', () => { test('gap', () => { const container = document.createElement('div'); From a00875aae0f11aeaeb987c16828ba946468cc110 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Sun, 10 Nov 2024 11:12:01 +0000 Subject: [PATCH 7/9] chore: fix sonar issue --- packages/dockview-core/src/dockview/dockviewComponent.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 78eed98c2..5a20f5b84 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -543,7 +543,7 @@ export class DockviewComponent case 'grid': super.setVisible(panel, visible); break; - case 'floating': + case 'floating': { const item = this.floatingGroups.find( (floatingGroup) => floatingGroup.group === panel ); @@ -555,6 +555,7 @@ export class DockviewComponent }); } break; + } case 'popout': console.warn( 'dockview: You cannot hide a group that is in a popout window' From 461c30dc5bb519ee90d1a2da0814718dfd4f7a2d Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Fri, 15 Nov 2024 20:46:00 +0000 Subject: [PATCH 8/9] feat: persist custom popout group urls --- .../dockview/dockviewComponent.spec.ts | 120 ++++++++++++++++++ .../src/dockview/dockviewComponent.ts | 38 ++++-- .../src/dockview/dockviewGroupPanelModel.ts | 2 +- 3 files changed, 150 insertions(+), 10 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index 66f4f023e..8792a9bfa 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -5191,6 +5191,126 @@ describe('dockviewComponent', () => { expect(dockview.groups.length).toBe(2); expect(dockview.panels.length).toBe(3); }); + + test('persistance with custom url', async () => { + const container = document.createElement('div'); + + window.open = () => setupMockWindow(); + + const dockview = new DockviewComponent(container, { + createComponent(options) { + switch (options.name) { + case 'default': + return new PanelContentPartTest( + options.id, + options.name + ); + default: + throw new Error(`unsupported`); + } + }, + }); + + dockview.layout(1000, 500); + + dockview.addPanel({ + id: 'panel_1', + component: 'default', + }); + + const panel2 = dockview.addPanel({ + id: 'panel_2', + component: 'default', + position: { direction: 'right' }, + }); + + const panel3 = dockview.addPanel({ + id: 'panel_3', + component: 'default', + position: { direction: 'right' }, + }); + + expect(await dockview.addPopoutGroup(panel2.group)).toBeTruthy(); + expect( + await dockview.addPopoutGroup(panel3.group, { + popoutUrl: '/custom.html', + }) + ).toBeTruthy(); + + const state = dockview.toJSON(); + + expect(state.popoutGroups).toEqual([ + { + data: { + activeView: 'panel_2', + id: '4', + views: ['panel_2'], + }, + gridReferenceGroup: '2', + position: { + height: 2001, + left: undefined, + top: undefined, + width: 1001, + }, + url: undefined, + }, + { + data: { + activeView: 'panel_3', + id: '5', + views: ['panel_3'], + }, + gridReferenceGroup: '3', + position: { + height: 2001, + left: undefined, + top: undefined, + width: 1001, + }, + url: '/custom.html', + }, + ]); + + dockview.clear(); + expect(dockview.groups.length).toBe(0); + + dockview.fromJSON(state); + await new Promise((resolve) => setTimeout(resolve, 0)); // popout views are completed as a promise so must complete microtask-queue + + expect(dockview.toJSON().popoutGroups).toEqual([ + { + data: { + activeView: 'panel_2', + id: '4', + views: ['panel_2'], + }, + gridReferenceGroup: '2', + position: { + height: 2001, + left: undefined, + top: undefined, + width: 1001, + }, + url: undefined, + }, + { + data: { + activeView: 'panel_3', + id: '5', + views: ['panel_3'], + }, + gridReferenceGroup: '3', + position: { + height: 2001, + left: undefined, + top: undefined, + width: 1001, + }, + url: '/custom.html', + }, + ]); + }); }); describe('maximized group', () => { diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 5a20f5b84..9d749039f 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -98,6 +98,22 @@ function moveGroupWithoutDestroying(options: { }); } +export interface DockviewPopoutGroupOptions { + /** + * The position of the popout group + */ + position?: Box; + /** + * The same-origin path at which the popout window will be created + * + * Defaults to `/popout.html` if not provided + */ + popoutUrl?: string; + onDidOpen?: (event: { id: string; window: Window }) => void; + onWillClose?: (event: { id: string; window: Window }) => void; + overridePopoutGroup?: DockviewGroupPanel; +} + export interface PanelReference { update: (event: { params: { [key: string]: any } }) => void; remove: () => void; @@ -110,6 +126,7 @@ export interface SerializedFloatingGroup { export interface SerializedPopoutGroup { data: GroupPanelViewState; + url?: string; gridReferenceGroup?: string; position: Box | null; } @@ -566,13 +583,7 @@ export class DockviewComponent addPopoutGroup( itemToPopout: DockviewPanel | DockviewGroupPanel, - options?: { - position?: Box; - popoutUrl?: string; - onDidOpen?: (event: { id: string; window: Window }) => void; - onWillClose?: (event: { id: string; window: Window }) => void; - overridePopoutGroup?: DockviewGroupPanel; - } + options?: DockviewPopoutGroupOptions ): Promise { if ( itemToPopout instanceof DockviewPanel && @@ -608,7 +619,10 @@ export class DockviewComponent `${this.id}-${groupId}`, // unique id theme ?? '', { - url: options?.popoutUrl ?? '/popout.html', + url: + options?.popoutUrl ?? + this.options?.popoutUrl ?? + '/popout.html', left: window.screenX + box.left, top: window.screenY + box.top, width: box.width, @@ -709,6 +723,7 @@ export class DockviewComponent group.model.location = { type: 'popout', getWindow: () => _window.window!, + popoutUrl: options?.popoutUrl, }; if ( @@ -1198,6 +1213,10 @@ export class DockviewComponent data: group.popoutGroup.toJSON() as GroupPanelViewState, gridReferenceGroup: group.referenceGroup, position: group.window.dimensions(), + url: + group.popoutGroup.api.location.type === 'popout' + ? group.popoutGroup.api.location.popoutUrl + : undefined, }; } ); @@ -1321,7 +1340,7 @@ export class DockviewComponent const serializedPopoutGroups = data.popoutGroups ?? []; for (const serializedPopoutGroup of serializedPopoutGroups) { - const { data, position, gridReferenceGroup } = + const { data, position, gridReferenceGroup, url } = serializedPopoutGroup; const group = createGroupFromSerializedState(data); @@ -1335,6 +1354,7 @@ export class DockviewComponent overridePopoutGroup: gridReferenceGroup ? group : undefined, + popoutUrl: url, } ); } diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index a377ed9ec..55b76585e 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -196,7 +196,7 @@ export interface IDockviewGroupPanelModel extends IPanel { export type DockviewGroupLocation = | { type: 'grid' } | { type: 'floating' } - | { type: 'popout'; getWindow: () => Window }; + | { type: 'popout'; getWindow: () => Window; popoutUrl?: string }; export class WillShowOverlayLocationEvent implements IDockviewEvent { get kind(): DockviewGroupDropLocation { From 56bdec846c4b1b76991b104e896aaaca95c06ecc Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Mon, 9 Dec 2024 19:40:49 +0000 Subject: [PATCH 9/9] bug: wrong event ordering --- .../src/dockview/dockviewComponent.ts | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 5a20f5b84..c1899e7f0 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -659,20 +659,23 @@ export class DockviewComponent const isGroupAddedToDom = referenceGroup.element.parentElement !== null; - const group = !isGroupAddedToDom - ? referenceGroup - : options?.overridePopoutGroup ?? - this.createGroup({ id: groupId }); + let group: DockviewGroupPanel; + + if (!isGroupAddedToDom) { + group = referenceGroup; + } else if (options?.overridePopoutGroup) { + group = options.overridePopoutGroup; + } else { + group = this.createGroup({ id: groupId }); + this._onDidAddGroup.fire(group); + } + group.model.renderContainer = overlayRenderContainer; group.layout( _window.window!.innerWidth, _window.window!.innerHeight ); - if (!this._groups.has(group.api.id)) { - this._onDidAddGroup.fire(group); - } - if (!options?.overridePopoutGroup && isGroupAddedToDom) { if (itemToPopout instanceof DockviewPanel) { this.movingLock(() => {