@eclipse-docks/core 0.7.126 → 0.7.130

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.
Files changed (106) hide show
  1. package/dist/api/index.js +4 -4
  2. package/dist/api/services.d.ts +4 -0
  3. package/dist/api/services.d.ts.map +1 -1
  4. package/dist/{api-B3RXoez_.js → api-oPg3Bv1S.js} +422 -293
  5. package/dist/api-oPg3Bv1S.js.map +1 -0
  6. package/dist/components/attribution.d.ts +1 -0
  7. package/dist/components/attribution.d.ts.map +1 -1
  8. package/dist/components/command.d.ts +4 -5
  9. package/dist/components/command.d.ts.map +1 -1
  10. package/dist/components/extensions.d.ts +3 -0
  11. package/dist/components/extensions.d.ts.map +1 -1
  12. package/dist/components/filebrowser.d.ts.map +1 -1
  13. package/dist/components/language-selector.d.ts.map +1 -1
  14. package/dist/components/layout-switcher.d.ts +1 -1
  15. package/dist/components/layout-switcher.d.ts.map +1 -1
  16. package/dist/components/npm-packages.d.ts +1 -0
  17. package/dist/components/npm-packages.d.ts.map +1 -1
  18. package/dist/components/release-history.d.ts +9 -2
  19. package/dist/components/release-history.d.ts.map +1 -1
  20. package/dist/components/tasks.d.ts.map +1 -1
  21. package/dist/core/apploader.d.ts +2 -9
  22. package/dist/core/apploader.d.ts.map +1 -1
  23. package/dist/core/contribution-names.d.ts +0 -2
  24. package/dist/core/contribution-names.d.ts.map +1 -1
  25. package/dist/core/contribution-targets.d.ts +1 -0
  26. package/dist/core/contribution-targets.d.ts.map +1 -1
  27. package/dist/core/contributionregistry.d.ts +3 -0
  28. package/dist/core/contributionregistry.d.ts.map +1 -1
  29. package/dist/core/dialogservice.d.ts +3 -1
  30. package/dist/core/dialogservice.d.ts.map +1 -1
  31. package/dist/core/dropdown-item.d.ts +43 -0
  32. package/dist/core/dropdown-item.d.ts.map +1 -0
  33. package/dist/core/dropdown-menu-utils.d.ts +5 -0
  34. package/dist/core/dropdown-menu-utils.d.ts.map +1 -1
  35. package/dist/core/layout-panels.d.ts +25 -0
  36. package/dist/core/layout-panels.d.ts.map +1 -0
  37. package/dist/dialogs/navigable-info-dialog.d.ts.map +1 -1
  38. package/dist/dialogs/version-info-dialog.d.ts +18 -2
  39. package/dist/dialogs/version-info-dialog.d.ts.map +1 -1
  40. package/dist/externals/lit.js +1 -1
  41. package/dist/externals/webawesome.js +1 -1
  42. package/dist/index.js +4 -4
  43. package/dist/layouts/standard-layout.d.ts +9 -1
  44. package/dist/layouts/standard-layout.d.ts.map +1 -1
  45. package/dist/parts/contextmenu.d.ts +5 -2
  46. package/dist/parts/contextmenu.d.ts.map +1 -1
  47. package/dist/parts/index.d.ts.map +1 -1
  48. package/dist/parts/index.js +1 -1
  49. package/dist/parts/part.d.ts +4 -0
  50. package/dist/parts/part.d.ts.map +1 -1
  51. package/dist/parts/resizable-grid.d.ts +10 -3
  52. package/dist/parts/resizable-grid.d.ts.map +1 -1
  53. package/dist/parts/tabs.d.ts +6 -0
  54. package/dist/parts/tabs.d.ts.map +1 -1
  55. package/dist/{parts-CsoNFVTw.js → parts-CAt8aeU8.js} +1361 -975
  56. package/dist/parts-CAt8aeU8.js.map +1 -0
  57. package/dist/{webawesome-Y1_HnKa_.js → webawesome-BGXn04Mw.js} +18 -10
  58. package/dist/webawesome-BGXn04Mw.js.map +1 -0
  59. package/dist/{widget-DbLusgAH.js → widget-BqQtioK1.js} +11 -5
  60. package/dist/widget-BqQtioK1.js.map +1 -0
  61. package/dist/widgets/index.js +1 -1
  62. package/dist/{widgets-DnnSZhsi.js → widgets-C9V42Mqq.js} +2 -2
  63. package/dist/{widgets-DnnSZhsi.js.map → widgets-C9V42Mqq.js.map} +1 -1
  64. package/package.json +1 -1
  65. package/src/api/services.ts +20 -0
  66. package/src/commands/filebrowser-contributions.ts +0 -16
  67. package/src/components/attribution.ts +2 -0
  68. package/src/components/command.ts +45 -119
  69. package/src/components/extensions.ts +20 -3
  70. package/src/components/filebrowser.ts +15 -12
  71. package/src/components/language-selector.ts +0 -1
  72. package/src/components/layout-switcher.ts +39 -26
  73. package/src/components/npm-packages.ts +2 -0
  74. package/src/components/release-history.ts +29 -40
  75. package/src/components/tasks.ts +0 -1
  76. package/src/contributions/default-layout-contributions.ts +7 -43
  77. package/src/contributions/default-ui-contributions.ts +4 -4
  78. package/src/core/apploader.ts +7 -54
  79. package/src/core/contribution-names.ts +0 -3
  80. package/src/core/contribution-targets.ts +1 -0
  81. package/src/core/contributionregistry.ts +19 -3
  82. package/src/core/dialogservice.ts +76 -19
  83. package/src/core/dropdown-item.ts +187 -0
  84. package/src/core/dropdown-menu-utils.ts +59 -0
  85. package/src/core/layout-panels.ts +121 -0
  86. package/src/dialogs/navigable-info-dialog.ts +5 -2
  87. package/src/dialogs/version-info-dialog.ts +163 -21
  88. package/src/icons/icons.txt +4 -2
  89. package/src/icons/layout-standard-bottom-panel.svg +4 -4
  90. package/src/icons/layout-standard-full.svg +4 -4
  91. package/src/icons/layout-standard-left-aux.svg +8 -0
  92. package/src/icons/layout-standard-left-sidebar.svg +5 -0
  93. package/src/icons/layout-standard-right-aux.svg +8 -0
  94. package/src/icons/layout-standard-right-sidebar.svg +5 -0
  95. package/src/layouts/standard-layout.ts +81 -5
  96. package/src/parts/contextmenu.ts +39 -44
  97. package/src/parts/index.ts +4 -1
  98. package/src/parts/part.ts +26 -0
  99. package/src/parts/resizable-grid.ts +125 -57
  100. package/src/parts/tabs.ts +103 -0
  101. package/dist/api-B3RXoez_.js.map +0 -1
  102. package/dist/parts-CsoNFVTw.js.map +0 -1
  103. package/dist/webawesome-Y1_HnKa_.js.map +0 -1
  104. package/dist/widget-DbLusgAH.js.map +0 -1
  105. package/src/icons/layout-standard-bottom-sidebar.svg +0 -6
  106. package/src/icons/layout-standard.svg +0 -6
