@memberjunction/ng-explorer-core 5.14.0 → 5.15.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 (28) hide show
  1. package/dist/lib/generic/resource-container-component.d.ts +2 -1
  2. package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
  3. package/dist/lib/generic/resource-container-component.js +13 -4
  4. package/dist/lib/generic/resource-container-component.js.map +1 -1
  5. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +2 -1
  6. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  7. package/dist/lib/resource-wrappers/dashboard-resource.component.js +15 -7
  8. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  9. package/dist/lib/services/lazy-feature-config.d.ts +16 -0
  10. package/dist/lib/services/lazy-feature-config.d.ts.map +1 -0
  11. package/dist/lib/services/lazy-feature-config.js +113 -0
  12. package/dist/lib/services/lazy-feature-config.js.map +1 -0
  13. package/dist/lib/services/lazy-module-registry.d.ts +28 -0
  14. package/dist/lib/services/lazy-module-registry.d.ts.map +1 -0
  15. package/dist/lib/services/lazy-module-registry.js +60 -0
  16. package/dist/lib/services/lazy-module-registry.js.map +1 -0
  17. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
  18. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  19. package/dist/lib/shell/components/tabs/tab-container.component.js +27 -7
  20. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  21. package/dist/module.d.ts +2 -2
  22. package/dist/module.js +4 -4
  23. package/dist/module.js.map +1 -1
  24. package/dist/public-api.d.ts +2 -0
  25. package/dist/public-api.d.ts.map +1 -1
  26. package/dist/public-api.js +3 -0
  27. package/dist/public-api.js.map +1 -1
  28. package/package.json +34 -34
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-feature-config.js","sourceRoot":"","sources":["../../../src/lib/services/lazy-feature-config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Maps resource type names to lazy-loading functions for each feature chunk.\n * The import() calls point to the feature module files in @memberjunction/ng-dashboards\n * and @memberjunction/ng-explorer-settings using subpath exports.\n *\n * When a resource type is not found in ClassFactory, the LazyModuleRegistry uses\n * this config to load the chunk containing that resource type. Loading a feature\n * module triggers all @RegisterClass decorators within it, making its components\n * available to ClassFactory.\n */\n\n/** Helper to create a loader that all resource types in a feature share. */\nfunction featureLoader(importFn: () => Promise<unknown>): () => Promise<void> {\n return () => importFn().then(() => {});\n}\n\n// --- AI Dashboard feature chunk ---\nconst loadAI = featureLoader(() => import('@memberjunction/ng-dashboards/ai-dashboards.module'));\n\n// --- Actions Dashboard feature chunk ---\nconst loadActions = featureLoader(() => import('@memberjunction/ng-dashboards/actions-dashboards.module'));\n\n// --- Testing Dashboard feature chunk ---\nconst loadTesting = featureLoader(() => import('@memberjunction/ng-dashboards/testing-dashboards.module'));\n\n// --- Scheduling Dashboard feature chunk ---\nconst loadScheduling = featureLoader(() => import('@memberjunction/ng-dashboards/scheduling-dashboards.module'));\n\n// --- Communication Dashboard feature chunk ---\nconst loadCommunication = featureLoader(() => import('@memberjunction/ng-dashboards/communication-dashboards.module'));\n\n// --- Credentials Dashboard feature chunk ---\nconst loadCredentials = featureLoader(() => import('@memberjunction/ng-dashboards/credentials-dashboards.module'));\n\n// --- Data Explorer feature chunk ---\nconst loadDataExplorer = featureLoader(() => import('@memberjunction/ng-dashboards/data-explorer-dashboards.module'));\n\n// --- Lists Dashboard feature chunk ---\nconst loadLists = featureLoader(() => import('@memberjunction/ng-dashboards/lists-dashboards.module'));\n\n// --- Component Studio feature chunk ---\nconst loadComponentStudio = featureLoader(() => import('@memberjunction/ng-dashboards/component-studio-dashboards.module'));\n\n// --- Integration feature chunk ---\nconst loadIntegration = featureLoader(() => import('@memberjunction/ng-dashboards/integration.module'));\n\n// --- MCP feature chunk ---\nconst loadMCP = featureLoader(() => import('@memberjunction/ng-dashboards/mcp.module'));\n\n// --- Explorer Settings feature chunk ---\nconst loadSettings = featureLoader(() => import(\n /* webpackChunkName: \"explorer-settings\" */\n '@memberjunction/ng-explorer-settings'\n));\n\n/**\n * Complete mapping of resource type strings to lazy-loading functions.\n * Covers both BaseResourceComponent and BaseDashboard registrations.\n */\nexport const LAZY_FEATURE_CONFIG: Record<string, () => Promise<void>> = {\n // ── AI Dashboard (BaseResourceComponent types) ──\n 'AIModelsResource': loadAI,\n 'AIPromptsResource': loadAI,\n 'AIAgentsResource': loadAI,\n 'AIMonitorResource': loadAI,\n 'AIConfigResource': loadAI,\n\n // ── Actions Dashboard (BaseResourceComponent types) ──\n 'ActionsOverviewResource': loadActions,\n 'ActionsMonitorResource': loadActions,\n 'ActionsScheduleResource': loadActions,\n 'ActionsCodeResource': loadActions,\n 'ActionsEntitiesResource': loadActions,\n 'ActionsSecurityResource': loadActions,\n 'ActionExplorerResource': loadActions,\n\n // ── Testing Dashboard ──\n 'TestingDashboard': loadTesting, // BaseDashboard\n 'TestingDashboardTabResource': loadTesting, // BaseResourceComponent\n 'TestingRunsResource': loadTesting,\n 'TestingAnalyticsResource': loadTesting,\n 'TestingReviewResource': loadTesting,\n 'TestingExplorerResource': loadTesting,\n\n // ── Scheduling Dashboard ──\n 'SchedulingDashboard': loadScheduling, // BaseDashboard\n 'SchedulingDashboardResource': loadScheduling, // BaseResourceComponent\n 'SchedulingJobsResource': loadScheduling,\n 'SchedulingActivityResource': loadScheduling,\n\n // ── Communication Dashboard ──\n 'CommunicationDashboard': loadCommunication, // BaseDashboard\n 'CommunicationLogsResource': loadCommunication,\n 'CommunicationMonitorResource': loadCommunication,\n 'CommunicationProvidersResource': loadCommunication,\n 'CommunicationRunsResource': loadCommunication,\n 'CommunicationTemplatesResource': loadCommunication,\n\n // ── Credentials Dashboard ──\n 'CredentialsDashboard': loadCredentials, // BaseDashboard\n 'CredentialsOverviewResource': loadCredentials,\n 'CredentialsListResource': loadCredentials,\n 'CredentialsTypesResource': loadCredentials,\n 'CredentialsCategoriesResource': loadCredentials,\n 'CredentialsAuditResource': loadCredentials,\n\n // ── Data Explorer ──\n 'DataExplorer': loadDataExplorer, // BaseDashboard\n 'DataExplorerResource': loadDataExplorer, // BaseResourceComponent\n\n // ── Lists Dashboard ──\n 'ListsBrowseResource': loadLists,\n 'ListsCategoriesResource': loadLists,\n 'ListsMyListsResource': loadLists,\n 'ListsOperationsResource': loadLists,\n\n // ── Component Studio ──\n 'ComponentStudioDashboard': loadComponentStudio, // BaseDashboard\n\n // ── Integration Dashboard ──\n 'IntegrationOverview': loadIntegration,\n 'IntegrationConnections': loadIntegration,\n 'IntegrationPipelines': loadIntegration,\n 'IntegrationMappingWorkspace': loadIntegration,\n 'IntegrationActivity': loadIntegration,\n 'IntegrationSchedules': loadIntegration,\n\n // ── MCP Dashboard ──\n 'MCPDashboard': loadMCP, // BaseDashboard\n 'MCPResource': loadMCP, // BaseResourceComponent\n\n // ── Explorer Settings (BaseDashboard types) ──\n 'ApplicationManagement': loadSettings,\n 'EntityPermissions': loadSettings,\n 'RoleManagement': loadSettings,\n 'UserManagement': loadSettings,\n 'SqlLogging': loadSettings,\n};\n"]}
@@ -0,0 +1,28 @@
1
+ import * as i0 from "@angular/core";
2
+ /**
3
+ * Registry that maps resource type strings to dynamic import() loaders.
4
+ * When ResourceContainerComponent cannot find a resource type in ClassFactory,
5
+ * it asks this registry to lazy-load the chunk containing that resource type.
6
+ */
7
+ export declare class LazyModuleRegistry {
8
+ private registry;
9
+ private loadedChunks;
10
+ private pendingLoads;
11
+ /**
12
+ * Register a single resource type with its loader function.
13
+ */
14
+ Register(resourceType: string, loader: () => Promise<void>): void;
15
+ /**
16
+ * Register multiple resource types at once.
17
+ */
18
+ RegisterBulk(mappings: Record<string, () => Promise<void>>): void;
19
+ /**
20
+ * Attempt to lazy-load the chunk for a given resource type.
21
+ * Returns true if the resource type was found in the registry and loaded.
22
+ * Deduplicates concurrent loads of the same chunk.
23
+ */
24
+ Load(resourceType: string): Promise<boolean>;
25
+ static ɵfac: i0.ɵɵFactoryDeclaration<LazyModuleRegistry, never>;
26
+ static ɵprov: i0.ɵɵInjectableDeclaration<LazyModuleRegistry>;
27
+ }
28
+ //# sourceMappingURL=lazy-module-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-module-registry.d.ts","sourceRoot":"","sources":["../../../src/lib/services/lazy-module-registry.ts"],"names":[],"mappings":";AAEA;;;;GAIG;AACH,qBACa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,YAAY,CAAoC;IAExD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIjE;;OAEG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI;IAMjE;;;;OAIG;IACG,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;yCA1BvC,kBAAkB;6CAAlB,kBAAkB;CAmD9B"}
@@ -0,0 +1,60 @@
1
+ import { Injectable } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Registry that maps resource type strings to dynamic import() loaders.
5
+ * When ResourceContainerComponent cannot find a resource type in ClassFactory,
6
+ * it asks this registry to lazy-load the chunk containing that resource type.
7
+ */
8
+ export class LazyModuleRegistry {
9
+ registry = new Map();
10
+ loadedChunks = new Set();
11
+ pendingLoads = new Map();
12
+ /**
13
+ * Register a single resource type with its loader function.
14
+ */
15
+ Register(resourceType, loader) {
16
+ this.registry.set(resourceType, loader);
17
+ }
18
+ /**
19
+ * Register multiple resource types at once.
20
+ */
21
+ RegisterBulk(mappings) {
22
+ for (const [resourceType, loader] of Object.entries(mappings)) {
23
+ this.registry.set(resourceType, loader);
24
+ }
25
+ }
26
+ /**
27
+ * Attempt to lazy-load the chunk for a given resource type.
28
+ * Returns true if the resource type was found in the registry and loaded.
29
+ * Deduplicates concurrent loads of the same chunk.
30
+ */
31
+ async Load(resourceType) {
32
+ const loader = this.registry.get(resourceType);
33
+ if (!loader)
34
+ return false;
35
+ // Use the loader function's string representation as chunk key for deduplication
36
+ const chunkKey = loader.toString();
37
+ if (this.loadedChunks.has(chunkKey))
38
+ return true;
39
+ // Deduplicate concurrent loads
40
+ const pending = this.pendingLoads.get(chunkKey);
41
+ if (pending) {
42
+ await pending;
43
+ return true;
44
+ }
45
+ const loadPromise = loader().then(() => {
46
+ this.loadedChunks.add(chunkKey);
47
+ this.pendingLoads.delete(chunkKey);
48
+ });
49
+ this.pendingLoads.set(chunkKey, loadPromise);
50
+ await loadPromise;
51
+ return true;
52
+ }
53
+ static ɵfac = function LazyModuleRegistry_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LazyModuleRegistry)(); };
54
+ static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: LazyModuleRegistry, factory: LazyModuleRegistry.ɵfac, providedIn: 'root' });
55
+ }
56
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LazyModuleRegistry, [{
57
+ type: Injectable,
58
+ args: [{ providedIn: 'root' }]
59
+ }], null, null); })();
60
+ //# sourceMappingURL=lazy-module-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-module-registry.js","sourceRoot":"","sources":["../../../src/lib/services/lazy-module-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;;AAE3C;;;;GAIG;AAEH,MAAM,OAAO,kBAAkB;IACrB,QAAQ,GAAG,IAAI,GAAG,EAA+B,CAAC;IAClD,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;IAExD;;OAEG;IACH,QAAQ,CAAC,YAAoB,EAAE,MAA2B;QACxD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,QAA6C;QACxD,KAAK,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,YAAoB;QAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAC/C,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAE1B,iFAAiF;QACjF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;QAEnC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,OAAO,IAAI,CAAC;QAEjD,+BAA+B;QAC/B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,OAAO,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE;YACrC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAChC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC7C,MAAM,WAAW,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;4GAlDU,kBAAkB;gEAAlB,kBAAkB,WAAlB,kBAAkB,mBADL,MAAM;;iFACnB,kBAAkB;cAD9B,UAAU;eAAC,EAAE,UAAU,EAAE,MAAM,EAAE","sourcesContent":["import { Injectable } from '@angular/core';\n\n/**\n * Registry that maps resource type strings to dynamic import() loaders.\n * When ResourceContainerComponent cannot find a resource type in ClassFactory,\n * it asks this registry to lazy-load the chunk containing that resource type.\n */\n@Injectable({ providedIn: 'root' })\nexport class LazyModuleRegistry {\n private registry = new Map<string, () => Promise<void>>();\n private loadedChunks = new Set<string>();\n private pendingLoads = new Map<string, Promise<void>>();\n\n /**\n * Register a single resource type with its loader function.\n */\n Register(resourceType: string, loader: () => Promise<void>): void {\n this.registry.set(resourceType, loader);\n }\n\n /**\n * Register multiple resource types at once.\n */\n RegisterBulk(mappings: Record<string, () => Promise<void>>): void {\n for (const [resourceType, loader] of Object.entries(mappings)) {\n this.registry.set(resourceType, loader);\n }\n }\n\n /**\n * Attempt to lazy-load the chunk for a given resource type.\n * Returns true if the resource type was found in the registry and loaded.\n * Deduplicates concurrent loads of the same chunk.\n */\n async Load(resourceType: string): Promise<boolean> {\n const loader = this.registry.get(resourceType);\n if (!loader) return false;\n\n // Use the loader function's string representation as chunk key for deduplication\n const chunkKey = loader.toString();\n\n if (this.loadedChunks.has(chunkKey)) return true;\n\n // Deduplicate concurrent loads\n const pending = this.pendingLoads.get(chunkKey);\n if (pending) {\n await pending;\n return true;\n }\n\n const loadPromise = loader().then(() => {\n this.loadedChunks.add(chunkKey);\n this.pendingLoads.delete(chunkKey);\n });\n\n this.pendingLoads.set(chunkKey, loadPromise);\n await loadPromise;\n return true;\n }\n}\n"]}
@@ -31,6 +31,7 @@ export declare class TabContainerComponent implements OnInit, OnDestroy, AfterVi
31
31
  * The shell can use this to show an error dialog and redirect.
