project-graph-mcp 2.3.2 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/analysis/analysis-cache.ctx +9 -0
- package/src/analysis/analysis-cache.js +1 -1
- package/src/analysis/complexity.ctx +6 -0
- package/src/analysis/complexity.js +1 -1
- package/src/analysis/custom-rules.ctx +14 -0
- package/src/analysis/custom-rules.js +1 -1
- package/src/analysis/db-analysis.ctx +7 -0
- package/src/analysis/db-analysis.js +1 -1
- package/src/analysis/dead-code.ctx +6 -0
- package/src/analysis/dead-code.js +1 -1
- package/src/analysis/full-analysis.ctx +9 -0
- package/src/analysis/full-analysis.js +1 -1
- package/src/analysis/jsdoc-checker.ctx +10 -0
- package/src/analysis/jsdoc-checker.js +1 -1
- package/src/analysis/jsdoc-generator.ctx +9 -0
- package/src/analysis/jsdoc-generator.js +1 -1
- package/src/analysis/large-files.ctx +6 -0
- package/src/analysis/large-files.js +1 -1
- package/src/analysis/outdated-patterns.ctx +7 -0
- package/src/analysis/outdated-patterns.js +1 -1
- package/src/analysis/similar-functions.ctx +6 -0
- package/src/analysis/similar-functions.js +1 -1
- package/src/analysis/test-annotations.ctx +11 -0
- package/src/analysis/test-annotations.js +1 -1
- package/src/analysis/type-checker.ctx +6 -0
- package/src/analysis/type-checker.js +1 -1
- package/src/analysis/undocumented.ctx +8 -0
- package/src/analysis/undocumented.js +1 -1
- package/src/cli/cli-handlers.ctx +7 -0
- package/src/cli/cli-handlers.js +1 -1
- package/src/cli/cli.ctx +6 -0
- package/src/cli/cli.js +1 -1
- package/src/compact/ai-context.ctx +6 -0
- package/src/compact/ai-context.js +1 -1
- package/src/compact/compact-migrate.ctx +8 -0
- package/src/compact/compact-migrate.js +1 -1
- package/src/compact/compact.ctx +11 -0
- package/src/compact/compact.js +1 -1
- package/src/compact/compress.ctx +7 -0
- package/src/compact/compress.js +1 -1
- package/src/compact/ctx-resolver.ctx +2 -0
- package/src/compact/ctx-resolver.js +1 -1
- package/src/compact/ctx-to-jsdoc.ctx +11 -0
- package/src/compact/ctx-to-jsdoc.js +1 -1
- package/src/compact/doc-dialect.ctx +11 -0
- package/src/compact/doc-dialect.js +2 -2
- package/src/compact/expand.ctx +14 -0
- package/src/compact/expand.js +1 -1
- package/src/compact/framework-references.ctx +7 -0
- package/src/compact/framework-references.js +1 -1
- package/src/compact/instructions.ctx +6 -0
- package/src/compact/instructions.js +1 -1
- package/src/compact/jsdoc-builder.ctx +4 -0
- package/src/compact/jsdoc-builder.js +1 -1
- package/src/compact/mode-config.ctx +8 -0
- package/src/compact/mode-config.js +1 -1
- package/src/compact/split-declarations.ctx +6 -0
- package/src/compact/split-declarations.js +1 -1
- package/src/compact/validate-pipeline.ctx +12 -0
- package/src/compact/validate-pipeline.js +1 -1
- package/src/core/event-bus.ctx +9 -0
- package/src/core/event-bus.js +1 -1
- package/src/core/file-walker.ctx +1 -0
- package/src/core/file-walker.js +1 -1
- package/src/core/filters.ctx +12 -0
- package/src/core/filters.js +1 -1
- package/src/core/graph-builder.ctx +7 -0
- package/src/core/graph-builder.js +1 -1
- package/src/core/parser.ctx +12 -0
- package/src/core/parser.js +1 -1
- package/src/core/utils.ctx +1 -0
- package/src/core/utils.js +1 -1
- package/src/core/workspace.ctx +7 -0
- package/src/core/workspace.js +1 -1
- package/src/lang/lang-go.ctx +8 -0
- package/src/lang/lang-go.js +1 -1
- package/src/lang/lang-python.ctx +5 -0
- package/src/lang/lang-python.js +1 -1
- package/src/lang/lang-sql.ctx +10 -0
- package/src/lang/lang-sql.js +1 -1
- package/src/lang/lang-typescript.ctx +6 -0
- package/src/lang/lang-typescript.js +1 -1
- package/src/lang/lang-utils.ctx +5 -0
- package/src/lang/lang-utils.js +1 -1
- package/src/mcp/mcp-server.ctx +6 -0
- package/src/mcp/mcp-server.js +1 -1
- package/src/mcp/tool-defs.ctx +2 -0
- package/src/mcp/tool-defs.js +1 -1
- package/src/mcp/tools.ctx +13 -0
- package/src/mcp/tools.js +1 -1
- package/src/network/backend-lifecycle.ctx +10 -0
- package/src/network/backend-lifecycle.js +1 -1
- package/src/network/backend.ctx +5 -0
- package/src/network/backend.js +1 -1
- package/src/network/local-gateway.ctx +9 -0
- package/src/network/local-gateway.js +1 -1
- package/src/network/mdns.ctx +6 -0
- package/src/network/mdns.js +1 -1
- package/src/network/server.ctx +2 -0
- package/src/network/server.js +2 -2
- package/src/network/web-server.ctx +17 -0
- package/src/network/web-server.js +2 -2
- package/web/follow-controller.js +94 -25
- package/web/panels/dep-graph.js +207 -21
- package/project-graph-mcp-2.3.0.tgz +0 -0
- package/vendor/symbiote-node/CHANGELOG.md +0 -31
- package/vendor/symbiote-node/LICENSE +0 -21
- package/vendor/symbiote-node/README.md +0 -206
- package/vendor/symbiote-node/canvas/AutoLayout.js +0 -725
- package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.css.js +0 -73
- package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.js +0 -93
- package/vendor/symbiote-node/canvas/Breadcrumb/Breadcrumb.tpl.js +0 -9
- package/vendor/symbiote-node/canvas/CanvasConnectionRenderer.js +0 -962
- package/vendor/symbiote-node/canvas/ConnectionRenderer.js +0 -1468
- package/vendor/symbiote-node/canvas/FlowSimulator.js +0 -323
- package/vendor/symbiote-node/canvas/ForceLayout.js +0 -189
- package/vendor/symbiote-node/canvas/ForceWorker.js +0 -1325
- package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.css.js +0 -97
- package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.js +0 -176
- package/vendor/symbiote-node/canvas/GraphTabs/GraphTabs.tpl.js +0 -12
- package/vendor/symbiote-node/canvas/LODManager.js +0 -88
- package/vendor/symbiote-node/canvas/Minimap/Minimap.css.js +0 -71
- package/vendor/symbiote-node/canvas/Minimap/Minimap.js +0 -207
- package/vendor/symbiote-node/canvas/Minimap/Minimap.tpl.js +0 -9
- package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.css.js +0 -261
- package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.js +0 -1840
- package/vendor/symbiote-node/canvas/NodeCanvas/NodeCanvas.tpl.js +0 -22
- package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.css.js +0 -97
- package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.js +0 -132
- package/vendor/symbiote-node/canvas/NodeSearch/NodeSearch.tpl.js +0 -21
- package/vendor/symbiote-node/canvas/NodeViewManager.js +0 -584
- package/vendor/symbiote-node/canvas/PinExpansion.js +0 -131
- package/vendor/symbiote-node/canvas/PseudoConnection.js +0 -80
- package/vendor/symbiote-node/canvas/SubgraphManager.js +0 -201
- package/vendor/symbiote-node/canvas/SubgraphRouter.js +0 -443
- package/vendor/symbiote-node/canvas/ViewportActions.js +0 -446
- package/vendor/symbiote-node/core/Connection.js +0 -45
- package/vendor/symbiote-node/core/Editor.js +0 -451
- package/vendor/symbiote-node/core/Frame.js +0 -31
- package/vendor/symbiote-node/core/GraphMermaid.js +0 -348
- package/vendor/symbiote-node/core/GraphText.js +0 -210
- package/vendor/symbiote-node/core/Node.js +0 -143
- package/vendor/symbiote-node/core/Portal.js +0 -104
- package/vendor/symbiote-node/core/Socket.js +0 -185
- package/vendor/symbiote-node/core/SubgraphNode.js +0 -125
- package/vendor/symbiote-node/engine/AgentUICommands.js +0 -100
- package/vendor/symbiote-node/engine/Executor.js +0 -371
- package/vendor/symbiote-node/engine/Graph.js +0 -314
- package/vendor/symbiote-node/engine/GraphServer.js +0 -353
- package/vendor/symbiote-node/engine/HandlerLoader.js +0 -145
- package/vendor/symbiote-node/engine/History.js +0 -83
- package/vendor/symbiote-node/engine/Lifecycle.js +0 -118
- package/vendor/symbiote-node/engine/Persistence.js +0 -84
- package/vendor/symbiote-node/engine/Registry.js +0 -264
- package/vendor/symbiote-node/engine/SocketTypes.js +0 -79
- package/vendor/symbiote-node/engine/cli.js +0 -404
- package/vendor/symbiote-node/engine/index.js +0 -56
- package/vendor/symbiote-node/engine/nanoid.js +0 -28
- package/vendor/symbiote-node/engine/package.json +0 -26
- package/vendor/symbiote-node/engine/packs/ai/beat-detect.handler.js +0 -215
- package/vendor/symbiote-node/engine/packs/ai/content-adapt.handler.js +0 -238
- package/vendor/symbiote-node/engine/packs/ai/face-detect.handler.js +0 -287
- package/vendor/symbiote-node/engine/packs/ai/grok-generate.handler.js +0 -565
- package/vendor/symbiote-node/engine/packs/ai/kling-lipsync.handler.js +0 -414
- package/vendor/symbiote-node/engine/packs/ai/lesson-generate.handler.js +0 -343
- package/vendor/symbiote-node/engine/packs/ai/opencode.handler.js +0 -164
- package/vendor/symbiote-node/engine/packs/ai/replicate-lipsync.handler.js +0 -341
- package/vendor/symbiote-node/engine/packs/ai/tts.handler.js +0 -241
- package/vendor/symbiote-node/engine/packs/ai/whisper.handler.js +0 -191
- package/vendor/symbiote-node/engine/packs/data/db-query.handler.js +0 -67
- package/vendor/symbiote-node/engine/packs/data/news-accumulate.handler.js +0 -281
- package/vendor/symbiote-node/engine/packs/data/personas.handler.js +0 -160
- package/vendor/symbiote-node/engine/packs/data/prompt-loader.handler.js +0 -193
- package/vendor/symbiote-node/engine/packs/data/roles.handler.js +0 -216
- package/vendor/symbiote-node/engine/packs/data/rss-feed.handler.js +0 -244
- package/vendor/symbiote-node/engine/packs/debug/inject.handler.js +0 -52
- package/vendor/symbiote-node/engine/packs/flow/agent.handler.js +0 -73
- package/vendor/symbiote-node/engine/packs/flow/if.handler.js +0 -107
- package/vendor/symbiote-node/engine/packs/flow/loop.handler.js +0 -58
- package/vendor/symbiote-node/engine/packs/flow/merge.handler.js +0 -60
- package/vendor/symbiote-node/engine/packs/flow/retry.handler.js +0 -65
- package/vendor/symbiote-node/engine/packs/flow/switch.handler.js +0 -64
- package/vendor/symbiote-node/engine/packs/flow/wait-all.handler.js +0 -39
- package/vendor/symbiote-node/engine/packs/io/http-request.handler.js +0 -82
- package/vendor/symbiote-node/engine/packs/io/read-file.handler.js +0 -60
- package/vendor/symbiote-node/engine/packs/io/write-file.handler.js +0 -63
- package/vendor/symbiote-node/engine/packs/transform/anchor-match.handler.js +0 -494
- package/vendor/symbiote-node/engine/packs/transform/effects-skeleton.handler.js +0 -417
- package/vendor/symbiote-node/engine/packs/transform/json-parse.handler.js +0 -43
- package/vendor/symbiote-node/engine/packs/transform/lipsync-select.handler.js +0 -339
- package/vendor/symbiote-node/engine/packs/transform/riopla-adapt.handler.js +0 -432
- package/vendor/symbiote-node/engine/packs/transform/set.handler.js +0 -57
- package/vendor/symbiote-node/engine/packs/transform/template-builder.handler.js +0 -134
- package/vendor/symbiote-node/engine/packs/transform/template.handler.js +0 -79
- package/vendor/symbiote-node/engine/packs/transform/timeline-build.handler.js +0 -399
- package/vendor/symbiote-node/engine/packs/util/delay.handler.js +0 -39
- package/vendor/symbiote-node/engine/packs/util/log.handler.js +0 -44
- package/vendor/symbiote-node/engine/packs/video-pack.js +0 -323
- package/vendor/symbiote-node/index.js +0 -103
- package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.css.js +0 -361
- package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.js +0 -332
- package/vendor/symbiote-node/inspector/InspectorPanel/InspectorPanel.tpl.js +0 -96
- package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.css.js +0 -104
- package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.js +0 -133
- package/vendor/symbiote-node/inspector/TemplatePreview/TemplatePreview.tpl.js +0 -33
- package/vendor/symbiote-node/interactions/ConnectFlow.js +0 -307
- package/vendor/symbiote-node/interactions/Drag.js +0 -102
- package/vendor/symbiote-node/interactions/Selector.js +0 -132
- package/vendor/symbiote-node/interactions/SnapGrid.js +0 -65
- package/vendor/symbiote-node/interactions/Zoom.js +0 -140
- package/vendor/symbiote-node/layout/ActionZone/ActionZone.css.js +0 -88
- package/vendor/symbiote-node/layout/ActionZone/ActionZone.js +0 -254
- package/vendor/symbiote-node/layout/ActionZone/ActionZone.tpl.js +0 -11
- package/vendor/symbiote-node/layout/Layout/Layout.css.js +0 -88
- package/vendor/symbiote-node/layout/Layout/Layout.js +0 -622
- package/vendor/symbiote-node/layout/Layout/Layout.tpl.js +0 -25
- package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.css.js +0 -293
- package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.js +0 -467
- package/vendor/symbiote-node/layout/LayoutNode/LayoutNode.tpl.js +0 -33
- package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.css.js +0 -46
- package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.js +0 -102
- package/vendor/symbiote-node/layout/LayoutPreview/LayoutPreview.tpl.js +0 -6
- package/vendor/symbiote-node/layout/LayoutRouter/LayoutRouter.js +0 -156
- package/vendor/symbiote-node/layout/LayoutRouter/routerSync.js +0 -250
- package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.css.js +0 -379
- package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.js +0 -263
- package/vendor/symbiote-node/layout/LayoutSidebar/LayoutSidebar.tpl.js +0 -20
- package/vendor/symbiote-node/layout/LayoutSidebar/SidebarSection.js +0 -183
- package/vendor/symbiote-node/layout/LayoutTree.js +0 -246
- package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.css.js +0 -43
- package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.js +0 -89
- package/vendor/symbiote-node/layout/PanelMenu/PanelMenu.tpl.js +0 -14
- package/vendor/symbiote-node/layout/index.js +0 -16
- package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.css.js +0 -61
- package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.js +0 -79
- package/vendor/symbiote-node/menu/ContextMenu/ContextMenu.tpl.js +0 -19
- package/vendor/symbiote-node/node/CtrlItem/CtrlItem.css.js +0 -41
- package/vendor/symbiote-node/node/CtrlItem/CtrlItem.js +0 -24
- package/vendor/symbiote-node/node/CtrlItem/CtrlItem.tpl.js +0 -16
- package/vendor/symbiote-node/node/GraphFrame/GraphFrame.css.js +0 -65
- package/vendor/symbiote-node/node/GraphFrame/GraphFrame.js +0 -29
- package/vendor/symbiote-node/node/GraphFrame/GraphFrame.tpl.js +0 -13
- package/vendor/symbiote-node/node/GraphNode/GraphNode.css.js +0 -683
- package/vendor/symbiote-node/node/GraphNode/GraphNode.js +0 -92
- package/vendor/symbiote-node/node/GraphNode/GraphNode.tpl.js +0 -17
- package/vendor/symbiote-node/node/NodeSocket/NodeSocket.js +0 -25
- package/vendor/symbiote-node/node/NodeSocket/NodeSocket.tpl.js +0 -7
- package/vendor/symbiote-node/node/PortItem/PortItem.css.js +0 -90
- package/vendor/symbiote-node/node/PortItem/PortItem.js +0 -87
- package/vendor/symbiote-node/node/PortItem/PortItem.tpl.js +0 -10
- package/vendor/symbiote-node/package.json +0 -59
- package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.css.js +0 -143
- package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.js +0 -131
- package/vendor/symbiote-node/palette/PaletteBrowser/PaletteBrowser.tpl.js +0 -16
- package/vendor/symbiote-node/plugins/History.js +0 -384
- package/vendor/symbiote-node/plugins/Readonly.js +0 -59
- package/vendor/symbiote-node/shapes/CircleShape.js +0 -80
- package/vendor/symbiote-node/shapes/CommentShape.js +0 -35
- package/vendor/symbiote-node/shapes/DiamondShape.js +0 -115
- package/vendor/symbiote-node/shapes/NodeShape.js +0 -80
- package/vendor/symbiote-node/shapes/PillShape.js +0 -91
- package/vendor/symbiote-node/shapes/RectShape.js +0 -72
- package/vendor/symbiote-node/shapes/SVGShape.js +0 -494
- package/vendor/symbiote-node/shapes/index.js +0 -53
- package/vendor/symbiote-node/themes/Palette.js +0 -32
- package/vendor/symbiote-node/themes/Skin.js +0 -113
- package/vendor/symbiote-node/themes/Theme.js +0 -84
- package/vendor/symbiote-node/themes/carbon.js +0 -137
- package/vendor/symbiote-node/themes/dark.js +0 -137
- package/vendor/symbiote-node/themes/ebook.js +0 -138
- package/vendor/symbiote-node/themes/grey.js +0 -137
- package/vendor/symbiote-node/themes/light.js +0 -137
- package/vendor/symbiote-node/themes/neon.js +0 -138
- package/vendor/symbiote-node/themes/pcb.js +0 -273
- package/vendor/symbiote-node/themes/synthwave.js +0 -137
- package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.css.js +0 -86
- package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.js +0 -128
- package/vendor/symbiote-node/toolbar/QuickToolbar/QuickToolbar.tpl.js +0 -29
|
@@ -1,622 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Layout - Root container for Blender-style panel layout
|
|
3
|
-
* Uses LayoutNode for recursive BSP tree rendering.
|
|
4
|
-
* Handles action zone events for split/join operations.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import Symbiote from '@symbiotejs/symbiote';
|
|
8
|
-
import * as LayoutTree from './../LayoutTree.js';
|
|
9
|
-
import { template } from './Layout.tpl.js';
|
|
10
|
-
import { styles } from './Layout.css.js';
|
|
11
|
-
import './../LayoutNode/LayoutNode.js';
|
|
12
|
-
import './../LayoutPreview/LayoutPreview.js';
|
|
13
|
-
import './../PanelMenu/PanelMenu.js';
|
|
14
|
-
|
|
15
|
-
export class Layout extends Symbiote {
|
|
16
|
-
static isoMode = true;
|
|
17
|
-
|
|
18
|
-
init$ = {
|
|
19
|
-
// Attributes
|
|
20
|
-
'@storage-key': '',
|
|
21
|
-
'@min-panel-size': 50,
|
|
22
|
-
|
|
23
|
-
// Layout tree data
|
|
24
|
-
layoutTree: null,
|
|
25
|
-
|
|
26
|
-
// Panel type registry
|
|
27
|
-
panelTypes: {},
|
|
28
|
-
|
|
29
|
-
// Current gesture state
|
|
30
|
-
activeGesture: null,
|
|
31
|
-
|
|
32
|
-
// Fullscreen panel ID (null = no fullscreen)
|
|
33
|
-
fullscreenPanelId: null,
|
|
34
|
-
|
|
35
|
-
// Tab bar state for Itemize API
|
|
36
|
-
hasFullscreenTabs: false,
|
|
37
|
-
tabItems: [],
|
|
38
|
-
|
|
39
|
-
// Tab click handler for Itemize
|
|
40
|
-
onTabClick: (e) => {
|
|
41
|
-
const panelId = e.target.closest('[data-panel-id]')?.dataset.panelId;
|
|
42
|
-
if (panelId && panelId !== this.$.fullscreenPanelId) {
|
|
43
|
-
this._switchFullscreenPanel(panelId);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
// Methods for LayoutNode to inherit
|
|
48
|
-
onLayoutChange: () => this._saveLayout(),
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Register panel type
|
|
53
|
-
* @param {string} name - Panel type name
|
|
54
|
-
* @param {Object} config - Panel configuration
|
|
55
|
-
* @param {string} [config.title] - Default title
|
|
56
|
-
* @param {string} [config.icon] - Material Symbols icon name
|
|
57
|
-
* @param {string} [config.component] - Custom element tag name
|
|
58
|
-
*/
|
|
59
|
-
registerPanelType(name, config) {
|
|
60
|
-
this.$.panelTypes = {
|
|
61
|
-
...this.$.panelTypes,
|
|
62
|
-
[name]: config
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
initCallback() {
|
|
67
|
-
this._loadLayout();
|
|
68
|
-
|
|
69
|
-
// Listen for layout changes from children
|
|
70
|
-
this.addEventListener('layout-change', () => this._saveLayout());
|
|
71
|
-
|
|
72
|
-
// Listen for action zone events
|
|
73
|
-
this.addEventListener('action-zone-start', (e) => this._onActionZoneStart(e));
|
|
74
|
-
this.addEventListener('action-zone-gesture', (e) => this._onActionZoneGesture(e));
|
|
75
|
-
this.addEventListener('action-zone-execute', (e) => this._onActionZoneExecute(e));
|
|
76
|
-
this.addEventListener('action-zone-end', (e) => this._onActionZoneEnd(e));
|
|
77
|
-
|
|
78
|
-
// Listen for panel UX events
|
|
79
|
-
this.addEventListener('panel-type-menu', (e) => this._onPanelTypeMenu(e));
|
|
80
|
-
this.addEventListener('panel-type-select', (e) => this._onPanelTypeSelect(e));
|
|
81
|
-
this.addEventListener('panel-fullscreen', (e) => this._onPanelFullscreen(e));
|
|
82
|
-
this.addEventListener('panel-collapse-toggle', (e) => this._onPanelCollapseToggle(e));
|
|
83
|
-
|
|
84
|
-
// Global fallback: hide preview when pointer is released anywhere
|
|
85
|
-
// This covers touchpad edge cases when pointer events don't bubble correctly
|
|
86
|
-
this._globalPointerFallback = () => {
|
|
87
|
-
if (this.$.activeGesture) {
|
|
88
|
-
this.$.activeGesture = null;
|
|
89
|
-
if (this.ref.preview) {
|
|
90
|
-
this.ref.preview.hide();
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
if (typeof document !== 'undefined') {
|
|
95
|
-
document.addEventListener('pointerup', this._globalPointerFallback);
|
|
96
|
-
document.addEventListener('pointercancel', this._globalPointerFallback);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
disconnectedCallback() {
|
|
101
|
-
if (this._globalPointerFallback && typeof document !== 'undefined') {
|
|
102
|
-
document.removeEventListener('pointerup', this._globalPointerFallback);
|
|
103
|
-
document.removeEventListener('pointercancel', this._globalPointerFallback);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
renderCallback() {
|
|
108
|
-
this._renderRoot();
|
|
109
|
-
this.sub('layoutTree', () => {
|
|
110
|
-
this._renderRoot();
|
|
111
|
-
// Recalculate tabs if in fullscreen mode
|
|
112
|
-
if (this.$.fullscreenPanelId) {
|
|
113
|
-
// Wait for DOM update, then recalculate tabs
|
|
114
|
-
if (typeof requestAnimationFrame !== 'undefined') {
|
|
115
|
-
requestAnimationFrame(() => {
|
|
116
|
-
const allPanels = this.querySelectorAll('layout-node[node-type="panel"]');
|
|
117
|
-
// Check if current fullscreen panel still exists
|
|
118
|
-
const panelExists = Array.from(allPanels).some(p => p.$.nodeId === this.$.fullscreenPanelId);
|
|
119
|
-
if (panelExists) {
|
|
120
|
-
this._updateTabItems(allPanels, this.$.fullscreenPanelId);
|
|
121
|
-
} else {
|
|
122
|
-
// Fullscreen panel was removed, exit fullscreen
|
|
123
|
-
this.$.fullscreenPanelId = null;
|
|
124
|
-
this.$.hasFullscreenTabs = false;
|
|
125
|
-
this.$.tabItems = [];
|
|
126
|
-
allPanels.forEach(p => {
|
|
127
|
-
p.removeAttribute('fullscreen');
|
|
128
|
-
p.$.isFullscreen = false;
|
|
129
|
-
p.style.display = '';
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
_loadLayout() {
|
|
139
|
-
const storageKey = this.$['@storage-key'];
|
|
140
|
-
|
|
141
|
-
// Try localStorage
|
|
142
|
-
if (storageKey && typeof localStorage !== 'undefined') {
|
|
143
|
-
const stored = localStorage.getItem(storageKey);
|
|
144
|
-
if (stored) {
|
|
145
|
-
try {
|
|
146
|
-
this.$.layoutTree = LayoutTree.deserialize(stored);
|
|
147
|
-
return;
|
|
148
|
-
} catch (e) {
|
|
149
|
-
console.warn('Failed to load layout:', e);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Try layout attribute
|
|
155
|
-
const layoutAttr = this.getAttribute('layout');
|
|
156
|
-
if (layoutAttr) {
|
|
157
|
-
try {
|
|
158
|
-
this.$.layoutTree = JSON.parse(layoutAttr);
|
|
159
|
-
return;
|
|
160
|
-
} catch (e) {
|
|
161
|
-
console.warn('Failed to parse layout:', e);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Default single panel
|
|
166
|
-
this.$.layoutTree = LayoutTree.createPanel('default');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
_saveLayout() {
|
|
170
|
-
const storageKey = this.$['@storage-key'];
|
|
171
|
-
if (storageKey && this.$.layoutTree && typeof localStorage !== 'undefined') {
|
|
172
|
-
localStorage.setItem(storageKey, LayoutTree.serialize(this.$.layoutTree));
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
_renderRoot() {
|
|
177
|
-
if (!this.$.layoutTree || !this.ref.root) return;
|
|
178
|
-
|
|
179
|
-
// Ensure root node exists
|
|
180
|
-
let rootNode = this.ref.root.querySelector('layout-node');
|
|
181
|
-
if (!rootNode) {
|
|
182
|
-
rootNode = document.createElement('layout-node');
|
|
183
|
-
this.ref.root.appendChild(rootNode);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// Pass data to root node
|
|
187
|
-
rootNode.$.nodeData = this.$.layoutTree;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Action Zone Event Handlers
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Called when action zone drag starts
|
|
194
|
-
* @param {CustomEvent} e
|
|
195
|
-
*/
|
|
196
|
-
_onActionZoneStart(e) {
|
|
197
|
-
const { panelId, corner } = e.detail;
|
|
198
|
-
this.$.activeGesture = { panelId, corner };
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Called during action zone drag with gesture type
|
|
203
|
-
* @param {CustomEvent} e
|
|
204
|
-
*/
|
|
205
|
-
_onActionZoneGesture(e) {
|
|
206
|
-
const { panelId, gesture, dx, dy } = e.detail;
|
|
207
|
-
|
|
208
|
-
// Find the panel element
|
|
209
|
-
const panelNode = this._findPanelNode(panelId);
|
|
210
|
-
if (!panelNode) return;
|
|
211
|
-
|
|
212
|
-
const panelRect = panelNode.getBoundingClientRect();
|
|
213
|
-
|
|
214
|
-
// Show preview
|
|
215
|
-
const preview = this.ref.preview;
|
|
216
|
-
if (!preview) return;
|
|
217
|
-
|
|
218
|
-
if (gesture === 'split-h' || gesture === 'split-v') {
|
|
219
|
-
preview.showSplit(gesture, panelRect, 0.5);
|
|
220
|
-
} else if (gesture === 'join') {
|
|
221
|
-
// For join, find the neighbor panel that would be removed
|
|
222
|
-
const neighborInfo = this._findJoinTarget(panelId, dx, dy);
|
|
223
|
-
if (neighborInfo) {
|
|
224
|
-
const neighborNode = this._findPanelNode(neighborInfo.id);
|
|
225
|
-
if (neighborNode) {
|
|
226
|
-
preview.showJoin(neighborNode.getBoundingClientRect());
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Called when action zone gesture is completed
|
|
234
|
-
* @param {CustomEvent} e
|
|
235
|
-
*/
|
|
236
|
-
_onActionZoneExecute(e) {
|
|
237
|
-
const { panelId, corner, gesture } = e.detail;
|
|
238
|
-
|
|
239
|
-
if (gesture === 'split-h') {
|
|
240
|
-
this.splitPanel(panelId, 'horizontal', 0.5);
|
|
241
|
-
} else if (gesture === 'split-v') {
|
|
242
|
-
this.splitPanel(panelId, 'vertical', 0.5);
|
|
243
|
-
} else if (gesture === 'join') {
|
|
244
|
-
// Join removes the current panel, expanding neighbor
|
|
245
|
-
this.joinPanels(panelId);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Called when action zone drag ends
|
|
251
|
-
* @param {CustomEvent} e
|
|
252
|
-
*/
|
|
253
|
-
_onActionZoneEnd(e) {
|
|
254
|
-
this.$.activeGesture = null;
|
|
255
|
-
|
|
256
|
-
// Hide preview
|
|
257
|
-
const preview = this.ref.preview;
|
|
258
|
-
if (preview) {
|
|
259
|
-
preview.hide();
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* Show panel type selection menu
|
|
265
|
-
* @param {CustomEvent} e
|
|
266
|
-
*/
|
|
267
|
-
_onPanelTypeMenu(e) {
|
|
268
|
-
const { panelId, currentType, x, y } = e.detail;
|
|
269
|
-
const menu = this.ref.menu;
|
|
270
|
-
if (!menu) return;
|
|
271
|
-
|
|
272
|
-
// Convert panelTypes to array for menu
|
|
273
|
-
const items = Object.entries(this.$.panelTypes).map(([type, config]) => ({
|
|
274
|
-
type,
|
|
275
|
-
title: config.title || type,
|
|
276
|
-
icon: config.icon || 'dashboard'
|
|
277
|
-
}));
|
|
278
|
-
|
|
279
|
-
menu.show(x, y, panelId, currentType, items);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Handle panel type change
|
|
284
|
-
* @param {CustomEvent} e
|
|
285
|
-
*/
|
|
286
|
-
_onPanelTypeSelect(e) {
|
|
287
|
-
const { panelId, type } = e.detail;
|
|
288
|
-
|
|
289
|
-
// Update tree
|
|
290
|
-
const tree = this.$.layoutTree;
|
|
291
|
-
if (!tree) return;
|
|
292
|
-
|
|
293
|
-
const updateNode = (node) => {
|
|
294
|
-
if (!node) return;
|
|
295
|
-
if (node.id === panelId) {
|
|
296
|
-
node.panelType = type;
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
if (node.first) updateNode(node.first);
|
|
300
|
-
if (node.second) updateNode(node.second);
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
updateNode(tree);
|
|
304
|
-
this.$.layoutTree = { ...tree };
|
|
305
|
-
this._saveLayout();
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Toggle panel collapse state
|
|
310
|
-
* @param {CustomEvent} e
|
|
311
|
-
*/
|
|
312
|
-
_onPanelCollapseToggle(e) {
|
|
313
|
-
const { panelId, collapsed } = e.detail;
|
|
314
|
-
const tree = this.$.layoutTree;
|
|
315
|
-
if (!tree) return;
|
|
316
|
-
|
|
317
|
-
// Update the node's collapsed state in tree
|
|
318
|
-
LayoutTree.updateNode(tree, panelId, { collapsed });
|
|
319
|
-
|
|
320
|
-
// Trigger full re-render to propagate changes to all split nodes
|
|
321
|
-
this.$.layoutTree = { ...tree };
|
|
322
|
-
this._renderRoot();
|
|
323
|
-
this._saveLayout();
|
|
324
|
-
|
|
325
|
-
// Update both panels' canCollapse state
|
|
326
|
-
// When one panel collapses/expands, both need to recalculate
|
|
327
|
-
if (typeof requestAnimationFrame !== 'undefined') {
|
|
328
|
-
requestAnimationFrame(() => {
|
|
329
|
-
const panelNode = this._findPanelNode(panelId);
|
|
330
|
-
if (panelNode) {
|
|
331
|
-
// Find parent split container
|
|
332
|
-
const container = panelNode.parentElement;
|
|
333
|
-
if (container?.classList.contains('split-first') || container?.classList.contains('split-second')) {
|
|
334
|
-
const siblingContainer = container.classList.contains('split-first')
|
|
335
|
-
? container.parentElement?.querySelector('.split-second')
|
|
336
|
-
: container.parentElement?.querySelector('.split-first');
|
|
337
|
-
|
|
338
|
-
// Update sibling panel
|
|
339
|
-
if (siblingContainer) {
|
|
340
|
-
const siblingPanel = siblingContainer.querySelector('layout-node[node-type="panel"]');
|
|
341
|
-
if (siblingPanel?._updatePanelInfo) {
|
|
342
|
-
siblingPanel._updatePanelInfo();
|
|
343
|
-
}
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
// Also update the collapsed panel itself (for when it expands)
|
|
347
|
-
if (panelNode._updatePanelInfo) {
|
|
348
|
-
panelNode._updatePanelInfo();
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
/**
|
|
357
|
-
* Toggle panel fullscreen
|
|
358
|
-
* @param {CustomEvent} e
|
|
359
|
-
*/
|
|
360
|
-
_onPanelFullscreen(e) {
|
|
361
|
-
const { panelId } = e.detail;
|
|
362
|
-
const panelNode = this._findPanelNode(panelId);
|
|
363
|
-
if (!panelNode) return;
|
|
364
|
-
|
|
365
|
-
const allPanels = this.querySelectorAll('layout-node[node-type="panel"]');
|
|
366
|
-
|
|
367
|
-
if (this.$.fullscreenPanelId === panelId) {
|
|
368
|
-
// Exit fullscreen
|
|
369
|
-
this.$.fullscreenPanelId = null;
|
|
370
|
-
this.$.hasFullscreenTabs = false;
|
|
371
|
-
this.$.tabItems = [];
|
|
372
|
-
|
|
373
|
-
panelNode.removeAttribute('fullscreen');
|
|
374
|
-
panelNode.$.isFullscreen = false;
|
|
375
|
-
panelNode.$.fullscreenIcon = 'fullscreen';
|
|
376
|
-
|
|
377
|
-
// Remove fullscreen styles from all panels
|
|
378
|
-
allPanels.forEach((p) => {
|
|
379
|
-
p.removeAttribute('fullscreen');
|
|
380
|
-
p.$.isFullscreen = false;
|
|
381
|
-
p.$.fullscreenIcon = 'fullscreen';
|
|
382
|
-
p.style.display = '';
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
// Force layout recalculation
|
|
386
|
-
this._renderRoot();
|
|
387
|
-
this.dispatchEvent(new CustomEvent('layout-change', { bubbles: true }));
|
|
388
|
-
} else {
|
|
389
|
-
// Enter fullscreen
|
|
390
|
-
this.$.fullscreenPanelId = panelId;
|
|
391
|
-
|
|
392
|
-
// Hide all panels except fullscreen one
|
|
393
|
-
allPanels.forEach((p) => {
|
|
394
|
-
if (p === panelNode) {
|
|
395
|
-
p.setAttribute('fullscreen', '');
|
|
396
|
-
p.$.isFullscreen = true;
|
|
397
|
-
p.$.fullscreenIcon = 'fullscreen_exit';
|
|
398
|
-
p.style.display = '';
|
|
399
|
-
} else {
|
|
400
|
-
p.style.display = 'none';
|
|
401
|
-
}
|
|
402
|
-
});
|
|
403
|
-
|
|
404
|
-
// Update tab bar via Itemize API
|
|
405
|
-
this._updateTabItems(allPanels, panelId);
|
|
406
|
-
this.$.hasFullscreenTabs = true;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* Update tabItems array for Itemize-based tab bar
|
|
412
|
-
* @param {NodeListOf<Element>} [allPanels] - Optional, will query DOM if not provided
|
|
413
|
-
* @param {string} [activePanelId] - Optional, defaults to fullscreenPanelId
|
|
414
|
-
*/
|
|
415
|
-
_updateTabItems(allPanels, activePanelId) {
|
|
416
|
-
const panels = allPanels || this.querySelectorAll('layout-node[node-type="panel"]');
|
|
417
|
-
const activeId = activePanelId || this.$.fullscreenPanelId;
|
|
418
|
-
|
|
419
|
-
this.$.tabItems = Array.from(panels).map((p) => {
|
|
420
|
-
const nodeData = p.$.nodeData;
|
|
421
|
-
const panelType = nodeData?.panelType || 'panel';
|
|
422
|
-
const typeConfig = this.$.panelTypes[panelType] || {};
|
|
423
|
-
|
|
424
|
-
return {
|
|
425
|
-
panelId: p.$.nodeId,
|
|
426
|
-
icon: typeConfig.icon || 'dashboard',
|
|
427
|
-
title: typeConfig.title || panelType,
|
|
428
|
-
isActive: p.$.nodeId === activeId
|
|
429
|
-
};
|
|
430
|
-
});
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
/**
|
|
434
|
-
* Switch fullscreen to another panel
|
|
435
|
-
* @param {string} panelId - Panel ID to switch to
|
|
436
|
-
*/
|
|
437
|
-
_switchFullscreenPanel(panelId) {
|
|
438
|
-
const allPanels = this.querySelectorAll('layout-node[node-type="panel"]');
|
|
439
|
-
const newPanel = this._findPanelNode(panelId);
|
|
440
|
-
if (!newPanel) return;
|
|
441
|
-
|
|
442
|
-
// Update panel states
|
|
443
|
-
allPanels.forEach((p) => {
|
|
444
|
-
if (p.$.nodeId === panelId) {
|
|
445
|
-
p.setAttribute('fullscreen', '');
|
|
446
|
-
p.$.isFullscreen = true;
|
|
447
|
-
p.$.fullscreenIcon = 'fullscreen_exit';
|
|
448
|
-
p.style.display = '';
|
|
449
|
-
} else {
|
|
450
|
-
p.removeAttribute('fullscreen');
|
|
451
|
-
p.$.isFullscreen = false;
|
|
452
|
-
p.$.fullscreenIcon = 'fullscreen';
|
|
453
|
-
p.style.display = 'none';
|
|
454
|
-
}
|
|
455
|
-
});
|
|
456
|
-
|
|
457
|
-
this.$.fullscreenPanelId = panelId;
|
|
458
|
-
|
|
459
|
-
// Update tab bar
|
|
460
|
-
this._updateTabItems(allPanels, panelId);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
/**
|
|
464
|
-
* Find a panel node by ID
|
|
465
|
-
* @param {string} panelId
|
|
466
|
-
* @returns {HTMLElement|null}
|
|
467
|
-
*/
|
|
468
|
-
_findPanelNode(panelId) {
|
|
469
|
-
const nodes = this.querySelectorAll('layout-node[node-type="panel"]');
|
|
470
|
-
for (const node of nodes) {
|
|
471
|
-
if (node.$.nodeId === panelId) {
|
|
472
|
-
return node;
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return null;
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Find the neighbor panel for join operation
|
|
480
|
-
* @param {string} panelId
|
|
481
|
-
* @param {number} dx
|
|
482
|
-
* @param {number} dy
|
|
483
|
-
* @returns {{id: string, direction: string}|null}
|
|
484
|
-
*/
|
|
485
|
-
_findJoinTarget(panelId, dx, dy) {
|
|
486
|
-
// Find parent split of this panel
|
|
487
|
-
const parentInfo = LayoutTree.findParent(this.$.layoutTree, panelId);
|
|
488
|
-
if (!parentInfo) return null;
|
|
489
|
-
|
|
490
|
-
const { parent, which } = parentInfo;
|
|
491
|
-
|
|
492
|
-
// The sibling is the join target (the panel that will expand)
|
|
493
|
-
const sibling = which === 'first' ? parent.second : parent.first;
|
|
494
|
-
if (!sibling) return null;
|
|
495
|
-
|
|
496
|
-
// For nested splits, get the leaf panel ID
|
|
497
|
-
const siblingId = this._getFirstPanelId(sibling);
|
|
498
|
-
|
|
499
|
-
return { id: siblingId, direction: parent.direction };
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* Get the first panel ID from a node (handles nested splits)
|
|
504
|
-
* @param {Object} node
|
|
505
|
-
* @returns {string}
|
|
506
|
-
*/
|
|
507
|
-
_getFirstPanelId(node) {
|
|
508
|
-
if (node.type === 'panel') return node.id;
|
|
509
|
-
// For split nodes, recursively get first panel
|
|
510
|
-
return this._getFirstPanelId(node.first);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
// Public API
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Split a panel
|
|
518
|
-
* @param {string} panelId - Panel ID to split
|
|
519
|
-
* @param {'horizontal' | 'vertical'} direction - Split direction
|
|
520
|
-
* @param {number} [ratio=0.5] - Split ratio
|
|
521
|
-
* @param {string} [newPanelType] - Type for new panel
|
|
522
|
-
*/
|
|
523
|
-
splitPanel(panelId, direction, ratio = 0.5, newPanelType) {
|
|
524
|
-
const newTree = LayoutTree.splitPanel(
|
|
525
|
-
LayoutTree.clone(this.$.layoutTree),
|
|
526
|
-
panelId,
|
|
527
|
-
direction,
|
|
528
|
-
ratio,
|
|
529
|
-
newPanelType
|
|
530
|
-
);
|
|
531
|
-
|
|
532
|
-
if (newTree) {
|
|
533
|
-
this.$.layoutTree = newTree;
|
|
534
|
-
this._saveLayout();
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Join panels (remove one)
|
|
540
|
-
* @param {string} panelToRemove - Panel ID to remove
|
|
541
|
-
*/
|
|
542
|
-
joinPanels(panelToRemove) {
|
|
543
|
-
const newTree = LayoutTree.joinPanels(
|
|
544
|
-
LayoutTree.clone(this.$.layoutTree),
|
|
545
|
-
panelToRemove
|
|
546
|
-
);
|
|
547
|
-
|
|
548
|
-
if (newTree) {
|
|
549
|
-
this.$.layoutTree = newTree;
|
|
550
|
-
this._saveLayout();
|
|
551
|
-
}
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
/**
|
|
555
|
-
* Get current layout
|
|
556
|
-
* @returns {import('./../LayoutTree.js').LayoutNode}
|
|
557
|
-
*/
|
|
558
|
-
getLayout() {
|
|
559
|
-
return LayoutTree.clone(this.$.layoutTree);
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
/**
|
|
563
|
-
* Set layout
|
|
564
|
-
* @param {import('./../LayoutTree.js').LayoutNode} layout
|
|
565
|
-
*/
|
|
566
|
-
setLayout(layout) {
|
|
567
|
-
// Clear fullscreen state
|
|
568
|
-
if (this.$.fullscreenPanelId) {
|
|
569
|
-
const panelNode = this._findPanelNode(this.$.fullscreenPanelId);
|
|
570
|
-
if (panelNode) {
|
|
571
|
-
panelNode.removeAttribute('fullscreen');
|
|
572
|
-
panelNode.$.isFullscreen = false;
|
|
573
|
-
panelNode.$.fullscreenIcon = 'fullscreen';
|
|
574
|
-
panelNode.style.left = '';
|
|
575
|
-
panelNode.style.width = '';
|
|
576
|
-
}
|
|
577
|
-
this.$.fullscreenPanelId = null;
|
|
578
|
-
this.$.hasFullscreenTabs = false;
|
|
579
|
-
this.$.tabItems = [];
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
// Clear stripe mode from all panels
|
|
583
|
-
this.querySelectorAll('layout-node[stripe]').forEach((node) => {
|
|
584
|
-
node.removeAttribute('stripe');
|
|
585
|
-
node.style.left = '';
|
|
586
|
-
node.style.top = '';
|
|
587
|
-
node.style.width = '';
|
|
588
|
-
node.style.height = '';
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
// Clear all collapsed states from DOM
|
|
592
|
-
this.querySelectorAll('layout-node[collapsed]').forEach((node) => {
|
|
593
|
-
node.removeAttribute('collapsed');
|
|
594
|
-
node.removeAttribute('collapse-dir');
|
|
595
|
-
node.$.isCollapsed = false;
|
|
596
|
-
// Reset collapse icon based on direction
|
|
597
|
-
if (node.$.collapseDirection === 'horizontal') {
|
|
598
|
-
node.$.collapseIcon = 'chevron_left';
|
|
599
|
-
} else {
|
|
600
|
-
node.$.collapseIcon = 'expand_less';
|
|
601
|
-
}
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
// Clear container collapsed-child attributes
|
|
605
|
-
this.querySelectorAll('[collapsed-child]').forEach((el) => {
|
|
606
|
-
el.removeAttribute('collapsed-child');
|
|
607
|
-
el.removeAttribute('saved-ratio');
|
|
608
|
-
el.style.width = '';
|
|
609
|
-
el.style.height = '';
|
|
610
|
-
el.style.flex = '';
|
|
611
|
-
});
|
|
612
|
-
|
|
613
|
-
this.$.layoutTree = layout;
|
|
614
|
-
this._saveLayout();
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
Layout.template = template;
|
|
619
|
-
Layout.rootStyles = styles;
|
|
620
|
-
|
|
621
|
-
Layout.reg('panel-layout');
|
|
622
|
-
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { html } from '@symbiotejs/symbiote';
|
|
2
|
-
|
|
3
|
-
export const template = html`
|
|
4
|
-
<div class="layout-root" ref="root"></div>
|
|
5
|
-
<layout-preview ref="preview"></layout-preview>
|
|
6
|
-
<panel-menu ref="menu"></panel-menu>
|
|
7
|
-
|
|
8
|
-
<!-- Fullscreen tab bar (hidden by default) -->
|
|
9
|
-
<div class="fullscreen-tab-bar" ${{ '@hidden': '!hasFullscreenTabs' }}>
|
|
10
|
-
<div class="tab-list" itemize="tabItems">
|
|
11
|
-
<template>
|
|
12
|
-
<button class="fullscreen-tab"
|
|
13
|
-
${{
|
|
14
|
-
onclick: '^onTabClick',
|
|
15
|
-
'@data-panel-id': 'panelId',
|
|
16
|
-
'@active': 'isActive'
|
|
17
|
-
}}>
|
|
18
|
-
<span class="material-symbols-outlined">{{icon}}</span>
|
|
19
|
-
<span>{{title}}</span>
|
|
20
|
-
</button>
|
|
21
|
-
</template>
|
|
22
|
-
</div>
|
|
23
|
-
<div class="tab-filler"></div>
|
|
24
|
-
</div>
|
|
25
|
-
`;
|