@@ -0,0 +1,121 @@
1
+ import type { LayoutDescriptor } from './apploader';
2
+ import { appSettings } from './settingsservice';
3
+ import type { DocksStandardLayout } from '../layouts/standard-layout';
4
+
5
+ export type LayoutPanelVisibility = {
6
+ showLeftSidebar: boolean;
7
+ showAuxSidebar: boolean;
8
+ showBottomPanel: boolean;
9
+ showLeftAux: boolean;
10
+ showRightAux: boolean;
11
+ };
12
+
13
+ export const DEFAULT_LAYOUT_PANEL_VISIBILITY: LayoutPanelVisibility = {
14
+ showLeftSidebar: true,
15
+ showAuxSidebar: true,
16
+ showBottomPanel: true,
17
+ showLeftAux: false,
18
+ showRightAux: false,
19
+ };
20
+
21
+ function normalizePanelVisibility(stored: Partial<LayoutPanelVisibility>): LayoutPanelVisibility {
22
+ return {
23
+ showLeftSidebar: stored.showLeftSidebar ?? DEFAULT_LAYOUT_PANEL_VISIBILITY.showLeftSidebar,
24
+ showAuxSidebar: stored.showAuxSidebar ?? DEFAULT_LAYOUT_PANEL_VISIBILITY.showAuxSidebar,
25
+ showBottomPanel: stored.showBottomPanel ?? DEFAULT_LAYOUT_PANEL_VISIBILITY.showBottomPanel,
26
+ showLeftAux: stored.showLeftAux ?? DEFAULT_LAYOUT_PANEL_VISIBILITY.showLeftAux,
27
+ showRightAux: stored.showRightAux ?? DEFAULT_LAYOUT_PANEL_VISIBILITY.showRightAux,
28
+ };
29
+ }
30
+
31
+ export const LAYOUT_PANEL_SETTINGS_KEY = 'layoutPanelVisibility';
32
+
33
+ /** @deprecated Legacy layout id persisted before panel visibility toggles. */
34
+ export const LEGACY_PREFERRED_LAYOUT_KEY = 'preferredLayoutId';
35
+
36
+ /** Maps legacy parameterized layout ids to panel visibility. */
37
+ export function layoutIdToPanelVisibility(layoutId: string): LayoutPanelVisibility {
38
+ switch (layoutId) {
39
+ case 'standard-bottom-panel':
40
+ return { ...DEFAULT_LAYOUT_PANEL_VISIBILITY, showBottomPanel: true, showLeftAux: false, showRightAux: false };
41
+ case 'standard-bottom-sidebar':
42
+ return { ...DEFAULT_LAYOUT_PANEL_VISIBILITY, showBottomPanel: false, showLeftAux: true, showRightAux: false };
43
+ case 'standard-full':
44
+ return {
45
+ ...DEFAULT_LAYOUT_PANEL_VISIBILITY,
46
+ showLeftAux: true,
47
+ showRightAux: true,
48
+ };
49
+ case 'standard':
50
+ default:
51
+ return {
52
+ ...DEFAULT_LAYOUT_PANEL_VISIBILITY,
53
+ showBottomPanel: false,
54
+ showLeftAux: false,
55
+ showRightAux: false,
56
+ };
57
+ }
58
+ }
59
+
60
+ export function resolveInitialPanelVisibilityFromApp(appLayout?: LayoutDescriptor): LayoutPanelVisibility {
61
+ if (typeof appLayout === 'object' && appLayout.props) {
62
+ return {
63
+ ...DEFAULT_LAYOUT_PANEL_VISIBILITY,
64
+ showLeftSidebar: appLayout.props.showLeftSidebar !== false,
65
+ showAuxSidebar: appLayout.props.showAuxSidebar !== false,
66
+ showBottomPanel: appLayout.props.showBottomPanel === true,
67
+ showLeftAux: appLayout.props.showLeftAux === true,
68
+ showRightAux: appLayout.props.showRightAux === true,
69
+ };
70
+ }
71
+ if (typeof appLayout === 'string') {
72
+ return layoutIdToPanelVisibility(appLayout);
73
+ }
74
+ return { ...DEFAULT_LAYOUT_PANEL_VISIBILITY };
75
+ }
76
+
77
+ export async function resolveStoredPanelVisibility(
78
+ appLayout?: LayoutDescriptor,
79
+ ): Promise<LayoutPanelVisibility> {
80
+ try {
81
+ const saved = await appSettings.get(LAYOUT_PANEL_SETTINGS_KEY) as Partial<LayoutPanelVisibility> | undefined;
82
+ if (saved && typeof saved === 'object') {
83
+ return normalizePanelVisibility(saved);
84
+ }
85
+ } catch {
86
+ // fall through to legacy/app defaults
87
+ }
88
+
89
+ try {
90
+ const legacyLayoutId = await appSettings.get(LEGACY_PREFERRED_LAYOUT_KEY) as string | undefined;
91
+ if (legacyLayoutId) {
92
+ return layoutIdToPanelVisibility(legacyLayoutId);
93
+ }
94
+ } catch {
95
+ // fall through to app defaults
96
+ }
97
+
98
+ return resolveInitialPanelVisibilityFromApp(appLayout);
99
+ }
100
+
101
+ export function findStandardLayout(container?: ParentNode | null): DocksStandardLayout | null {
102
+ const root = container ?? document.getElementById('app-root') ?? document.body;
103
+ if (!root || typeof root.querySelector !== 'function') {
104
+ return null;
105
+ }
106
+ return root.querySelector('docks-standard-layout');
107
+ }
108
+
109
+ export type LayoutPanelOption = {
110
+ key: keyof LayoutPanelVisibility;
111
+ label: string;
112
+ icon: string;
113
+ };
114
+
115
+ export const LAYOUT_PANEL_OPTIONS: LayoutPanelOption[] = [
116
+ { key: 'showLeftSidebar', label: 'Left sidebar', icon: 'docks layout-standard-left-sidebar' },
117
+ { key: 'showAuxSidebar', label: 'Right sidebar', icon: 'docks layout-standard-right-sidebar' },
118
+ { key: 'showBottomPanel', label: 'Bottom panel', icon: 'docks layout-standard-bottom-panel' },
119
+ { key: 'showLeftAux', label: 'Left Aux', icon: 'docks layout-standard-left-aux' },
120
+ { key: 'showRightAux', label: 'Right Aux', icon: 'docks layout-standard-right-aux' },
121
+ ];
@@ -85,10 +85,13 @@ export class DocksNavigableInfoDialogContent extends DocksDialogContent {
85
85
  }