32
32
  */
33
33
  layoutInitError: EventEmitter<void>;
34
+ private lazyRegistry;
34
35
  private subscriptions;
35
36
  private layoutInitRetryCount;
36
37
  private readonly MAX_LAYOUT_INIT_RETRIES;
@@ -1 +1 @@
1
- {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,10 @@
1
- import { Component, ViewChild, createComponent, ViewEncapsulation, HostListener, Output, EventEmitter } from '@angular/core';
1
+ import { Component, ViewChild, createComponent, ViewEncapsulation, HostListener, Output, EventEmitter, inject } from '@angular/core';
2
2
  import { MJGlobal } from '@memberjunction/global';
3
3
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
4
4
  import { ResourceData } from '@memberjunction/core-entities';
5
5
  import { LogError, Metadata } from '@memberjunction/core';
6
6
  import { ComponentCacheManager } from './component-cache-manager';
7
+ import { LazyModuleRegistry } from '../../../services/lazy-module-registry';
7
8
  import * as i0 from "@angular/core";
8
9
  import * as i1 from "@memberjunction/ng-base-application";
9
10
  const _c0 = ["glContainer"];
@@ -77,6 +78,7 @@ export class TabContainerComponent {
77
78
  * The shell can use this to show an error dialog and redirect.
78
79
  */
79
80
  layoutInitError = new EventEmitter();
81
+ lazyRegistry = inject(LazyModuleRegistry);
80
82
  subscriptions = [];
81
83
  layoutInitRetryCount = 0;
82
84
  MAX_LAYOUT_INIT_RETRIES = 5;
@@ -410,8 +412,14 @@ export class TabContainerComponent {
410
412
  this.singleResourceComponentRef = cached.componentRef;
411
413
  return;
412
414
  }
413
- // Get the component registration
414
- const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
415
+ // Get the component registration (with lazy loading fallback)
416
+ let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
417
+ if (!resourceReg) {
418
+ const loaded = await this.lazyRegistry.Load(driverClass);
419
+ if (loaded) {
420
+ resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
421
+ }
422
+ }
415
423
  if (!resourceReg) {
416
424
  LogError(`Unable to find resource registration for driver class: ${driverClass}`);
417
425
  return;
@@ -547,8 +555,14 @@ export class TabContainerComponent {
547
555
  }
548
556
  return;
549
557
  }
550
- // Get the component registration using the driver class
551
- const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
558
+ // Get the component registration using the driver class (with lazy loading fallback)
559
+ let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
560
+ if (!resourceReg) {
561
+ const loaded = await this.lazyRegistry.Load(driverClass);
562
+ if (loaded) {
563
+ resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
564
+ }
565
+ }
552
566
  if (!resourceReg) {
553
567
  LogError(`Unable to find resource registration for driver class: ${driverClass}`);
554
568
  return;
@@ -610,7 +624,13 @@ export class TabContainerComponent {
610
624
  }
611
625
  // Get the resource registration to access GetResourceDisplayName without loading full component
612
626
  const driverClass = resourceData.Configuration?.resourceTypeDriverClass || resourceData.ResourceType;
613
- const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
627
+ let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
628
+ if (!resourceReg) {
629
+ const loaded = await this.lazyRegistry.Load(driverClass);
630
+ if (loaded) {
631
+ resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);
632
+ }
633
+ }
614
634
  if (!resourceReg) {
615
635
  return;
616
636
  }
@@ -990,5 +1010,5 @@ export class TabContainerComponent {
990
1010
  type: HostListener,
991
1011
  args: ['window:resize']
992
1012
  }] }); })();
