@memberjunction/ng-explorer-core 5.22.0 → 5.23.0

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 (73) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +1 -1
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +3 -2
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +49 -49
  6. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  7. package/dist/lib/generic/form-toolbar.js +10 -10
  8. package/dist/lib/generic/form-toolbar.js.map +1 -1
  9. package/dist/lib/oauth/oauth-callback.component.js +6 -6
  10. package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
  11. package/dist/lib/oauth/oauth.module.d.ts +2 -3
  12. package/dist/lib/oauth/oauth.module.d.ts.map +1 -1
  13. package/dist/lib/oauth/oauth.module.js +0 -4
  14. package/dist/lib/oauth/oauth.module.js.map +1 -1
  15. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +6 -25
  16. package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
  17. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +30 -124
  18. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  19. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +7 -23
  20. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  21. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +50 -142
  22. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  23. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +3 -19
  24. package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
  25. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +16 -98
  26. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  27. package/dist/lib/resource-wrappers/view-resource.component.d.ts +13 -11
  28. package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
  29. package/dist/lib/resource-wrappers/view-resource.component.js +80 -89
  30. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  31. package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
  32. package/dist/lib/shell/components/header/app-nav.component.js +18 -3
  33. package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
  34. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +38 -16
  35. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  36. package/dist/lib/shell/components/tabs/component-cache-manager.js +57 -35
  37. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  38. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +33 -0
  39. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  40. package/dist/lib/shell/components/tabs/tab-container.component.js +99 -16
  41. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  42. package/dist/lib/shell/services/settings-dialog.service.d.ts +8 -8
  43. package/dist/lib/shell/services/settings-dialog.service.d.ts.map +1 -1
  44. package/dist/lib/shell/services/settings-dialog.service.js +20 -26
  45. package/dist/lib/shell/services/settings-dialog.service.js.map +1 -1
  46. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  47. package/dist/lib/shell/shell.component.js +17 -16
  48. package/dist/lib/shell/shell.component.js.map +1 -1
  49. package/dist/lib/shell/shell.module.d.ts +4 -5
  50. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  51. package/dist/lib/shell/shell.module.js +4 -8
  52. package/dist/lib/shell/shell.module.js.map +1 -1
  53. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +72 -71
  54. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  55. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +11 -11
  56. package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
  57. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +36 -12
  58. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts.map +1 -1
  59. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +78 -50
  60. package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
  61. package/dist/lib/single-dashboard/single-dashboard.component.d.ts +12 -5
  62. package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
  63. package/dist/lib/single-dashboard/single-dashboard.component.js +44 -55
  64. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  65. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +10 -2
  66. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  67. package/dist/lib/single-list-detail/single-list-detail.component.js +313 -243
  68. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  69. package/dist/module.d.ts +23 -34
  70. package/dist/module.d.ts.map +1 -1
  71. package/dist/module.js +33 -74
  72. package/dist/module.js.map +1 -1
  73. package/package.json +37 -47