86
86
 
87
87
  private handleClose() {
88
- const dialog = this.closest('wa-dialog');
89
- if (dialog && this.resolveCallback) {
88
+ if (this.resolveCallback) {
90
89
  this.resolveCallback();
91
90
  }
91
+ const dialog = this.closest('wa-dialog') as (HTMLElement & { open?: boolean }) | null;
92
+ if (dialog && dialog.open !== false) {
93
+ dialog.open = false;
94
+ }
92
95
  }
93
96
 
94
97
  static styles = [
@@ -1,22 +1,42 @@
1
- import { html, css } from "lit";
2
- import { customElement } from "lit/decorators.js";
1
+ import { html, css, nothing } from "lit";
2
+ import { customElement, property, state } from "lit/decorators.js";
3
3
  import type { PropertyValues } from "lit";
4
4
  import { DocksDialogContent } from "../parts/dialog-content";
5
5
  import { contributionRegistry } from "../core/contributionregistry";
6
6
  import {
7
7
  DIALOG_CONTRIBUTION_TARGET,
8
- CLOSE_BUTTON,
9
8
  type DialogContribution,
10
- type DialogButton,
11
9
  dialogService,
12
10
  } from "../core/dialogservice";
13
11
  import { ABOUT_TABS } from "../core/contribution-targets";
12
+ import { ABOUT_TAB_RELEASE } from "../core/contribution-names";
14
13
  import { appLoaderService } from "../core/apploader";
14
+ import { DocksReleaseHistory, type ReleaseHistoryNavState } from "../components/release-history";
15
+ import type { DocksTabs } from "../parts/tabs";
15
16
 
16
- const CLOSE_PRIMARY: DialogButton = { ...CLOSE_BUTTON, variant: "primary" };
17
+ const EMPTY_NAV: ReleaseHistoryNavState = {
18
+ hasMultiple: false,
19
+ atOldest: true,
20
+ atNewest: true,
21
+ };
22
+
23
+ @customElement("docks-version-info-dialog")
24
+ export class DocksVersionInfoDialog extends DocksDialogContent {
25
+ @property({ type: String })
26
+ label = "";
27
+
28
+ @property({ attribute: false })
29
+ close?: () => void;
30
+
31
+ @property({ attribute: false })
32
+ onAfterHide?: () => void;
33
+
34
+ @state()
35
+ private activeTab: string | null = null;
36
+
37
+ @state()
38
+ private releaseNav: ReleaseHistoryNavState = EMPTY_NAV;
17
39
 
18
- @customElement("docks-version-info-dialog-content")
19
- export class DocksVersionInfoDialogContent extends DocksDialogContent {
20
40
  static styles = [
21
41
  ...DocksDialogContent.styles,
22
42
  css`
@@ -24,54 +44,176 @@ export class DocksVersionInfoDialogContent extends DocksDialogContent {
24
44
  display: block;
25
45
  }
26
46
 
47
+ wa-dialog {
48
+ --width: 600px;
49
+ }
50
+
51
+ wa-dialog::part(body) {
52
+ display: flex;
53
+ flex-direction: column;
54
+ min-height: 0;
55
+ overflow: hidden;
56
+ }
57
+
27
58
  .dialog-body {
28
59
  display: flex;
29
60
  flex-direction: column;
30
61
  gap: 0.75rem;
31
62
  min-width: 32rem;
32
- height: 600px;
63
+ height: min(70vh, 36rem);
64
+ min-height: min(70vh, 36rem);
65
+ overflow: hidden;
33
66
  }
34
67
 
35
68
  .dialog-body docks-tabs {
36
- flex: 1;
69
+ flex: 1 1 auto;
37
70
  min-height: 0;
71
+ overflow: hidden;
72
+ }
73
+
74
+ .dialog-footer {
75
+ display: flex;
76
+ gap: 0.5rem;
77
+ justify-content: flex-end;
78
+ width: 100%;
38
79
  }
39
80
  `,
40
81
  ];
41
82
 
42
83
  protected firstUpdated(changed: PropertyValues) {
43
84
  super.firstUpdated(changed);
44
- const dialog = this.closest("wa-dialog");
45
- if (dialog) {
46
- dialog.style.setProperty("--width", "600px");
47
- dialog.setAttribute("light-dismiss", "");
85
+ this.addEventListener("release-history-changed", this.onReleaseHistoryChanged);
86
+ this.updateComplete.then(() => {
87
+ this.attachTabListener();
88
+ this.syncActiveTab();
89
+ this.syncReleaseNav();
90
+ });
91
+ }
92
+
93
+ disconnectedCallback() {
94
+ this.removeEventListener("release-history-changed", this.onReleaseHistoryChanged);
95
+ super.disconnectedCallback();
96
+ }
97
+
98
+ private onReleaseHistoryChanged = () => {
99
+ this.syncReleaseNav();
100
+ };
101
+
102
+ private attachTabListener() {
103
+ const tabGroup = this.getAboutTabs()?.shadowRoot?.querySelector("wa-tab-group");
104
+ if (!tabGroup || tabGroup.hasAttribute("data-version-info-listener")) {
105
+ return;
48
106
  }
107
+ tabGroup.setAttribute("data-version-info-listener", "");
108
+ tabGroup.addEventListener("wa-tab-show", (event: Event) => {
109
+ const name = (event as CustomEvent<{ name: string }>).detail?.name;
110
+ if (name) {
111
+ this.activeTab = name;
112
+ }
113
+ });
114
+ }
115
+
116
+ private getAboutTabs(): DocksTabs | null {
117
+ return this.renderRoot.querySelector("docks-tabs") as DocksTabs | null;
118
+ }
119
+
120
+ private getReleaseHistory(): DocksReleaseHistory | null {
121
+ const part = this.getAboutTabs()?.getTabPart(ABOUT_TAB_RELEASE);
122
+ return part instanceof DocksReleaseHistory ? part : null;
123
+ }
124
+
125
+ private syncActiveTab() {
126
+ const tabGroup = this.getAboutTabs()?.shadowRoot?.querySelector("wa-tab-group") as
127
+ | (HTMLElement & { active?: string })
128
+ | null;
129
+ this.activeTab = tabGroup?.getAttribute("active") || tabGroup?.active || null;
130
+ }
131
+
132
+ private syncReleaseNav() {
133
+ this.releaseNav = this.getReleaseHistory()?.getNavState() ?? EMPTY_NAV;
134
+ }
135
+
136
+ private handleClose() {
137
+ const dialog = this.renderRoot.querySelector("wa-dialog") as (HTMLElement & { open?: boolean }) | null;
138
+ if (dialog && dialog.open !== false) {
139
+ dialog.open = false;
140
+ return;
141
+ }
142
+ this.close?.();
143
+ }
144
+
145
+ private handleAfterHide() {
146
+ this.onAfterHide?.();
147
+ }
148
+
149
+ private showOlderRelease() {
150
+ this.getReleaseHistory()?.showOlder();
151
+ }
152
+
153
+ private showNewerRelease() {
154
+ this.getReleaseHistory()?.showNewer();
49
155
  }
50
156
 
51
157
  render() {
52
158
  const app = appLoaderService.getCurrentApp();
159
+ const onReleaseTab = this.activeTab === ABOUT_TAB_RELEASE;
160
+ const showReleaseNav = onReleaseTab && this.releaseNav.hasMultiple;
53
161
 
54
162
  return html`
55
- <div class="dialog-body">
56
- ${app?.description ? html`<small>${app.description}</small>` : ""}
57
- <docks-tabs id=${ABOUT_TABS}></docks-tabs>
58
- </div>
163
+ <wa-dialog
164
+ label=${this.label}
165
+ open
166
+ light-dismiss
167
+ with-footer
168
+ @wa-after-hide=${this.handleAfterHide}
169
+ >
170
+ <div class="dialog-body">
171
+ ${app?.description ? html`<small>${app.description}</small>` : ""}
172
+ <docks-tabs id=${ABOUT_TABS} fill-height></docks-tabs>
173
+ </div>
174
+ <div slot="footer" class="dialog-footer">
175
+ ${showReleaseNav
176
+ ? html`
177
+ <wa-button
178
+ variant="default"
179
+ ?disabled=${this.releaseNav.atOldest}
180
+ @click=${this.showOlderRelease}
181
+ >
182
+ ← Previous
183
+ </wa-button>
184
+ <wa-button
185
+ variant="default"
186
+ ?disabled=${this.releaseNav.atNewest}
187
+ @click=${this.showNewerRelease}
188
+ >
189
+ Next →
190
+ </wa-button>
191
+ `
192
+ : nothing}
193
+ <wa-button variant="primary" @click=${this.handleClose}>Close</wa-button>
194
+ </div>
195
+ </wa-dialog>
59
196
  `;
60
197
  }
61
198
  }
62
199
 
63
200
  declare global {
64
201
  interface HTMLElementTagNameMap {
65
- "docks-version-info-dialog-content": DocksVersionInfoDialogContent;
202
+ "docks-version-info-dialog": DocksVersionInfoDialog;
66
203
  }
67
204
  }
68
205
 
69
206
  contributionRegistry.registerContribution<DialogContribution>(DIALOG_CONTRIBUTION_TARGET, {
70
207
  id: "version-info",
71
208
  label: "About",
72
- buttons: [CLOSE_PRIMARY],
73
- component: () => html`<docks-version-info-dialog-content></docks-version-info-dialog-content>`,
74
- onButton: async () => true,
209
+ selfContained: true,
210
+ component: (state) => html`
211
+ <docks-version-info-dialog
212
+ .label=${state?.label ?? ""}
213
+ .close=${state?.close}
214
+ .onAfterHide=${state?.onAfterHide}
215
+ ></docks-version-info-dialog>
216
+ `,
75
217
  });
76
218
 
77
219
  export function versionInfoDialog(): Promise<void> {
@@ -4,9 +4,11 @@
4
4
  - python.svg: Licence=MIT, Author=Garuda Technology, Source=https://www.svgrepo.com/svg/452091/python
5
5
  - js.svg: Licence=MIT, Author=Garuda Technology, Source=https://www.svgrepo.com/svg/452045/js
6
6
  - jupyter.svg: Licence=Logo License, Author=gilbarbara, Source=https://www.svgrepo.com/svg/353949/jupyter
7
- - layout-standard.svg: Licence=Project-internal, Author=Eclipse Docks Team
7
+ - layout-standard-left-sidebar.svg: Licence=Project-internal, Author=Eclipse Docks Team
8
+ - layout-standard-right-sidebar.svg: Licence=Project-internal, Author=Eclipse Docks Team
8
9
  - layout-standard-bottom-panel.svg: Licence=Project-internal, Author=Eclipse Docks Team
9
- - layout-standard-bottom-sidebar.svg: Licence=Project-internal, Author=Eclipse Docks Team
10
+ - layout-standard-left-aux.svg: Licence=Project-internal, Author=Eclipse Docks Team
11
+ - layout-standard-right-aux.svg: Licence=Project-internal, Author=Eclipse Docks Team
10
12
  - layout-standard-full.svg: Licence=Project-internal, Author=Eclipse Docks Team
11
13
  - mark-github.svg: Licence=MIT, Author=GitHub, Source=https://github.com/primer/octicons (icons/mark-github-16.svg)
12
14
  - file-plus.svg: Licence=Project-internal, Author=Eclipse Docks Team
@@ -1,6 +1,6 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
- <rect x="4" y="3" width="12" height="8" rx="1.25" ry="1.25"
3
- fill="none" stroke="currentColor" stroke-width="1.25" stroke-linejoin="round"/>
4
- <line x1="2" y1="20" x2="18" y2="20" stroke="#3b82f6" stroke-width="2" stroke-linecap="round"/>
5
- <line x1="20" y1="2" x2="20" y2="22" stroke="#3b82f6" stroke-width="2" stroke-linecap="round"/>
2
+ <rect x="4" y="3" width="16" height="11" rx="1.25" ry="1.25"
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <rect x="4" y="16" width="16" height="5" rx="1.25" ry="1.25"
5
+ fill="#2563eb" fill-opacity="0.2" stroke="#2563eb" stroke-width="1.25" stroke-linejoin="round"/>
6
6
  </svg>
@@ -1,7 +1,7 @@
1
1
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
2
  <rect x="8" y="4" width="8" height="8" rx="1.25" ry="1.25"
3
- fill="none" stroke="currentColor" stroke-width="1.25" stroke-linejoin="round"/>
4
- <line x1="2.5" y1="2" x2="2.5" y2="22" stroke="#3b82f6" stroke-width="2" stroke-linecap="round"/>
5
- <line x1="21.5" y1="2" x2="21.5" y2="22" stroke="#3b82f6" stroke-width="2" stroke-linecap="round"/>
6
- <line x1="6" y1="20" x2="18" y2="20" stroke="#3b82f6" stroke-width="2" stroke-linecap="round"/>
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <line x1="2.5" y1="2" x2="2.5" y2="22" stroke="#2563eb" stroke-width="2" stroke-linecap="round"/>
5
+ <line x1="21.5" y1="2" x2="21.5" y2="22" stroke="#2563eb" stroke-width="2" stroke-linecap="round"/>
6
+ <line x1="6" y1="20" x2="18" y2="20" stroke="#2563eb" stroke-width="2" stroke-linecap="round"/>
7
7
  </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
+ <rect x="8" y="4" width="12" height="16" rx="1.25" ry="1.25"
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <rect x="2" y="4" width="5" height="7" rx="1" ry="1"
5
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
6
+ <rect x="2" y="13" width="5" height="7" rx="1" ry="1"
7
+ fill="#2563eb" fill-opacity="0.2" stroke="#2563eb" stroke-width="1.25" stroke-linejoin="round"/>
8
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
+ <rect x="7" y="4" width="13" height="16" rx="1.25" ry="1.25"
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <line x1="2.5" y1="2" x2="2.5" y2="22" stroke="#2563eb" stroke-width="2" stroke-linecap="round"/>
5
+ </svg>
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
+ <rect x="4" y="4" width="12" height="16" rx="1.25" ry="1.25"
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <rect x="17" y="4" width="5" height="7" rx="1" ry="1"
5
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
6
+ <rect x="17" y="13" width="5" height="7" rx="1" ry="1"
7
+ fill="#2563eb" fill-opacity="0.2" stroke="#2563eb" stroke-width="1.25" stroke-linejoin="round"/>
8
+ </svg>
@@ -0,0 +1,5 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true">
2
+ <rect x="4" y="4" width="13" height="16" rx="1.25" ry="1.25"
3
+ fill="none" stroke="#9ca3af" stroke-width="1.25" stroke-linejoin="round"/>
4
+ <line x1="21.5" y1="2" x2="21.5" y2="22" stroke="#2563eb" stroke-width="2" stroke-linecap="round"/>
5
+ </svg>
@@ -6,6 +6,7 @@ import {
6
6
  SIDEBAR_MAIN,
7
7
  SIDEBAR_MAIN_BOTTOM,
8
8
  SIDEBAR_AUXILIARY,
9
+ SIDEBAR_AUXILIARY_BOTTOM,
9
10
  PANEL_BOTTOM,
10
11
  TOOLBAR_MAIN,
11
12
  TOOLBAR_MAIN_CENTER,
@@ -14,15 +15,22 @@ import {
14
15
  TOOLBAR_BOTTOM_CENTER,
15
16
  TOOLBAR_BOTTOM_END
16
17
  } from "../core/contribution-targets";
18
+ import { appLoaderService } from "../core/apploader";
19
+ import { appSettings } from "../core/settingsservice";
20
+ import {
21
+ LAYOUT_PANEL_SETTINGS_KEY,
22
+ resolveStoredPanelVisibility,
23
+ type LayoutPanelVisibility,
24
+ } from "../core/layout-panels";
17
25
  import {DocksContainer} from "../parts/container";
18
26
 
19
27
  @customElement('docks-standard-layout')
20
28
  export class DocksStandardLayout extends DocksContainer {
21
- @property({type: Boolean, attribute: 'show-bottom-sidebar'})
22
- showBottomSidebar: boolean = false;
29
+ @property({type: Boolean, attribute: 'show-left-aux'})
30
+ showLeftAux: boolean = false;
23
31
 
24
32
  @property({type: Boolean, attribute: 'show-bottom-panel'})
25
- showBottomPanel: boolean = false;
33
+ showBottomPanel: boolean = true;
26
34
 
27
35
  @property({type: Boolean, attribute: 'show-left-sidebar'})
28
36
  showLeftSidebar: boolean = true;
@@ -30,10 +38,65 @@ export class DocksStandardLayout extends DocksContainer {
30
38
  @property({type: Boolean, attribute: 'show-aux-sidebar'})
31
39
  showAuxSidebar: boolean = true;
32
40
 
41
+ @property({type: Boolean, attribute: 'show-right-aux'})
42
+ showRightAux: boolean = false;
43
+
44
+ private panelsInitialized = false;
45
+
33
46
  createRenderRoot() {
34
47
  return this;
35
48
  }
36
49
 
50
+ getPanelVisibility(): LayoutPanelVisibility {
51
+ return {
52
+ showLeftSidebar: this.showLeftSidebar,
53
+ showAuxSidebar: this.showAuxSidebar,
54
+ showBottomPanel: this.showBottomPanel,
55
+ showLeftAux: this.showLeftAux,
56
+ showRightAux: this.showRightAux,
57
+ };
58
+ }
59
+
60
+ private applyPanelVisibility(panels: LayoutPanelVisibility): void {
61
+ this.showLeftSidebar = panels.showLeftSidebar;
62
+ this.showAuxSidebar = panels.showAuxSidebar;
63
+ this.showBottomPanel = panels.showBottomPanel;
64
+ this.showLeftAux = panels.showLeftAux;
65
+ this.showRightAux = panels.showRightAux;
66
+ }
67
+
68
+ async setPanelVisibility(panels: Partial<LayoutPanelVisibility>): Promise<void> {
69
+ const next = { ...this.getPanelVisibility(), ...panels };
70
+ this.applyPanelVisibility(next);
71
+ try {
72
+ await appSettings.set(LAYOUT_PANEL_SETTINGS_KEY, next);
73
+ } catch (error) {
74
+ console.error('Failed to persist layout panel visibility:', error);
75
+ throw error;
76
+ }
77
+ window.dispatchEvent(new CustomEvent('layout-panels-changed', {
78
+ detail: { panels: this.getPanelVisibility() },
79
+ }));
80
+ }
81
+
82
+ protected doInitUI() {
83
+ void this.initializePanelVisibility();
84
+ }
85
+
86
+ private async initializePanelVisibility(): Promise<void> {
87
+ if (this.panelsInitialized) {
88
+ return;
89
+ }
90
+ this.panelsInitialized = true;
91
+
92
+ const appLayout = appLoaderService.getCurrentApp()?.layout;
93
+ const panels = await resolveStoredPanelVisibility(appLayout);
94
+ this.applyPanelVisibility(panels);
95
+ window.dispatchEvent(new CustomEvent('layout-panels-changed', {
96
+ detail: { panels: this.getPanelVisibility() },
97
+ }));
98
+ }
99
+
37
100
  private getGridSizes(): string {
38
101
  if (this.showLeftSidebar && this.showAuxSidebar) {
39
102
  return "20%, 60%, 20%";
@@ -133,7 +196,7 @@ export class DocksStandardLayout extends DocksContainer {
133
196
 
134
197
  ${this.showLeftSidebar
135
198
  ? html`
136
- ${this.showBottomSidebar
199
+ ${this.showLeftAux
137
200
  ? html`
138
201
  <docks-resizable-grid
139
202
  id="left-sidebar-split"
@@ -163,7 +226,20 @@ export class DocksStandardLayout extends DocksContainer {
163
226
  }
164
227
 
165
228
  ${this.showAuxSidebar
166
- ? html`<docks-tabs id="${SIDEBAR_AUXILIARY}"></docks-tabs>`
229
+ ? html`
230
+ ${this.showRightAux
231
+ ? html`
232
+ <docks-resizable-grid
233
+ id="right-sidebar-split"
234
+ orientation="vertical"
235
+ sizes="50%, 50%">
236
+ <docks-tabs id="${SIDEBAR_AUXILIARY}"></docks-tabs>
237
+ <docks-tabs id="${SIDEBAR_AUXILIARY_BOTTOM}" placement="start" icon-only></docks-tabs>
238
+ </docks-resizable-grid>
239
+ `
240
+ : html`<docks-tabs id="${SIDEBAR_AUXILIARY}"></docks-tabs>`
241
+ }
242
+ `
167
243
  : nothing
168
244
  }
169
245
  </docks-resizable-grid>