993
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber: 51 }); })();
1013
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabContainerComponent, { className: "TabContainerComponent", filePath: "src/lib/shell/components/tabs/tab-container.component.ts", lineNumber: 53 }); })();
994
1014
  //# sourceMappingURL=tab-container.component.js.map
@@ -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":"AAAA,OAAO,EACL,SAAS,EAIT,SAAS,EAIT,eAAe,EAEf,iBAAiB,EAEjB,YAAY,EACZ,MAAM,EACN,YAAY,EACb,MAAM,eAAe,CAAC;AAWvB,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,YAAY,EAAwB,MAAM,+BAA+B,CAAC;AACnF,OAAO,EAAqB,QAAQ,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;;;;;IC1B9D,4BAAoE;;;IAGpE,4BAA6C;;;;IAS3C,AAJF,8BAGgC,aAC0B;IAAzB,sLAAS,qBAAc,KAAC;IACrD,uBAAqC;IACrC,4BAAM;IAAA,YAAkD;IAC1D,AAD0D,iBAAO,EAC3D;IACN,yBAAwC;IACxC,8BAA0D;IAA3B,sLAAS,uBAAgB,KAAC;IACvD,wBAAiC;IACjC,4BAAM;IAAA,yBAAS;IACjB,AADiB,iBAAO,EAClB;IACN,+BAAgE;IAAjC,uLAAS,6BAAsB,KAAC;IAC7D,yBAAuC;IACvC,6BAAM;IAAA,6BAAY;IACpB,AADoB,iBAAO,EACrB;IACN,+BAAiE;IAAlC,uLAAS,8BAAuB,KAAC;IAC9D,yBAAwC;IACxC,6BAAM;IAAA,+BAAc;IAExB,AADE,AADsB,iBAAO,EACvB,EACF;;;IAlBJ,AADA,iDAA8B,kCACD;IAGrB,eAAkD;IAAlD,yEAAkD;;ADchE;;;;;;;;;GASG;AAQH,MAAM,OAAO,qBAAqB;IA4CtB;IACA;IACA;IACA;IACA;IACA;IAhDmC,WAAW,CAA8B;IAC9B,sBAAsB,CAA8B;IAE5G;;;;OAIG;IACO,yBAAyB,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE/D;;;OAGG;IACO,eAAe,GAAG,IAAI,YAAY,EAAQ,CAAC;IAE7C,aAAa,GAAmB,EAAE,CAAC;IACnC,oBAAoB,GAAG,CAAC,CAAC;IAChB,uBAAuB,GAAG,CAAC,CAAC;IACrC,iBAAiB,GAAG,KAAK,CAAC;IAC1B,yBAAyB,GAAG,KAAK,CAAC,CAAC,mDAAmD;IAE9F,+FAA+F;IACvF,aAAa,GAAG,IAAI,GAAG,EAA+C,CAAC;IAE/E,sEAAsE;IAC9D,YAAY,CAAwB;IAE5C,wEAAwE;IACxE,6DAA6D;IAC7D,qBAAqB,GAAG,KAAK,CAAC;IACtB,0BAA0B,GAA+C,IAAI,CAAC;IAC9E,qBAAqB,GAAmB,IAAI,CAAC;IAC7C,8BAA8B,GAAkB,IAAI,CAAC,CAAC,8DAA8D;IACpH,qBAAqB,GAAG,KAAK,CAAC,CAAC,wEAAwE;IAE/G,qBAAqB;IACrB,kBAAkB,GAAG,KAAK,CAAC;IAC3B,YAAY,GAAG,CAAC,CAAC;IACjB,YAAY,GAAG,CAAC,CAAC;IACjB,gBAAgB,GAAkB,IAAI,CAAC;IAEvC,YACU,aAAkC,EAClC,gBAAuC,EACvC,UAA8B,EAC9B,MAAsB,EACtB,mBAAwC,EACxC,GAAsB;QALtB,kBAAa,GAAb,aAAa,CAAqB;QAClC,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,eAAU,GAAV,UAAU,CAAoB;QAC9B,WAAM,GAAN,MAAM,CAAgB;QACtB,wBAAmB,GAAnB,mBAAmB,CAAqB;QACxC,QAAG,GAAH,GAAG,CAAmB;QAE9B,qCAAqC;QACrC,IAAI,CAAC,YAAY,GAAG,IAAI,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,QAAQ;QACN,0BAA0B;QAC1B,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAC5C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC,CAAC,EACF,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAC7C,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAChC,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,EACF,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;YAC/C,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC7C,CAAC,CAAC,EACF,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAC7C,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,CAAC,EACF,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YACpD,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,EACF,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YACnD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACtD,CAAC,CAAC,CACH,CAAC;QAEF,kDAAkD;QAClD,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE;YACrD,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;oBAC/B,qEAAqE;oBACrE,+DAA+D;oBAC/D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACvF,IAAI,SAAS,EAAE,CAAC;wBACd,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;wBACzD,IAAI,SAAS,KAAK,IAAI,CAAC,8BAA8B,EAAE,CAAC;4BACtD,IAAI,CAAC,yBAAyB,EAAE,CAAC;wBACnC,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,IAAI,CAAC,yBAAyB,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;oBACzE,6CAA6C;oBAC7C,6FAA6F;oBAC7F,sFAAsF;oBACtF,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAC9C,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QAEF,mEAAmE;QACnE,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE;YAC5D,IAAI,CAAC,4BAA4B,CAAC,aAAa,CAAC,CAAC;QACnD,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,eAAe;QACb,qEAAqE;QACrE,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAChC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,iDAAiD;YACjD,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAAC,eAAe,GAAG,KAAK;QACpD,mHAAmH;QACnH,IAAI,IAAI,CAAC,qBAAqB;YAC5B,OAAO;QAET,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAE5B,IAAI,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;gBAC7D,OAAO,CAAC,KAAK,CAAC,+CAA+C,IAAI,CAAC,uBAAuB,0BAA0B,CAAC,CAAC;gBACrH,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC;gBAC5B,OAAO;YACT,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,gDAAgD,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,uBAAuB,KAAK,CAAC,CAAC;YAC7H,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,oBAAoB,GAAG,CAAC,CAAC;QAE9B,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC3B,OAAO,CAAC,sBAAsB;QAChC,CAAC;QAED,sCAAsC;QACtC,qDAAqD;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,6CAA6C;YAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE;gBAC7E,IAAI,YAAY,EAAE,CAAC;oBACjB,SAAS,CAAC,WAAW,EAAE,CAAC;oBACxB,8DAA8D;oBAC9D,IAAI,CAAC,sBAAsB,CAAC,eAAe,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,gDAAgD;QAChD,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAE9D,6BAA6B;QAC7B,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAE9B,8BAA8B;QAC9B,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC7B,oDAAoD;YACpD,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;YACtC,OAAO;QACT,CAAC;QAED,gEAAgE;QAChE,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAE7F,IAAI,cAAc,IAAI,CAAC,eAAe,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YACxD,uEAAuE;YACvE,MAAM,oBAAoB,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC5E,IAAI,oBAAoB,KAAK,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChD,OAAO,CAAC,IAAI,CAAC,0EAA0E,oBAAoB,kCAAkC,MAAM,CAAC,IAAI,CAAC,MAAM,yBAAyB,CAAC,CAAC;gBAC1L,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;gBACpC,oCAAoC;YACtC,CAAC;iBAAM,CAAC;gBACN,kFAAkF;gBAClF,4DAA4D;gBAC5D,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAElE,IAAI,YAAY,EAAE,CAAC;oBACjB,6DAA6D;oBAC7D,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;oBAEtC,4CAA4C;oBAC5C,yEAAyE;oBACzE,sEAAsE;oBACtE,UAAU,CAAC,GAAG,EAAE;wBACd,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;4BACvB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;wBAClD,CAAC;wBACD,+EAA+E;wBAC/E,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;oBAClC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACP,OAAO,CAAC,+BAA+B;gBACzC,CAAC;gBAED,wFAAwF;gBACxF,OAAO,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;gBACxF,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAED,8EAA8E;QAC9E,2EAA2E;QAC3E,MAAM,UAAU,GAAG,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;QAE5E,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAClC,IAAI,CAAC;YACH,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACvB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACrC,CAAC;QAED,6DAA6D;QAC7D,IAAI,CAAC,yBAAyB,GAAG,IAAI,CAAC;QAEtC,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAED,WAAW;QACT,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;QAErD,mDAAmD;QACnD,IAAI,CAAC,8BAA8B,EAAE,CAAC;QAEtC,sDAAsD;QACtD,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;QAE/B,mCAAmC;QACnC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;YACzC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrC,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IAEH,cAAc;QACZ,IAAI,IAAI,CAAC,iBAAiB,IAAI,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC1D,IAAI,CAAC,aAAa,CAAC,UAAU,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;OAEG;IACK,4BAA4B,CAAC,aAAsB;QACzD,oBAAoB;QACpB,IAAI,IAAI,CAAC,qBAAqB,KAAK,aAAa,EAAE,CAAC;YACjD,OAAO;QACT,CAAC;QACD,IAAI,CAAC,qBAAqB,GAAG,aAAa,CAAC;QAE3C,kDAAkD;QAClD,MAAM,2BAA2B,GAAG,CAAC,aAAa,CAAC;QAEnD,IAAI,2BAA2B,KAAK,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/D,IAAI,CAAC,qBAAqB,GAAG,2BAA2B,CAAC;YACzD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAEzB,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAC/B,wCAAwC;gBACxC,2EAA2E;gBAC3E,+FAA+F;gBAC/F,UAAU,CAAC,GAAG,EAAE;oBACd,4EAA4E;oBAC5E,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;wBAC3B,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;wBAC7B,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;oBACjC,CAAC;oBACD,oEAAoE;oBACpE,IAAI,CAAC,yBAAyB,EAAE,CAAC;gBACnC,CAAC,EAAE,CAAC,CAAC,CAAC;YACR,CAAC;iBAAM,CAAC;gBACN,kCAAkC;gBAClC,0FAA0F;gBAC1F,wDAAwD;gBACxD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;gBACxD,IAAI,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACrC,oEAAoE;oBACpE,wEAAwE;oBACxE,gCAAgC;oBAChC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;wBACxC,wEAAwE;wBACxE,IAAI,GAAG,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;4BACnD,OAAO,EAAE,GAAG,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;wBACpC,CAAC;wBACD,OAAO,GAAG,CAAC;oBACb,CAAC,CAAC,CAAC;oBAEH,+CAA+C;oBAC/C,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;oBAC1F,IAAI,UAAU,EAAE,CAAC;wBACf,IAAI,CAAC,gBAAgB,CAAC,mBAAmB,CAAC;4BACxC,GAAG,MAAM;4BACT,IAAI,EAAE,WAAW;yBAClB,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBAED,4DAA4D;gBAC5D,IAAI,CAAC,8BAA8B,EAAE,CAAC;gBACtC,IAAI,CAAC,8BAA8B,GAAG,IAAI,CAAC,CAAC,iBAAiB;gBAE7D,gFAAgF;gBAChF,sFAAsF;gBACtF,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;gBAE/B,kFAAkF;gBAClF,oDAAoD;gBACpD,4EAA4E;gBAC5E,gEAAgE;gBAChE,UAAU,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;gBAC1D,CAAC,EAAE,CAAC,CAAC,CAAC;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,yBAAyB;QACrC,yDAAyD;QACzD,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO;QACT,CAAC;QAED,oCAAoC;QACpC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,qFAAqF;QACrF,MAAM,YAAY,GAAG,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAC5D,IAAI,IAAI,CAAC,8BAA8B,KAAK,YAAY,EAAE,CAAC;YACzD,2CAA2C;YAC3C,OAAO;QACT,CAAC;QACD,IAAI,CAAC,8BAA8B,GAAG,YAAY,CAAC;QAEnD,4BAA4B;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,EAAE,aAAa,CAAC;QAC7D,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAC;YACxE,8BAA8B;YAC9B,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,EAAE,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAC;QAClE,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,QAAQ,CAAC,0CAA0C,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QAED,wCAAwC;QACxC,MAAM,WAAW,GAAG,YAAY,CAAC,aAAa,EAAE,uBAAuB,IAAI,YAAY,CAAC,YAAY,CAAC;QAErG,yEAAyE;QACzE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CACjD,WAAW,EACX,YAAY,CAAC,gBAAgB,IAAI,EAAE,EACnC,SAAS,CAAC,aAAa,CACxB,CAAC;QAEF,IAAI,MAAM,EAAE,CAAC;YACX,6DAA6D;YAC7D,IAAI,CAAC,8BAA8B,EAAE,CAAC;YAEtC,uEAAuE;YACvE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;YAE/C,mEAAmE;YACnE,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,qBAAqB;YAClE,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAE7C,8BAA8B;YAC9B,IAAI,CAAC,0BAA0B,GAAG,MAAM,CAAC,YAAY,CAAC;YAEtD,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,eAAe,CAChE,qBAAqB,EACrB,WAAW,CACZ,CAAC;QAEF,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,QAAQ,CAAC,0DAA0D,WAAW,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,qCAAqC;QACrC,IAAI,CAAC,8BAA8B,EAAE,CAAC;QAEtC,mCAAmC;QACnC,MAAM,YAAY,GAAG,eAAe,CAAC,WAAW,CAAC,QAAQ,EAAE;YACzD,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;SAC9C,CAAC,CAAC;QAEH,uCAAuC;QACvC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE9C,yCAAyC;QACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAiC,CAAC;QAChE,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAC;QAE7B,iBAAiB;QACjB,QAAQ,CAAC,iBAAiB,GAAG,GAAG,EAAE;YAChC,IAAI,CAAC,yBAAyB,EAAE,CAAC;QACnC,CAAC,CAAC;QAEF,iDAAiD;QACjD,MAAM,aAAa,GAAI,YAAY,CAAC,QAAoD,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACtG,SAAS,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QACrC,iEAAiE;QACjE,IAAI,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAS,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;QACvD,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,0BAA0B,GAAG,YAAmD,CAAC;IACxF,CAAC;IAED;;OAEG;IACK,8BAA8B;QACpC,IAAI,IAAI,CAAC,0BAA0B,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACjE,IAAI,CAAC,0BAA0B,CAAC,OAAO,EAAE,CAAC;YAC1C,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;QACzC,CAAC;QAED,sBAAsB;QACtB,MAAM,SAAS,GAAG,IAAI,CAAC,sBAAsB,EAAE,aAAa,CAAC;QAC7D,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,CAAC,SAAS,GAAG,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,sBAAsB,CAAC,GAAiB;QAC9C,gFAAgF;QAChF,oEAAoE;QACpE,uFAAuF;QACvF,MAAM,iBAAiB,GAAG,GAAG,CAAC,gBAAgB,IAAK,GAAG,CAAC,aAAa,EAAE,QAAmB,IAAI,EAAE,CAAC;QAChG,MAAM,KAAK,GAAG;YACZ,GAAG,CAAC,aAAa;YACjB,GAAG,CAAC,aAAa,EAAE,YAAY,IAAI,EAAE;YACrC,GAAG,CAAC,aAAa,EAAE,WAAW,IAAI,EAAE;YACpC,GAAG,CAAC,aAAa,EAAE,MAAM,IAAI,EAAE,EAAG,gDAAgD;YAClF,iBAAiB;YACjB,GAAG,CAAC,aAAa,EAAE,KAAK,IAAI,EAAE;SAC/B,CAAC;QACF,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,GAAiB;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC1D,MAAM,QAAQ,GAAG,GAAG,EAAE,QAAQ,EAAE,IAAI,SAAS,CAAC;QAE9C,MAAM,KAAK,GAAsB;YAC/B,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,KAAK,EAAE,GAAG,CAAC,aAAa;YACxB,QAAQ;YACR,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,KAAK,EAAE,GAAG,CAAC,aAAa,CAAC,OAAO,CAAW,IAAI,EAAE;YACjD,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,QAAQ,EAAE,KAAK;SAChB,CAAC;QAEF,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEjC,iEAAiE;QACjE,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,KAAoB;QAC3C,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,4BAA4B;YAC5B,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;YACxD,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,cAAc,CAAC,KAAa,EAAE,SAAkB;QAC5D,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,QAAQ,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;gBACpC,OAAO;YACT,CAAC;YAED,+CAA+C;YAC/C,MAAM,WAAW,GAAG,SAAqC,CAAC;YAC1D,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,CAAC;gBAC1B,QAAQ,CAAC,2CAA2C,CAAC,CAAC;gBACtD,OAAO;YACT,CAAC;YAED,+CAA+C;YAC/C,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5D,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,QAAQ,CAAC,0CAA0C,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;gBAChE,OAAO;YACT,CAAC;YAED,0EAA0E;YAC1E,WAAW,CAAC,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;YAEnC,8EAA8E;YAC9E,MAAM,WAAW,GAAG,YAAY,CAAC,aAAa,EAAE,uBAAuB,IAAI,YAAY,CAAC,YAAY,CAAC;YAErG,wDAAwD;YACxD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,kBAAkB,CACjD,WAAW,EACX,YAAY,CAAC,gBAAgB,IAAI,EAAE,EACnC,GAAG,CAAC,aAAa,CAClB,CAAC;YAEF,IAAI,MAAM,EAAE,CAAC;gBACX,sCAAsC;gBACtC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBAEvD,+BAA+B;gBAC/B,IAAI,CAAC,YAAY,CAAC,cAAc,CAC9B,WAAW,EACX,YAAY,CAAC,gBAAgB,IAAI,EAAE,EACnC,GAAG,CAAC,aAAa,EACjB,KAAK,CACN,CAAC;gBAEF,wCAAwC;gBACxC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC;gBAEnD,8DAA8D;gBAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,QAAiC,CAAC;gBACvE,IAAI,QAAQ,CAAC,YAAY,EAAE,CAAC;oBAC1B,IAAI,CAAC,0BAA0B,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;gBACjE,CAAC;gBAED,OAAO;YACT,CAAC;YAED,wDAAwD;YACxD,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,eAAe,CAChE,qBAAqB,EACrB,WAAW,CACZ,CAAC;YAEF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,QAAQ,CAAC,0DAA0D,WAAW,EAAE,CAAC,CAAC;gBAClF,OAAO;YACT,CAAC;YAED,mCAAmC;YACnC,MAAM,YAAY,GAAG,eAAe,CAAC,WAAW,CAAC,QAAQ,EAAE;gBACzD,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;aAC9C,CAAC,CAAC;YAEH,uCAAuC;YACvC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE9C,yCAAyC;YACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAiC,CAAC;YAChE,QAAQ,CAAC,IAAI,GAAG,YAAY,CAAC;YAE7B,iBAAiB;YACjB,QAAQ,CAAC,iBAAiB,GAAG,GAAG,EAAE;gBAChC,mEAAmE;gBACnE,IAAI,CAAC,0BAA0B,CAAC,KAAK,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;gBAC/D,IAAI,CAAC,yBAAyB,EAAE,CAAC;YACnC,CAAC,CAAC;YAEF,QAAQ,CAAC,wBAAwB,GAAG,CAAC,MAA0C,EAAE,EAAE;gBACjF,6BAA6B;gBAC7B,IAAI,MAAM,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/C,0DAA0D;gBAC5D,CAAC;YACH,CAAC,CAAC;YAEF,2CAA2C;YAC3C,MAAM,gBAAgB,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YACvD,gBAAgB,CAAC,SAAS,GAAG,qBAAqB,CAAC;YACnD,gBAAgB,CAAC,KAAK,CAAC,OAAO,GAAG,4BAA4B,CAAC;YAE9D,wCAAwC;YACxC,MAAM,aAAa,GAAI,YAAY,CAAC,QAAoD,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACtG,gBAAgB,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;YAE5C,iCAAiC;YACjC,WAAW,CAAC,OAAO,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC;YAElD,uCAAuC;YACvC,IAAI,CAAC,YAAY,CAAC,cAAc,CAC9B,YAAmD,EACnD,gBAAgB,EAChB,YAAY,EACZ,KAAK,CACN,CAAC;YAEF,uCAAuC;YACvC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,YAAmD,CAAC,CAAC;QAErF,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,QAAQ,CAAC,CAAC,CAAC,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,oBAAoB,CAAC,GAAiB;QAClD,IAAI,CAAC;YACH,oDAAoD;YACpD,MAAM,YAAY,GAAG,GAAG,CAAC,aAAa,CAAC,cAAc,CAAW,CAAC;YACjE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;YAED,4BAA4B;YAC5B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC5D,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;YAED,gGAAgG;YAChG,MAAM,WAAW,GAAG,YAAY,CAAC,aAAa,EAAE,uBAAuB,IAAI,YAAY,CAAC,YAAY,CAAC;YACrG,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,eAAe,CAChE,qBAAqB,EACrB,WAAW,CACZ,CAAC;YAEF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,oEAAoE;YACpE,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC,QAAQ,EAA2B,CAAC;YACzE,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;YAE5E,IAAI,WAAW,IAAI,WAAW,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC;gBAC7C,wCAAwC;gBACxC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;gBAElE,kEAAkE;gBAClE,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sEAAsE,EAAE,KAAK,CAAC,CAAC;QAC/F,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,0BAA0B,CACtC,KAAa,EACb,iBAAwC,EACxC,YAA0B;QAE1B,IAAI,CAAC;YACH,mDAAmD;YACnD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;YAEjF,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,wCAAwC;YACxC,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;YAEjE,kEAAkE;YAClE,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAE3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,qEAAqE,EAAE,KAAK,CAAC,CAAC;QAC9F,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,sBAAsB,CAAC,GAAiB;QACpD,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC;QAEjC,oDAAoD;QACpD,IAAI,YAAY,GAAG,MAAM,CAAC,cAAc,CAAW,CAAC;QAEpD,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YACrC,yCAAyC;YACzC,YAAY,GAAG,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,OAAO,CAAW,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;YAChG,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gEAAgE;QAChE,IAAI,WAAW,GAAG,YAAY,CAAC,CAAC,4CAA4C;QAE5E,wFAAwF;QACxF,IAAI,YAAY,CAAC,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC5C,kDAAkD;YAClD,WAAW,GAAG,MAAM,CAAC,aAAa,CAAW,CAAC;YAE9C,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,QAAQ,CAAC,4DAA4D,CAAC,CAAC;gBACvE,OAAO,CAAC,KAAK,CAAC,oFAAoF,CAAC,CAAC;gBACpG,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,iEAAiE;YACjE,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;YAE1E,IAAI,kBAAkB,EAAE,WAAW,EAAE,CAAC;gBACpC,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC;YAC/C,CAAC;YACD,oFAAoF;QACtF,CAAC;QAED,yDAAyD;QACzD,MAAM,cAAc,GAAG;YACrB,GAAG,MAAM;YACT,aAAa,EAAE,GAAG,CAAC,aAAa;YAChC,uBAAuB,EAAE,WAAW,CAAE,mDAAmD;SAC1F,CAAC;QAEF,wEAAwE;QACxE,iGAAiG;QACjG,MAAM,gBAAgB,GAAI,MAAM,CAAC,UAAU,CAAY,IAAI,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;QAEtF,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC;YACpC,cAAc,EAAE,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC;YAC1D,gBAAgB,EAAE,gBAAgB;YAClC,aAAa,EAAE,cAAc;SAC9B,CAAC,CAAC;QAEH,OAAO,YAAY,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,qBAAqB,GAA6B,IAAI,CAAC;IAEtE;;OAEG;IACK,KAAK,CAAC,qBAAqB,CAAC,YAAoB;QACtD,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,GAAG,qBAAqB,CAAC,qBAAqB,IAAI,MAAM,EAAE,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC;QACrG,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;QAED,IAAI,CAAC,qBAAqB,CAAC,qBAAqB,EAAE,CAAC;YACjD,qBAAqB,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC,sBAAsB;QAC1E,CAAC;QAED,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,CAAC;QACrF,IAAI,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAyB,CAAC;YACjI,OAAO,EAAE,IAAI,IAAI,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,YAAoB;QAClD,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,EAAE,EAAE,CAAC;YACP,OAAO,EAAE,CAAC,EAAE,CAAC;QACf,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uCAAuC,YAAY,EAAE,CAAC,CAAC;IACzE,CAAC;IAED;;OAEG;IACK,wBAAwB,CAAC,KAAa;QAC5C,kDAAkD;QAClD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEjD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,wBAAwB;QACxB,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YAClC,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,iCAAiC;QACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,IAAgB;QAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,CAAC;QACX,CAAC;QAED,wCAAwC;QACxC,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC9B,OAAO,CAAC,CAAC;QACX,CAAC;QAED,yEAAyE;QACzE,IAAI,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAChD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,CAAC;QAED,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;;OAGG;IACK,mBAAmB,CAAC,KAAa;QACvC,kEAAkE;QAClE,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAE3D,IAAI,UAAU,EAAE,CAAC;YACf,qDAAqD;YACrD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,sEAAsE;YACtE,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACnD,IAAI,YAAY,EAAE,CAAC;gBACjB,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;gBAC9C,YAAY,CAAC,OAAO,EAAE,CAAC;gBACvB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,yBAAyB,CAAC,IAAoB;QACpD,0CAA0C;QAC1C,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QAEzD,iCAAiC;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7C,kDAAkD;QAClD,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC7B,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,mCAAmC;QACnC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACjB,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBACrC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,2EAA2E;gBAC3E,MAAM,oBAAoB,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC5D,IAAI,oBAAoB,EAAE,CAAC;oBACzB,MAAM,oBAAoB,GAAG,oBAAoB,CAAC,QAAQ,CAAC,IAAI,CAAC;oBAEhE,sGAAsG;oBACtG,MAAM,mBAAmB,GAAG,oBAAoB,EAAE,aAAa,EAAE,WAAW,IAAI,oBAAoB,EAAE,aAAa,EAAE,uBAAuB,CAAC;oBAC7I,MAAM,cAAc,GAAG,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,GAAG,CAAC,aAAa,CAAC,yBAAyB,CAAC,CAAC;oBAExG,6EAA6E;oBAC7E,+EAA+E;oBAC/E,uFAAuF;oBACvF,MAAM,gBAAgB,GAAG,oBAAoB,EAAE,gBAAgB,IAAI,EAAE,CAAC;oBACtE,MAAM,WAAW,GAAG,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,aAAa,CAAC,UAAU,CAAW,IAAI,EAAE,CAAC;oBAE1F,MAAM,WAAW,GAAG,oBAAoB,EAAE,YAAY,KAAK,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC;wBACzE,oBAAoB,EAAE,aAAa,EAAE,aAAa,KAAK,GAAG,CAAC,aAAa;wBACxE,gBAAgB,KAAK,WAAW;wBAChC,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,CAAC,KAAK,QAAQ,IAAI,mBAAmB,KAAK,cAAc,CAAC,CAAC;oBAE9G,IAAI,WAAW,EAAE,CAAC;wBAChB,yBAAyB;wBACzB,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBAEjC,sDAAsD;wBACtD,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBAE5C,oCAAoC;wBACpC,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC;wBAE/B,yDAAyD;wBACzD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;wBACxD,IAAI,MAAM,EAAE,WAAW,KAAK,GAAG,CAAC,EAAE,EAAE,CAAC;4BACnC,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;4BAC5D,IAAI,WAAW,EAAE,CAAC;gCAChB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;4BAC3C,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,mCAAmC;gBACnC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBAC1D,IAAI,CAAC,aAAa,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE;oBACxC,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,SAAS;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;YACxB,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAGD;;OAEG;IACH,eAAe,CAAC,CAAS,EAAE,CAAS,EAAE,KAAa;QACjD,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QACtB,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAE/B,+EAA+E;QAC/E,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,YAAY,GAAG,CAAC,KAAiB,EAAE,EAAE;gBACzC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB,CAAC;gBAC3C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;oBACrC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvB,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;oBACpD,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,UAAU,GAAG,CAAC,KAAoB,EAAE,EAAE;gBAC1C,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;oBAC3B,IAAI,CAAC,eAAe,EAAE,CAAC;oBACvB,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;oBACpD,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;gBACtD,CAAC;YACH,CAAC,CAAC;YAEF,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YACjD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QACnD,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAED;;OAEG;IACH,eAAe;QACb,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAChC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,IAAI,kBAAkB;QACpB,IAAI,CAAC,IAAI,CAAC,gBAAgB;YAAE,OAAO,KAAK,CAAC;QACzC,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChE,OAAO,GAAG,EAAE,QAAQ,IAAI,KAAK,CAAC;IAChC,CAAC;IAED;;OAEG;IACH,YAAY;QACV,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,oBAAoB;QAClB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACK,yBAAyB;QAC/B,IAAI,CAAC,yBAAyB,CAAC,IAAI,EAAE,CAAC,CAAC,0DAA0D;IACnG,CAAC;+GA3jCU,qBAAqB;6DAArB,qBAAqB;;;;;;;YAArB,4FAAA,oBAAgB,wBAAK;;YClDlC,8BAA2B;YAMvB,AAFF,uFAA6B,iEAEpB;YAMT,wFAA0B;YAwB5B,iBAAM;;YAhCJ,cAKC;YALD,mDAKC;YAGD,eAuBC;YAvBD,iDAuBC;;;iFDeU,qBAAqB;cAPjC,SAAS;6BACI,KAAK,YACP,kBAAkB,iBAGb,iBAAiB,CAAC,IAAI;;kBAGpC,SAAS;mBAAC,aAAa,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBAC1C,SAAS;mBAAC,wBAAwB,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;;kBAOrD,MAAM;;kBAMN,MAAM;;kBA0PN,YAAY;mBAAC,eAAe;;kFAzQlB,qBAAqB","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} 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 } from '@memberjunction/ng-shared';\nimport { ResourceData, MJResourceTypeEntity } from '@memberjunction/core-entities';\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 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 // 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\n const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(\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 // 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 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\n const resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(\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 // 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 }\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 = MJGlobal.Instance.ClassFactory.GetRegistration(\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 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 * 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\" (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 } from '@memberjunction/ng-shared';\nimport { ResourceData, MJResourceTypeEntity } from '@memberjunction/core-entities';\nimport { DatasetResultType, LogError, Metadata } from '@memberjunction/core';\nimport { ComponentCacheManager } from './component-cache-manager';\nimport { LazyModuleRegistry } from '../../../services/lazy-module-registry';\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 lazyRegistry = inject(LazyModuleRegistry);\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 // 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)\n let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n const loaded = await this.lazyRegistry.Load(driverClass);\n if (loaded) {\n resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);\n }\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 // 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 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)\n let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n const loaded = await this.lazyRegistry.Load(driverClass);\n if (loaded) {\n resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);\n }\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 // 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 }\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 let resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(\n BaseResourceComponent,\n driverClass\n );\n\n if (!resourceReg) {\n const loaded = await this.lazyRegistry.Load(driverClass);\n if (loaded) {\n resourceReg = MJGlobal.Instance.ClassFactory.GetRegistration(BaseResourceComponent, driverClass);\n }\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 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 * 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\" (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"]}