@memberjunction/ng-dashboard-viewer 6.2.0-edge.2 → 6.2.0-edge.4
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/README.md +165 -17
- package/dist/lib/config-dialogs/confirm-dialog.component.d.ts +3 -4
- package/dist/lib/config-dialogs/confirm-dialog.component.d.ts.map +1 -1
- package/dist/lib/config-dialogs/confirm-dialog.component.js +3 -2
- package/dist/lib/config-dialogs/confirm-dialog.component.js.map +1 -1
- package/dist/lib/config-panels/artifact-config-panel.component.d.ts.map +1 -1
- package/dist/lib/config-panels/artifact-config-panel.component.js +59 -50
- package/dist/lib/config-panels/artifact-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/base-config-panel.d.ts +8 -3
- package/dist/lib/config-panels/base-config-panel.d.ts.map +1 -1
- package/dist/lib/config-panels/base-config-panel.js +10 -3
- package/dist/lib/config-panels/base-config-panel.js.map +1 -1
- package/dist/lib/config-panels/query-config-panel.component.js +124 -99
- package/dist/lib/config-panels/query-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/view-config-panel.component.js +111 -103
- package/dist/lib/config-panels/view-config-panel.component.js.map +1 -1
- package/dist/lib/config-panels/weburl-config-panel.component.js +89 -80
- package/dist/lib/config-panels/weburl-config-panel.component.js.map +1 -1
- package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts +79 -28
- package/dist/lib/dashboard-browser/dashboard-browser.component.d.ts.map +1 -1
- package/dist/lib/dashboard-browser/dashboard-browser.component.js +446 -447
- package/dist/lib/dashboard-browser/dashboard-browser.component.js.map +1 -1
- package/dist/lib/dashboard-card/dashboard-card.component.d.ts +69 -0
- package/dist/lib/dashboard-card/dashboard-card.component.d.ts.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.component.js +281 -0
- package/dist/lib/dashboard-card/dashboard-card.component.js.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts +18 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.d.ts.map +1 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.js +43 -0
- package/dist/lib/dashboard-card/dashboard-card.helpers.js.map +1 -0
- package/dist/lib/dashboard-card/layout-preview-cache.d.ts +15 -0
- package/dist/lib/dashboard-card/layout-preview-cache.d.ts.map +1 -0
- package/dist/lib/dashboard-card/layout-preview-cache.js +22 -0
- package/dist/lib/dashboard-card/layout-preview-cache.js.map +1 -0
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts +69 -12
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.d.ts.map +1 -1
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.js +173 -145
- package/dist/lib/dashboard-viewer/dashboard-viewer.component.js.map +1 -1
- package/dist/lib/dashboard-viewer.module.d.ts +24 -20
- package/dist/lib/dashboard-viewer.module.d.ts.map +1 -1
- package/dist/lib/dashboard-viewer.module.js +42 -5
- package/dist/lib/dashboard-viewer.module.js.map +1 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts +7 -12
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.d.ts.map +1 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js +3 -1
- package/dist/lib/dialogs/add-panel-dialog/add-panel-dialog.component.js.map +1 -1
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts +54 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.d.ts.map +1 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js +156 -0
- package/dist/lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component.js.map +1 -0
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts +5 -11
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.d.ts.map +1 -1
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js +3 -1
- package/dist/lib/dialogs/edit-part-dialog/edit-part-dialog.component.js.map +1 -1
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts +147 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.d.ts.map +1 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js +536 -0
- package/dist/lib/dialogs/part-dialog/dashboard-part-dialog.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts +20 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js +80 -0
- package/dist/lib/layout-preview/dashboard-layout-preview-node.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts +28 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.js +62 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.component.js.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.d.ts +33 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.d.ts.map +1 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.js +138 -0
- package/dist/lib/layout-preview/dashboard-layout-preview.js.map +1 -0
- package/dist/lib/models/dashboard-layout-editor.d.ts +78 -0
- package/dist/lib/models/dashboard-layout-editor.d.ts.map +1 -0
- package/dist/lib/models/dashboard-layout-editor.js +374 -0
- package/dist/lib/models/dashboard-layout-editor.js.map +1 -0
- package/dist/lib/models/remove-part-confirm.d.ts +8 -0
- package/dist/lib/models/remove-part-confirm.d.ts.map +1 -0
- package/dist/lib/models/remove-part-confirm.js +23 -0
- package/dist/lib/models/remove-part-confirm.js.map +1 -0
- package/dist/lib/parts/artifact-part.component.js +2 -2
- package/dist/lib/parts/artifact-part.component.js.map +1 -1
- package/dist/lib/parts/query-part.component.js +2 -2
- package/dist/lib/parts/query-part.component.js.map +1 -1
- package/dist/lib/parts/view-part.component.js +2 -2
- package/dist/lib/parts/view-part.component.js.map +1 -1
- package/dist/lib/parts/weburl-part.component.js +2 -2
- package/dist/lib/parts/weburl-part.component.js.map +1 -1
- package/dist/lib/services/golden-layout-wrapper.service.d.ts +40 -0
- package/dist/lib/services/golden-layout-wrapper.service.d.ts.map +1 -1
- package/dist/lib/services/golden-layout-wrapper.service.js +117 -9
- package/dist/lib/services/golden-layout-wrapper.service.js.map +1 -1
- package/dist/lib/services/stack-part-actions.d.ts +11 -0
- package/dist/lib/services/stack-part-actions.d.ts.map +1 -0
- package/dist/lib/services/stack-part-actions.js +41 -0
- package/dist/lib/services/stack-part-actions.js.map +1 -0
- package/dist/public-api.d.ts +9 -0
- package/dist/public-api.d.ts.map +1 -1
- package/dist/public-api.js +13 -0
- package/dist/public-api.js.map +1 -1
- package/package.json +13 -13
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
2
|
import { Subject, BehaviorSubject } from 'rxjs';
|
|
3
3
|
import { LayoutConfig, VirtualLayout } from 'golden-layout';
|
|
4
|
+
import { BuildStackPartActions, LabelStackPartActions, STACK_PART_ACTIONS_CLASS } from './stack-part-actions';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
6
|
+
/** The height of a stack header (part tabs and part buttons), in pixels. The viewer CSS uses the same value. */
|
|
7
|
+
export const DASHBOARD_STACK_HEADER_HEIGHT = 44;
|
|
8
|
+
/** Room Golden Layout keeps beside a stack's tabs, in pixels: the tab track's inset, borders and padding, the tab dropdown button with its gaps, and the controls' inset. The viewer CSS uses the same values. */
|
|
9
|
+
export const DASHBOARD_TAB_CONTROL_OFFSET = 78;
|
|
5
10
|
/**
|
|
6
11
|
* Service that wraps Golden Layout for Angular integration.
|
|
7
12
|
* Uses Golden Layout 2.6.0 VirtualLayout API.
|
|
@@ -58,6 +63,8 @@ export class GoldenLayoutWrapperService {
|
|
|
58
63
|
set onPanelSelected(value) {
|
|
59
64
|
this.OnPanelSelected = value;
|
|
60
65
|
}
|
|
66
|
+
/** Emitted when the user clicks Edit part or Remove in a stack header. Edit mode only. */
|
|
67
|
+
OnStackAction = new Subject();
|
|
61
68
|
/** Current panels in layout */
|
|
62
69
|
Panels$ = new BehaviorSubject([]);
|
|
63
70
|
/** @deprecated Use {@link Panels$}. */
|
|
@@ -97,13 +104,16 @@ export class GoldenLayoutWrapperService {
|
|
|
97
104
|
this._layout.on('stateChanged', () => {
|
|
98
105
|
this.emitLayoutChanged('resize');
|
|
99
106
|
});
|
|
107
|
+
// Wire each stack and tab as Golden Layout creates it; loadLayout creates the first ones
|
|
108
|
+
this._layout.on('itemCreated', (event) => this.onItemCreated(event));
|
|
109
|
+
this._layout.on('tabCreated', (tab) => this.onTabCreated(tab));
|
|
100
110
|
// Build the LayoutConfig to load
|
|
101
111
|
const glConfig = this.buildLayoutConfig(savedLayout);
|
|
102
112
|
// Load the layout configuration
|
|
103
113
|
this._layout.loadLayout(glConfig);
|
|
104
114
|
// Set the size of Golden Layout to match the container
|
|
105
|
-
const
|
|
106
|
-
this._layout.setSize(
|
|
115
|
+
const size = this.containerLayoutSize(container);
|
|
116
|
+
this._layout.setSize(size.width, size.height);
|
|
107
117
|
this._initialized = true;
|
|
108
118
|
this.updatePanelsList();
|
|
109
119
|
}
|
|
@@ -117,16 +127,22 @@ export class GoldenLayoutWrapperService {
|
|
|
117
127
|
* then applies current edit mode settings.
|
|
118
128
|
*/
|
|
119
129
|
buildLayoutConfig(savedLayout) {
|
|
120
|
-
// Base settings
|
|
121
|
-
//
|
|
130
|
+
// Base settings: tabs can be dragged only in edit mode, stack headers have room for the part buttons,
|
|
131
|
+
// and Golden Layout counts the spacing the viewer CSS adds beside the tabs
|
|
122
132
|
const baseSettings = {
|
|
123
133
|
settings: {
|
|
124
|
-
reorderEnabled: this._isEditing
|
|
134
|
+
reorderEnabled: this._isEditing,
|
|
135
|
+
tabControlOffset: DASHBOARD_TAB_CONTROL_OFFSET
|
|
136
|
+
},
|
|
137
|
+
dimensions: {
|
|
138
|
+
headerHeight: DASHBOARD_STACK_HEADER_HEIGHT
|
|
125
139
|
},
|
|
126
140
|
header: {
|
|
127
141
|
show: 'top',
|
|
128
142
|
popout: false,
|
|
129
143
|
maximise: false,
|
|
144
|
+
// Truthy in edit mode: GL cancels a drag of the only tab of a stack whose header cannot close.
|
|
145
|
+
// The viewer CSS hides the stack close button.
|
|
130
146
|
close: this._isEditing ? 'tab' : false
|
|
131
147
|
},
|
|
132
148
|
root: undefined
|
|
@@ -148,6 +164,10 @@ export class GoldenLayoutWrapperService {
|
|
|
148
164
|
...convertedConfig.settings,
|
|
149
165
|
...baseSettings.settings
|
|
150
166
|
},
|
|
167
|
+
dimensions: {
|
|
168
|
+
...convertedConfig.dimensions,
|
|
169
|
+
...baseSettings.dimensions
|
|
170
|
+
},
|
|
151
171
|
header: {
|
|
152
172
|
...convertedConfig.header,
|
|
153
173
|
...baseSettings.header
|
|
@@ -204,12 +224,20 @@ export class GoldenLayoutWrapperService {
|
|
|
204
224
|
*/
|
|
205
225
|
UpdateSize() {
|
|
206
226
|
if (this._layout && this._containerElement) {
|
|
207
|
-
const
|
|
208
|
-
if (
|
|
209
|
-
this._layout.setSize(
|
|
227
|
+
const size = this.containerLayoutSize(this._containerElement);
|
|
228
|
+
if (size.width > 0 && size.height > 0) {
|
|
229
|
+
this._layout.setSize(size.width, size.height);
|
|
210
230
|
}
|
|
211
231
|
}
|
|
212
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* The container's layout size (offsetWidth / offsetHeight). Golden Layout lays out in this size
|
|
235
|
+
* and reads it itself when it resizes with the container. It differs from the on-screen size
|
|
236
|
+
* (getBoundingClientRect) when a host scales the viewer, for example with a CSS transform.
|
|
237
|
+
*/
|
|
238
|
+
containerLayoutSize(container) {
|
|
239
|
+
return { width: container.offsetWidth, height: container.offsetHeight };
|
|
240
|
+
}
|
|
213
241
|
/** @deprecated Use {@link UpdateSize}. */
|
|
214
242
|
updateSize() {
|
|
215
243
|
return this.UpdateSize();
|
|
@@ -231,6 +259,8 @@ export class GoldenLayoutWrapperService {
|
|
|
231
259
|
wrapper.innerHTML = '<div class="panel-error">No panel ID provided</div>';
|
|
232
260
|
}
|
|
233
261
|
else {
|
|
262
|
+
// A host finds and measures a panel's content by this attribute
|
|
263
|
+
wrapper.dataset['panelId'] = panel.id;
|
|
234
264
|
// Store reference to container
|
|
235
265
|
this._containerMap.set(panel.id, container);
|
|
236
266
|
// Set the tab title (plain text - GL escapes HTML)
|
|
@@ -285,6 +315,80 @@ export class GoldenLayoutWrapperService {
|
|
|
285
315
|
unbindComponentEventListener(_container) {
|
|
286
316
|
// Cleanup handled in beforeComponentRelease
|
|
287
317
|
}
|
|
318
|
+
/**
|
|
319
|
+
* Wires each stack Golden Layout creates: on load, on add, and when a dragged tab makes a new stack.
|
|
320
|
+
* Every stack gets tab list ARIA; in edit mode it also gets the part buttons.
|
|
321
|
+
*/
|
|
322
|
+
onItemCreated(event) {
|
|
323
|
+
const item = event.target;
|
|
324
|
+
if (!isStack(item))
|
|
325
|
+
return;
|
|
326
|
+
this.addTabListAria(item);
|
|
327
|
+
if (this._isEditing) {
|
|
328
|
+
this.addStackActions(item);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Marks the stack header's tab list as a tablist, and the tab dropdown list too (Golden Layout moves the
|
|
333
|
+
* tabs that do not fit there). Keeps aria-selected on each tab in step with the stack's active tab.
|
|
334
|
+
*/
|
|
335
|
+
addTabListAria(stack) {
|
|
336
|
+
const header = stack.header;
|
|
337
|
+
if (header.tabsContainerElement.getAttribute('role') === 'tablist')
|
|
338
|
+
return;
|
|
339
|
+
header.tabsContainerElement.setAttribute('role', 'tablist');
|
|
340
|
+
header.element.querySelector('.lm_tabdropdown_list')?.setAttribute('role', 'tablist');
|
|
341
|
+
const markSelected = () => {
|
|
342
|
+
for (const tab of header.tabs) {
|
|
343
|
+
tab.element.setAttribute('aria-selected', String(tab.isActive));
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
stack.on('activeContentItemChanged', markSelected);
|
|
347
|
+
markSelected();
|
|
348
|
+
}
|
|
349
|
+
/** Adds Edit part and Remove to the stack header. They act on the stack's active tab at click time. */
|
|
350
|
+
addStackActions(stack) {
|
|
351
|
+
const controls = stack.header.controlsContainerElement;
|
|
352
|
+
if (controls.querySelector(`.${STACK_PART_ACTIONS_CLASS}`))
|
|
353
|
+
return;
|
|
354
|
+
const group = BuildStackPartActions(action => this.emitStackAction(stack, action));
|
|
355
|
+
controls.appendChild(group);
|
|
356
|
+
const relabel = () => LabelStackPartActions(group, stack.getActiveComponentItem()?.title ?? '');
|
|
357
|
+
stack.on('activeContentItemChanged', relabel);
|
|
358
|
+
relabel();
|
|
359
|
+
}
|
|
360
|
+
/** Emits the action for the panel in the stack's active tab. Does nothing when the active tab has no panel. */
|
|
361
|
+
emitStackAction(stack, action) {
|
|
362
|
+
const container = stack.getActiveComponentItem()?.container;
|
|
363
|
+
const panelId = container ? this.panelIdOf(container) : null;
|
|
364
|
+
if (panelId) {
|
|
365
|
+
this.OnStackAction.next({ Action: action, PanelId: panelId });
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
/** The ID of the panel bound to a component container, or null. */
|
|
369
|
+
panelIdOf(container) {
|
|
370
|
+
for (const [panelId, bound] of this._containerMap) {
|
|
371
|
+
if (bound === container)
|
|
372
|
+
return panelId;
|
|
373
|
+
}
|
|
374
|
+
return null;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Allows tab dragging only in edit mode (a saved part's own reorderEnabled would allow it in view mode),
|
|
378
|
+
* and makes the tab reachable from the keyboard.
|
|
379
|
+
*/
|
|
380
|
+
onTabCreated(tab) {
|
|
381
|
+
tab.reorderEnabled = this._isEditing;
|
|
382
|
+
const element = tab.element;
|
|
383
|
+
element.setAttribute('role', 'tab');
|
|
384
|
+
element.tabIndex = 0;
|
|
385
|
+
element.addEventListener('keydown', (event) => {
|
|
386
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
387
|
+
event.preventDefault();
|
|
388
|
+
element.click(); // GL's own click handler activates the tab
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
}
|
|
288
392
|
/**
|
|
289
393
|
* Check if Golden Layout is initialized
|
|
290
394
|
*/
|
|
@@ -536,7 +640,7 @@ export class GoldenLayoutWrapperService {
|
|
|
536
640
|
return true;
|
|
537
641
|
// Create icon element and insert at the beginning of tabElement
|
|
538
642
|
// This preserves GL's .lm_title structure for drag/drop
|
|
539
|
-
//
|
|
643
|
+
// The viewer CSS keeps the icon in the tab's flow, before the title
|
|
540
644
|
const iconEl = document.createElement('i');
|
|
541
645
|
iconEl.className = `${normalizedIconClass} panel-icon`;
|
|
542
646
|
// Insert icon as first child of tab element
|
|
@@ -562,4 +666,8 @@ export class GoldenLayoutWrapperService {
|
|
|
562
666
|
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(GoldenLayoutWrapperService, [{
|
|
563
667
|
type: Injectable
|
|
564
668
|
}], null, null); })();
|
|
669
|
+
/** True when the Golden Layout item is a stack. */
|
|
670
|
+
function isStack(item) {
|
|
671
|
+
return 'isStack' in item && item.isStack === true;
|
|
672
|
+
}
|
|
565
673
|
//# sourceMappingURL=golden-layout-wrapper.service.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"golden-layout-wrapper.service.js","sourceRoot":"","sources":["../../../src/lib/services/golden-layout-wrapper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport {\n LayoutConfig,\n ResolvedLayoutConfig,\n ComponentContainer,\n JsonValue,\n ComponentItemConfig,\n VirtualLayout\n} from 'golden-layout';\nimport {\n DashboardPanel,\n LayoutChangedEvent\n} from '../models/dashboard-types';\n\n// Golden Layout interfaces for VirtualLayout\ninterface GLVirtualLayout {\n rootItem: GLLayoutItem | null;\n on(event: string, callback: (item?: unknown) => void): void;\n destroy(): void;\n loadLayout(config: LayoutConfig): void;\n saveLayout(): ResolvedLayoutConfig;\n addItemAtLocation(config: ComponentItemConfig, location: Array<{ typeId: number }>): void;\n addComponent(componentType: string, componentState: Record<string, unknown>, title: string): void;\n setSize(width: number, height: number): void;\n}\n\ninterface GLLayoutItem {\n type: string;\n contentItems?: GLLayoutItem[];\n container?: ComponentContainer;\n addItem(config: ComponentItemConfig): void;\n}\n\n/**\n * Location specifier for adding panels\n */\nexport interface LayoutLocation {\n /** Target panel ID (add next to this panel) */\n targetPanelId?: string;\n /** Position relative to target */\n position?: 'left' | 'right' | 'top' | 'bottom' | 'tab';\n}\n\n/**\n * Panel component factory function type.\n * Receives the full DashboardPanel from GL's componentState (single source of truth).\n */\nexport type PanelComponentFactory = (panel: DashboardPanel, container: HTMLElement) => void;\n\n/**\n * Service that wraps Golden Layout for Angular integration.\n * Uses Golden Layout 2.6.0 VirtualLayout API.\n *\n * DESIGN: This service works with GL's native ResolvedLayoutConfig format.\n * Full DashboardPanel objects are stored in componentState - no conversion needed.\n */\n@Injectable()\nexport class GoldenLayoutWrapperService {\n private _initialized = false;\n private _layout: GLVirtualLayout | null = null;\n private _containerElement: HTMLElement | null = null;\n private _componentFactory: PanelComponentFactory | null = null;\n private _containerMap = new Map<string, ComponentContainer>();\n private _isEditing = false;\n /** Tracks which panels have been lazily loaded (content created) */\n private _loadedPanels = new Set<string>();\n\n /** Emitted when layout configuration changes */\n public OnLayoutChanged = new Subject<LayoutChangedEvent>();\n\n /** @deprecated Use {@link OnLayoutChanged}. */\n public get onLayoutChanged() {\n return this.OnLayoutChanged;\n }\n /** @deprecated Use {@link OnLayoutChanged}. */\n public set onLayoutChanged(value) {\n this.OnLayoutChanged = value;\n }\n\n /** Emitted when a panel is closed */\n public OnPanelClosed = new Subject<string>();\n\n /** @deprecated Use {@link OnPanelClosed}. */\n public get onPanelClosed() {\n return this.OnPanelClosed;\n }\n /** @deprecated Use {@link OnPanelClosed}. */\n public set onPanelClosed(value) {\n this.OnPanelClosed = value;\n }\n\n /** Emitted when a panel is maximized/restored */\n public OnPanelMaximized = new Subject<{ panelId: string; maximized: boolean }>();\n\n /** @deprecated Use {@link OnPanelMaximized}. */\n public get onPanelMaximized() {\n return this.OnPanelMaximized;\n }\n /** @deprecated Use {@link OnPanelMaximized}. */\n public set onPanelMaximized(value) {\n this.OnPanelMaximized = value;\n }\n\n /** Emitted when a panel is selected (in a stack) */\n public OnPanelSelected = new Subject<string>();\n\n /** @deprecated Use {@link OnPanelSelected}. */\n public get onPanelSelected() {\n return this.OnPanelSelected;\n }\n /** @deprecated Use {@link OnPanelSelected}. */\n public set onPanelSelected(value) {\n this.OnPanelSelected = value;\n }\n\n /** Current panels in layout */\n public Panels$ = new BehaviorSubject<string[]>([]);\n\n /** @deprecated Use {@link Panels$}. */\n public get panels$() {\n return this.Panels$;\n }\n /** @deprecated Use {@link Panels$}. */\n public set panels$(value) {\n this.Panels$ = value;\n }\n\n /** Whether layout editing (drag/drop/resize/close) is enabled */\n public get IsEditing(): boolean {\n return this._isEditing;\n }\n\n /** @deprecated Use {@link IsEditing}. */\n public get isEditing(): boolean {\n return this.IsEditing;\n }\n\n /**\n * Initialize Golden Layout in the specified container.\n * @param container The HTML element to render Golden Layout in\n * @param savedLayout Previously saved layout (from saveLayout()) or null for empty\n * @param componentFactory Factory function to create panel content\n * @param isEditing Whether editing (drag/drop/resize/close) is enabled\n */\n public Initialize(\n container: HTMLElement,\n savedLayout: ResolvedLayoutConfig | null,\n componentFactory: PanelComponentFactory,\n isEditing = false\n ): void {\n this._componentFactory = componentFactory;\n this._containerElement = container;\n this._isEditing = isEditing;\n\n // Create VirtualLayout instance with bind/unbind callbacks\n // Cast through unknown: GLVirtualLayout is a subset interface used throughout this service;\n // the structural mismatch with golden-layout's VirtualLayout is intentional.\n this._layout = new VirtualLayout(\n container,\n this.bindComponentEventListener.bind(this) as VirtualLayout.BindComponentEventHandler,\n this.unbindComponentEventListener.bind(this) as VirtualLayout.UnbindComponentEventHandler\n ) as unknown as GLVirtualLayout;\n\n // Enable automatic resize when container size changes\n (this._layout as unknown as { resizeWithContainerAutomatically: boolean }).resizeWithContainerAutomatically = true;\n\n // Subscribe to events\n this._layout.on('stateChanged', () => {\n this.emitLayoutChanged('resize');\n });\n\n // Build the LayoutConfig to load\n const glConfig = this.buildLayoutConfig(savedLayout);\n\n // Load the layout configuration\n this._layout.loadLayout(glConfig);\n\n // Set the size of Golden Layout to match the container\n const rect = container.getBoundingClientRect();\n this._layout.setSize(rect.width, rect.height);\n\n this._initialized = true;\n this.updatePanelsList();\n }\n\n /** @deprecated Use {@link Initialize}. */\n public initialize(\n container: HTMLElement,\n savedLayout: ResolvedLayoutConfig | null,\n componentFactory: PanelComponentFactory,\n isEditing = false\n ): void {\n return this.Initialize(container, savedLayout, componentFactory, isEditing);\n }\n\n /**\n * Build LayoutConfig from saved ResolvedLayoutConfig.\n * Uses GL's LayoutConfig.fromResolved() for proper conversion,\n * then applies current edit mode settings.\n */\n private buildLayoutConfig(savedLayout: ResolvedLayoutConfig | null): LayoutConfig {\n // Base settings - reorderEnabled is always true so users can click tabs and\n // rearrange in view mode (changes won't be saved). Close button only in edit mode.\n const baseSettings: LayoutConfig = {\n settings: {\n reorderEnabled: this._isEditing\n },\n header: {\n show: 'top',\n popout: false,\n maximise: false,\n close: this._isEditing ? 'tab' : false\n },\n root: undefined\n };\n\n // If we have a saved layout, convert it properly using GL's conversion\n if (savedLayout && savedLayout.root) {\n try {\n // Validate the saved layout has required structure\n if (!this.isValidLayoutConfig(savedLayout)) {\n console.warn('[GoldenLayoutWrapper] Invalid saved layout structure, using default');\n return baseSettings;\n }\n\n // Use GL's built-in conversion from ResolvedLayoutConfig to LayoutConfig\n const convertedConfig = LayoutConfig.fromResolved(savedLayout) as LayoutConfig;\n\n // Merge our base settings with the converted config\n return {\n ...convertedConfig,\n settings: {\n ...convertedConfig.settings,\n ...baseSettings.settings\n },\n header: {\n ...convertedConfig.header,\n ...baseSettings.header\n }\n };\n } catch (err) {\n console.error('[GoldenLayoutWrapper] Error converting saved layout, using default:', err);\n // Fall through to return base settings\n }\n }\n\n return baseSettings;\n }\n\n /**\n * Validate that a saved layout config has the required structure for GL conversion.\n * GL's fromResolved() can crash if certain properties are undefined.\n */\n private isValidLayoutConfig(config: ResolvedLayoutConfig): boolean {\n if (!config || !config.root) {\n return false;\n }\n\n // Check that root has a type\n if (!config.root.type) {\n return false;\n }\n\n // Recursively validate content items have required properties\n return this.validateLayoutItem(config.root);\n }\n\n /**\n * Recursively validate a layout item and its children.\n */\n private validateLayoutItem(item: unknown): boolean {\n if (!item || typeof item !== 'object') {\n return false;\n }\n\n const layoutItem = item as Record<string, unknown>;\n\n // Must have a type\n if (!layoutItem['type']) {\n return false;\n }\n\n // If it has content, validate each child\n const content = layoutItem['content'] as unknown[] | undefined;\n if (content && Array.isArray(content)) {\n for (const child of content) {\n if (!this.validateLayoutItem(child)) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Update layout size to match container.\n */\n public UpdateSize(): void {\n if (this._layout && this._containerElement) {\n const rect = this._containerElement.getBoundingClientRect();\n if (rect.width > 0 && rect.height > 0) {\n this._layout.setSize(rect.width, rect.height);\n }\n }\n }\n\n /** @deprecated Use {@link UpdateSize}. */\n public updateSize(): void {\n return this.UpdateSize();\n }\n\n /**\n * Bind component event listener (called by Golden Layout VirtualLayout).\n * The componentState contains the full DashboardPanel object.\n */\n private bindComponentEventListener(\n container: ComponentContainer,\n _itemConfig: { componentState: Record<string, unknown> }\n ): { component: HTMLElement; virtual: boolean } {\n // componentState IS the DashboardPanel\n const panel = container.state as unknown as DashboardPanel;\n\n // Create a wrapper element for our panel content\n const wrapper = document.createElement('div');\n wrapper.className = 'dashboard-panel-content';\n wrapper.style.width = '100%';\n wrapper.style.height = '100%';\n wrapper.style.overflow = 'auto';\n\n if (!panel?.id) {\n wrapper.innerHTML = '<div class=\"panel-error\">No panel ID provided</div>';\n } else {\n // Store reference to container\n this._containerMap.set(panel.id, container);\n\n // Set the tab title (plain text - GL escapes HTML)\n container.setTitle(panel.title);\n\n // Add icon to the tab element via DOM manipulation\n // This must happen after GL has created the tab element\n // Always add an icon - use panel's icon or a default fallback (cube = generic widget)\n // IMPORTANT: We append to tabElement, NOT modify .lm_title, to preserve GL's drag/drop\n const iconClass = panel.icon || 'fa-solid fa-cube';\n this.addIconToTab(container, iconClass);\n\n // LAZY LOADING: Show loading placeholder initially\n // Actual content is created when panel is first shown (visible)\n wrapper.innerHTML = `\n <div class=\"panel-loading\" style=\"display: flex; align-items: center; justify-content: center; height: 100%; color: var(--mj-text-secondary);\">\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"margin-right: 8px;\"></i>\n Loading...\n </div>\n `;\n\n // Listen for close events\n container.on('beforeComponentRelease', () => {\n this._containerMap.delete(panel.id);\n this._loadedPanels.delete(panel.id);\n this.OnPanelClosed.next(panel.id);\n this.updatePanelsList();\n });\n\n // Listen for show/focus events - LAZY LOAD on first show\n container.on('show', () => {\n // Check if this is first time panel is shown\n if (!this._loadedPanels.has(panel.id)) {\n // First show - create actual content\n wrapper.innerHTML = ''; // Clear loading placeholder\n if (this._componentFactory) {\n this._componentFactory(panel, wrapper);\n }\n this._loadedPanels.add(panel.id);\n }\n this.OnPanelSelected.next(panel.id);\n });\n\n this.updatePanelsList();\n }\n\n // Append the wrapper to container.element (.lm_content)\n container.element.appendChild(wrapper);\n\n // Return the bindable component object\n return {\n component: wrapper,\n virtual: false\n };\n }\n\n /**\n * Unbind component event listener (called by Golden Layout VirtualLayout)\n */\n private unbindComponentEventListener(_container: ComponentContainer): void {\n // Cleanup handled in beforeComponentRelease\n }\n\n /**\n * Check if Golden Layout is initialized\n */\n public IsInitialized(): boolean {\n return this._initialized;\n }\n\n /** @deprecated Use {@link IsInitialized}. */\n public isInitialized(): boolean {\n return this.IsInitialized();\n }\n\n /**\n * Destroy Golden Layout and clean up\n */\n public Destroy(): void {\n if (this._layout) {\n this._layout.destroy();\n this._layout = null;\n }\n\n this._containerMap.clear();\n this._loadedPanels.clear();\n this._initialized = false;\n this._componentFactory = null;\n this._containerElement = null;\n }\n\n /** @deprecated Use {@link Destroy}. */\n public destroy(): void {\n return this.Destroy();\n }\n\n /**\n * Add a panel to the layout.\n * The full DashboardPanel is stored in componentState.\n */\n public AddPanel(panel: DashboardPanel, _location?: LayoutLocation): void {\n if (!this._layout) {\n return;\n }\n\n // Try to add to existing stack first, otherwise create new\n const existingStack = this.findFirstStack();\n if (existingStack) {\n const componentConfig: ComponentItemConfig = {\n type: 'component',\n componentType: 'dashboard-panel',\n componentState: panel as unknown as JsonValue,\n title: panel.title,\n isClosable: true\n };\n existingStack.addItem(componentConfig);\n } else {\n // Use addComponent which will create a stack\n this._layout.addComponent(\n 'dashboard-panel',\n panel as unknown as Record<string, unknown>,\n panel.title\n );\n }\n\n this.emitLayoutChanged('resize');\n }\n\n /** @deprecated Use {@link AddPanel}. */\n public addPanel(panel: DashboardPanel, _location?: LayoutLocation): void {\n return this.AddPanel(panel, _location);\n }\n\n /**\n * Find first stack in layout\n */\n private findFirstStack(): GLLayoutItem | null {\n if (!this._layout || !this._layout.rootItem) return null;\n\n const findStack = (item: GLLayoutItem): GLLayoutItem | null => {\n if (item.type === 'stack') {\n return item;\n }\n if (item.contentItems) {\n for (const child of item.contentItems) {\n const found = findStack(child);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findStack(this._layout.rootItem);\n }\n\n /**\n * Remove a panel from the layout\n */\n public RemovePanel(panelId: string): void {\n const container = this._containerMap.get(panelId);\n if (container) {\n container.close();\n }\n }\n\n /** @deprecated Use {@link RemovePanel}. */\n public removePanel(panelId: string): void {\n return this.RemovePanel(panelId);\n }\n\n /**\n * Split a panel horizontally (add panel to the right)\n */\n public SplitHorizontal(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'right' });\n }\n\n /** @deprecated Use {@link SplitHorizontal}. */\n public splitHorizontal(panelId: string, newPanel: DashboardPanel): void {\n return this.SplitHorizontal(panelId, newPanel);\n }\n\n /**\n * Split a panel vertically (add panel below)\n */\n public SplitVertical(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'bottom' });\n }\n\n /** @deprecated Use {@link SplitVertical}. */\n public splitVertical(panelId: string, newPanel: DashboardPanel): void {\n return this.SplitVertical(panelId, newPanel);\n }\n\n /**\n * Add a panel as a tab to an existing stack\n */\n public AddToStack(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'tab' });\n }\n\n /** @deprecated Use {@link AddToStack}. */\n public addToStack(panelId: string, newPanel: DashboardPanel): void {\n return this.AddToStack(panelId, newPanel);\n }\n\n /**\n * Maximize a panel\n */\n public MaximizePanel(panelId: string): void {\n this.OnPanelMaximized.next({ panelId, maximized: true });\n }\n\n /** @deprecated Use {@link MaximizePanel}. */\n public maximizePanel(panelId: string): void {\n return this.MaximizePanel(panelId);\n }\n\n /**\n * Restore a maximized panel\n */\n public RestorePanel(panelId: string): void {\n this.OnPanelMaximized.next({ panelId, maximized: false });\n }\n\n /** @deprecated Use {@link RestorePanel}. */\n public restorePanel(panelId: string): void {\n return this.RestorePanel(panelId);\n }\n\n /**\n * Focus a panel by ID\n */\n public FocusPanel(panelId: string): void {\n const container = this._containerMap.get(panelId);\n if (container) {\n container.focus();\n }\n }\n\n /** @deprecated Use {@link FocusPanel}. */\n public focusPanel(panelId: string): void {\n return this.FocusPanel(panelId);\n }\n\n /**\n * Get the current layout configuration.\n * Returns GL's native ResolvedLayoutConfig - no conversion.\n */\n public GetLayoutConfig(): ResolvedLayoutConfig | null {\n if (!this._layout) return null;\n\n try {\n return this._layout.saveLayout();\n } catch (error) {\n console.error('[GLWrapper] Failed to save layout:', error);\n return null;\n }\n }\n\n /** @deprecated Use {@link GetLayoutConfig}. */\n public getLayoutConfig(): ResolvedLayoutConfig | null {\n return this.GetLayoutConfig();\n }\n\n /**\n * Get the container element for a panel\n */\n public GetPanelContainer(panelId: string): HTMLElement | null {\n const container = this._containerMap.get(panelId);\n return container?.element || null;\n }\n\n /** @deprecated Use {@link GetPanelContainer}. */\n public getPanelContainer(panelId: string): HTMLElement | null {\n return this.GetPanelContainer(panelId);\n }\n\n /**\n * Get all panel IDs in the current layout\n */\n public GetPanelIds(): string[] {\n return Array.from(this._containerMap.keys());\n }\n\n /** @deprecated Use {@link GetPanelIds}. */\n public getPanelIds(): string[] {\n return this.GetPanelIds();\n }\n\n /**\n * Set editing mode.\n * Note: Golden Layout 2 doesn't support changing settings after initialization.\n * The layout must be reinitialized to apply new settings.\n */\n public SetEditingMode(isEditing: boolean): void {\n this._isEditing = isEditing;\n }\n\n /** @deprecated Use {@link SetEditingMode}. */\n public setEditingMode(isEditing: boolean): void {\n return this.SetEditingMode(isEditing);\n }\n\n private updatePanelsList(): void {\n this.Panels$.next(Array.from(this._containerMap.keys()));\n }\n\n private emitLayoutChanged(changeType: LayoutChangedEvent['changeType']): void {\n const layoutConfig = this.GetLayoutConfig();\n if (layoutConfig) {\n this.OnLayoutChanged.next({\n layout: layoutConfig,\n changeType\n });\n }\n }\n\n /**\n * Add an icon to a tab element via DOM manipulation.\n * IMPORTANT: We append to tabElement, NOT modify .lm_title, to preserve GL's drag/drop.\n * This follows the same pattern as the shell's GoldenLayoutManager.\n */\n private addIconToTab(container: ComponentContainer, iconClass: string): void {\n // Normalize the icon class - ensure it has the Font Awesome prefix\n let normalizedIconClass = iconClass.trim();\n if (!normalizedIconClass.includes('fa-') && !normalizedIconClass.includes('fa ')) {\n // If no FA prefix, assume it's a Font Awesome icon name and add fa-solid prefix\n normalizedIconClass = `fa-solid fa-${normalizedIconClass}`;\n } else if (!normalizedIconClass.startsWith('fa-') && !normalizedIconClass.startsWith('fa ')) {\n // Has fa- in it but not at the start - likely just the icon name like \"globe\"\n // Check if it's missing the style prefix (fa-solid, fa-regular, etc.)\n if (!normalizedIconClass.match(/^fa[srldb]?\\s/) && !normalizedIconClass.match(/^fa-(solid|regular|light|duotone|brands)\\s/)) {\n normalizedIconClass = `fa-solid ${normalizedIconClass}`;\n }\n }\n\n // Try immediately, then retry with delay if tab not ready\n const tryAddIcon = (): boolean => {\n const tab = container.tab;\n if (!tab) return false;\n\n const tabElement = tab.element as HTMLElement;\n if (!tabElement) return false;\n\n // Check if icon already added to tab element\n if (tabElement.querySelector('.panel-icon')) return true;\n\n // Create icon element and insert at the beginning of tabElement\n // This preserves GL's .lm_title structure for drag/drop\n // Icon is positioned absolutely via CSS in the left padding area\n const iconEl = document.createElement('i');\n iconEl.className = `${normalizedIconClass} panel-icon`;\n\n // Insert icon as first child of tab element\n tabElement.insertBefore(iconEl, tabElement.firstChild);\n return true;\n };\n\n // Try immediately\n if (tryAddIcon()) return;\n\n // Tab may not be created yet - try again after a delay\n setTimeout(() => {\n if (tryAddIcon()) return;\n\n // Still not ready - try one more time with longer delay\n setTimeout(() => {\n tryAddIcon();\n }, 100);\n }, 50);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"golden-layout-wrapper.service.js","sourceRoot":"","sources":["../../../src/lib/services/golden-layout-wrapper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport {\n LayoutConfig,\n ResolvedLayoutConfig,\n JsonValue,\n ComponentItemConfig,\n VirtualLayout\n} from 'golden-layout';\nimport type { ComponentContainer, EventEmitter, Stack, Tab } from 'golden-layout';\nimport {\n DashboardPanel,\n LayoutChangedEvent\n} from '../models/dashboard-types';\nimport { BuildStackPartActions, LabelStackPartActions, STACK_PART_ACTIONS_CLASS } from './stack-part-actions';\n\n// Golden Layout interfaces for VirtualLayout\ninterface GLVirtualLayout {\n rootItem: GLLayoutItem | null;\n on(event: 'itemCreated', callback: (event: EventEmitter.BubblingEvent) => void): void;\n on(event: 'tabCreated', callback: (tab: Tab) => void): void;\n on(event: string, callback: (item?: unknown) => void): void;\n destroy(): void;\n loadLayout(config: LayoutConfig): void;\n saveLayout(): ResolvedLayoutConfig;\n addItemAtLocation(config: ComponentItemConfig, location: Array<{ typeId: number }>): void;\n addComponent(componentType: string, componentState: Record<string, unknown>, title: string): void;\n setSize(width: number, height: number): void;\n}\n\ninterface GLLayoutItem {\n type: string;\n contentItems?: GLLayoutItem[];\n container?: ComponentContainer;\n addItem(config: ComponentItemConfig): void;\n}\n\n/**\n * Location specifier for adding panels\n */\nexport interface LayoutLocation {\n /** Target panel ID (add next to this panel) */\n targetPanelId?: string;\n /** Position relative to target */\n position?: 'left' | 'right' | 'top' | 'bottom' | 'tab';\n}\n\n/**\n * Panel component factory function type.\n * Receives the full DashboardPanel from GL's componentState (single source of truth).\n */\nexport type PanelComponentFactory = (panel: DashboardPanel, container: HTMLElement) => void;\n\n/** What a part button in a stack header asks for. */\nexport type StackAction = 'edit' | 'remove';\n\n/** A click on a stack header's part button: the action, and the panel in the stack's active tab. */\nexport interface StackActionEvent {\n Action: StackAction;\n PanelId: string;\n}\n\n/** The height of a stack header (part tabs and part buttons), in pixels. The viewer CSS uses the same value. */\nexport const DASHBOARD_STACK_HEADER_HEIGHT = 44;\n\n/** Room Golden Layout keeps beside a stack's tabs, in pixels: the tab track's inset, borders and padding, the tab dropdown button with its gaps, and the controls' inset. The viewer CSS uses the same values. */\nexport const DASHBOARD_TAB_CONTROL_OFFSET = 78;\n\n/**\n * Service that wraps Golden Layout for Angular integration.\n * Uses Golden Layout 2.6.0 VirtualLayout API.\n *\n * DESIGN: This service works with GL's native ResolvedLayoutConfig format.\n * Full DashboardPanel objects are stored in componentState - no conversion needed.\n */\n@Injectable()\nexport class GoldenLayoutWrapperService {\n private _initialized = false;\n private _layout: GLVirtualLayout | null = null;\n private _containerElement: HTMLElement | null = null;\n private _componentFactory: PanelComponentFactory | null = null;\n private _containerMap = new Map<string, ComponentContainer>();\n private _isEditing = false;\n /** Tracks which panels have been lazily loaded (content created) */\n private _loadedPanels = new Set<string>();\n\n /** Emitted when layout configuration changes */\n public OnLayoutChanged = new Subject<LayoutChangedEvent>();\n\n /** @deprecated Use {@link OnLayoutChanged}. */\n public get onLayoutChanged() {\n return this.OnLayoutChanged;\n }\n /** @deprecated Use {@link OnLayoutChanged}. */\n public set onLayoutChanged(value) {\n this.OnLayoutChanged = value;\n }\n\n /** Emitted when a panel is closed */\n public OnPanelClosed = new Subject<string>();\n\n /** @deprecated Use {@link OnPanelClosed}. */\n public get onPanelClosed() {\n return this.OnPanelClosed;\n }\n /** @deprecated Use {@link OnPanelClosed}. */\n public set onPanelClosed(value) {\n this.OnPanelClosed = value;\n }\n\n /** Emitted when a panel is maximized/restored */\n public OnPanelMaximized = new Subject<{ panelId: string; maximized: boolean }>();\n\n /** @deprecated Use {@link OnPanelMaximized}. */\n public get onPanelMaximized() {\n return this.OnPanelMaximized;\n }\n /** @deprecated Use {@link OnPanelMaximized}. */\n public set onPanelMaximized(value) {\n this.OnPanelMaximized = value;\n }\n\n /** Emitted when a panel is selected (in a stack) */\n public OnPanelSelected = new Subject<string>();\n\n /** @deprecated Use {@link OnPanelSelected}. */\n public get onPanelSelected() {\n return this.OnPanelSelected;\n }\n /** @deprecated Use {@link OnPanelSelected}. */\n public set onPanelSelected(value) {\n this.OnPanelSelected = value;\n }\n\n /** Emitted when the user clicks Edit part or Remove in a stack header. Edit mode only. */\n public OnStackAction = new Subject<StackActionEvent>();\n\n /** Current panels in layout */\n public Panels$ = new BehaviorSubject<string[]>([]);\n\n /** @deprecated Use {@link Panels$}. */\n public get panels$() {\n return this.Panels$;\n }\n /** @deprecated Use {@link Panels$}. */\n public set panels$(value) {\n this.Panels$ = value;\n }\n\n /** Whether layout editing (drag/drop/resize/close) is enabled */\n public get IsEditing(): boolean {\n return this._isEditing;\n }\n\n /** @deprecated Use {@link IsEditing}. */\n public get isEditing(): boolean {\n return this.IsEditing;\n }\n\n /**\n * Initialize Golden Layout in the specified container.\n * @param container The HTML element to render Golden Layout in\n * @param savedLayout Previously saved layout (from saveLayout()) or null for empty\n * @param componentFactory Factory function to create panel content\n * @param isEditing Whether editing (drag/drop/resize/close) is enabled\n */\n public Initialize(\n container: HTMLElement,\n savedLayout: ResolvedLayoutConfig | null,\n componentFactory: PanelComponentFactory,\n isEditing = false\n ): void {\n this._componentFactory = componentFactory;\n this._containerElement = container;\n this._isEditing = isEditing;\n\n // Create VirtualLayout instance with bind/unbind callbacks\n // Cast through unknown: GLVirtualLayout is a subset interface used throughout this service;\n // the structural mismatch with golden-layout's VirtualLayout is intentional.\n this._layout = new VirtualLayout(\n container,\n this.bindComponentEventListener.bind(this) as VirtualLayout.BindComponentEventHandler,\n this.unbindComponentEventListener.bind(this) as VirtualLayout.UnbindComponentEventHandler\n ) as unknown as GLVirtualLayout;\n\n // Enable automatic resize when container size changes\n (this._layout as unknown as { resizeWithContainerAutomatically: boolean }).resizeWithContainerAutomatically = true;\n\n // Subscribe to events\n this._layout.on('stateChanged', () => {\n this.emitLayoutChanged('resize');\n });\n\n // Wire each stack and tab as Golden Layout creates it; loadLayout creates the first ones\n this._layout.on('itemCreated', (event: EventEmitter.BubblingEvent) => this.onItemCreated(event));\n this._layout.on('tabCreated', (tab: Tab) => this.onTabCreated(tab));\n\n // Build the LayoutConfig to load\n const glConfig = this.buildLayoutConfig(savedLayout);\n\n // Load the layout configuration\n this._layout.loadLayout(glConfig);\n\n // Set the size of Golden Layout to match the container\n const size = this.containerLayoutSize(container);\n this._layout.setSize(size.width, size.height);\n\n this._initialized = true;\n this.updatePanelsList();\n }\n\n /** @deprecated Use {@link Initialize}. */\n public initialize(\n container: HTMLElement,\n savedLayout: ResolvedLayoutConfig | null,\n componentFactory: PanelComponentFactory,\n isEditing = false\n ): void {\n return this.Initialize(container, savedLayout, componentFactory, isEditing);\n }\n\n /**\n * Build LayoutConfig from saved ResolvedLayoutConfig.\n * Uses GL's LayoutConfig.fromResolved() for proper conversion,\n * then applies current edit mode settings.\n */\n private buildLayoutConfig(savedLayout: ResolvedLayoutConfig | null): LayoutConfig {\n // Base settings: tabs can be dragged only in edit mode, stack headers have room for the part buttons,\n // and Golden Layout counts the spacing the viewer CSS adds beside the tabs\n const baseSettings: LayoutConfig = {\n settings: {\n reorderEnabled: this._isEditing,\n tabControlOffset: DASHBOARD_TAB_CONTROL_OFFSET\n },\n dimensions: {\n headerHeight: DASHBOARD_STACK_HEADER_HEIGHT\n },\n header: {\n show: 'top',\n popout: false,\n maximise: false,\n // Truthy in edit mode: GL cancels a drag of the only tab of a stack whose header cannot close.\n // The viewer CSS hides the stack close button.\n close: this._isEditing ? 'tab' : false\n },\n root: undefined\n };\n\n // If we have a saved layout, convert it properly using GL's conversion\n if (savedLayout && savedLayout.root) {\n try {\n // Validate the saved layout has required structure\n if (!this.isValidLayoutConfig(savedLayout)) {\n console.warn('[GoldenLayoutWrapper] Invalid saved layout structure, using default');\n return baseSettings;\n }\n\n // Use GL's built-in conversion from ResolvedLayoutConfig to LayoutConfig\n const convertedConfig = LayoutConfig.fromResolved(savedLayout) as LayoutConfig;\n\n // Merge our base settings with the converted config\n return {\n ...convertedConfig,\n settings: {\n ...convertedConfig.settings,\n ...baseSettings.settings\n },\n dimensions: {\n ...convertedConfig.dimensions,\n ...baseSettings.dimensions\n },\n header: {\n ...convertedConfig.header,\n ...baseSettings.header\n }\n };\n } catch (err) {\n console.error('[GoldenLayoutWrapper] Error converting saved layout, using default:', err);\n // Fall through to return base settings\n }\n }\n\n return baseSettings;\n }\n\n /**\n * Validate that a saved layout config has the required structure for GL conversion.\n * GL's fromResolved() can crash if certain properties are undefined.\n */\n private isValidLayoutConfig(config: ResolvedLayoutConfig): boolean {\n if (!config || !config.root) {\n return false;\n }\n\n // Check that root has a type\n if (!config.root.type) {\n return false;\n }\n\n // Recursively validate content items have required properties\n return this.validateLayoutItem(config.root);\n }\n\n /**\n * Recursively validate a layout item and its children.\n */\n private validateLayoutItem(item: unknown): boolean {\n if (!item || typeof item !== 'object') {\n return false;\n }\n\n const layoutItem = item as Record<string, unknown>;\n\n // Must have a type\n if (!layoutItem['type']) {\n return false;\n }\n\n // If it has content, validate each child\n const content = layoutItem['content'] as unknown[] | undefined;\n if (content && Array.isArray(content)) {\n for (const child of content) {\n if (!this.validateLayoutItem(child)) {\n return false;\n }\n }\n }\n\n return true;\n }\n\n /**\n * Update layout size to match container.\n */\n public UpdateSize(): void {\n if (this._layout && this._containerElement) {\n const size = this.containerLayoutSize(this._containerElement);\n if (size.width > 0 && size.height > 0) {\n this._layout.setSize(size.width, size.height);\n }\n }\n }\n\n /**\n * The container's layout size (offsetWidth / offsetHeight). Golden Layout lays out in this size\n * and reads it itself when it resizes with the container. It differs from the on-screen size\n * (getBoundingClientRect) when a host scales the viewer, for example with a CSS transform.\n */\n private containerLayoutSize(container: HTMLElement): { width: number; height: number } {\n return { width: container.offsetWidth, height: container.offsetHeight };\n }\n\n /** @deprecated Use {@link UpdateSize}. */\n public updateSize(): void {\n return this.UpdateSize();\n }\n\n /**\n * Bind component event listener (called by Golden Layout VirtualLayout).\n * The componentState contains the full DashboardPanel object.\n */\n private bindComponentEventListener(\n container: ComponentContainer,\n _itemConfig: { componentState: Record<string, unknown> }\n ): { component: HTMLElement; virtual: boolean } {\n // componentState IS the DashboardPanel\n const panel = container.state as unknown as DashboardPanel;\n\n // Create a wrapper element for our panel content\n const wrapper = document.createElement('div');\n wrapper.className = 'dashboard-panel-content';\n wrapper.style.width = '100%';\n wrapper.style.height = '100%';\n wrapper.style.overflow = 'auto';\n\n if (!panel?.id) {\n wrapper.innerHTML = '<div class=\"panel-error\">No panel ID provided</div>';\n } else {\n // A host finds and measures a panel's content by this attribute\n wrapper.dataset['panelId'] = panel.id;\n\n // Store reference to container\n this._containerMap.set(panel.id, container);\n\n // Set the tab title (plain text - GL escapes HTML)\n container.setTitle(panel.title);\n\n // Add icon to the tab element via DOM manipulation\n // This must happen after GL has created the tab element\n // Always add an icon - use panel's icon or a default fallback (cube = generic widget)\n // IMPORTANT: We append to tabElement, NOT modify .lm_title, to preserve GL's drag/drop\n const iconClass = panel.icon || 'fa-solid fa-cube';\n this.addIconToTab(container, iconClass);\n\n // LAZY LOADING: Show loading placeholder initially\n // Actual content is created when panel is first shown (visible)\n wrapper.innerHTML = `\n <div class=\"panel-loading\" style=\"display: flex; align-items: center; justify-content: center; height: 100%; color: var(--mj-text-secondary);\">\n <i class=\"fa-solid fa-spinner fa-spin\" style=\"margin-right: 8px;\"></i>\n Loading...\n </div>\n `;\n\n // Listen for close events\n container.on('beforeComponentRelease', () => {\n this._containerMap.delete(panel.id);\n this._loadedPanels.delete(panel.id);\n this.OnPanelClosed.next(panel.id);\n this.updatePanelsList();\n });\n\n // Listen for show/focus events - LAZY LOAD on first show\n container.on('show', () => {\n // Check if this is first time panel is shown\n if (!this._loadedPanels.has(panel.id)) {\n // First show - create actual content\n wrapper.innerHTML = ''; // Clear loading placeholder\n if (this._componentFactory) {\n this._componentFactory(panel, wrapper);\n }\n this._loadedPanels.add(panel.id);\n }\n this.OnPanelSelected.next(panel.id);\n });\n\n this.updatePanelsList();\n }\n\n // Append the wrapper to container.element (.lm_content)\n container.element.appendChild(wrapper);\n\n // Return the bindable component object\n return {\n component: wrapper,\n virtual: false\n };\n }\n\n /**\n * Unbind component event listener (called by Golden Layout VirtualLayout)\n */\n private unbindComponentEventListener(_container: ComponentContainer): void {\n // Cleanup handled in beforeComponentRelease\n }\n\n /**\n * Wires each stack Golden Layout creates: on load, on add, and when a dragged tab makes a new stack.\n * Every stack gets tab list ARIA; in edit mode it also gets the part buttons.\n */\n private onItemCreated(event: EventEmitter.BubblingEvent): void {\n const item = event.target;\n if (!isStack(item)) return;\n this.addTabListAria(item);\n if (this._isEditing) {\n this.addStackActions(item);\n }\n }\n\n /**\n * Marks the stack header's tab list as a tablist, and the tab dropdown list too (Golden Layout moves the\n * tabs that do not fit there). Keeps aria-selected on each tab in step with the stack's active tab.\n */\n private addTabListAria(stack: Stack): void {\n const header = stack.header;\n if (header.tabsContainerElement.getAttribute('role') === 'tablist') return;\n header.tabsContainerElement.setAttribute('role', 'tablist');\n header.element.querySelector('.lm_tabdropdown_list')?.setAttribute('role', 'tablist');\n const markSelected = (): void => {\n for (const tab of header.tabs) {\n tab.element.setAttribute('aria-selected', String(tab.isActive));\n }\n };\n stack.on('activeContentItemChanged', markSelected);\n markSelected();\n }\n\n /** Adds Edit part and Remove to the stack header. They act on the stack's active tab at click time. */\n private addStackActions(stack: Stack): void {\n const controls = stack.header.controlsContainerElement;\n if (controls.querySelector(`.${STACK_PART_ACTIONS_CLASS}`)) return;\n const group = BuildStackPartActions(action => this.emitStackAction(stack, action));\n controls.appendChild(group);\n const relabel = (): void => LabelStackPartActions(group, stack.getActiveComponentItem()?.title ?? '');\n stack.on('activeContentItemChanged', relabel);\n relabel();\n }\n\n /** Emits the action for the panel in the stack's active tab. Does nothing when the active tab has no panel. */\n private emitStackAction(stack: Stack, action: StackAction): void {\n const container = stack.getActiveComponentItem()?.container;\n const panelId = container ? this.panelIdOf(container) : null;\n if (panelId) {\n this.OnStackAction.next({ Action: action, PanelId: panelId });\n }\n }\n\n /** The ID of the panel bound to a component container, or null. */\n private panelIdOf(container: ComponentContainer): string | null {\n for (const [panelId, bound] of this._containerMap) {\n if (bound === container) return panelId;\n }\n return null;\n }\n\n /**\n * Allows tab dragging only in edit mode (a saved part's own reorderEnabled would allow it in view mode),\n * and makes the tab reachable from the keyboard.\n */\n private onTabCreated(tab: Tab): void {\n tab.reorderEnabled = this._isEditing;\n const element = tab.element;\n element.setAttribute('role', 'tab');\n element.tabIndex = 0;\n element.addEventListener('keydown', (event: KeyboardEvent) => {\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n element.click(); // GL's own click handler activates the tab\n }\n });\n }\n\n /**\n * Check if Golden Layout is initialized\n */\n public IsInitialized(): boolean {\n return this._initialized;\n }\n\n /** @deprecated Use {@link IsInitialized}. */\n public isInitialized(): boolean {\n return this.IsInitialized();\n }\n\n /**\n * Destroy Golden Layout and clean up\n */\n public Destroy(): void {\n if (this._layout) {\n this._layout.destroy();\n this._layout = null;\n }\n\n this._containerMap.clear();\n this._loadedPanels.clear();\n this._initialized = false;\n this._componentFactory = null;\n this._containerElement = null;\n }\n\n /** @deprecated Use {@link Destroy}. */\n public destroy(): void {\n return this.Destroy();\n }\n\n /**\n * Add a panel to the layout.\n * The full DashboardPanel is stored in componentState.\n */\n public AddPanel(panel: DashboardPanel, _location?: LayoutLocation): void {\n if (!this._layout) {\n return;\n }\n\n // Try to add to existing stack first, otherwise create new\n const existingStack = this.findFirstStack();\n if (existingStack) {\n const componentConfig: ComponentItemConfig = {\n type: 'component',\n componentType: 'dashboard-panel',\n componentState: panel as unknown as JsonValue,\n title: panel.title,\n isClosable: true\n };\n existingStack.addItem(componentConfig);\n } else {\n // Use addComponent which will create a stack\n this._layout.addComponent(\n 'dashboard-panel',\n panel as unknown as Record<string, unknown>,\n panel.title\n );\n }\n\n this.emitLayoutChanged('resize');\n }\n\n /** @deprecated Use {@link AddPanel}. */\n public addPanel(panel: DashboardPanel, _location?: LayoutLocation): void {\n return this.AddPanel(panel, _location);\n }\n\n /**\n * Find first stack in layout\n */\n private findFirstStack(): GLLayoutItem | null {\n if (!this._layout || !this._layout.rootItem) return null;\n\n const findStack = (item: GLLayoutItem): GLLayoutItem | null => {\n if (item.type === 'stack') {\n return item;\n }\n if (item.contentItems) {\n for (const child of item.contentItems) {\n const found = findStack(child);\n if (found) return found;\n }\n }\n return null;\n };\n\n return findStack(this._layout.rootItem);\n }\n\n /**\n * Remove a panel from the layout\n */\n public RemovePanel(panelId: string): void {\n const container = this._containerMap.get(panelId);\n if (container) {\n container.close();\n }\n }\n\n /** @deprecated Use {@link RemovePanel}. */\n public removePanel(panelId: string): void {\n return this.RemovePanel(panelId);\n }\n\n /**\n * Split a panel horizontally (add panel to the right)\n */\n public SplitHorizontal(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'right' });\n }\n\n /** @deprecated Use {@link SplitHorizontal}. */\n public splitHorizontal(panelId: string, newPanel: DashboardPanel): void {\n return this.SplitHorizontal(panelId, newPanel);\n }\n\n /**\n * Split a panel vertically (add panel below)\n */\n public SplitVertical(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'bottom' });\n }\n\n /** @deprecated Use {@link SplitVertical}. */\n public splitVertical(panelId: string, newPanel: DashboardPanel): void {\n return this.SplitVertical(panelId, newPanel);\n }\n\n /**\n * Add a panel as a tab to an existing stack\n */\n public AddToStack(panelId: string, newPanel: DashboardPanel): void {\n this.AddPanel(newPanel, { targetPanelId: panelId, position: 'tab' });\n }\n\n /** @deprecated Use {@link AddToStack}. */\n public addToStack(panelId: string, newPanel: DashboardPanel): void {\n return this.AddToStack(panelId, newPanel);\n }\n\n /**\n * Maximize a panel\n */\n public MaximizePanel(panelId: string): void {\n this.OnPanelMaximized.next({ panelId, maximized: true });\n }\n\n /** @deprecated Use {@link MaximizePanel}. */\n public maximizePanel(panelId: string): void {\n return this.MaximizePanel(panelId);\n }\n\n /**\n * Restore a maximized panel\n */\n public RestorePanel(panelId: string): void {\n this.OnPanelMaximized.next({ panelId, maximized: false });\n }\n\n /** @deprecated Use {@link RestorePanel}. */\n public restorePanel(panelId: string): void {\n return this.RestorePanel(panelId);\n }\n\n /**\n * Focus a panel by ID\n */\n public FocusPanel(panelId: string): void {\n const container = this._containerMap.get(panelId);\n if (container) {\n container.focus();\n }\n }\n\n /** @deprecated Use {@link FocusPanel}. */\n public focusPanel(panelId: string): void {\n return this.FocusPanel(panelId);\n }\n\n /**\n * Get the current layout configuration.\n * Returns GL's native ResolvedLayoutConfig - no conversion.\n */\n public GetLayoutConfig(): ResolvedLayoutConfig | null {\n if (!this._layout) return null;\n\n try {\n return this._layout.saveLayout();\n } catch (error) {\n console.error('[GLWrapper] Failed to save layout:', error);\n return null;\n }\n }\n\n /** @deprecated Use {@link GetLayoutConfig}. */\n public getLayoutConfig(): ResolvedLayoutConfig | null {\n return this.GetLayoutConfig();\n }\n\n /**\n * Get the container element for a panel\n */\n public GetPanelContainer(panelId: string): HTMLElement | null {\n const container = this._containerMap.get(panelId);\n return container?.element || null;\n }\n\n /** @deprecated Use {@link GetPanelContainer}. */\n public getPanelContainer(panelId: string): HTMLElement | null {\n return this.GetPanelContainer(panelId);\n }\n\n /**\n * Get all panel IDs in the current layout\n */\n public GetPanelIds(): string[] {\n return Array.from(this._containerMap.keys());\n }\n\n /** @deprecated Use {@link GetPanelIds}. */\n public getPanelIds(): string[] {\n return this.GetPanelIds();\n }\n\n /**\n * Set editing mode.\n * Note: Golden Layout 2 doesn't support changing settings after initialization.\n * The layout must be reinitialized to apply new settings.\n */\n public SetEditingMode(isEditing: boolean): void {\n this._isEditing = isEditing;\n }\n\n /** @deprecated Use {@link SetEditingMode}. */\n public setEditingMode(isEditing: boolean): void {\n return this.SetEditingMode(isEditing);\n }\n\n private updatePanelsList(): void {\n this.Panels$.next(Array.from(this._containerMap.keys()));\n }\n\n private emitLayoutChanged(changeType: LayoutChangedEvent['changeType']): void {\n const layoutConfig = this.GetLayoutConfig();\n if (layoutConfig) {\n this.OnLayoutChanged.next({\n layout: layoutConfig,\n changeType\n });\n }\n }\n\n /**\n * Add an icon to a tab element via DOM manipulation.\n * IMPORTANT: We append to tabElement, NOT modify .lm_title, to preserve GL's drag/drop.\n * This follows the same pattern as the shell's GoldenLayoutManager.\n */\n private addIconToTab(container: ComponentContainer, iconClass: string): void {\n // Normalize the icon class - ensure it has the Font Awesome prefix\n let normalizedIconClass = iconClass.trim();\n if (!normalizedIconClass.includes('fa-') && !normalizedIconClass.includes('fa ')) {\n // If no FA prefix, assume it's a Font Awesome icon name and add fa-solid prefix\n normalizedIconClass = `fa-solid fa-${normalizedIconClass}`;\n } else if (!normalizedIconClass.startsWith('fa-') && !normalizedIconClass.startsWith('fa ')) {\n // Has fa- in it but not at the start - likely just the icon name like \"globe\"\n // Check if it's missing the style prefix (fa-solid, fa-regular, etc.)\n if (!normalizedIconClass.match(/^fa[srldb]?\\s/) && !normalizedIconClass.match(/^fa-(solid|regular|light|duotone|brands)\\s/)) {\n normalizedIconClass = `fa-solid ${normalizedIconClass}`;\n }\n }\n\n // Try immediately, then retry with delay if tab not ready\n const tryAddIcon = (): boolean => {\n const tab = container.tab;\n if (!tab) return false;\n\n const tabElement = tab.element as HTMLElement;\n if (!tabElement) return false;\n\n // Check if icon already added to tab element\n if (tabElement.querySelector('.panel-icon')) return true;\n\n // Create icon element and insert at the beginning of tabElement\n // This preserves GL's .lm_title structure for drag/drop\n // The viewer CSS keeps the icon in the tab's flow, before the title\n const iconEl = document.createElement('i');\n iconEl.className = `${normalizedIconClass} panel-icon`;\n\n // Insert icon as first child of tab element\n tabElement.insertBefore(iconEl, tabElement.firstChild);\n return true;\n };\n\n // Try immediately\n if (tryAddIcon()) return;\n\n // Tab may not be created yet - try again after a delay\n setTimeout(() => {\n if (tryAddIcon()) return;\n\n // Still not ready - try one more time with longer delay\n setTimeout(() => {\n tryAddIcon();\n }, 100);\n }, 50);\n }\n}\n\n/** True when the Golden Layout item is a stack. */\nfunction isStack(item: EventEmitter): item is Stack {\n return 'isStack' in item && item.isStack === true;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { StackAction } from './golden-layout-wrapper.service';
|
|
2
|
+
/** The class of the group that holds a stack header's part buttons. */
|
|
3
|
+
export declare const STACK_PART_ACTIONS_CLASS = "dashboard-stack-actions";
|
|
4
|
+
/**
|
|
5
|
+
* The part buttons for a stack header. Golden Layout renders outside Angular, so each button is a plain
|
|
6
|
+
* element with the classes that `<button mjButton [Variant] Size="sm">` applies (button.scss styles them).
|
|
7
|
+
*/
|
|
8
|
+
export declare function BuildStackPartActions(onAction: (action: StackAction) => void): HTMLElement;
|
|
9
|
+
/** Names each button for the active part, for example "Edit part Revenue" and "Remove Revenue". */
|
|
10
|
+
export declare function LabelStackPartActions(group: HTMLElement, partTitle: string): void;
|
|
11
|
+
//# sourceMappingURL=stack-part-actions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-part-actions.d.ts","sourceRoot":"","sources":["../../../src/lib/services/stack-part-actions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,4BAA4B,CAAC;AAelE;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,GAAG,WAAW,CAS1F;AAED,mGAAmG;AACnG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAKjF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** The class of the group that holds a stack header's part buttons. */
|
|
2
|
+
export const STACK_PART_ACTIONS_CLASS = 'dashboard-stack-actions';
|
|
3
|
+
const STACK_PART_ACTIONS = [
|
|
4
|
+
{ Action: 'edit', Label: 'Edit part', Icon: 'fa-solid fa-sliders', Variant: 'secondary' },
|
|
5
|
+
{ Action: 'remove', Label: 'Remove', Icon: 'fa-solid fa-trash-can', Variant: 'flat' },
|
|
6
|
+
];
|
|
7
|
+
/**
|
|
8
|
+
* The part buttons for a stack header. Golden Layout renders outside Angular, so each button is a plain
|
|
9
|
+
* element with the classes that `<button mjButton [Variant] Size="sm">` applies (button.scss styles them).
|
|
10
|
+
*/
|
|
11
|
+
export function BuildStackPartActions(onAction) {
|
|
12
|
+
const group = document.createElement('div');
|
|
13
|
+
group.className = STACK_PART_ACTIONS_CLASS;
|
|
14
|
+
group.setAttribute('role', 'group');
|
|
15
|
+
group.setAttribute('aria-label', 'Part actions');
|
|
16
|
+
for (const spec of STACK_PART_ACTIONS) {
|
|
17
|
+
group.appendChild(buildButton(spec, onAction));
|
|
18
|
+
}
|
|
19
|
+
return group;
|
|
20
|
+
}
|
|
21
|
+
/** Names each button for the active part, for example "Edit part Revenue" and "Remove Revenue". */
|
|
22
|
+
export function LabelStackPartActions(group, partTitle) {
|
|
23
|
+
for (const button of Array.from(group.querySelectorAll('button[data-stack-action]'))) {
|
|
24
|
+
const label = button.dataset['label'] ?? '';
|
|
25
|
+
button.setAttribute('aria-label', partTitle ? `${label} ${partTitle}` : label);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function buildButton(spec, onAction) {
|
|
29
|
+
const button = document.createElement('button');
|
|
30
|
+
button.type = 'button';
|
|
31
|
+
button.className = `mj-btn mj-btn--${spec.Variant} mj-btn--sm`;
|
|
32
|
+
button.dataset['stackAction'] = spec.Action;
|
|
33
|
+
button.dataset['label'] = spec.Label;
|
|
34
|
+
const icon = document.createElement('i');
|
|
35
|
+
icon.className = spec.Icon;
|
|
36
|
+
icon.setAttribute('aria-hidden', 'true');
|
|
37
|
+
button.append(icon, document.createTextNode(spec.Label)); // text nodes, no innerHTML
|
|
38
|
+
button.addEventListener('click', () => onAction(spec.Action));
|
|
39
|
+
return button;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=stack-part-actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-part-actions.js","sourceRoot":"","sources":["../../../src/lib/services/stack-part-actions.ts"],"names":[],"mappings":"AAEA,uEAAuE;AACvE,MAAM,CAAC,MAAM,wBAAwB,GAAG,yBAAyB,CAAC;AAUlE,MAAM,kBAAkB,GAAmC;IACvD,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,WAAW,EAAE;IACzF,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,uBAAuB,EAAE,OAAO,EAAE,MAAM,EAAE;CACxF,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAuC;IACzE,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,CAAC,SAAS,GAAG,wBAAwB,CAAC;IAC3C,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACjD,KAAK,MAAM,IAAI,IAAI,kBAAkB,EAAE,CAAC;QACpC,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,qBAAqB,CAAC,KAAkB,EAAE,SAAiB;IACvE,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAoB,2BAA2B,CAAC,CAAC,EAAE,CAAC;QACtG,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACnF,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,IAAyB,EAAE,QAAuC;IACnF,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,MAAM,CAAC,SAAS,GAAG,kBAAkB,IAAI,CAAC,OAAO,aAAa,CAAC;IAC/D,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IAC5C,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;IACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC;IAC3B,IAAI,CAAC,YAAY,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACzC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,2BAA2B;IACrF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,OAAO,MAAM,CAAC;AAClB,CAAC","sourcesContent":["import type { StackAction } from './golden-layout-wrapper.service';\n\n/** The class of the group that holds a stack header's part buttons. */\nexport const STACK_PART_ACTIONS_CLASS = 'dashboard-stack-actions';\n\n/** One part button: what it does, its label and icon, and the mjButton variant it looks like. */\ninterface StackPartActionSpec {\n Action: StackAction;\n Label: string;\n Icon: string;\n Variant: 'secondary' | 'flat';\n}\n\nconst STACK_PART_ACTIONS: readonly StackPartActionSpec[] = [\n { Action: 'edit', Label: 'Edit part', Icon: 'fa-solid fa-sliders', Variant: 'secondary' },\n { Action: 'remove', Label: 'Remove', Icon: 'fa-solid fa-trash-can', Variant: 'flat' },\n];\n\n/**\n * The part buttons for a stack header. Golden Layout renders outside Angular, so each button is a plain\n * element with the classes that `<button mjButton [Variant] Size=\"sm\">` applies (button.scss styles them).\n */\nexport function BuildStackPartActions(onAction: (action: StackAction) => void): HTMLElement {\n const group = document.createElement('div');\n group.className = STACK_PART_ACTIONS_CLASS;\n group.setAttribute('role', 'group');\n group.setAttribute('aria-label', 'Part actions');\n for (const spec of STACK_PART_ACTIONS) {\n group.appendChild(buildButton(spec, onAction));\n }\n return group;\n}\n\n/** Names each button for the active part, for example \"Edit part Revenue\" and \"Remove Revenue\". */\nexport function LabelStackPartActions(group: HTMLElement, partTitle: string): void {\n for (const button of Array.from(group.querySelectorAll<HTMLButtonElement>('button[data-stack-action]'))) {\n const label = button.dataset['label'] ?? '';\n button.setAttribute('aria-label', partTitle ? `${label} ${partTitle}` : label);\n }\n}\n\nfunction buildButton(spec: StackPartActionSpec, onAction: (action: StackAction) => void): HTMLButtonElement {\n const button = document.createElement('button');\n button.type = 'button';\n button.className = `mj-btn mj-btn--${spec.Variant} mj-btn--sm`;\n button.dataset['stackAction'] = spec.Action;\n button.dataset['label'] = spec.Label;\n const icon = document.createElement('i');\n icon.className = spec.Icon;\n icon.setAttribute('aria-hidden', 'true');\n button.append(icon, document.createTextNode(spec.Label)); // text nodes, no innerHTML\n button.addEventListener('click', () => onAction(spec.Action));\n return button;\n}\n"]}
|
package/dist/public-api.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ export * from './lib/dashboard-viewer.module';
|
|
|
2
2
|
export * from './lib/dashboard-viewer/dashboard-viewer.component';
|
|
3
3
|
export * from './lib/dashboard-browser/dashboard-browser.component';
|
|
4
4
|
export * from './lib/breadcrumb/dashboard-breadcrumb.component';
|
|
5
|
+
export * from './lib/layout-preview/dashboard-layout-preview';
|
|
6
|
+
export * from './lib/layout-preview/dashboard-layout-preview.component';
|
|
7
|
+
export * from './lib/layout-preview/dashboard-layout-preview-node.component';
|
|
8
|
+
export * from './lib/dashboard-card/dashboard-card.component';
|
|
9
|
+
export * from './lib/dashboard-card/dashboard-card.helpers';
|
|
10
|
+
export * from './lib/dialogs/part-dialog/dashboard-part-dialog.component';
|
|
11
|
+
export * from './lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component';
|
|
5
12
|
export * from './lib/dialogs/add-panel-dialog/add-panel-dialog.component';
|
|
6
13
|
export * from './lib/dialogs/edit-part-dialog/edit-part-dialog.component';
|
|
7
14
|
export * from './lib/config-dialogs/confirm-dialog.component';
|
|
@@ -16,5 +23,7 @@ export * from './lib/parts/view-part.component';
|
|
|
16
23
|
export * from './lib/parts/query-part.component';
|
|
17
24
|
export * from './lib/parts/artifact-part.component';
|
|
18
25
|
export * from './lib/models/dashboard-types';
|
|
26
|
+
export * from './lib/models/dashboard-layout-editor';
|
|
27
|
+
export * from './lib/models/remove-part-confirm';
|
|
19
28
|
export * from './lib/services/golden-layout-wrapper.service';
|
|
20
29
|
//# sourceMappingURL=public-api.d.ts.map
|
package/dist/public-api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,+BAA+B,CAAC;AAG9C,cAAc,mDAAmD,CAAC;AAGlE,cAAc,qDAAqD,CAAC;AAGpE,cAAc,iDAAiD,CAAC;
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAKA,cAAc,+BAA+B,CAAC;AAG9C,cAAc,mDAAmD,CAAC;AAGlE,cAAc,qDAAqD,CAAC;AAGpE,cAAc,iDAAiD,CAAC;AAIhE,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yDAAyD,CAAC;AACxE,cAAc,8DAA8D,CAAC;AAI7E,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAG5D,cAAc,2DAA2D,CAAC;AAC1E,cAAc,qEAAqE,CAAC;AACpF,cAAc,2DAA2D,CAAC;AAC1E,cAAc,2DAA2D,CAAC;AAC1E,cAAc,+CAA+C,CAAC;AAG9D,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAGhD,cAAc,mDAAmD,CAAC;AAClE,cAAc,iDAAiD,CAAC;AAChE,cAAc,kDAAkD,CAAC;AACjE,cAAc,qDAAqD,CAAC;AAGpE,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AAGpD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AAGjD,cAAc,8CAA8C,CAAC"}
|
package/dist/public-api.js
CHANGED
|
@@ -9,7 +9,18 @@ export * from './lib/dashboard-viewer/dashboard-viewer.component';
|
|
|
9
9
|
export * from './lib/dashboard-browser/dashboard-browser.component';
|
|
10
10
|
// Breadcrumb Component
|
|
11
11
|
export * from './lib/breadcrumb/dashboard-breadcrumb.component';
|
|
12
|
+
// Layout Preview (a miniature of a saved dashboard layout). A host that declares the preview
|
|
13
|
+
// component itself (for example a test module) declares the node component with it.
|
|
14
|
+
export * from './lib/layout-preview/dashboard-layout-preview';
|
|
15
|
+
export * from './lib/layout-preview/dashboard-layout-preview.component';
|
|
16
|
+
export * from './lib/layout-preview/dashboard-layout-preview-node.component';
|
|
17
|
+
// Dashboard Card (one dashboard: picture, name, owner, Shared marker, favorite star). A host that
|
|
18
|
+
// declares the card itself (for example a test module) declares the layout preview components with it.
|
|
19
|
+
export * from './lib/dashboard-card/dashboard-card.component';
|
|
20
|
+
export * from './lib/dashboard-card/dashboard-card.helpers';
|
|
12
21
|
// Generic Dialogs
|
|
22
|
+
export * from './lib/dialogs/part-dialog/dashboard-part-dialog.component';
|
|
23
|
+
export * from './lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component';
|
|
13
24
|
export * from './lib/dialogs/add-panel-dialog/add-panel-dialog.component';
|
|
14
25
|
export * from './lib/dialogs/edit-part-dialog/edit-part-dialog.component';
|
|
15
26
|
export * from './lib/config-dialogs/confirm-dialog.component';
|
|
@@ -28,6 +39,8 @@ export * from './lib/parts/query-part.component';
|
|
|
28
39
|
export * from './lib/parts/artifact-part.component';
|
|
29
40
|
// Types and Models
|
|
30
41
|
export * from './lib/models/dashboard-types';
|
|
42
|
+
export * from './lib/models/dashboard-layout-editor';
|
|
43
|
+
export * from './lib/models/remove-part-confirm';
|
|
31
44
|
// Services
|
|
32
45
|
export * from './lib/services/golden-layout-wrapper.service';
|
|
33
46
|
//# sourceMappingURL=public-api.js.map
|
package/dist/public-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,+BAA+B,CAAC;AAE9C,iBAAiB;AACjB,cAAc,mDAAmD,CAAC;AAElE,8BAA8B;AAC9B,cAAc,qDAAqD,CAAC;AAEpE,uBAAuB;AACvB,cAAc,iDAAiD,CAAC;AAEhE,kBAAkB;AAClB,cAAc,2DAA2D,CAAC;AAC1E,cAAc,2DAA2D,CAAC;AAC1E,cAAc,+CAA+C,CAAC;AAE9D,iCAAiC;AACjC,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAEhD,oEAAoE;AACpE,cAAc,mDAAmD,CAAC;AAClE,cAAc,iDAAiD,CAAC;AAChE,cAAc,kDAAkD,CAAC;AACjE,cAAc,qDAAqD,CAAC;AAEpE,wEAAwE;AACxE,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AAEpD,mBAAmB;AACnB,cAAc,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../src/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,SAAS;AACT,cAAc,+BAA+B,CAAC;AAE9C,iBAAiB;AACjB,cAAc,mDAAmD,CAAC;AAElE,8BAA8B;AAC9B,cAAc,qDAAqD,CAAC;AAEpE,uBAAuB;AACvB,cAAc,iDAAiD,CAAC;AAEhE,6FAA6F;AAC7F,oFAAoF;AACpF,cAAc,+CAA+C,CAAC;AAC9D,cAAc,yDAAyD,CAAC;AACxE,cAAc,8DAA8D,CAAC;AAE7E,kGAAkG;AAClG,uGAAuG;AACvG,cAAc,+CAA+C,CAAC;AAC9D,cAAc,6CAA6C,CAAC;AAE5D,kBAAkB;AAClB,cAAc,2DAA2D,CAAC;AAC1E,cAAc,qEAAqE,CAAC;AACpF,cAAc,2DAA2D,CAAC;AAC1E,cAAc,2DAA2D,CAAC;AAC1E,cAAc,+CAA+C,CAAC;AAE9D,iCAAiC;AACjC,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAEhD,oEAAoE;AACpE,cAAc,mDAAmD,CAAC;AAClE,cAAc,iDAAiD,CAAC;AAChE,cAAc,kDAAkD,CAAC;AACjE,cAAc,qDAAqD,CAAC;AAEpE,wEAAwE;AACxE,cAAc,mCAAmC,CAAC;AAClD,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,qCAAqC,CAAC;AAEpD,mBAAmB;AACnB,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sCAAsC,CAAC;AACrD,cAAc,kCAAkC,CAAC;AAEjD,WAAW;AACX,cAAc,8CAA8C,CAAC","sourcesContent":["/*\n * Public API Surface of @memberjunction/ng-dashboard-viewer\n */\n\n// Module\nexport * from './lib/dashboard-viewer.module';\n\n// Main Component\nexport * from './lib/dashboard-viewer/dashboard-viewer.component';\n\n// Dashboard Browser Component\nexport * from './lib/dashboard-browser/dashboard-browser.component';\n\n// Breadcrumb Component\nexport * from './lib/breadcrumb/dashboard-breadcrumb.component';\n\n// Layout Preview (a miniature of a saved dashboard layout). A host that declares the preview\n// component itself (for example a test module) declares the node component with it.\nexport * from './lib/layout-preview/dashboard-layout-preview';\nexport * from './lib/layout-preview/dashboard-layout-preview.component';\nexport * from './lib/layout-preview/dashboard-layout-preview-node.component';\n\n// Dashboard Card (one dashboard: picture, name, owner, Shared marker, favorite star). A host that\n// declares the card itself (for example a test module) declares the layout preview components with it.\nexport * from './lib/dashboard-card/dashboard-card.component';\nexport * from './lib/dashboard-card/dashboard-card.helpers';\n\n// Generic Dialogs\nexport * from './lib/dialogs/part-dialog/dashboard-part-dialog.component';\nexport * from './lib/dialogs/dashboard-name-dialog/dashboard-name-dialog.component';\nexport * from './lib/dialogs/add-panel-dialog/add-panel-dialog.component';\nexport * from './lib/dialogs/edit-part-dialog/edit-part-dialog.component';\nexport * from './lib/config-dialogs/confirm-dialog.component';\n\n// Base Classes for Extensibility\nexport * from './lib/config-panels/base-config-panel';\nexport * from './lib/parts/base-dashboard-part';\n\n// Config Panels (pluggable form components loaded via ClassFactory)\nexport * from './lib/config-panels/weburl-config-panel.component';\nexport * from './lib/config-panels/view-config-panel.component';\nexport * from './lib/config-panels/query-config-panel.component';\nexport * from './lib/config-panels/artifact-config-panel.component';\n\n// Runtime Part Components (pluggable renderers loaded via ClassFactory)\nexport * from './lib/parts/weburl-part.component';\nexport * from './lib/parts/view-part.component';\nexport * from './lib/parts/query-part.component';\nexport * from './lib/parts/artifact-part.component';\n\n// Types and Models\nexport * from './lib/models/dashboard-types';\nexport * from './lib/models/dashboard-layout-editor';\nexport * from './lib/models/remove-part-confirm';\n\n// Services\nexport * from './lib/services/golden-layout-wrapper.service';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ng-dashboard-viewer",
|
|
3
|
-
"version": "6.2.0-edge.
|
|
3
|
+
"version": "6.2.0-edge.4",
|
|
4
4
|
"description": "MemberJunction: Angular components for metadata-driven dashboards with Golden Layout panels, supporting views, queries, artifacts, and custom content",
|
|
5
5
|
"main": "./dist/public-api.js",
|
|
6
6
|
"typings": "./dist/public-api.d.ts",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@angular/compiler": "21.2.22",
|
|
23
23
|
"@angular/compiler-cli": "21.2.22",
|
|
24
|
-
"@memberjunction/ng-test-utils": "6.2.0-edge.
|
|
24
|
+
"@memberjunction/ng-test-utils": "6.2.0-edge.4",
|
|
25
25
|
"vitest": "^4.0.18"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"golden-layout": "^2.6.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@memberjunction/ng-ui-components": "6.2.0-edge.
|
|
37
|
-
"@memberjunction/core": "6.2.0-edge.
|
|
38
|
-
"@memberjunction/core-entities": "6.2.0-edge.
|
|
39
|
-
"@memberjunction/global": "6.2.0-edge.
|
|
40
|
-
"@memberjunction/ng-artifacts": "6.2.0-edge.
|
|
41
|
-
"@memberjunction/ng-base-types": "6.2.0-edge.
|
|
42
|
-
"@memberjunction/ng-entity-viewer": "6.2.0-edge.
|
|
43
|
-
"@memberjunction/ng-map-view": "6.2.0-edge.
|
|
44
|
-
"@memberjunction/ng-query-viewer": "6.2.0-edge.
|
|
45
|
-
"@memberjunction/ng-shared-generic": "6.2.0-edge.
|
|
46
|
-
"@memberjunction/ng-trees": "6.2.0-edge.
|
|
36
|
+
"@memberjunction/ng-ui-components": "6.2.0-edge.4",
|
|
37
|
+
"@memberjunction/core": "6.2.0-edge.4",
|
|
38
|
+
"@memberjunction/core-entities": "6.2.0-edge.4",
|
|
39
|
+
"@memberjunction/global": "6.2.0-edge.4",
|
|
40
|
+
"@memberjunction/ng-artifacts": "6.2.0-edge.4",
|
|
41
|
+
"@memberjunction/ng-base-types": "6.2.0-edge.4",
|
|
42
|
+
"@memberjunction/ng-entity-viewer": "6.2.0-edge.4",
|
|
43
|
+
"@memberjunction/ng-map-view": "6.2.0-edge.4",
|
|
44
|
+
"@memberjunction/ng-query-viewer": "6.2.0-edge.4",
|
|
45
|
+
"@memberjunction/ng-shared-generic": "6.2.0-edge.4",
|
|
46
|
+
"@memberjunction/ng-trees": "6.2.0-edge.4",
|
|
47
47
|
"rxjs": "^7.8.2",
|
|
48
48
|
"tslib": "^2.8.1"
|
|
49
49
|
},
|