@@ -119,6 +119,8 @@ export class TabContainerComponent {
119
119
  // This avoids the 20px height issue when GL header is hidden
120
120
  useSingleResourceMode = false;
121
121
  singleResourceComponentRef = null;
122
+ /** Cache identity of the current single-resource component for detachment */
123
+ singleResourceCacheIdentity = null;
122
124
  previousTabBarVisible = null;
123
125
  currentSingleResourceSignature = null; // Track loaded content signature to avoid unnecessary reloads
124
126
  isCreatingInitialTabs = false; // Flag to prevent syncTabsWithConfiguration during initial tab creation
@@ -166,8 +168,17 @@ export class TabContainerComponent {
166
168
  if (activeTab) {
167
169
  const signature = this.getTabContentSignature(activeTab);
168
170
  if (signature !== this.currentSingleResourceSignature) {
171
+ // DO NOT call saveCurrentComponentQueryParams() here — by the time this
172
+ // subscription fires, OpenTab has already replaced the tab config with the
173
+ // new nav item's config, so queryParams are gone. The cache entry already
174
+ // has the correct queryParams from the most recent unchanged-signature save.
169
175
  this.loadSingleResourceContent();
170
176
  }
177
+ else {
178
+ // Signature unchanged — sync queryParams to cache entry so it stays current.
179
+ // This catches incremental queryParam updates (e.g., user selects a conversation).
180
+ this.saveCurrentComponentQueryParams();
181
+ }
171
182
  }
172
183
  }
173
184
  else if (this.layoutRestorationComplete && !this.isCreatingInitialTabs) {
@@ -331,7 +342,9 @@ export class TabContainerComponent {
331
342
  const shouldUseSingleResourceMode = !tabBarVisible;
332
343
  if (shouldUseSingleResourceMode !== this.useSingleResourceMode) {
333
344
  this.useSingleResourceMode = shouldUseSingleResourceMode;
334
- this.cdr.detectChanges();
345
+ // Defer detectChanges to next microtask to avoid ExpressionChangedAfterItHasBeenCheckedError
346
+ // when this handler fires during an already-running change detection cycle.
347
+ Promise.resolve().then(() => this.cdr.detectChanges());
335
348
  if (this.useSingleResourceMode) {
336
349
  // Transitioning to single-resource mode
337
350
  // **CRITICAL FIX**: Wait for the template to render directContentContainer
@@ -430,13 +443,26 @@ export class TabContainerComponent {
430
443
  if (cached) {
431
444
  // Clean up previous single-resource component (if different)
432
445
  this.cleanupSingleResourceComponent();
433
- // Detach from tab tracking (it was attached to a tab in Golden Layout)
434
- this.cacheManager.markAsDetached(activeTab.id);
446
+ // Mark cached component as attached to this tab (it was detached / available for reuse).
447
+ // IMPORTANT: We use markAsAttached here, NOT markAsDetached — the component is being
448
+ // reattached to the DOM and should NOT be eligible for LRU eviction.
449
+ this.cacheManager.markAsAttached(driverClass, resourceData.ResourceRecordID || '', activeTab.applicationId, activeTab.id);
435
450
  // Reattach the cached wrapper element to single-resource container
436
451
  cached.wrapperElement.style.height = "100%"; // Ensure full height
437
452
  container.appendChild(cached.wrapperElement);
438
- // Store reference for cleanup
453
+ // Store reference and identity for cleanup/detachment
439
454
  this.singleResourceComponentRef = cached.componentRef;
455
+ this.singleResourceCacheIdentity = { driverClass, recordId: resourceData.ResourceRecordID || '', appId: activeTab.applicationId, tabId: activeTab.id };
456
+ // Restore saved queryParams to the tab config so the URL reflects
457
+ // the component's preserved state (e.g., selected conversation, collection drill-down).
458
+ if (cached.savedQueryParams) {
459
+ this.workspaceManager.UpdateTabConfiguration(activeTab.id, {
460
+ queryParams: cached.savedQueryParams
461
+ });
462
+ // Do NOT clear savedQueryParams here — the else branch (unchanged-signature saves)
463
+ // will keep it current while the component is active. Clearing it would cause the
464
+ // queryParams to be lost on the next detach/reattach cycle.
465
+ }
440
466
  return;
441
467
  }
442
468
  // Get the component registration (with lazy loading fallback via ClassFactory)
@@ -460,13 +486,16 @@ export class TabContainerComponent {
460
486
  instance.LoadCompleteEvent = () => {
461
487
  this.emitFirstLoadCompleteOnce();
462
488
  };
463
- // Wire up display name change for single-resource mode
464
- // Use a closure that resolves the tab ID at call time, not at wire-up time,
465
- // because the tab may not be active yet when the component is first created.
489
+ // Wire up display name change for single-resource mode.
490
+ // Guard: only update the title if THIS component is the currently displayed one.
491
+ // Without this guard, cached components (detached but alive) can fire this callback
492
+ // and overwrite the active tab's title with a stale name.
466
493
  instance.DisplayNameChangedEvent = (newName) => {
467
- const tabId = this.workspaceManager.GetActiveTabId();
468
- if (tabId) {
469
- this.workspaceManager.UpdateTabTitle(tabId, newName);
494
+ if (this.singleResourceComponentRef?.instance === instance) {
495
+ const tabId = this.workspaceManager.GetActiveTabId();
496
+ if (tabId) {
497
+ this.workspaceManager.UpdateTabTitle(tabId, newName);
498
+ }
470
499
  }
471
500
  };
472
501
  // Get the native element and append to container
@@ -476,22 +505,76 @@ export class TabContainerComponent {
476
505
  if (container.children?.length > 0) {
477
506
  container.children[0].style.height = "100%";
478
507
  }
479
- // Store reference for cleanup
508
+ // Cache the component for reuse when switching between nav items within the same app.
509
+ // Without this, every nav switch creates a brand new component from scratch.
510
+ const wrapperElement = nativeElement;
511
+ this.cacheManager.cacheComponent(componentRef, wrapperElement, resourceData, activeTab.id);
512
+ // Store reference and identity for cleanup/detachment
480
513
  this.singleResourceComponentRef = componentRef;
514
+ this.singleResourceCacheIdentity = { driverClass, recordId: resourceData.ResourceRecordID || '', appId: activeTab.applicationId, tabId: activeTab.id };
481
515
  }
482
516
  /**
483
517
  * Clean up single-resource mode component
484
518
  */
519
+ /**
520
+ * Detaches the current single-resource component from the DOM and marks it as
521
+ * available for reuse in the component cache.
522
+ *
523
+ * ╔══════════════════════════════════════════════════════════════════════════╗
524
+ * ║ ⚠️ DO NOT DESTROY THE COMPONENT HERE — INTENTIONAL DESIGN CHOICE ⚠️ ║
525
+ * ║ ║
526
+ * ║ The component is DETACHED from the DOM, NOT destroyed. It stays alive ║
527
+ * ║ in the ComponentCacheManager with its full Angular state preserved ║
528
+ * ║ (properties, subscriptions, loaded data, scroll position, etc). ║
529
+ * ║ ║
530
+ * ║ When the user returns to this tab, the cached component is reattached ║
531
+ * ║ instantly — no data reload, no API calls, no flash of empty content. ║
532
+ * ║ ║
533
+ * ║ Destroying components here "for memory optimization" is a net ║
534
+ * ║ NEGATIVE: the reload on return is far more expensive (DB queries, ║
535
+ * ║ API calls, re-rendering) than keeping the component in memory. ║
536
+ * ║ The LRU eviction in ComponentCacheManager handles memory limits — ║
537
+ * ║ when MaxDetachedComponents is exceeded, the LEAST recently used ║
538
+ * ║ components are evicted automatically. ║
539
+ * ║ ║
540
+ * ║ If you think memory is a problem, adjust MaxDetachedComponents ║
541
+ * ║ instead of destroying components here. ║
542
+ * ╚══════════════════════════════════════════════════════════════════════════╝
543
+ */
544
+ /**
545
+ * Save the currently displayed component's queryParams to its cache entry.
546
+ * Called on every config change so the cache entry always has the latest queryParams,
547
+ * even after the tab config is overwritten by a new nav item.
548
+ */
549
+ saveCurrentComponentQueryParams() {
550
+ if (!this.singleResourceCacheIdentity)
551
+ return;
552
+ const { tabId } = this.singleResourceCacheIdentity;
553
+ const tab = this.workspaceManager.GetTab(tabId);
554
+ const qp = tab?.configuration?.['queryParams'];
555
+ const cached = this.cacheManager.getComponentByTabId(tabId);
556
+ if (cached) {
557
+ cached.savedQueryParams = (qp && Object.keys(qp).length > 0) ? { ...qp } : undefined;
558
+ }
559
+ }
485
560
  cleanupSingleResourceComponent() {
486
561
  if (this.singleResourceComponentRef) {
487
- this.appRef.detachView(this.singleResourceComponentRef.hostView);
488
- this.singleResourceComponentRef.destroy();
562
+ if (this.singleResourceCacheIdentity) {
563
+ const { driverClass, recordId, appId } = this.singleResourceCacheIdentity;
564
+ // Mark as DETACHED by resource identity — the ONE consistent key used everywhere.
565
+ this.cacheManager.markAsDetached(driverClass, recordId, appId);
566
+ }
489
567
  this.singleResourceComponentRef = null;
568
+ this.singleResourceCacheIdentity = null;
490
569
  }
491
- // Clear the container
570
+ // Remove children from the container. This detaches the wrapper DOM element
571
+ // without destroying the Angular component — it lives on in the cache.
572
+ // Using removeChild (not innerHTML='') to avoid aggressive DOM cleanup.
492
573
  const container = this.directContentContainer?.nativeElement;
493
574
  if (container) {
494
- container.innerHTML = '';
575
+ while (container.firstChild) {
576
+ container.removeChild(container.firstChild);
577
+ }
495
578
  }
496
579
  }
497
580
  /**
@@ -842,7 +925,7 @@ export class TabContainerComponent {
842
925
  */
843
926
  cleanupTabComponent(tabId) {
844
927
  // First, try to detach from cache (preserves component for reuse)
845
- const cachedInfo = this.cacheManager.markAsDetached(tabId);
928
+ const cachedInfo = this.cacheManager.findAndDetachByTabId(tabId);
846
929
  if (cachedInfo) {
847
930
  // Remove from legacy componentRefs but keep in cache
848
931
  this.componentRefs.delete(tabId);
@@ -1 +1 @@
1
- {"version":3,"file":"tab-container.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts","../../../../../src/lib/shell/components/tabs/tab-container.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n OnInit,\n OnDestroy,\n AfterViewInit,\n ViewChild,\n ElementRef,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n ComponentRef,\n ViewEncapsulation,\n ChangeDetectorRef,\n HostListener,\n Output,\n EventEmitter,\n inject\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport {\n GoldenLayoutManager,\n WorkspaceStateManager,\n ApplicationManager,\n TabComponentState,\n TabShownEvent,\n WorkspaceTab,\n LayoutNode\n} from '@memberjunction/ng-base-application';\nimport { MJGlobal } from '@memberjunction/global';\nimport { BaseResourceComponent, HomeAppPinService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJResourceTypeEntity, ResourcePermissionEngine } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { DatasetResultType, LogError, Metadata } from '@memberjunction/core';\nimport { ComponentCacheManager } from './component-cache-manager';\n\n/**\n * Container for Golden Layout tabs with app-colored styling.\n *\n * Handles:\n * - Golden Layout initialization\n * - Tab creation and styling\n * - Lazy loading of tab content\n * - Context menu for pin/close\n * - Layout persistence\n */\n@Component({\n standalone: false,\n selector: 'mj-tab-container',\n templateUrl: './tab-container.component.html',\n styleUrls: ['./tab-container.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class TabContainerComponent implements OnInit, OnDestroy, AfterViewInit {\n @ViewChild('glContainer', { static: false }) glContainer!: ElementRef<HTMLDivElement>;\n @ViewChild('directContentContainer', { static: false }) directContentContainer!: ElementRef<HTMLDivElement>;\n\n /**\n * Emitted when the first resource component finishes loading.\n * This allows the shell to keep showing its loading indicator until the first\n * resource is ready, eliminating the visual gap between shell loading and resource loading.\n */\n @Output() firstResourceLoadComplete = new EventEmitter<void>();\n\n /**\n * Emitted when Golden Layout fails to initialize after multiple retries.\n * The shell can use this to show an error dialog and redirect.\n */\n @Output() layoutInitError = new EventEmitter<void>();\n\n private pinService = inject(HomeAppPinService);\n private subscriptions: Subscription[] = [];\n private layoutInitRetryCount = 0;\n private readonly MAX_LAYOUT_INIT_RETRIES = 5;\n private layoutInitialized = false;\n private layoutRestorationComplete = false; // True only AFTER layout is fully restored/created\n\n // Track component references for cleanup (legacy - keep for backward compat during transition)\n private componentRefs = new Map<string, ComponentRef<BaseResourceComponent>>();\n\n // Guard against concurrent loadTabContent calls for the same tab.\n // When a tab's content changes while active, both the reload path (workspace config subscription)\n // and onTabShown can race to call loadTabContent, resulting in duplicate component rendering.\n private tabsCurrentlyLoading = new Set<string>();\n\n // NEW: Smart component cache for preserving state across tab switches\n private cacheManager: ComponentCacheManager;\n\n // Single-resource mode: render component directly without Golden Layout\n // This avoids the 20px height issue when GL header is hidden\n useSingleResourceMode = false;\n private singleResourceComponentRef: ComponentRef<BaseResourceComponent> | null = null;\n private previousTabBarVisible: boolean | null = null;\n private currentSingleResourceSignature: string | null = null; // Track loaded content signature to avoid unnecessary reloads\n private isCreatingInitialTabs = false; // Flag to prevent syncTabsWithConfiguration during initial tab creation\n\n // Context menu state\n contextMenuVisible = false;\n contextMenuX = 0;\n contextMenuY = 0;\n contextMenuTabId: string | null = null;\n\n constructor(\n private layoutManager: GoldenLayoutManager,\n private workspaceManager: WorkspaceStateManager,\n private appManager: ApplicationManager,\n private appRef: ApplicationRef,\n private environmentInjector: EnvironmentInjector,\n private cdr: ChangeDetectorRef\n ) {\n // Initialize component cache manager\n this.cacheManager = new ComponentCacheManager(this.appRef);\n }\n\n ngOnInit(): void {\n // Subscribe to tab events\n this.subscriptions.push(\n this.layoutManager.TabShown.subscribe(event => {\n this.onTabShown(event);\n }),\n this.layoutManager.TabClosed.subscribe(tabId => {\n this.cleanupTabComponent(tabId);\n this.workspaceManager.CloseTab(tabId);\n }),\n this.layoutManager.LayoutChanged.subscribe(event => {\n const layout = this.layoutManager.SaveLayout();\n this.workspaceManager.UpdateLayout(layout);\n }),\n this.layoutManager.ActiveTab.subscribe(tabId => {\n if (tabId) {\n this.workspaceManager.SetActiveTab(tabId);\n }\n }),\n this.layoutManager.TabDoubleClicked.subscribe(tabId => {\n this.workspaceManager.TogglePin(tabId);\n }),\n this.layoutManager.TabRightClicked.subscribe(event => {\n this.showContextMenu(event.x, event.y, event.tabId);\n })\n );\n\n // Subscribe to configuration changes to sync tabs\n this.subscriptions.push(\n this.workspaceManager.Configuration.subscribe(config => {\n if (config) {\n if (this.useSingleResourceMode) {\n // In single-resource mode, reload content if the tab content changed\n // The same tab ID can have different content (tab gets reused)\n const activeTab = config.tabs.find(t => t.id === config.activeTabId) || config.tabs[0];\n if (activeTab) {\n const signature = this.getTabContentSignature(activeTab);\n if (signature !== this.currentSingleResourceSignature) {\n this.loadSingleResourceContent();\n }\n }\n } else if (this.layoutRestorationComplete && !this.isCreatingInitialTabs) {\n // In multi-tab mode, sync with Golden Layout\n // IMPORTANT: Only sync AFTER layout restoration is complete to avoid creating duplicate tabs\n // layoutRestorationComplete is set to true only after initializeGoldenLayout finishes\n this.syncTabsWithConfiguration(config.tabs);\n }\n }\n })\n );\n\n // Subscribe to tab bar visibility changes for single-resource mode\n this.subscriptions.push(\n this.workspaceManager.TabBarVisible.subscribe(tabBarVisible => {\n this.handleTabBarVisibilityChange(tabBarVisible);\n })\n );\n }\n\n ngAfterViewInit(): void {\n // Initialize Golden Layout only if we're not in single-resource mode\n if (!this.useSingleResourceMode) {\n this.initializeGoldenLayout();\n } else {\n // In single-resource mode, load content directly\n this.loadSingleResourceContent();\n }\n }\n\n /**\n * Initialize Golden Layout and load tabs\n * @param forceCreateTabs - If true, always creates tabs fresh from config.tabs instead of restoring saved layout\n */\n private initializeGoldenLayout(forceCreateTabs = false): void {\n // If we are in single resource mode we do NOT need to do this work as golden layout should not exist in that state\n if (this.useSingleResourceMode)\n return;\n\n if (!this.glContainer?.nativeElement) {\n this.layoutInitRetryCount++;\n\n if (this.layoutInitRetryCount > this.MAX_LAYOUT_INIT_RETRIES) {\n console.error(`Golden Layout container not available after ${this.MAX_LAYOUT_INIT_RETRIES} retries, emitting error`);\n this.layoutInitError.emit();\n return;\n }\n\n console.warn(`Golden Layout container not available, retry ${this.layoutInitRetryCount}/${this.MAX_LAYOUT_INIT_RETRIES}...`);\n setTimeout(() => this.initializeGoldenLayout(forceCreateTabs), 50);\n return;\n }\n\n // Reset retry counter on success\n this.layoutInitRetryCount = 0;\n\n if (this.layoutInitialized) {\n return; // Already initialized\n }\n\n // Check if configuration is available\n // If not, wait for it to be loaded before proceeding\n const config = this.workspaceManager.GetConfiguration();\n if (!config) {\n // Configuration not loaded yet - wait for it\n const configSub = this.workspaceManager.Configuration.subscribe(loadedConfig => {\n if (loadedConfig) {\n configSub.unsubscribe();\n // Re-call initializeGoldenLayout now that config is available\n this.initializeGoldenLayout(forceCreateTabs);\n }\n });\n return;\n }\n\n // Initialize Golden Layout (we have config now)\n this.layoutManager.Initialize(this.glContainer.nativeElement);\n\n // Mark layout as initialized\n this.layoutInitialized = true;\n\n // Check if config has no tabs\n if (config.tabs.length === 0) {\n // No tabs to load, but mark restoration as complete\n this.layoutRestorationComplete = true;\n return;\n }\n\n // Check if we have a saved layout structure with actual content\n const hasSavedLayout = config.layout?.root?.content && config.layout.root.content.length > 0;\n\n if (hasSavedLayout && !forceCreateTabs && config.layout) {\n // VALIDATE: Check that layout component count matches tabs array count\n const layoutComponentCount = this.countLayoutComponents(config.layout.root);\n if (layoutComponentCount !== config.tabs.length) {\n console.warn(`[TabContainer.initializeGoldenLayout] Layout/tabs mismatch: layout has ${layoutComponentCount} components but tabs array has ${config.tabs.length} tabs. Clearing layout.`);\n this.workspaceManager.ClearLayout();\n // Fall through to create fresh tabs\n } else {\n // RESTORE SAVED LAYOUT - preserves drag/drop arrangements (stacks, columns, rows)\n // This is the single source of truth for visual arrangement\n const layoutLoaded = this.layoutManager.LoadLayout(config.layout);\n\n if (layoutLoaded) {\n // Mark layout restoration as complete AFTER layout is loaded\n this.layoutRestorationComplete = true;\n\n // Focus active tab and ensure proper sizing\n // Also trigger updateSize() to force Golden Layout to fire 'show' events\n // for the active tab in ALL stacks (not just the globally active tab)\n setTimeout(() => {\n if (config.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n // Trigger resize to ensure all visible tabs in all stacks render their content\n this.layoutManager.updateSize();\n }, 50);\n return; // Layout restored successfully\n }\n\n // Layout load FAILED - clear the corrupted layout and fall through to create tabs fresh\n console.warn('[TabContainer] Saved layout was corrupted, clearing and recreating tabs');\n this.workspaceManager.ClearLayout();\n }\n }\n\n // CREATE FRESH - no saved layout, forceCreateTabs=true, or layout load failed\n // Use config.tabs sorted by sequence to build a simple single-stack layout\n const sortedTabs = [...config.tabs].sort((a, b) => a.sequence - b.sequence);\n\n this.isCreatingInitialTabs = true;\n try {\n sortedTabs.forEach(tab => {\n this.createTab(tab);\n });\n } finally {\n this.isCreatingInitialTabs = false;\n }\n\n // Mark layout restoration as complete AFTER tabs are created\n this.layoutRestorationComplete = true;\n\n setTimeout(() => {\n if (config.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n }, 50);\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach(sub => sub.unsubscribe());\n\n // Cleanup single-resource mode component if exists\n this.cleanupSingleResourceComponent();\n\n // Clear the component cache (destroys all components)\n this.cacheManager.clearCache();\n\n // Cleanup any legacy componentRefs\n this.componentRefs.forEach((ref, _tabId) => {\n this.appRef.detachView(ref.hostView);\n ref.destroy();\n });\n this.componentRefs.clear();\n }\n\n /**\n * Handle window resize events as a fallback safety mechanism.\n * Golden Layout's ResizeObserver should handle most cases, but this\n * ensures the layout is properly sized after browser window changes.\n */\n @HostListener('window:resize')\n onWindowResize(): void {\n if (this.layoutInitialized && !this.useSingleResourceMode) {\n this.layoutManager.updateSize();\n }\n }\n\n /**\n * Handle changes to tab bar visibility - switches between single-resource and multi-tab modes\n */\n private handleTabBarVisibilityChange(tabBarVisible: boolean): void {\n // Skip if no change\n if (this.previousTabBarVisible === tabBarVisible) {\n return;\n }\n this.previousTabBarVisible = tabBarVisible;\n\n // Determine if we should use single-resource mode\n const shouldUseSingleResourceMode = !tabBarVisible;\n\n if (shouldUseSingleResourceMode !== this.useSingleResourceMode) {\n this.useSingleResourceMode = shouldUseSingleResourceMode;\n this.cdr.detectChanges();\n\n if (this.useSingleResourceMode) {\n // Transitioning to single-resource mode\n // **CRITICAL FIX**: Wait for the template to render directContentContainer\n // before trying to load content. detectChanges() only marks dirty, doesn't render immediately.\n setTimeout(() => {\n // First, destroy Golden Layout if it was initialized (prevents stale state)\n if (this.layoutInitialized) {\n this.layoutManager.Destroy();\n this.layoutInitialized = false;\n }\n // Load the active tab's content directly (now container will exist)\n this.loadSingleResourceContent();\n }, 0);\n } else {\n // Transitioning to multi-tab mode\n // Pin the previously displayed tab (it was the \"current\" content in single-resource mode)\n // This ensures we only have ONE temporary tab at a time\n const config = this.workspaceManager.GetConfiguration();\n if (config && config.tabs.length > 0) {\n // The new tab (just added via OpenTabForced) is now the activeTabId\n // All OTHER unpinned tabs should be pinned since they represent content\n // the user explicitly kept open\n const updatedTabs = config.tabs.map(tab => {\n // Pin all tabs except the newly active one (which is the temporary tab)\n if (tab.id !== config.activeTabId && !tab.isPinned) {\n return { ...tab, isPinned: true };\n }\n return tab;\n });\n\n // Only update if we actually changed something\n const hasChanges = updatedTabs.some((tab, i) => tab.isPinned !== config.tabs[i].isPinned);\n if (hasChanges) {\n this.workspaceManager.UpdateConfiguration({\n ...config,\n tabs: updatedTabs\n });\n }\n }\n\n // Clean up direct component, Golden Layout will handle tabs\n this.cleanupSingleResourceComponent();\n this.currentSingleResourceSignature = null; // Reset tracking\n\n // Reset layout initialized flag since we're switching from single-resource mode\n // The gl-container is a new DOM element (due to @if), so we need fresh initialization\n this.layoutInitialized = false;\n\n // Initialize Golden Layout - use setTimeout to allow the template to update first\n // and ensure the gl-container div exists in the DOM\n // IMPORTANT: Use forceCreateTabs=true to create tabs fresh from config.tabs\n // instead of restoring potentially stale saved layout structure\n setTimeout(() => {\n this.initializeGoldenLayout(true /* forceCreateTabs */);\n }, 0);\n }\n }\n }\n\n /**\n * Load content directly for single-resource mode (bypasses Golden Layout)\n */\n private async loadSingleResourceContent(): Promise<void> {\n // Wait for next tick to ensure the container is rendered\n await Promise.resolve();\n\n const config = this.workspaceManager.GetConfiguration();\n if (!config || config.tabs.length === 0) {\n return;\n }\n\n // Get the active tab (or first tab)\n const activeTab = config.tabs.find(t => t.id === config.activeTabId) || config.tabs[0];\n if (!activeTab) {\n return;\n }\n\n // Track which content we're loading (signature includes resource type and record ID)\n const newSignature = this.getTabContentSignature(activeTab);\n if (this.currentSingleResourceSignature === newSignature) {\n // Content already loaded, no action needed\n return;\n }\n this.currentSingleResourceSignature = newSignature;\n\n // Get the container element\n const container = this.directContentContainer?.nativeElement;\n if (!container) {\n console.warn('Direct content container not available yet, retrying...');\n // Retry after view is updated\n setTimeout(() => this.loadSingleResourceContent(), 50);\n return;\n }\n\n // Create ResourceData from tab\n const resourceData = await this.getResourceDataFromTab(activeTab);\n if (!resourceData) {\n LogError(`Unable to create ResourceData for tab: ${activeTab.title}`);\n return;\n }\n\n // Get driver class for component lookup\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n\n // **OPTIMIZATION: Check cache first to reuse existing loaded component**\n const cached = this.cacheManager.getCachedComponent(\n driverClass,\n resourceData.ResourceRecordID || '',\n activeTab.applicationId\n );\n\n if (cached) {\n // Clean up previous single-resource component (if different)\n this.cleanupSingleResourceComponent();\n\n // Detach from tab tracking (it was attached to a tab in Golden Layout)\n this.cacheManager.markAsDetached(activeTab.id);\n\n // Reattach the cached wrapper element to single-resource container\n cached.wrapperElement.style.height = \"100%\"; // Ensure full height\n container.appendChild(cached.wrapperElement);\n\n // Store reference for cleanup\n this.singleResourceComponentRef = cached.componentRef;\n\n return;\n }\n\n // Get the component registration (with lazy loading fallback via ClassFactory)\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n LogError(`Unable to find resource registration for driver class: ${driverClass}`);\n return;\n }\n\n // Clean up previous component if any\n this.cleanupSingleResourceComponent();\n\n // Create the component dynamically\n const componentRef = createComponent(resourceReg.SubClass, {\n environmentInjector: this.environmentInjector\n });\n\n // Attach to Angular's change detection\n this.appRef.attachView(componentRef.hostView);\n\n // Set the resource data on the component\n const instance = componentRef.instance as BaseResourceComponent;\n instance.Data = resourceData;\n\n // Wire up events\n instance.LoadCompleteEvent = () => {\n this.emitFirstLoadCompleteOnce();\n };\n\n // Wire up display name change for single-resource mode\n // Use a closure that resolves the tab ID at call time, not at wire-up time,\n // because the tab may not be active yet when the component is first created.\n instance.DisplayNameChangedEvent = (newName: string) => {\n const tabId = this.workspaceManager.GetActiveTabId();\n if (tabId) {\n this.workspaceManager.UpdateTabTitle(tabId, newName);\n }\n };\n\n // Get the native element and append to container\n const nativeElement = (componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n container.appendChild(nativeElement);\n // now make sure that the container's direct child is 100% height\n if (container.children?.length > 0) {\n (container.children[0] as any).style.height = \"100%\";\n }\n\n // Store reference for cleanup\n this.singleResourceComponentRef = componentRef as ComponentRef<BaseResourceComponent>;\n }\n\n /**\n * Clean up single-resource mode component\n */\n private cleanupSingleResourceComponent(): void {\n if (this.singleResourceComponentRef) {\n this.appRef.detachView(this.singleResourceComponentRef.hostView);\n this.singleResourceComponentRef.destroy();\n this.singleResourceComponentRef = null;\n }\n\n // Clear the container\n const container = this.directContentContainer?.nativeElement;\n if (container) {\n container.innerHTML = '';\n }\n }\n\n /**\n * Generate a signature for tab content to detect when content changes\n * This is needed because in single-resource mode, the same tab ID can have different content\n */\n private getTabContentSignature(tab: WorkspaceTab): string {\n // Include key identifying fields that determine what component/content is shown\n // IMPORTANT: Check both resourceRecordId AND configuration.recordId\n // because for nav items, the recordId is stored in configuration, not resourceRecordId\n const effectiveRecordId = tab.resourceRecordId || (tab.configuration?.recordId as string) || '';\n const parts = [\n tab.applicationId,\n tab.configuration?.resourceType || '',\n tab.configuration?.driverClass || '',\n tab.configuration?.Entity || '', // Include Entity name for Records resource type\n effectiveRecordId,\n tab.configuration?.route || ''\n ];\n return parts.join('|');\n }\n\n /**\n * Create a tab in Golden Layout from workspace tab data\n */\n private createTab(tab: WorkspaceTab): void {\n const app = this.appManager.GetAppById(tab.applicationId);\n const appColor = app?.GetColor() || '#757575';\n\n const state: TabComponentState = {\n tabId: tab.id,\n appId: tab.applicationId,\n appColor,\n title: tab.title,\n route: tab.configuration['route'] as string || '',\n isPinned: tab.isPinned,\n isLoaded: false\n };\n\n this.layoutManager.AddTab(state);\n\n // Load display name in background without loading full component\n this.updateTabDisplayName(tab);\n }\n\n /**\n * Handle tab shown event for lazy loading\n */\n private async onTabShown(event: TabShownEvent): Promise<void> {\n if (event.isFirstShow) {\n // Load content for this tab\n await this.loadTabContent(event.tabId, event.container);\n this.layoutManager.MarkTabLoaded(event.tabId);\n }\n }\n\n /**\n * Load content into a tab container\n * Uses component cache to reuse components for same resources\n */\n private async loadTabContent(tabId: string, container: unknown): Promise<void> {\n // Per-tab guard: prevent concurrent loads of the same tab content.\n // This can happen when a tab's content changes while active — both the workspace\n // config subscription reload path and onTabShown can race to call this method.\n if (this.tabsCurrentlyLoading.has(tabId)) {\n return;\n }\n this.tabsCurrentlyLoading.add(tabId);\n\n try {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n LogError(`Tab not found: ${tabId}`);\n return;\n }\n\n // Get the container element from Golden Layout\n const glContainer = container as { element: HTMLElement };\n if (!glContainer?.element) {\n LogError('Golden Layout container element not found');\n return;\n }\n\n // Extract resource data from tab configuration\n const resourceData = await this.getResourceDataFromTab(tab);\n if (!resourceData) {\n LogError(`Unable to create ResourceData for tab: ${tab.title}`);\n return;\n }\n\n // Clear any existing content from the container (important for tab reuse)\n glContainer.element.innerHTML = '';\n\n // Get driver class for cache lookup (resolves to actual component class name)\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n\n // Check if we have a cached component for this resource\n const cached = this.cacheManager.getCachedComponent(\n driverClass,\n resourceData.ResourceRecordID || '',\n tab.applicationId\n );\n\n if (cached) {\n // Reattach the cached wrapper element\n glContainer.element.appendChild(cached.wrapperElement);\n\n // Mark as attached to this tab\n this.cacheManager.markAsAttached(\n driverClass,\n resourceData.ResourceRecordID || '',\n tab.applicationId,\n tabId\n );\n\n // Keep legacy componentRefs map updated\n this.componentRefs.set(tabId, cached.componentRef);\n\n // If resource is already loaded, update tab title immediately\n const instance = cached.componentRef.instance as BaseResourceComponent;\n if (instance.LoadComplete) {\n this.updateTabTitleFromResource(tabId, instance, resourceData);\n }\n\n return;\n }\n\n // Get the component registration using the driver class (with lazy loading fallback via ClassFactory)\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n LogError(`Unable to find resource registration for driver class: ${driverClass}`);\n return;\n }\n\n // Create the component dynamically\n const componentRef = createComponent(resourceReg.SubClass, {\n environmentInjector: this.environmentInjector\n });\n\n // Attach to Angular's change detection\n this.appRef.attachView(componentRef.hostView);\n\n // Set the resource data on the component\n const instance = componentRef.instance as BaseResourceComponent;\n instance.Data = resourceData;\n\n // Wire up events\n instance.LoadCompleteEvent = () => {\n // Tab content loaded - update tab title with resource display name\n this.updateTabTitleFromResource(tabId, instance, resourceData);\n this.emitFirstLoadCompleteOnce();\n };\n\n instance.ResourceRecordSavedEvent = (entity: { Get?: (key: string) => unknown }) => {\n // Update tab title if needed\n if (entity && entity.Get && entity.Get('Name')) {\n // TODO: Implement UpdateTabTitle in WorkspaceStateManager\n }\n };\n\n // Wire up display name change notifications\n instance.DisplayNameChangedEvent = (newName: string) => {\n this.layoutManager.UpdateTabStyle(tabId, { title: newName });\n this.workspaceManager.UpdateTabTitle(tabId, newName);\n };\n\n // Create a container div for the component\n const componentElement = document.createElement('div');\n componentElement.className = 'tab-content-wrapper';\n componentElement.style.cssText = 'width: 100%; height: 100%;';\n\n // Append the component's native element\n const nativeElement = (componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n componentElement.appendChild(nativeElement);\n\n // Add to Golden Layout container\n glContainer.element.appendChild(componentElement);\n\n // Cache the component for future reuse\n this.cacheManager.cacheComponent(\n componentRef as ComponentRef<BaseResourceComponent>,\n componentElement,\n resourceData,\n tabId\n );\n\n // Store reference for cleanup (legacy)\n this.componentRefs.set(tabId, componentRef as ComponentRef<BaseResourceComponent>);\n\n } catch (e) {\n LogError(e);\n } finally {\n this.tabsCurrentlyLoading.delete(tabId);\n }\n }\n\n /**\n * Update tab display name in background without loading full component\n * This ensures all tabs show proper names immediately, not just when clicked\n */\n private async updateTabDisplayName(tab: WorkspaceTab): Promise<void> {\n try {\n // Only update display names for resource-based tabs\n const resourceType = tab.configuration['resourceType'] as string;\n if (!resourceType) {\n return;\n }\n\n // Get ResourceData from tab\n const resourceData = await this.getResourceDataFromTab(tab);\n if (!resourceData) {\n return;\n }\n\n // Get the resource registration to access GetResourceDisplayName without loading full component\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n return;\n }\n\n // Create a lightweight instance just to call GetResourceDisplayName\n const tempInstance = new resourceReg.SubClass() as BaseResourceComponent;\n const displayName = await tempInstance.GetResourceDisplayName(resourceData);\n\n if (displayName && displayName !== tab.title) {\n // Update the tab title in Golden Layout\n this.layoutManager.UpdateTabStyle(tab.id, { title: displayName });\n\n // Update the tab title in workspace configuration for persistence\n this.workspaceManager.UpdateTabTitle(tab.id, displayName);\n }\n } catch (error) {\n console.error('[TabContainer.updateTabDisplayName] Error updating tab display name:', error);\n }\n }\n\n /**\n * Update tab title with resource display name after resource loads\n */\n private async updateTabTitleFromResource(\n tabId: string,\n resourceComponent: BaseResourceComponent,\n resourceData: ResourceData\n ): Promise<void> {\n try {\n // Get the display name from the resource component\n const displayName = await resourceComponent.GetResourceDisplayName(resourceData);\n\n if (!displayName) {\n return;\n }\n\n // Update the tab title in Golden Layout\n this.layoutManager.UpdateTabStyle(tabId, { title: displayName });\n\n // Update the tab title in workspace configuration for persistence\n this.workspaceManager.UpdateTabTitle(tabId, displayName);\n\n } catch (error) {\n console.error('[TabContainer.updateTabTitleFromResource] Error updating tab title:', error);\n }\n }\n\n /**\n * Convert tab configuration to ResourceData\n */\n private async getResourceDataFromTab(tab: WorkspaceTab): Promise<ResourceData | null> {\n const config = tab.configuration;\n\n // Extract resource type from configuration or route\n let resourceType = config['resourceType'] as string;\n\n if (!resourceType && config['route']) {\n // Parse route to determine resource type\n resourceType = this.getResourceTypeFromRoute(config['route'] as string);\n }\n\n if (!resourceType) {\n console.error('[TabContainer.getResourceDataFromTab] No resourceType found in config or route');\n return null;\n }\n\n // Determine the driver class to use for component instantiation\n let driverClass = resourceType; // Default: use resourceType as driver class\n\n // For Custom resource type, get DriverClass from configuration or ResourceType metadata\n if (resourceType.toLowerCase() === 'custom') {\n // Custom resource type uses NavItem's DriverClass\n driverClass = config['driverClass'] as string;\n\n if (!driverClass) {\n LogError('Custom resource type requires driverClass in configuration');\n console.error('[TabContainer.getResourceDataFromTab] Missing driverClass for Custom resource type');\n return null;\n }\n } else {\n // For standard resource types, look up DriverClass from metadata\n const resourceTypeEntity = await this.getResourceTypeEntity(resourceType);\n\n if (resourceTypeEntity?.DriverClass) {\n driverClass = resourceTypeEntity.DriverClass;\n } \n // If no DriverClass in metadata, fall back to resourceType (backward compatibility)\n }\n\n // Include applicationId and driverClass in configuration\n const resourceConfig = {\n ...config,\n applicationId: tab.applicationId,\n resourceTypeDriverClass: driverClass // Store resolved driver class for component lookup\n };\n\n // Get ResourceRecordID from config or fall back to tab.resourceRecordId\n // Important: Some tabs store the record ID in config['recordId'], others in tab.resourceRecordId\n const resourceRecordId = (config['recordId'] as string) || tab.resourceRecordId || '';\n\n const resourceData = new ResourceData({\n ResourceTypeID: await this.getResourceTypeId(resourceType),\n ResourceRecordID: resourceRecordId,\n Configuration: resourceConfig\n });\n\n return resourceData;\n }\n\n private static _resourceTypesDataset: DatasetResultType | null = null;\n\n /**\n * Get ResourceType entity by name (includes DriverClass field)\n */\n private async getResourceTypeEntity(resourceType: string): Promise<MJResourceTypeEntity | null> {\n // Use ResourcePermissionEngine's cached data instead of fetching the dataset again.\n // The engine loads ResourceTypes during startup and keeps them in memory.\n const resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;\n if (resourceTypes && resourceTypes.length > 0) {\n const rt = resourceTypes.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase());\n return rt || null;\n }\n\n // Fallback: if engine hasn't loaded yet (shouldn't happen in normal flow),\n // fetch the dataset directly\n const md = new Metadata();\n const ds = TabContainerComponent._resourceTypesDataset || await md.GetDatasetByName(\"ResourceTypes\");\n if (!ds || !ds.Success || ds.Results.length === 0) {\n return null;\n }\n\n if (!TabContainerComponent._resourceTypesDataset) {\n TabContainerComponent._resourceTypesDataset = ds; // cache for next time\n }\n\n const result = ds.Results.find(r => r.Code.trim().toLowerCase() === 'resourcetypes');\n if (result && result.Results?.length > 0) {\n const rt = result.Results.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase()) as MJResourceTypeEntity;\n return rt || null;\n }\n\n return null;\n }\n\n private async getResourceTypeId(resourceType: string): Promise<string> {\n const rt = await this.getResourceTypeEntity(resourceType);\n if (rt) {\n return rt.ID;\n }\n throw new Error(`ResourceType ID not found for type: ${resourceType}`);\n }\n\n /**\n * Determine resource type from route\n */\n private getResourceTypeFromRoute(route: string): string {\n // Parse route segments to determine resource type\n const segments = route.split('/').filter(s => s);\n\n if (segments.length === 0) {\n return 'home';\n }\n\n // Common route patterns\n if (route.includes('/record/')) {\n return 'record';\n }\n if (route.includes('/view/')) {\n return 'view';\n }\n if (route.includes('/dashboard/')) {\n return 'dashboard';\n }\n if (route.includes('/report/')) {\n return 'report';\n }\n if (route.includes('/search')) {\n return 'search';\n }\n if (route.includes('/query/')) {\n return 'query';\n }\n\n // Default based on first segment\n return segments[0] || 'home';\n }\n\n /**\n * Count the number of component nodes in a layout tree.\n * Used to validate that saved layout matches the tabs array before restoring.\n */\n private countLayoutComponents(node: LayoutNode): number {\n if (!node) {\n return 0;\n }\n\n // If this is a component node, count it\n if (node.type === 'component') {\n return 1;\n }\n\n // If this node has children (row, column, stack), recursively count them\n if (node.content && Array.isArray(node.content)) {\n return node.content.reduce((count, child) => count + this.countLayoutComponents(child), 0);\n }\n\n return 0;\n }\n\n /**\n * Cleanup a tab's component\n * Detaches from DOM but keeps in cache for potential reuse\n */\n private cleanupTabComponent(tabId: string): void {\n // First, try to detach from cache (preserves component for reuse)\n const cachedInfo = this.cacheManager.markAsDetached(tabId);\n\n if (cachedInfo) {\n // Remove from legacy componentRefs but keep in cache\n this.componentRefs.delete(tabId);\n } else {\n // Fallback: destroy if not in cache (shouldn't happen in normal flow)\n const componentRef = this.componentRefs.get(tabId);\n if (componentRef) {\n this.appRef.detachView(componentRef.hostView);\n componentRef.destroy();\n this.componentRefs.delete(tabId);\n }\n }\n }\n\n /**\n * Sync tabs with configuration changes\n */\n private syncTabsWithConfiguration(tabs: WorkspaceTab[]): void {\n // Get existing tab IDs from Golden Layout\n const existingTabIds = this.layoutManager.GetAllTabIds();\n\n // Get tab IDs from configuration\n const configTabIds = tabs.map(tab => tab.id);\n\n // Remove tabs that are no longer in configuration\n existingTabIds.forEach(tabId => {\n if (!configTabIds.includes(tabId)) {\n this.layoutManager.RemoveTab(tabId);\n }\n });\n\n // Create tabs that don't exist yet\n tabs.forEach(tab => {\n if (!existingTabIds.includes(tab.id)) {\n this.createTab(tab);\n } else {\n // Check if tab content needs to be reloaded (app or resource type changed)\n const existingComponentRef = this.componentRefs.get(tab.id);\n if (existingComponentRef) {\n const existingResourceData = existingComponentRef.instance.Data;\n\n // For Custom resource types, also check driverClass to distinguish between different custom resources\n const existingDriverClass = existingResourceData?.Configuration?.driverClass || existingResourceData?.Configuration?.resourceTypeDriverClass;\n const newDriverClass = tab.configuration['driverClass'] || tab.configuration['resourceTypeDriverClass'];\n\n // Normalize record IDs for comparison (treat null/undefined as empty string)\n // IMPORTANT: Check both tab.resourceRecordId AND tab.configuration['recordId']\n // because for nav items, the recordId is stored in configuration, not resourceRecordId\n const existingRecordId = existingResourceData?.ResourceRecordID || '';\n const newRecordId = tab.resourceRecordId || tab.configuration['recordId'] as string || '';\n\n const needsReload = existingResourceData?.ResourceType !== tab.configuration['resourceType'] ||\n existingResourceData?.Configuration?.applicationId !== tab.applicationId ||\n existingRecordId !== newRecordId ||\n (tab.configuration['resourceType'] === 'Custom' && existingDriverClass !== newDriverClass);\n\n if (needsReload) {\n // Clean up old component\n this.cleanupTabComponent(tab.id);\n\n // Mark tab as not loaded so it will reload when shown\n this.layoutManager.MarkTabNotLoaded(tab.id);\n\n // Update display name in background\n this.updateTabDisplayName(tab);\n\n // If this tab is currently active, reload it immediately\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId === tab.id) {\n const glContainer = this.layoutManager.GetContainer(tab.id);\n if (glContainer) {\n this.loadTabContent(tab.id, glContainer);\n }\n }\n }\n }\n\n // Update styling for existing tabs\n const app = this.appManager.GetAppById(tab.applicationId);\n this.layoutManager.UpdateTabStyle(tab.id, {\n isPinned: tab.isPinned,\n title: tab.title,\n appColor: app?.GetColor() || '#757575'\n });\n }\n });\n\n // Focus the active tab\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n }\n\n\n /**\n * Show context menu\n */\n showContextMenu(x: number, y: number, tabId: string): void {\n this.contextMenuX = x;\n this.contextMenuY = y;\n this.contextMenuTabId = tabId;\n this.contextMenuVisible = true;\n\n // Close menu when clicking outside - use setTimeout to avoid immediate trigger\n setTimeout(() => {\n const clickHandler = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest('.context-menu')) {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n const keyHandler = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n document.addEventListener('click', clickHandler);\n document.addEventListener('keydown', keyHandler);\n }, 0);\n }\n\n /**\n * Hide context menu\n */\n hideContextMenu(): void {\n this.contextMenuVisible = false;\n this.contextMenuTabId = null;\n }\n\n /**\n * Check if context menu tab is pinned\n */\n get isContextTabPinned(): boolean {\n if (!this.contextMenuTabId) return false;\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n return tab?.isPinned || false;\n }\n\n /**\n * Toggle pin from context menu\n */\n onContextPin(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.TogglePin(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tab from context menu\n */\n onContextClose(): void {\n if (this.contextMenuTabId) {\n this.layoutManager.RemoveTab(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close all other tabs from context menu\n */\n onContextCloseOthers(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseOtherTabs(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tabs to the right from context menu\n */\n onContextCloseToRight(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseTabsToRight(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Check if context menu tab is pinned to Home dashboard\n */\n get isContextTabPinnedToHome(): boolean {\n if (!this.contextMenuTabId) return false;\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n if (!tab) return false;\n const resourceType = this.resolveResourceType(tab);\n return this.pinService.IsPinned(resourceType, tab.configuration as Record<string, unknown>);\n }\n\n /**\n * Pin current context menu tab to Home dashboard\n */\n async onContextPinToHome(): Promise<void> {\n if (this.isContextTabPinnedToHome) {\n this.hideContextMenu();\n return;\n }\n if (!this.contextMenuTabId) {\n this.hideContextMenu();\n return;\n }\n\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n if (!tab) {\n this.hideContextMenu();\n return;\n }\n\n const resourceType = this.resolveResourceType(tab);\n const activeApp = this.appManager.GetActiveApp();\n\n // Resolve nav item icon for Custom pins\n let pinIcon: string | undefined;\n if (resourceType === 'Custom' && activeApp) {\n const navItemName = tab.configuration?.['navItemName'] as string;\n if (navItemName) {\n const navItems = await activeApp.GetNavItems();\n const navItem = navItems.find(ni => ni.Label === navItemName);\n pinIcon = navItem?.Icon || undefined;\n }\n }\n\n const added = this.pinService.AddPin({\n DisplayName: tab.title || 'Untitled',\n ResourceType: resourceType,\n ApplicationID: tab.applicationId || activeApp?.ID,\n ApplicationName: activeApp?.Name,\n Icon: pinIcon,\n Color: activeApp?.GetColor() || undefined,\n Configuration: tab.configuration as Record<string, unknown>,\n });\n\n if (added) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Pinned \"${tab.title}\" to Home`, 'success', 2000\n );\n this.captureContextTabThumbnail(tab);\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${tab.title}\" is already pinned to Home`, 'info', 3000\n );\n }\n\n this.hideContextMenu();\n }\n\n /**\n * Resolve a WorkspaceTab's resource type string for pin matching\n */\n private resolveResourceType(tab: WorkspaceTab): string {\n const config = tab.configuration;\n const rt = (config.resourceType as string) || '';\n if (rt === 'Dashboards' || config['dashboardId']) return 'Dashboards';\n if (rt === 'User Views' || rt === 'MJ: User Views' || config['viewId']) return 'User Views';\n if (rt === 'Queries' || config['queryId']) return 'Queries';\n if (rt === 'Reports' || config['reportId']) return 'Reports';\n if (rt === 'Records' || (config['entity'] && config['recordId'])) return 'Records';\n if (rt === 'Custom' || config['navItemName']) return 'Custom';\n return rt || 'Custom';\n }\n\n /**\n * Capture thumbnail for a just-pinned tab (async, non-blocking)\n */\n private async captureContextTabThumbnail(tab: WorkspaceTab): Promise<void> {\n try {\n // Find the active content element — differs by mode\n let contentEl: HTMLElement | null = null;\n if (this.useSingleResourceMode) {\n contentEl = this.directContentContainer?.nativeElement ?? null;\n } else {\n // In Golden Layout mode, find the active tab's content pane\n contentEl = this.glContainer?.nativeElement?.querySelector(\n '.lm_item_container .lm_content'\n ) as HTMLElement | null;\n }\n if (!contentEl) return;\n\n const thumbnail = await this.pinService.CaptureThumbnail(contentEl);\n if (thumbnail) {\n const resourceType = this.resolveResourceType(tab);\n const pin = this.pinService.FindPin(resourceType, tab.configuration as Record<string, unknown>);\n if (pin) {\n this.pinService.UpdatePin(pin.Id, { Thumbnail: thumbnail });\n }\n }\n } catch {\n // Thumbnail capture is best-effort\n }\n }\n\n /**\n * Public method for external callers (e.g. shell) to capture a thumbnail\n * of the currently visible content, regardless of mode.\n */\n public async CaptureActiveThumbnail(): Promise<string | undefined> {\n try {\n let contentEl: HTMLElement | null = null;\n if (this.useSingleResourceMode) {\n contentEl = this.directContentContainer?.nativeElement ?? null;\n } else {\n contentEl = this.glContainer?.nativeElement?.querySelector(\n '.lm_item_container .lm_content'\n ) as HTMLElement | null;\n }\n if (!contentEl) return undefined;\n return await this.pinService.CaptureThumbnail(contentEl);\n } catch {\n return undefined;\n }\n }\n\n /**\n * While the naming implies this is only invoked once, components we DO NOT CONTROL might have race\n * conditions that result in unpredictable behavior. To avoid those causing loading screen overaly to show\n * forever we emit all events upstream\n */\n private emitFirstLoadCompleteOnce(): void {\n this.firstResourceLoadComplete.emit(); // do this each time to be sure we don't suppress messages\n }\n}\n","<div class=\"tab-container\">\n\n <!-- Single-Resource Mode: Direct component rendering without Golden Layout -->\n <!-- This avoids the 20px height issue when GL header is hidden -->\n @if (useSingleResourceMode) {\n <div #directContentContainer class=\"direct-content-container\"></div>\n } @else {\n <!-- Multi-Tab Mode: Golden Layout Container -->\n <div #glContainer class=\"gl-container\"></div>\n }\n\n <!-- Context Menu (only relevant in multi-tab mode) -->\n @if (contextMenuVisible) {\n <div\n class=\"context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\">\n <div class=\"context-menu-item\" (click)=\"onContextPin()\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n <span>{{ isContextTabPinned ? 'Unpin Tab' : 'Pin Tab' }}</span>\n </div>\n <div class=\"context-menu-divider\"></div>\n <div class=\"context-menu-item\" [class.new-item]=\"!isContextTabPinnedToHome\" [class.disabled]=\"isContextTabPinnedToHome\" (click)=\"onContextPinToHome()\">\n <i class=\"fa-solid fa-house-chimney\"></i>\n @if (isContextTabPinnedToHome) {\n <span>Pinned to Home</span>\n <span class=\"check\"><i class=\"fa-solid fa-check\"></i></span>\n } @else {\n <span>Pin to Home</span>\n }\n </div>\n <div class=\"context-menu-divider\"></div>\n <div class=\"context-menu-item\" (click)=\"onContextClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n <span>Close Tab</span>\n </div>\n <div class=\"context-menu-item\" (click)=\"onContextCloseOthers()\">\n <i class=\"fa-solid fa-layer-group\"></i>\n <span>Close Others</span>\n </div>\n <div class=\"context-menu-item\" (click)=\"onContextCloseToRight()\">\n <i class=\"fa-solid fa-angles-right\"></i>\n <span>Close to Right</span>\n </div>\n </div>\n }\n</div>\n"]}
1
+ {"version":3,"file":"tab-container.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts","../../../../../src/lib/shell/components/tabs/tab-container.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n OnInit,\n OnDestroy,\n AfterViewInit,\n ViewChild,\n ElementRef,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n ComponentRef,\n ViewEncapsulation,\n ChangeDetectorRef,\n HostListener,\n Output,\n EventEmitter,\n inject\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport {\n GoldenLayoutManager,\n WorkspaceStateManager,\n ApplicationManager,\n TabComponentState,\n TabShownEvent,\n WorkspaceTab,\n LayoutNode\n} from '@memberjunction/ng-base-application';\nimport { MJGlobal } from '@memberjunction/global';\nimport { BaseResourceComponent, HomeAppPinService } from '@memberjunction/ng-shared';\nimport { ResourceData, MJResourceTypeEntity, ResourcePermissionEngine } from '@memberjunction/core-entities';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { DatasetResultType, LogError, Metadata } from '@memberjunction/core';\nimport { ComponentCacheManager } from './component-cache-manager';\n\n/**\n * Container for Golden Layout tabs with app-colored styling.\n *\n * Handles:\n * - Golden Layout initialization\n * - Tab creation and styling\n * - Lazy loading of tab content\n * - Context menu for pin/close\n * - Layout persistence\n */\n@Component({\n standalone: false,\n selector: 'mj-tab-container',\n templateUrl: './tab-container.component.html',\n styleUrls: ['./tab-container.component.css'],\n encapsulation: ViewEncapsulation.None\n})\nexport class TabContainerComponent implements OnInit, OnDestroy, AfterViewInit {\n @ViewChild('glContainer', { static: false }) glContainer!: ElementRef<HTMLDivElement>;\n @ViewChild('directContentContainer', { static: false }) directContentContainer!: ElementRef<HTMLDivElement>;\n\n /**\n * Emitted when the first resource component finishes loading.\n * This allows the shell to keep showing its loading indicator until the first\n * resource is ready, eliminating the visual gap between shell loading and resource loading.\n */\n @Output() firstResourceLoadComplete = new EventEmitter<void>();\n\n /**\n * Emitted when Golden Layout fails to initialize after multiple retries.\n * The shell can use this to show an error dialog and redirect.\n */\n @Output() layoutInitError = new EventEmitter<void>();\n\n private pinService = inject(HomeAppPinService);\n private subscriptions: Subscription[] = [];\n private layoutInitRetryCount = 0;\n private readonly MAX_LAYOUT_INIT_RETRIES = 5;\n private layoutInitialized = false;\n private layoutRestorationComplete = false; // True only AFTER layout is fully restored/created\n\n // Track component references for cleanup (legacy - keep for backward compat during transition)\n private componentRefs = new Map<string, ComponentRef<BaseResourceComponent>>();\n\n // Guard against concurrent loadTabContent calls for the same tab.\n // When a tab's content changes while active, both the reload path (workspace config subscription)\n // and onTabShown can race to call loadTabContent, resulting in duplicate component rendering.\n private tabsCurrentlyLoading = new Set<string>();\n\n // NEW: Smart component cache for preserving state across tab switches\n private cacheManager: ComponentCacheManager;\n\n // Single-resource mode: render component directly without Golden Layout\n // This avoids the 20px height issue when GL header is hidden\n useSingleResourceMode = false;\n private singleResourceComponentRef: ComponentRef<BaseResourceComponent> | null = null;\n /** Cache identity of the current single-resource component for detachment */\n private singleResourceCacheIdentity: { driverClass: string; recordId: string; appId: string; tabId: string } | null = null;\n private previousTabBarVisible: boolean | null = null;\n private currentSingleResourceSignature: string | null = null; // Track loaded content signature to avoid unnecessary reloads\n private isCreatingInitialTabs = false; // Flag to prevent syncTabsWithConfiguration during initial tab creation\n\n // Context menu state\n contextMenuVisible = false;\n contextMenuX = 0;\n contextMenuY = 0;\n contextMenuTabId: string | null = null;\n\n constructor(\n private layoutManager: GoldenLayoutManager,\n private workspaceManager: WorkspaceStateManager,\n private appManager: ApplicationManager,\n private appRef: ApplicationRef,\n private environmentInjector: EnvironmentInjector,\n private cdr: ChangeDetectorRef\n ) {\n // Initialize component cache manager\n this.cacheManager = new ComponentCacheManager(this.appRef);\n }\n\n ngOnInit(): void {\n // Subscribe to tab events\n this.subscriptions.push(\n this.layoutManager.TabShown.subscribe(event => {\n this.onTabShown(event);\n }),\n this.layoutManager.TabClosed.subscribe(tabId => {\n this.cleanupTabComponent(tabId);\n this.workspaceManager.CloseTab(tabId);\n }),\n this.layoutManager.LayoutChanged.subscribe(event => {\n const layout = this.layoutManager.SaveLayout();\n this.workspaceManager.UpdateLayout(layout);\n }),\n this.layoutManager.ActiveTab.subscribe(tabId => {\n if (tabId) {\n this.workspaceManager.SetActiveTab(tabId);\n }\n }),\n this.layoutManager.TabDoubleClicked.subscribe(tabId => {\n this.workspaceManager.TogglePin(tabId);\n }),\n this.layoutManager.TabRightClicked.subscribe(event => {\n this.showContextMenu(event.x, event.y, event.tabId);\n })\n );\n\n // Subscribe to configuration changes to sync tabs\n this.subscriptions.push(\n this.workspaceManager.Configuration.subscribe(config => {\n if (config) {\n if (this.useSingleResourceMode) {\n // In single-resource mode, reload content if the tab content changed\n // The same tab ID can have different content (tab gets reused)\n const activeTab = config.tabs.find(t => t.id === config.activeTabId) || config.tabs[0];\n if (activeTab) {\n const signature = this.getTabContentSignature(activeTab);\n if (signature !== this.currentSingleResourceSignature) {\n // DO NOT call saveCurrentComponentQueryParams() here — by the time this\n // subscription fires, OpenTab has already replaced the tab config with the\n // new nav item's config, so queryParams are gone. The cache entry already\n // has the correct queryParams from the most recent unchanged-signature save.\n this.loadSingleResourceContent();\n } else {\n // Signature unchanged — sync queryParams to cache entry so it stays current.\n // This catches incremental queryParam updates (e.g., user selects a conversation).\n this.saveCurrentComponentQueryParams();\n }\n }\n } else if (this.layoutRestorationComplete && !this.isCreatingInitialTabs) {\n // In multi-tab mode, sync with Golden Layout\n // IMPORTANT: Only sync AFTER layout restoration is complete to avoid creating duplicate tabs\n // layoutRestorationComplete is set to true only after initializeGoldenLayout finishes\n this.syncTabsWithConfiguration(config.tabs);\n }\n }\n })\n );\n\n // Subscribe to tab bar visibility changes for single-resource mode\n this.subscriptions.push(\n this.workspaceManager.TabBarVisible.subscribe(tabBarVisible => {\n this.handleTabBarVisibilityChange(tabBarVisible);\n })\n );\n }\n\n ngAfterViewInit(): void {\n // Initialize Golden Layout only if we're not in single-resource mode\n if (!this.useSingleResourceMode) {\n this.initializeGoldenLayout();\n } else {\n // In single-resource mode, load content directly\n this.loadSingleResourceContent();\n }\n }\n\n /**\n * Initialize Golden Layout and load tabs\n * @param forceCreateTabs - If true, always creates tabs fresh from config.tabs instead of restoring saved layout\n */\n private initializeGoldenLayout(forceCreateTabs = false): void {\n // If we are in single resource mode we do NOT need to do this work as golden layout should not exist in that state\n if (this.useSingleResourceMode)\n return;\n\n if (!this.glContainer?.nativeElement) {\n this.layoutInitRetryCount++;\n\n if (this.layoutInitRetryCount > this.MAX_LAYOUT_INIT_RETRIES) {\n console.error(`Golden Layout container not available after ${this.MAX_LAYOUT_INIT_RETRIES} retries, emitting error`);\n this.layoutInitError.emit();\n return;\n }\n\n console.warn(`Golden Layout container not available, retry ${this.layoutInitRetryCount}/${this.MAX_LAYOUT_INIT_RETRIES}...`);\n setTimeout(() => this.initializeGoldenLayout(forceCreateTabs), 50);\n return;\n }\n\n // Reset retry counter on success\n this.layoutInitRetryCount = 0;\n\n if (this.layoutInitialized) {\n return; // Already initialized\n }\n\n // Check if configuration is available\n // If not, wait for it to be loaded before proceeding\n const config = this.workspaceManager.GetConfiguration();\n if (!config) {\n // Configuration not loaded yet - wait for it\n const configSub = this.workspaceManager.Configuration.subscribe(loadedConfig => {\n if (loadedConfig) {\n configSub.unsubscribe();\n // Re-call initializeGoldenLayout now that config is available\n this.initializeGoldenLayout(forceCreateTabs);\n }\n });\n return;\n }\n\n // Initialize Golden Layout (we have config now)\n this.layoutManager.Initialize(this.glContainer.nativeElement);\n\n // Mark layout as initialized\n this.layoutInitialized = true;\n\n // Check if config has no tabs\n if (config.tabs.length === 0) {\n // No tabs to load, but mark restoration as complete\n this.layoutRestorationComplete = true;\n return;\n }\n\n // Check if we have a saved layout structure with actual content\n const hasSavedLayout = config.layout?.root?.content && config.layout.root.content.length > 0;\n\n if (hasSavedLayout && !forceCreateTabs && config.layout) {\n // VALIDATE: Check that layout component count matches tabs array count\n const layoutComponentCount = this.countLayoutComponents(config.layout.root);\n if (layoutComponentCount !== config.tabs.length) {\n console.warn(`[TabContainer.initializeGoldenLayout] Layout/tabs mismatch: layout has ${layoutComponentCount} components but tabs array has ${config.tabs.length} tabs. Clearing layout.`);\n this.workspaceManager.ClearLayout();\n // Fall through to create fresh tabs\n } else {\n // RESTORE SAVED LAYOUT - preserves drag/drop arrangements (stacks, columns, rows)\n // This is the single source of truth for visual arrangement\n const layoutLoaded = this.layoutManager.LoadLayout(config.layout);\n\n if (layoutLoaded) {\n // Mark layout restoration as complete AFTER layout is loaded\n this.layoutRestorationComplete = true;\n\n // Focus active tab and ensure proper sizing\n // Also trigger updateSize() to force Golden Layout to fire 'show' events\n // for the active tab in ALL stacks (not just the globally active tab)\n setTimeout(() => {\n if (config.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n // Trigger resize to ensure all visible tabs in all stacks render their content\n this.layoutManager.updateSize();\n }, 50);\n return; // Layout restored successfully\n }\n\n // Layout load FAILED - clear the corrupted layout and fall through to create tabs fresh\n console.warn('[TabContainer] Saved layout was corrupted, clearing and recreating tabs');\n this.workspaceManager.ClearLayout();\n }\n }\n\n // CREATE FRESH - no saved layout, forceCreateTabs=true, or layout load failed\n // Use config.tabs sorted by sequence to build a simple single-stack layout\n const sortedTabs = [...config.tabs].sort((a, b) => a.sequence - b.sequence);\n\n this.isCreatingInitialTabs = true;\n try {\n sortedTabs.forEach(tab => {\n this.createTab(tab);\n });\n } finally {\n this.isCreatingInitialTabs = false;\n }\n\n // Mark layout restoration as complete AFTER tabs are created\n this.layoutRestorationComplete = true;\n\n setTimeout(() => {\n if (config.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n }, 50);\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach(sub => sub.unsubscribe());\n\n // Cleanup single-resource mode component if exists\n this.cleanupSingleResourceComponent();\n\n // Clear the component cache (destroys all components)\n this.cacheManager.clearCache();\n\n // Cleanup any legacy componentRefs\n this.componentRefs.forEach((ref, _tabId) => {\n this.appRef.detachView(ref.hostView);\n ref.destroy();\n });\n this.componentRefs.clear();\n }\n\n /**\n * Handle window resize events as a fallback safety mechanism.\n * Golden Layout's ResizeObserver should handle most cases, but this\n * ensures the layout is properly sized after browser window changes.\n */\n @HostListener('window:resize')\n onWindowResize(): void {\n if (this.layoutInitialized && !this.useSingleResourceMode) {\n this.layoutManager.updateSize();\n }\n }\n\n /**\n * Handle changes to tab bar visibility - switches between single-resource and multi-tab modes\n */\n private handleTabBarVisibilityChange(tabBarVisible: boolean): void {\n // Skip if no change\n if (this.previousTabBarVisible === tabBarVisible) {\n return;\n }\n this.previousTabBarVisible = tabBarVisible;\n\n // Determine if we should use single-resource mode\n const shouldUseSingleResourceMode = !tabBarVisible;\n\n if (shouldUseSingleResourceMode !== this.useSingleResourceMode) {\n this.useSingleResourceMode = shouldUseSingleResourceMode;\n // Defer detectChanges to next microtask to avoid ExpressionChangedAfterItHasBeenCheckedError\n // when this handler fires during an already-running change detection cycle.\n Promise.resolve().then(() => this.cdr.detectChanges());\n\n if (this.useSingleResourceMode) {\n // Transitioning to single-resource mode\n // **CRITICAL FIX**: Wait for the template to render directContentContainer\n // before trying to load content. detectChanges() only marks dirty, doesn't render immediately.\n setTimeout(() => {\n // First, destroy Golden Layout if it was initialized (prevents stale state)\n if (this.layoutInitialized) {\n this.layoutManager.Destroy();\n this.layoutInitialized = false;\n }\n // Load the active tab's content directly (now container will exist)\n this.loadSingleResourceContent();\n }, 0);\n } else {\n // Transitioning to multi-tab mode\n // Pin the previously displayed tab (it was the \"current\" content in single-resource mode)\n // This ensures we only have ONE temporary tab at a time\n const config = this.workspaceManager.GetConfiguration();\n if (config && config.tabs.length > 0) {\n // The new tab (just added via OpenTabForced) is now the activeTabId\n // All OTHER unpinned tabs should be pinned since they represent content\n // the user explicitly kept open\n const updatedTabs = config.tabs.map(tab => {\n // Pin all tabs except the newly active one (which is the temporary tab)\n if (tab.id !== config.activeTabId && !tab.isPinned) {\n return { ...tab, isPinned: true };\n }\n return tab;\n });\n\n // Only update if we actually changed something\n const hasChanges = updatedTabs.some((tab, i) => tab.isPinned !== config.tabs[i].isPinned);\n if (hasChanges) {\n this.workspaceManager.UpdateConfiguration({\n ...config,\n tabs: updatedTabs\n });\n }\n }\n\n // Clean up direct component, Golden Layout will handle tabs\n this.cleanupSingleResourceComponent();\n this.currentSingleResourceSignature = null; // Reset tracking\n\n // Reset layout initialized flag since we're switching from single-resource mode\n // The gl-container is a new DOM element (due to @if), so we need fresh initialization\n this.layoutInitialized = false;\n\n // Initialize Golden Layout - use setTimeout to allow the template to update first\n // and ensure the gl-container div exists in the DOM\n // IMPORTANT: Use forceCreateTabs=true to create tabs fresh from config.tabs\n // instead of restoring potentially stale saved layout structure\n setTimeout(() => {\n this.initializeGoldenLayout(true /* forceCreateTabs */);\n }, 0);\n }\n }\n }\n\n /**\n * Load content directly for single-resource mode (bypasses Golden Layout)\n */\n private async loadSingleResourceContent(): Promise<void> {\n // Wait for next tick to ensure the container is rendered\n await Promise.resolve();\n\n const config = this.workspaceManager.GetConfiguration();\n if (!config || config.tabs.length === 0) {\n return;\n }\n\n // Get the active tab (or first tab)\n const activeTab = config.tabs.find(t => t.id === config.activeTabId) || config.tabs[0];\n if (!activeTab) {\n return;\n }\n\n // Track which content we're loading (signature includes resource type and record ID)\n const newSignature = this.getTabContentSignature(activeTab);\n if (this.currentSingleResourceSignature === newSignature) {\n // Content already loaded, no action needed\n return;\n }\n this.currentSingleResourceSignature = newSignature;\n\n // Get the container element\n const container = this.directContentContainer?.nativeElement;\n if (!container) {\n console.warn('Direct content container not available yet, retrying...');\n // Retry after view is updated\n setTimeout(() => this.loadSingleResourceContent(), 50);\n return;\n }\n\n // Create ResourceData from tab\n const resourceData = await this.getResourceDataFromTab(activeTab);\n if (!resourceData) {\n LogError(`Unable to create ResourceData for tab: ${activeTab.title}`);\n return;\n }\n\n // Get driver class for component lookup\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n\n // **OPTIMIZATION: Check cache first to reuse existing loaded component**\n const cached = this.cacheManager.getCachedComponent(\n driverClass,\n resourceData.ResourceRecordID || '',\n activeTab.applicationId\n );\n\n if (cached) {\n // Clean up previous single-resource component (if different)\n this.cleanupSingleResourceComponent();\n\n // Mark cached component as attached to this tab (it was detached / available for reuse).\n // IMPORTANT: We use markAsAttached here, NOT markAsDetached — the component is being\n // reattached to the DOM and should NOT be eligible for LRU eviction.\n this.cacheManager.markAsAttached(\n driverClass,\n resourceData.ResourceRecordID || '',\n activeTab.applicationId,\n activeTab.id\n );\n\n // Reattach the cached wrapper element to single-resource container\n cached.wrapperElement.style.height = \"100%\"; // Ensure full height\n container.appendChild(cached.wrapperElement);\n\n // Store reference and identity for cleanup/detachment\n this.singleResourceComponentRef = cached.componentRef;\n this.singleResourceCacheIdentity = { driverClass, recordId: resourceData.ResourceRecordID || '', appId: activeTab.applicationId, tabId: activeTab.id };\n\n // Restore saved queryParams to the tab config so the URL reflects\n // the component's preserved state (e.g., selected conversation, collection drill-down).\n if (cached.savedQueryParams) {\n this.workspaceManager.UpdateTabConfiguration(activeTab.id, {\n queryParams: cached.savedQueryParams\n });\n // Do NOT clear savedQueryParams here — the else branch (unchanged-signature saves)\n // will keep it current while the component is active. Clearing it would cause the\n // queryParams to be lost on the next detach/reattach cycle.\n }\n\n return;\n }\n\n // Get the component registration (with lazy loading fallback via ClassFactory)\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n LogError(`Unable to find resource registration for driver class: ${driverClass}`);\n return;\n }\n\n // Clean up previous component if any\n this.cleanupSingleResourceComponent();\n\n // Create the component dynamically\n const componentRef = createComponent(resourceReg.SubClass, {\n environmentInjector: this.environmentInjector\n });\n\n // Attach to Angular's change detection\n this.appRef.attachView(componentRef.hostView);\n\n // Set the resource data on the component\n const instance = componentRef.instance as BaseResourceComponent;\n instance.Data = resourceData;\n\n // Wire up events\n instance.LoadCompleteEvent = () => {\n this.emitFirstLoadCompleteOnce();\n };\n\n // Wire up display name change for single-resource mode.\n // Guard: only update the title if THIS component is the currently displayed one.\n // Without this guard, cached components (detached but alive) can fire this callback\n // and overwrite the active tab's title with a stale name.\n instance.DisplayNameChangedEvent = (newName: string) => {\n if (this.singleResourceComponentRef?.instance === instance) {\n const tabId = this.workspaceManager.GetActiveTabId();\n if (tabId) {\n this.workspaceManager.UpdateTabTitle(tabId, newName);\n }\n }\n };\n\n // Get the native element and append to container\n const nativeElement = (componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n container.appendChild(nativeElement);\n // now make sure that the container's direct child is 100% height\n if (container.children?.length > 0) {\n (container.children[0] as any).style.height = \"100%\";\n }\n\n // Cache the component for reuse when switching between nav items within the same app.\n // Without this, every nav switch creates a brand new component from scratch.\n const wrapperElement = nativeElement;\n this.cacheManager.cacheComponent(\n componentRef as ComponentRef<BaseResourceComponent>,\n wrapperElement,\n resourceData,\n activeTab.id\n );\n\n // Store reference and identity for cleanup/detachment\n this.singleResourceComponentRef = componentRef as ComponentRef<BaseResourceComponent>;\n this.singleResourceCacheIdentity = { driverClass, recordId: resourceData.ResourceRecordID || '', appId: activeTab.applicationId, tabId: activeTab.id };\n }\n\n /**\n * Clean up single-resource mode component\n */\n /**\n * Detaches the current single-resource component from the DOM and marks it as\n * available for reuse in the component cache.\n *\n * ╔══════════════════════════════════════════════════════════════════════════╗\n * ║ ⚠️ DO NOT DESTROY THE COMPONENT HERE — INTENTIONAL DESIGN CHOICE ⚠️ ║\n * ║ ║\n * ║ The component is DETACHED from the DOM, NOT destroyed. It stays alive ║\n * ║ in the ComponentCacheManager with its full Angular state preserved ║\n * ║ (properties, subscriptions, loaded data, scroll position, etc). ║\n * ║ ║\n * ║ When the user returns to this tab, the cached component is reattached ║\n * ║ instantly — no data reload, no API calls, no flash of empty content. ║\n * ║ ║\n * ║ Destroying components here \"for memory optimization\" is a net ║\n * ║ NEGATIVE: the reload on return is far more expensive (DB queries, ║\n * ║ API calls, re-rendering) than keeping the component in memory. ║\n * ║ The LRU eviction in ComponentCacheManager handles memory limits — ║\n * ║ when MaxDetachedComponents is exceeded, the LEAST recently used ║\n * ║ components are evicted automatically. ║\n * ║ ║\n * ║ If you think memory is a problem, adjust MaxDetachedComponents ║\n * ║ instead of destroying components here. ║\n * ╚══════════════════════════════════════════════════════════════════════════╝\n */\n /**\n * Save the currently displayed component's queryParams to its cache entry.\n * Called on every config change so the cache entry always has the latest queryParams,\n * even after the tab config is overwritten by a new nav item.\n */\n private saveCurrentComponentQueryParams(): void {\n if (!this.singleResourceCacheIdentity) return;\n\n const { tabId } = this.singleResourceCacheIdentity;\n const tab = this.workspaceManager.GetTab(tabId);\n const qp = tab?.configuration?.['queryParams'] as Record<string, string> | undefined;\n const cached = this.cacheManager.getComponentByTabId(tabId);\n if (cached) {\n cached.savedQueryParams = (qp && Object.keys(qp).length > 0) ? { ...qp } : undefined;\n }\n }\n\n private cleanupSingleResourceComponent(): void {\n if (this.singleResourceComponentRef) {\n if (this.singleResourceCacheIdentity) {\n const { driverClass, recordId, appId } = this.singleResourceCacheIdentity;\n // Mark as DETACHED by resource identity — the ONE consistent key used everywhere.\n this.cacheManager.markAsDetached(driverClass, recordId, appId);\n }\n this.singleResourceComponentRef = null;\n this.singleResourceCacheIdentity = null;\n }\n\n // Remove children from the container. This detaches the wrapper DOM element\n // without destroying the Angular component — it lives on in the cache.\n // Using removeChild (not innerHTML='') to avoid aggressive DOM cleanup.\n const container = this.directContentContainer?.nativeElement;\n if (container) {\n while (container.firstChild) {\n container.removeChild(container.firstChild);\n }\n }\n }\n\n /**\n * Generate a signature for tab content to detect when content changes\n * This is needed because in single-resource mode, the same tab ID can have different content\n */\n private getTabContentSignature(tab: WorkspaceTab): string {\n // Include key identifying fields that determine what component/content is shown\n // IMPORTANT: Check both resourceRecordId AND configuration.recordId\n // because for nav items, the recordId is stored in configuration, not resourceRecordId\n const effectiveRecordId = tab.resourceRecordId || (tab.configuration?.recordId as string) || '';\n const parts = [\n tab.applicationId,\n tab.configuration?.resourceType || '',\n tab.configuration?.driverClass || '',\n tab.configuration?.Entity || '', // Include Entity name for Records resource type\n effectiveRecordId,\n tab.configuration?.route || ''\n ];\n return parts.join('|');\n }\n\n /**\n * Create a tab in Golden Layout from workspace tab data\n */\n private createTab(tab: WorkspaceTab): void {\n const app = this.appManager.GetAppById(tab.applicationId);\n const appColor = app?.GetColor() || '#757575';\n\n const state: TabComponentState = {\n tabId: tab.id,\n appId: tab.applicationId,\n appColor,\n title: tab.title,\n route: tab.configuration['route'] as string || '',\n isPinned: tab.isPinned,\n isLoaded: false\n };\n\n this.layoutManager.AddTab(state);\n\n // Load display name in background without loading full component\n this.updateTabDisplayName(tab);\n }\n\n /**\n * Handle tab shown event for lazy loading\n */\n private async onTabShown(event: TabShownEvent): Promise<void> {\n if (event.isFirstShow) {\n // Load content for this tab\n await this.loadTabContent(event.tabId, event.container);\n this.layoutManager.MarkTabLoaded(event.tabId);\n }\n }\n\n /**\n * Load content into a tab container\n * Uses component cache to reuse components for same resources\n */\n private async loadTabContent(tabId: string, container: unknown): Promise<void> {\n // Per-tab guard: prevent concurrent loads of the same tab content.\n // This can happen when a tab's content changes while active — both the workspace\n // config subscription reload path and onTabShown can race to call this method.\n if (this.tabsCurrentlyLoading.has(tabId)) {\n return;\n }\n this.tabsCurrentlyLoading.add(tabId);\n\n try {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n LogError(`Tab not found: ${tabId}`);\n return;\n }\n\n // Get the container element from Golden Layout\n const glContainer = container as { element: HTMLElement };\n if (!glContainer?.element) {\n LogError('Golden Layout container element not found');\n return;\n }\n\n // Extract resource data from tab configuration\n const resourceData = await this.getResourceDataFromTab(tab);\n if (!resourceData) {\n LogError(`Unable to create ResourceData for tab: ${tab.title}`);\n return;\n }\n\n // Clear any existing content from the container (important for tab reuse)\n glContainer.element.innerHTML = '';\n\n // Get driver class for cache lookup (resolves to actual component class name)\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n\n // Check if we have a cached component for this resource\n const cached = this.cacheManager.getCachedComponent(\n driverClass,\n resourceData.ResourceRecordID || '',\n tab.applicationId\n );\n\n if (cached) {\n // Reattach the cached wrapper element\n glContainer.element.appendChild(cached.wrapperElement);\n\n // Mark as attached to this tab\n this.cacheManager.markAsAttached(\n driverClass,\n resourceData.ResourceRecordID || '',\n tab.applicationId,\n tabId\n );\n\n // Keep legacy componentRefs map updated\n this.componentRefs.set(tabId, cached.componentRef);\n\n // If resource is already loaded, update tab title immediately\n const instance = cached.componentRef.instance as BaseResourceComponent;\n if (instance.LoadComplete) {\n this.updateTabTitleFromResource(tabId, instance, resourceData);\n }\n\n return;\n }\n\n // Get the component registration using the driver class (with lazy loading fallback via ClassFactory)\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n LogError(`Unable to find resource registration for driver class: ${driverClass}`);\n return;\n }\n\n // Create the component dynamically\n const componentRef = createComponent(resourceReg.SubClass, {\n environmentInjector: this.environmentInjector\n });\n\n // Attach to Angular's change detection\n this.appRef.attachView(componentRef.hostView);\n\n // Set the resource data on the component\n const instance = componentRef.instance as BaseResourceComponent;\n instance.Data = resourceData;\n\n // Wire up events\n instance.LoadCompleteEvent = () => {\n // Tab content loaded - update tab title with resource display name\n this.updateTabTitleFromResource(tabId, instance, resourceData);\n this.emitFirstLoadCompleteOnce();\n };\n\n instance.ResourceRecordSavedEvent = (entity: { Get?: (key: string) => unknown }) => {\n // Update tab title if needed\n if (entity && entity.Get && entity.Get('Name')) {\n // TODO: Implement UpdateTabTitle in WorkspaceStateManager\n }\n };\n\n // Wire up display name change notifications\n instance.DisplayNameChangedEvent = (newName: string) => {\n this.layoutManager.UpdateTabStyle(tabId, { title: newName });\n this.workspaceManager.UpdateTabTitle(tabId, newName);\n };\n\n // Create a container div for the component\n const componentElement = document.createElement('div');\n componentElement.className = 'tab-content-wrapper';\n componentElement.style.cssText = 'width: 100%; height: 100%;';\n\n // Append the component's native element\n const nativeElement = (componentRef.hostView as unknown as { rootNodes: HTMLElement[] }).rootNodes[0];\n componentElement.appendChild(nativeElement);\n\n // Add to Golden Layout container\n glContainer.element.appendChild(componentElement);\n\n // Cache the component for future reuse\n this.cacheManager.cacheComponent(\n componentRef as ComponentRef<BaseResourceComponent>,\n componentElement,\n resourceData,\n tabId\n );\n\n // Store reference for cleanup (legacy)\n this.componentRefs.set(tabId, componentRef as ComponentRef<BaseResourceComponent>);\n\n } catch (e) {\n LogError(e);\n } finally {\n this.tabsCurrentlyLoading.delete(tabId);\n }\n }\n\n /**\n * Update tab display name in background without loading full component\n * This ensures all tabs show proper names immediately, not just when clicked\n */\n private async updateTabDisplayName(tab: WorkspaceTab): Promise<void> {\n try {\n // Only update display names for resource-based tabs\n const resourceType = tab.configuration['resourceType'] as string;\n if (!resourceType) {\n return;\n }\n\n // Get ResourceData from tab\n const resourceData = await this.getResourceDataFromTab(tab);\n if (!resourceData) {\n return;\n }\n\n // Get the resource registration to access GetResourceDisplayName without loading full component\n const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;\n const resourceReg = await MJGlobal.Instance.ClassFactory.GetRegistrationAsync(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n return;\n }\n\n // Create a lightweight instance just to call GetResourceDisplayName\n const tempInstance = new resourceReg.SubClass() as BaseResourceComponent;\n const displayName = await tempInstance.GetResourceDisplayName(resourceData);\n\n if (displayName && displayName !== tab.title) {\n // Update the tab title in Golden Layout\n this.layoutManager.UpdateTabStyle(tab.id, { title: displayName });\n\n // Update the tab title in workspace configuration for persistence\n this.workspaceManager.UpdateTabTitle(tab.id, displayName);\n }\n } catch (error) {\n console.error('[TabContainer.updateTabDisplayName] Error updating tab display name:', error);\n }\n }\n\n /**\n * Update tab title with resource display name after resource loads\n */\n private async updateTabTitleFromResource(\n tabId: string,\n resourceComponent: BaseResourceComponent,\n resourceData: ResourceData\n ): Promise<void> {\n try {\n // Get the display name from the resource component\n const displayName = await resourceComponent.GetResourceDisplayName(resourceData);\n\n if (!displayName) {\n return;\n }\n\n // Update the tab title in Golden Layout\n this.layoutManager.UpdateTabStyle(tabId, { title: displayName });\n\n // Update the tab title in workspace configuration for persistence\n this.workspaceManager.UpdateTabTitle(tabId, displayName);\n\n } catch (error) {\n console.error('[TabContainer.updateTabTitleFromResource] Error updating tab title:', error);\n }\n }\n\n /**\n * Convert tab configuration to ResourceData\n */\n private async getResourceDataFromTab(tab: WorkspaceTab): Promise<ResourceData | null> {\n const config = tab.configuration;\n\n // Extract resource type from configuration or route\n let resourceType = config['resourceType'] as string;\n\n if (!resourceType && config['route']) {\n // Parse route to determine resource type\n resourceType = this.getResourceTypeFromRoute(config['route'] as string);\n }\n\n if (!resourceType) {\n console.error('[TabContainer.getResourceDataFromTab] No resourceType found in config or route');\n return null;\n }\n\n // Determine the driver class to use for component instantiation\n let driverClass = resourceType; // Default: use resourceType as driver class\n\n // For Custom resource type, get DriverClass from configuration or ResourceType metadata\n if (resourceType.toLowerCase() === 'custom') {\n // Custom resource type uses NavItem's DriverClass\n driverClass = config['driverClass'] as string;\n\n if (!driverClass) {\n LogError('Custom resource type requires driverClass in configuration');\n console.error('[TabContainer.getResourceDataFromTab] Missing driverClass for Custom resource type');\n return null;\n }\n } else {\n // For standard resource types, look up DriverClass from metadata\n const resourceTypeEntity = await this.getResourceTypeEntity(resourceType);\n\n if (resourceTypeEntity?.DriverClass) {\n driverClass = resourceTypeEntity.DriverClass;\n } \n // If no DriverClass in metadata, fall back to resourceType (backward compatibility)\n }\n\n // Include applicationId and driverClass in configuration\n const resourceConfig = {\n ...config,\n applicationId: tab.applicationId,\n resourceTypeDriverClass: driverClass // Store resolved driver class for component lookup\n };\n\n // Get ResourceRecordID from config or fall back to tab.resourceRecordId\n // Important: Some tabs store the record ID in config['recordId'], others in tab.resourceRecordId\n const resourceRecordId = (config['recordId'] as string) || tab.resourceRecordId || '';\n\n const resourceData = new ResourceData({\n ResourceTypeID: await this.getResourceTypeId(resourceType),\n ResourceRecordID: resourceRecordId,\n Configuration: resourceConfig\n });\n\n return resourceData;\n }\n\n private static _resourceTypesDataset: DatasetResultType | null = null;\n\n /**\n * Get ResourceType entity by name (includes DriverClass field)\n */\n private async getResourceTypeEntity(resourceType: string): Promise<MJResourceTypeEntity | null> {\n // Use ResourcePermissionEngine's cached data instead of fetching the dataset again.\n // The engine loads ResourceTypes during startup and keeps them in memory.\n const resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;\n if (resourceTypes && resourceTypes.length > 0) {\n const rt = resourceTypes.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase());\n return rt || null;\n }\n\n // Fallback: if engine hasn't loaded yet (shouldn't happen in normal flow),\n // fetch the dataset directly\n const md = new Metadata();\n const ds = TabContainerComponent._resourceTypesDataset || await md.GetDatasetByName(\"ResourceTypes\");\n if (!ds || !ds.Success || ds.Results.length === 0) {\n return null;\n }\n\n if (!TabContainerComponent._resourceTypesDataset) {\n TabContainerComponent._resourceTypesDataset = ds; // cache for next time\n }\n\n const result = ds.Results.find(r => r.Code.trim().toLowerCase() === 'resourcetypes');\n if (result && result.Results?.length > 0) {\n const rt = result.Results.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase()) as MJResourceTypeEntity;\n return rt || null;\n }\n\n return null;\n }\n\n private async getResourceTypeId(resourceType: string): Promise<string> {\n const rt = await this.getResourceTypeEntity(resourceType);\n if (rt) {\n return rt.ID;\n }\n throw new Error(`ResourceType ID not found for type: ${resourceType}`);\n }\n\n /**\n * Determine resource type from route\n */\n private getResourceTypeFromRoute(route: string): string {\n // Parse route segments to determine resource type\n const segments = route.split('/').filter(s => s);\n\n if (segments.length === 0) {\n return 'home';\n }\n\n // Common route patterns\n if (route.includes('/record/')) {\n return 'record';\n }\n if (route.includes('/view/')) {\n return 'view';\n }\n if (route.includes('/dashboard/')) {\n return 'dashboard';\n }\n if (route.includes('/report/')) {\n return 'report';\n }\n if (route.includes('/search')) {\n return 'search';\n }\n if (route.includes('/query/')) {\n return 'query';\n }\n\n // Default based on first segment\n return segments[0] || 'home';\n }\n\n /**\n * Count the number of component nodes in a layout tree.\n * Used to validate that saved layout matches the tabs array before restoring.\n */\n private countLayoutComponents(node: LayoutNode): number {\n if (!node) {\n return 0;\n }\n\n // If this is a component node, count it\n if (node.type === 'component') {\n return 1;\n }\n\n // If this node has children (row, column, stack), recursively count them\n if (node.content && Array.isArray(node.content)) {\n return node.content.reduce((count, child) => count + this.countLayoutComponents(child), 0);\n }\n\n return 0;\n }\n\n /**\n * Cleanup a tab's component\n * Detaches from DOM but keeps in cache for potential reuse\n */\n private cleanupTabComponent(tabId: string): void {\n // First, try to detach from cache (preserves component for reuse)\n const cachedInfo = this.cacheManager.findAndDetachByTabId(tabId);\n\n if (cachedInfo) {\n // Remove from legacy componentRefs but keep in cache\n this.componentRefs.delete(tabId);\n } else {\n // Fallback: destroy if not in cache (shouldn't happen in normal flow)\n const componentRef = this.componentRefs.get(tabId);\n if (componentRef) {\n this.appRef.detachView(componentRef.hostView);\n componentRef.destroy();\n this.componentRefs.delete(tabId);\n }\n }\n }\n\n /**\n * Sync tabs with configuration changes\n */\n private syncTabsWithConfiguration(tabs: WorkspaceTab[]): void {\n // Get existing tab IDs from Golden Layout\n const existingTabIds = this.layoutManager.GetAllTabIds();\n\n // Get tab IDs from configuration\n const configTabIds = tabs.map(tab => tab.id);\n\n // Remove tabs that are no longer in configuration\n existingTabIds.forEach(tabId => {\n if (!configTabIds.includes(tabId)) {\n this.layoutManager.RemoveTab(tabId);\n }\n });\n\n // Create tabs that don't exist yet\n tabs.forEach(tab => {\n if (!existingTabIds.includes(tab.id)) {\n this.createTab(tab);\n } else {\n // Check if tab content needs to be reloaded (app or resource type changed)\n const existingComponentRef = this.componentRefs.get(tab.id);\n if (existingComponentRef) {\n const existingResourceData = existingComponentRef.instance.Data;\n\n // For Custom resource types, also check driverClass to distinguish between different custom resources\n const existingDriverClass = existingResourceData?.Configuration?.driverClass || existingResourceData?.Configuration?.resourceTypeDriverClass;\n const newDriverClass = tab.configuration['driverClass'] || tab.configuration['resourceTypeDriverClass'];\n\n // Normalize record IDs for comparison (treat null/undefined as empty string)\n // IMPORTANT: Check both tab.resourceRecordId AND tab.configuration['recordId']\n // because for nav items, the recordId is stored in configuration, not resourceRecordId\n const existingRecordId = existingResourceData?.ResourceRecordID || '';\n const newRecordId = tab.resourceRecordId || tab.configuration['recordId'] as string || '';\n\n const needsReload = existingResourceData?.ResourceType !== tab.configuration['resourceType'] ||\n existingResourceData?.Configuration?.applicationId !== tab.applicationId ||\n existingRecordId !== newRecordId ||\n (tab.configuration['resourceType'] === 'Custom' && existingDriverClass !== newDriverClass);\n\n if (needsReload) {\n // Clean up old component\n this.cleanupTabComponent(tab.id);\n\n // Mark tab as not loaded so it will reload when shown\n this.layoutManager.MarkTabNotLoaded(tab.id);\n\n // Update display name in background\n this.updateTabDisplayName(tab);\n\n // If this tab is currently active, reload it immediately\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId === tab.id) {\n const glContainer = this.layoutManager.GetContainer(tab.id);\n if (glContainer) {\n this.loadTabContent(tab.id, glContainer);\n }\n }\n }\n }\n\n // Update styling for existing tabs\n const app = this.appManager.GetAppById(tab.applicationId);\n this.layoutManager.UpdateTabStyle(tab.id, {\n isPinned: tab.isPinned,\n title: tab.title,\n appColor: app?.GetColor() || '#757575'\n });\n }\n });\n\n // Focus the active tab\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n }\n\n\n /**\n * Show context menu\n */\n showContextMenu(x: number, y: number, tabId: string): void {\n this.contextMenuX = x;\n this.contextMenuY = y;\n this.contextMenuTabId = tabId;\n this.contextMenuVisible = true;\n\n // Close menu when clicking outside - use setTimeout to avoid immediate trigger\n setTimeout(() => {\n const clickHandler = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest('.context-menu')) {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n const keyHandler = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n document.addEventListener('click', clickHandler);\n document.addEventListener('keydown', keyHandler);\n }, 0);\n }\n\n /**\n * Hide context menu\n */\n hideContextMenu(): void {\n this.contextMenuVisible = false;\n this.contextMenuTabId = null;\n }\n\n /**\n * Check if context menu tab is pinned\n */\n get isContextTabPinned(): boolean {\n if (!this.contextMenuTabId) return false;\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n return tab?.isPinned || false;\n }\n\n /**\n * Toggle pin from context menu\n */\n onContextPin(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.TogglePin(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tab from context menu\n */\n onContextClose(): void {\n if (this.contextMenuTabId) {\n this.layoutManager.RemoveTab(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close all other tabs from context menu\n */\n onContextCloseOthers(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseOtherTabs(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tabs to the right from context menu\n */\n onContextCloseToRight(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseTabsToRight(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Check if context menu tab is pinned to Home dashboard\n */\n get isContextTabPinnedToHome(): boolean {\n if (!this.contextMenuTabId) return false;\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n if (!tab) return false;\n const resourceType = this.resolveResourceType(tab);\n return this.pinService.IsPinned(resourceType, tab.configuration as Record<string, unknown>);\n }\n\n /**\n * Pin current context menu tab to Home dashboard\n */\n async onContextPinToHome(): Promise<void> {\n if (this.isContextTabPinnedToHome) {\n this.hideContextMenu();\n return;\n }\n if (!this.contextMenuTabId) {\n this.hideContextMenu();\n return;\n }\n\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n if (!tab) {\n this.hideContextMenu();\n return;\n }\n\n const resourceType = this.resolveResourceType(tab);\n const activeApp = this.appManager.GetActiveApp();\n\n // Resolve nav item icon for Custom pins\n let pinIcon: string | undefined;\n if (resourceType === 'Custom' && activeApp) {\n const navItemName = tab.configuration?.['navItemName'] as string;\n if (navItemName) {\n const navItems = await activeApp.GetNavItems();\n const navItem = navItems.find(ni => ni.Label === navItemName);\n pinIcon = navItem?.Icon || undefined;\n }\n }\n\n const added = this.pinService.AddPin({\n DisplayName: tab.title || 'Untitled',\n ResourceType: resourceType,\n ApplicationID: tab.applicationId || activeApp?.ID,\n ApplicationName: activeApp?.Name,\n Icon: pinIcon,\n Color: activeApp?.GetColor() || undefined,\n Configuration: tab.configuration as Record<string, unknown>,\n });\n\n if (added) {\n MJNotificationService.Instance.CreateSimpleNotification(\n `Pinned \"${tab.title}\" to Home`, 'success', 2000\n );\n this.captureContextTabThumbnail(tab);\n } else {\n MJNotificationService.Instance.CreateSimpleNotification(\n `\"${tab.title}\" is already pinned to Home`, 'info', 3000\n );\n }\n\n this.hideContextMenu();\n }\n\n /**\n * Resolve a WorkspaceTab's resource type string for pin matching\n */\n private resolveResourceType(tab: WorkspaceTab): string {\n const config = tab.configuration;\n const rt = (config.resourceType as string) || '';\n if (rt === 'Dashboards' || config['dashboardId']) return 'Dashboards';\n if (rt === 'User Views' || rt === 'MJ: User Views' || config['viewId']) return 'User Views';\n if (rt === 'Queries' || config['queryId']) return 'Queries';\n if (rt === 'Reports' || config['reportId']) return 'Reports';\n if (rt === 'Records' || (config['entity'] && config['recordId'])) return 'Records';\n if (rt === 'Custom' || config['navItemName']) return 'Custom';\n return rt || 'Custom';\n }\n\n /**\n * Capture thumbnail for a just-pinned tab (async, non-blocking)\n */\n private async captureContextTabThumbnail(tab: WorkspaceTab): Promise<void> {\n try {\n // Find the active content element — differs by mode\n let contentEl: HTMLElement | null = null;\n if (this.useSingleResourceMode) {\n contentEl = this.directContentContainer?.nativeElement ?? null;\n } else {\n // In Golden Layout mode, find the active tab's content pane\n contentEl = this.glContainer?.nativeElement?.querySelector(\n '.lm_item_container .lm_content'\n ) as HTMLElement | null;\n }\n if (!contentEl) return;\n\n const thumbnail = await this.pinService.CaptureThumbnail(contentEl);\n if (thumbnail) {\n const resourceType = this.resolveResourceType(tab);\n const pin = this.pinService.FindPin(resourceType, tab.configuration as Record<string, unknown>);\n if (pin) {\n this.pinService.UpdatePin(pin.Id, { Thumbnail: thumbnail });\n }\n }\n } catch {\n // Thumbnail capture is best-effort\n }\n }\n\n /**\n * Public method for external callers (e.g. shell) to capture a thumbnail\n * of the currently visible content, regardless of mode.\n */\n public async CaptureActiveThumbnail(): Promise<string | undefined> {\n try {\n let contentEl: HTMLElement | null = null;\n if (this.useSingleResourceMode) {\n contentEl = this.directContentContainer?.nativeElement ?? null;\n } else {\n contentEl = this.glContainer?.nativeElement?.querySelector(\n '.lm_item_container .lm_content'\n ) as HTMLElement | null;\n }\n if (!contentEl) return undefined;\n return await this.pinService.CaptureThumbnail(contentEl);\n } catch {\n return undefined;\n }\n }\n\n /**\n * While the naming implies this is only invoked once, components we DO NOT CONTROL might have race\n * conditions that result in unpredictable behavior. To avoid those causing loading screen overaly to show\n * forever we emit all events upstream\n */\n private emitFirstLoadCompleteOnce(): void {\n this.firstResourceLoadComplete.emit(); // do this each time to be sure we don't suppress messages\n }\n}\n","<div class=\"tab-container\">\n\n <!-- Single-Resource Mode: Direct component rendering without Golden Layout -->\n <!-- This avoids the 20px height issue when GL header is hidden -->\n @if (useSingleResourceMode) {\n <div #directContentContainer class=\"direct-content-container\"></div>\n } @else {\n <!-- Multi-Tab Mode: Golden Layout Container -->\n <div #glContainer class=\"gl-container\"></div>\n }\n\n <!-- Context Menu (only relevant in multi-tab mode) -->\n @if (contextMenuVisible) {\n <div\n class=\"context-menu\"\n [style.left.px]=\"contextMenuX\"\n [style.top.px]=\"contextMenuY\">\n <div class=\"context-menu-item\" (click)=\"onContextPin()\">\n <i class=\"fa-solid fa-thumbtack\"></i>\n <span>{{ isContextTabPinned ? 'Unpin Tab' : 'Pin Tab' }}</span>\n </div>\n <div class=\"context-menu-divider\"></div>\n <div class=\"context-menu-item\" [class.new-item]=\"!isContextTabPinnedToHome\" [class.disabled]=\"isContextTabPinnedToHome\" (click)=\"onContextPinToHome()\">\n <i class=\"fa-solid fa-house-chimney\"></i>\n @if (isContextTabPinnedToHome) {\n <span>Pinned to Home</span>\n <span class=\"check\"><i class=\"fa-solid fa-check\"></i></span>\n } @else {\n <span>Pin to Home</span>\n }\n </div>\n <div class=\"context-menu-divider\"></div>\n <div class=\"context-menu-item\" (click)=\"onContextClose()\">\n <i class=\"fa-solid fa-xmark\"></i>\n <span>Close Tab</span>\n </div>\n <div class=\"context-menu-item\" (click)=\"onContextCloseOthers()\">\n <i class=\"fa-solid fa-layer-group\"></i>\n <span>Close Others</span>\n </div>\n <div class=\"context-menu-item\" (click)=\"onContextCloseToRight()\">\n <i class=\"fa-solid fa-angles-right\"></i>\n <span>Close to Right</span>\n </div>\n </div>\n }\n</div>\n"]}