@memberjunction/ng-explorer-core 5.15.0 → 5.16.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.
@@ -1 +1 @@
1
- {"version":3,"file":"tab-container.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EACN,SAAS,EACT,aAAa,EAEb,UAAU,EACV,cAAc,EACd,mBAAmB,EAInB,iBAAiB,EAGjB,YAAY,EAEb,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAKnB,MAAM,qCAAqC,CAAC;;AAQ7C;;;;;;;;;GASG;AACH,qBAOa,qBAAsB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;IA6C1E,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,GAAG;IAjDgC,WAAW,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC9B,sBAAsB,EAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAE5G;;;;OAIG;IACO,yBAAyB,qBAA4B;IAE/D;;;OAGG;IACO,eAAe,qBAA4B;IAErD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,oBAAoB,CAAK;IACjC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAK;IAC7C,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,yBAAyB,CAAS;IAG1C,OAAO,CAAC,aAAa,CAA0D;IAG/E,OAAO,CAAC,YAAY,CAAwB;IAI5C,qBAAqB,UAAS;IAC9B,OAAO,CAAC,0BAA0B,CAAoD;IACtF,OAAO,CAAC,qBAAqB,CAAwB;IACrD,OAAO,CAAC,8BAA8B,CAAuB;IAC7D,OAAO,CAAC,qBAAqB,CAAS;IAGtC,kBAAkB,UAAS;IAC3B,YAAY,SAAK;IACjB,YAAY,SAAK;IACjB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAQ;gBAG7B,aAAa,EAAE,mBAAmB,EAClC,gBAAgB,EAAE,qBAAqB,EACvC,UAAU,EAAE,kBAAkB,EAC9B,MAAM,EAAE,cAAc,EACtB,mBAAmB,EAAE,mBAAmB,EACxC,GAAG,EAAE,iBAAiB;IAMhC,QAAQ,IAAI,IAAI;IA2DhB,eAAe,IAAI,IAAI;IAUvB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAmH9B,WAAW,IAAI,IAAI;IAiBnB;;;;OAIG;IAEH,cAAc,IAAI,IAAI;IAMtB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAyEpC;;OAEG;YACW,yBAAyB;IAoHvC;;OAEG;IACH,OAAO,CAAC,8BAA8B;IActC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAgB9B;;OAEG;IACH,OAAO,CAAC,SAAS;IAoBjB;;OAEG;YACW,UAAU;IAQxB;;;OAGG;YACW,cAAc;IAmI5B;;;OAGG;YACW,oBAAoB;IAgDlC;;OAEG;YACW,0BAA0B;IAwBxC;;OAEG;YACW,sBAAsB;IA2DpC,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAkC;IAEtE;;OAEG;YACW,qBAAqB;YAoBrB,iBAAiB;IAQ/B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgChC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA8EjC;;OAEG;IACH,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA8B1D;;OAEG;IACH,eAAe,IAAI,IAAI;IAKvB;;OAEG;IACH,IAAI,kBAAkB,IAAI,OAAO,CAIhC;IAED;;OAEG;IACH,YAAY,IAAI,IAAI;IAOpB;;OAEG;IACH,cAAc,IAAI,IAAI;IAOtB;;OAEG;IACH,oBAAoB,IAAI,IAAI;IAO5B;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAO7B;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;yCA/kCtB,qBAAqB;2CAArB,qBAAqB;CAklCjC"}
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,7 +1,7 @@
1
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
- import { ResourceData } from '@memberjunction/core-entities';
4
+ import { ResourceData, ResourcePermissionEngine } from '@memberjunction/core-entities';
5
5
  import { LogError, Metadata } from '@memberjunction/core';
6
6
  import { ComponentCacheManager } from './component-cache-manager';
7
7
  import { LazyModuleRegistry } from '../../../services/lazy-module-registry';
@@ -723,6 +723,15 @@ export class TabContainerComponent {
723
723
  * Get ResourceType entity by name (includes DriverClass field)
724
724
  */
725
725
  async getResourceTypeEntity(resourceType) {
726
+ // Use ResourcePermissionEngine's cached data instead of fetching the dataset again.
727
+ // The engine loads ResourceTypes during startup and keeps them in memory.
728
+ const resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;
729
+ if (resourceTypes && resourceTypes.length > 0) {
730
+ const rt = resourceTypes.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase());
731
+ return rt || null;
732
+ }
733
+ // Fallback: if engine hasn't loaded yet (shouldn't happen in normal flow),
734
+ // fetch the dataset directly
726
735
  const md = new Metadata();
727
736
  const ds = TabContainerComponent._resourceTypesDataset || await md.GetDatasetByName("ResourceTypes");
728
737
  if (!ds || !ds.Success || ds.Results.length === 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"tab-container.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/tab-container.component.ts","../../../../../src/lib/shell/components/tabs/tab-container.component.html"],"names":[],"mappings":"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","sourcesContent":["import {\n Component,\n OnInit,\n OnDestroy,\n AfterViewInit,\n ViewChild,\n ElementRef,\n ApplicationRef,\n EnvironmentInjector,\n createComponent,\n ComponentRef,\n ViewEncapsulation,\n ChangeDetectorRef,\n HostListener,\n Output,\n EventEmitter,\n inject\n} from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport {\n GoldenLayoutManager,\n WorkspaceStateManager,\n ApplicationManager,\n TabComponentState,\n TabShownEvent,\n WorkspaceTab,\n LayoutNode\n} from '@memberjunction/ng-base-application';\nimport { MJGlobal } from '@memberjunction/global';\nimport { BaseResourceComponent } 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"]}
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, ResourcePermissionEngine } 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 // Use ResourcePermissionEngine's cached data instead of fetching the dataset again.\n // The engine loads ResourceTypes during startup and keeps them in memory.\n const resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;\n if (resourceTypes && resourceTypes.length > 0) {\n const rt = resourceTypes.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase());\n return rt || null;\n }\n\n // Fallback: if engine hasn't loaded yet (shouldn't happen in normal flow),\n // fetch the dataset directly\n const md = new Metadata();\n const ds = TabContainerComponent._resourceTypesDataset || await md.GetDatasetByName(\"ResourceTypes\");\n if (!ds || !ds.Success || ds.Results.length === 0) {\n return null;\n }\n\n if (!TabContainerComponent._resourceTypesDataset) {\n TabContainerComponent._resourceTypesDataset = ds; // cache for next time\n }\n\n const result = ds.Results.find(r => r.Code.trim().toLowerCase() === 'resourcetypes');\n if (result && result.Results?.length > 0) {\n const rt = result.Results.find(rt => rt.Name.trim().toLowerCase() === resourceType.trim().toLowerCase()) as MJResourceTypeEntity;\n return rt || null;\n }\n\n return null;\n }\n\n private async getResourceTypeId(resourceType: string): Promise<string> {\n const rt = await this.getResourceTypeEntity(resourceType);\n if (rt) {\n return rt.ID;\n }\n throw new Error(`ResourceType ID not found for type: ${resourceType}`);\n }\n\n /**\n * Determine resource type from route\n */\n private getResourceTypeFromRoute(route: string): string {\n // Parse route segments to determine resource type\n const segments = route.split('/').filter(s => s);\n\n if (segments.length === 0) {\n return 'home';\n }\n\n // Common route patterns\n if (route.includes('/record/')) {\n return 'record';\n }\n if (route.includes('/view/')) {\n return 'view';\n }\n if (route.includes('/dashboard/')) {\n return 'dashboard';\n }\n if (route.includes('/report/')) {\n return 'report';\n }\n if (route.includes('/search')) {\n return 'search';\n }\n if (route.includes('/query/')) {\n return 'query';\n }\n\n // Default based on first segment\n return segments[0] || 'home';\n }\n\n /**\n * Count the number of component nodes in a layout tree.\n * Used to validate that saved layout matches the tabs array before restoring.\n */\n private countLayoutComponents(node: LayoutNode): number {\n if (!node) {\n return 0;\n }\n\n // If this is a component node, count it\n if (node.type === 'component') {\n return 1;\n }\n\n // If this node has children (row, column, stack), recursively count them\n if (node.content && Array.isArray(node.content)) {\n return node.content.reduce((count, child) => count + this.countLayoutComponents(child), 0);\n }\n\n return 0;\n }\n\n /**\n * Cleanup a tab's component\n * Detaches from DOM but keeps in cache for potential reuse\n */\n private cleanupTabComponent(tabId: string): void {\n // First, try to detach from cache (preserves component for reuse)\n const cachedInfo = this.cacheManager.markAsDetached(tabId);\n\n if (cachedInfo) {\n // Remove from legacy componentRefs but keep in cache\n this.componentRefs.delete(tabId);\n } else {\n // Fallback: destroy if not in cache (shouldn't happen in normal flow)\n const componentRef = this.componentRefs.get(tabId);\n if (componentRef) {\n this.appRef.detachView(componentRef.hostView);\n componentRef.destroy();\n this.componentRefs.delete(tabId);\n }\n }\n }\n\n /**\n * Sync tabs with configuration changes\n */\n private syncTabsWithConfiguration(tabs: WorkspaceTab[]): void {\n // Get existing tab IDs from Golden Layout\n const existingTabIds = this.layoutManager.GetAllTabIds();\n\n // Get tab IDs from configuration\n const configTabIds = tabs.map(tab => tab.id);\n\n // Remove tabs that are no longer in configuration\n existingTabIds.forEach(tabId => {\n if (!configTabIds.includes(tabId)) {\n this.layoutManager.RemoveTab(tabId);\n }\n });\n\n // Create tabs that don't exist yet\n tabs.forEach(tab => {\n if (!existingTabIds.includes(tab.id)) {\n this.createTab(tab);\n } else {\n // Check if tab content needs to be reloaded (app or resource type changed)\n const existingComponentRef = this.componentRefs.get(tab.id);\n if (existingComponentRef) {\n const existingResourceData = existingComponentRef.instance.Data;\n\n // For Custom resource types, also check driverClass to distinguish between different custom resources\n const existingDriverClass = existingResourceData?.Configuration?.driverClass || existingResourceData?.Configuration?.resourceTypeDriverClass;\n const newDriverClass = tab.configuration['driverClass'] || tab.configuration['resourceTypeDriverClass'];\n\n // Normalize record IDs for comparison (treat null/undefined as empty string)\n // IMPORTANT: Check both tab.resourceRecordId AND tab.configuration['recordId']\n // because for nav items, the recordId is stored in configuration, not resourceRecordId\n const existingRecordId = existingResourceData?.ResourceRecordID || '';\n const newRecordId = tab.resourceRecordId || tab.configuration['recordId'] as string || '';\n\n const needsReload = existingResourceData?.ResourceType !== tab.configuration['resourceType'] ||\n existingResourceData?.Configuration?.applicationId !== tab.applicationId ||\n existingRecordId !== newRecordId ||\n (tab.configuration['resourceType'] === 'Custom' && existingDriverClass !== newDriverClass);\n\n if (needsReload) {\n // Clean up old component\n this.cleanupTabComponent(tab.id);\n\n // Mark tab as not loaded so it will reload when shown\n this.layoutManager.MarkTabNotLoaded(tab.id);\n\n // Update display name in background\n this.updateTabDisplayName(tab);\n\n // If this tab is currently active, reload it immediately\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId === tab.id) {\n const glContainer = this.layoutManager.GetContainer(tab.id);\n if (glContainer) {\n this.loadTabContent(tab.id, glContainer);\n }\n }\n }\n }\n\n // Update styling for existing tabs\n const app = this.appManager.GetAppById(tab.applicationId);\n this.layoutManager.UpdateTabStyle(tab.id, {\n isPinned: tab.isPinned,\n title: tab.title,\n appColor: app?.GetColor() || '#757575'\n });\n }\n });\n\n // Focus the active tab\n const config = this.workspaceManager.GetConfiguration();\n if (config?.activeTabId) {\n this.layoutManager.FocusTab(config.activeTabId);\n }\n }\n\n\n /**\n * Show context menu\n */\n showContextMenu(x: number, y: number, tabId: string): void {\n this.contextMenuX = x;\n this.contextMenuY = y;\n this.contextMenuTabId = tabId;\n this.contextMenuVisible = true;\n\n // Close menu when clicking outside - use setTimeout to avoid immediate trigger\n setTimeout(() => {\n const clickHandler = (event: MouseEvent) => {\n const target = event.target as HTMLElement;\n if (!target.closest('.context-menu')) {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n const keyHandler = (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.hideContextMenu();\n document.removeEventListener('click', clickHandler);\n document.removeEventListener('keydown', keyHandler);\n }\n };\n\n document.addEventListener('click', clickHandler);\n document.addEventListener('keydown', keyHandler);\n }, 0);\n }\n\n /**\n * Hide context menu\n */\n hideContextMenu(): void {\n this.contextMenuVisible = false;\n this.contextMenuTabId = null;\n }\n\n /**\n * Check if context menu tab is pinned\n */\n get isContextTabPinned(): boolean {\n if (!this.contextMenuTabId) return false;\n const tab = this.workspaceManager.GetTab(this.contextMenuTabId);\n return tab?.isPinned || false;\n }\n\n /**\n * Toggle pin from context menu\n */\n onContextPin(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.TogglePin(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tab from context menu\n */\n onContextClose(): void {\n if (this.contextMenuTabId) {\n this.layoutManager.RemoveTab(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close all other tabs from context menu\n */\n onContextCloseOthers(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseOtherTabs(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * Close tabs to the right from context menu\n */\n onContextCloseToRight(): void {\n if (this.contextMenuTabId) {\n this.workspaceManager.CloseTabsToRight(this.contextMenuTabId);\n }\n this.hideContextMenu();\n }\n\n /**\n * 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 +1 @@
1
- {"version":3,"file":"user-notifications.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"user-notifications.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAoD,wBAAwB,EAAE,4BAA4B,EAAkB,MAAM,+BAA+B,CAAC;AACzK,OAAO,EAAY,oBAAoB,EAAuB,MAAM,sBAAsB,CAAC;AAC3F,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAGzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;;AAEzE;;GAEG;AACH,KAAK,gBAAgB,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AA6BlD;;GAEG;AACH,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,qBAMa,0BAA2B,YAAW,MAAM,EAAE,aAAa;IAY7D,aAAa,EAAE,aAAa;IACnC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,UAAU;IAdG,QAAQ,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IACrC,WAAW,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC7C,SAAS,EAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAE1D,aAAa,EAAE,gBAAgB,CAAS;IACxC,aAAa,EAAE,MAAM,CAAM;IAC3B,iBAAiB,EAAE,4BAA4B,EAAE,CAAM;IACvD,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAQ;IACzC,YAAY,EAAE,OAAO,CAAQ;gBAG3B,aAAa,EAAE,aAAa,EAC3B,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,iBAAiB,EACpC,UAAU,EAAE,kBAAkB;IAGlC,QAAQ;IAId,eAAe,IAAI,IAAI;IAIvB,OAAO,CAAC,qBAAqB;IAc7B,IAAW,mBAAmB,IAAI,wBAAwB,EAAE,CA4B3D;IAEM,uBAAuB,CAAC,YAAY,EAAE,wBAAwB,GAAG,OAAO;IAaxE,eAAe,CAAC,YAAY,EAAE,wBAAwB,GAAG,mBAAmB;IAkDnF,IAAW,gBAAgB,IAAI,wBAAwB,EAAE,CAExD;IAED,IAAW,mBAAmB,IAAI,wBAAwB,EAAE,CAE3D;IAED,IAAW,iBAAiB,IAAI,wBAAwB,EAAE,CAEzD;IAED,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI;IAgBhD,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMtC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIpC,iBAAiB,CAAC,YAAY,EAAE,wBAAwB,GAAG,MAAM;IAOjE,mBAAmB,CAAC,YAAY,EAAE,wBAAwB,GAAG,MAAM;IAY7D,UAAU,CAAC,YAAY,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,oBAAoB,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAoCtH,aAAa;IAOb,6BAA6B;IAkC7B,eAAe;IAIf,OAAO,CAAC,KAAK,EAAE,OAAO;IAoBnC,mBAAmB,CAAC,YAAY,EAAE,wBAAwB,GAAG,IAAI;IAwBjE;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAmC9B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA8BvB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,4BAA4B,GAAG,IAAI;IAK/E,WAAW,CAAC,YAAY,EAAE,wBAAwB,GAAG,MAAM;IAK3D,YAAY,CAAC,YAAY,EAAE,wBAAwB,GAAG,MAAM;IAK5D,WAAW,CAAC,YAAY,EAAE,wBAAwB,GAAG,MAAM;IAK3D,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;yCAxZ3C,0BAA0B;2CAA1B,0BAA0B;CA2ZtC"}
@@ -569,12 +569,19 @@ export class UserNotificationsComponent {
569
569
  if (!config || config.type?.trim().toLowerCase() !== 'agent-request' || !config.requestId) {
570
570
  return false;
571
571
  }
572
+ // Try the AI app first (has dedicated Agent Requests nav item)
572
573
  const aiApp = this.appManager.GetAppByName('AI');
573
- if (!aiApp) {
574
- return false;
574
+ if (aiApp) {
575
+ this.navigationService.OpenNavItemByName('Agent Requests', { requestId: config.requestId }, aiApp.ID);
576
+ return true;
575
577
  }
576
- this.navigationService.OpenNavItemByName('Agent Requests', { requestId: config.requestId }, aiApp.ID);
577
- return true;
578
+ // Fallback: navigate to Chat app's Conversations with the request context
579
+ const chatApp = this.appManager.GetAppByName('Chat');
580
+ if (chatApp) {
581
+ this.navigationService.OpenNavItemByName('Conversations', { requestId: config.requestId }, chatApp.ID);
582
+ return true;
583
+ }
584
+ return false;
578
585
  }
579
586
  /**
580
587
  * Handle navigation to a conversation via NavigationService.
@@ -1 +1 @@
1
- {"version":3,"file":"user-notifications.component.js","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts","../../../src/lib/user-notifications/user-notifications.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\nimport { SharedService, NavigationService } from '@memberjunction/ng-shared';\nimport { MJConversationDetailEntity, MJConversationEntity, MJUserNotificationEntity, MJUserNotificationTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { Metadata, TransactionGroupBase, TransactionVariable } from '@memberjunction/core';\nimport { Router } from '@angular/router';\nimport { SafeJSONParse , UUIDsEqual } from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ApplicationManager } from '@memberjunction/ng-base-application';\n\n/**\n * Radio button filter options for notification read status\n */\ntype ReadFilterOption = 'All' | 'Unread' | 'Read';\n\n/**\n * Configuration for record-type resource navigation\n */\ninterface RecordResourceConfig {\n Entity?: string;\n}\n\n/**\n * Configuration for conversation-type resource navigation\n */\ninterface ConversationResourceConfig {\n type: 'conversation';\n conversationId?: string;\n messageId?: string;\n artifactId?: string;\n versionNumber?: string;\n taskId?: string;\n}\n\n/**\n * Configuration for agent-request-type resource navigation\n */\ninterface AgentRequestResourceConfig {\n type: 'agent-request';\n requestId: string;\n}\n\n/**\n * Result of parsing a notification URL\n */\ninterface NotificationUrlInfo {\n urlParts: string[];\n queryString: string;\n}\n\n@Component({\n standalone: false,\n selector: 'app-user-notifications',\n templateUrl: './user-notifications.component.html',\n styleUrls: ['./user-notifications.component.css']\n})\nexport class UserNotificationsComponent implements OnInit, AfterViewInit {\n @ViewChild('allRadio') allRadio!: ElementRef<HTMLInputElement>;\n @ViewChild('unreadRadio') unreadRadio!: ElementRef<HTMLInputElement>;\n @ViewChild('readRadio') readRadio!: ElementRef<HTMLInputElement>;\n\n public radioSelected: ReadFilterOption = 'All';\n public currentFilter: string = '';\n public notificationTypes: MJUserNotificationTypeEntity[] = [];\n public selectedTypeFilter: string | null = null;\n public loadingTypes: boolean = true;\n\n constructor (\n public sharedService: SharedService,\n private router: Router,\n private navigationService: NavigationService,\n private appManager: ApplicationManager\n ) {}\n\n async ngOnInit() {\n this.loadNotificationTypes();\n }\n\n ngAfterViewInit(): void {\n this.sharedService.InvokeManualResize(); // make sure the notifications component is sized correctly\n }\n\n private loadNotificationTypes() {\n // Get notification types from UserInfoEngine cache, sorted client-side\n // UserInfoEngine is auto-configured via @RegisterForStartup()\n this.notificationTypes = [...UserInfoEngine.Instance.NotificationTypes].sort((a, b) => {\n const priorityA = a.Priority ?? 999;\n const priorityB = b.Priority ?? 999;\n if (priorityA !== priorityB) {\n return priorityA - priorityB;\n }\n return a.Name.localeCompare(b.Name);\n });\n this.loadingTypes = false;\n }\n\n public get NotificationsToShow(): MJUserNotificationEntity[] {\n let temp: MJUserNotificationEntity[] = [];\n switch (this.radioSelected) {\n case 'All':\n temp = this.AllNotifications;\n break;\n case 'Unread':\n temp = this.AllNotifications.filter(n => n.Unread);\n break;\n case 'Read':\n temp = this.AllNotifications.filter(n => !n.Unread);\n break;\n }\n\n // Apply type filter if selected\n if (this.selectedTypeFilter) {\n temp = temp.filter(n => UUIDsEqual(n.NotificationTypeID, this.selectedTypeFilter));\n }\n\n // Apply text filter if it is not empty\n if (this.currentFilter.trim().length > 0) {\n // check for inclusion of filter value in title or message\n temp = temp.filter(n => n.Title?.toLowerCase().includes(this.currentFilter.trim().toLowerCase()) ||\n n.Message?.toLowerCase().includes(this.currentFilter.trim().toLowerCase())\n );\n }\n\n return temp;\n }\n\n public isNotificationClickable(notification: MJUserNotificationEntity): boolean {\n // Check for agent-request type (navigated via NavigationService, not URL)\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'agent-request' && config.requestId) {\n return true;\n }\n }\n\n const info = this.notificationUrl(notification);\n return (info !== null && info.urlParts && info.urlParts.length > 0);\n }\n\n public notificationUrl(notification: MJUserNotificationEntity): NotificationUrlInfo {\n const url: string[] = [];\n let queryString = '';\n if (notification.ResourceRecordID && notification.ResourceRecordID.length > 0 &&\n notification.ResourceTypeID && notification.ResourceTypeID.length > 0) {\n // we have a resource here, like a Report, Dashboard, etc\n // we can generate a url to navigate to it\n const rt = this.sharedService.ResourceTypeByID(notification.ResourceTypeID);\n let routeSegment: string | null | undefined;\n if (rt)\n routeSegment = this.sharedService.mapResourceTypeNameToRouteSegment(rt.Name);\n\n if (rt && routeSegment && routeSegment.trim().length > 0) {\n url.push('resource');\n url.push(routeSegment);\n url.push(notification.ResourceRecordID.toString());\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n if (rt.Name.trim().toLowerCase() === 'records') {\n // special handling for records\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration);\n if (config && config.Entity)\n queryString = `Entity=${config.Entity}`;\n }\n else\n queryString = notification.ResourceConfiguration;\n }\n }\n }\n else if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n // we do NOT have a resource type or resource record id, but we do have a ResourceConfiguration\n // string, which means we might have information on how to navigate to what we want if we parse the config\n // HOME screen stuff is done this way\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'conversation') {\n url.push('chat');\n // Build query string with conversation and artifact navigation\n const queryParams: string[] = [];\n if (config.conversationId) queryParams.push(`conversationId=${config.conversationId}`);\n if (config.messageId) queryParams.push(`messageId=${config.messageId}`);\n if (config.artifactId) queryParams.push(`artifactId=${config.artifactId}`);\n if (config.versionNumber) queryParams.push(`versionNumber=${config.versionNumber}`);\n if (config.taskId) queryParams.push(`taskId=${config.taskId}`);\n queryString = queryParams.join('&');\n }\n }\n\n return { urlParts: url, queryString };\n }\n\n public get AllNotifications(): MJUserNotificationEntity[] {\n return SharedService.UserNotifications;\n }\n\n public get UnreadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => n.Unread);\n }\n\n public get ReadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => !n.Unread);\n }\n\n selectReadOption(option: ReadFilterOption): void {\n this.radioSelected = option;\n // now update the radio button group in the UI\n switch (option) {\n case 'All':\n this.allRadio.nativeElement.checked = true;\n break;\n case 'Unread':\n this.unreadRadio.nativeElement.checked = true;\n break;\n case 'Read':\n this.readRadio.nativeElement.checked = true;\n break;\n }\n }\n\n onReadRadioChanged(event: Event): void {\n if (event.target instanceof HTMLInputElement) {\n this.radioSelected = event.target.value as ReadFilterOption;\n }\n }\n\n onFilterChanged(value: string): void {\n this.currentFilter = value;\n }\n\n getItemTitleClass(notification: MJUserNotificationEntity): string {\n if (notification.Unread) {\n return 'notification-title notification-title-unread';\n }\n return 'notification-title';\n }\n\n getItemWrapperClass(notification: MJUserNotificationEntity): string {\n let classInfo = 'notification-wrap';\n\n if (this.isNotificationClickable(notification))\n classInfo += ' notification-wrap-clickable';\n\n if (notification.Unread)\n classInfo += ' notification-wrap-unread';\n\n return classInfo;\n }\n\n async markAsRead(notification: MJUserNotificationEntity, bRead: boolean, transGroup: TransactionGroupBase | null): Promise<boolean> {\n if (notification) {\n const notificationId = notification.ID;\n notification.Unread = !bRead;\n let notificationEntity: MJUserNotificationEntity;\n if (notification instanceof MJUserNotificationEntity) {\n // the passed in param truly is a MJUserNotificationEntity or subclass, so just use it, saves a DB round trip\n notificationEntity = notification;\n }\n else {\n // the passed in param is just a plain object, so we need to load the entity\n const md = new Metadata();\n notificationEntity = await md.GetEntityObject<MJUserNotificationEntity>('MJ: User Notifications');\n await notificationEntity.Load(notificationId); \n notificationEntity.Unread = !bRead; \n }\n\n // part of a transaction group, if so, add it as that will defer the actual network traffic/save\n if (transGroup) {\n notificationEntity.TransactionGroup = transGroup;\n await notificationEntity.Save()\n return true;\n }\n else {\n // Save the notification (not part of transaction group)\n await notificationEntity.Save();\n // Update the observables so badge count refreshes immediately\n MJNotificationService.UpdateNotificationObservables();\n return true;\n }\n }\n else {\n return false;\n }\n }\n\n public async markAllAsRead() {\n await this.markAll(true);\n\n // test harness for creating Conversations and Conversation Details record in a single transaction using variables\n await this.TestTransactionGroupVariables();\n }\n\n public async TestTransactionGroupVariables() {\n const md = new Metadata();\n const transGroup = await md.CreateTransactionGroup();\n\n const conversation = await md.GetEntityObject<MJConversationEntity>('MJ: Conversations');\n conversation.UserID = md.CurrentUser.ID;\n conversation.Description = 'Test Conversation';\n conversation.TransactionGroup = transGroup;\n if (!await conversation.Save()) {\n this.sharedService.CreateSimpleNotification('Unable to create conversation', 'error', 5000);\n }\n\n const tvDefine = new TransactionVariable('NewConvoID', conversation, 'ID', 'Define')\n transGroup.AddVariable(tvDefine);\n\n const conversationDetail = await md.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details');\n conversationDetail.Message = 'Test Message';\n conversationDetail.Role = 'User';\n conversationDetail.ConversationID = 'x'; // fake UUID must be non-null to pass validation, this will be replaced by the variable, since we're part of a TG, not a real save, so doesn't validate it as a true fkey\n conversationDetail.TransactionGroup = transGroup;\n if (!await conversationDetail.Save()) {\n this.sharedService.CreateSimpleNotification('Unable to create conversation detail', 'error', 500);\n } \n const tvUse = new TransactionVariable('NewConvoID', conversationDetail, 'ConversationID', 'Use')\n transGroup.AddVariable(tvUse);\n\n if (await transGroup.Submit()) {\n this.sharedService.CreateSimpleNotification('Transaction Group with Variables worked', 'success', 5000);\n }\n else {\n this.sharedService.CreateSimpleNotification('Transaction Group with Variables failed', 'error', 5000);\n }\n }\n\n public async markAllAsUnread() {\n await this.markAll(false);\n }\n\n public async markAll(bRead: boolean) {\n // Use transaction group for batching - all saves are queued and sent in one round-trip\n const md = new Metadata();\n const transGroup = await md.CreateTransactionGroup();\n\n // Queue all saves - no need to await individual saves since transaction group queues them\n for (const notification of this.AllNotifications) {\n if (notification.Unread && bRead || !notification.Unread && !bRead) {\n // Don't await - Save() with transaction group queues the operation immediately\n this.markAsRead(notification, bRead, transGroup);\n }\n }\n\n // Submit transaction group - this is where the actual network call happens\n if (!await transGroup.Submit())\n this.sharedService.CreateSimpleNotification('Unable to mark all notifications as read', 'error', 5000);\n else\n SharedService.RefreshUserNotifications();\n }\n \n notificationClicked(notification: MJUserNotificationEntity): void {\n if (this.isNotificationClickable(notification)) {\n // also mark this as read when we click it\n this.markAsRead(notification, true, null);\n\n // Check for special navigation types that use NavigationService (not router)\n if (this.navigateToAgentRequest(notification)) {\n return;\n }\n if (this.navigateToConversation(notification)) {\n return;\n }\n\n const info = this.notificationUrl(notification);\n if (info.queryString && info.queryString.trim().length > 0) {\n const fullUrl = `${info.urlParts.join('/')}${info.queryString ? '?' + info.queryString : ''}`;\n this.router.navigateByUrl(fullUrl);\n }\n else {\n this.router.navigate(info.urlParts);\n }\n }\n }\n\n /**\n * Handle navigation to an agent request via NavigationService.\n * Returns true if the notification was an agent-request type and navigation was attempted.\n */\n private navigateToAgentRequest(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'agent-request' || !config.requestId) {\n return false;\n }\n\n const aiApp = this.appManager.GetAppByName('AI');\n if (!aiApp) {\n return false;\n }\n\n this.navigationService.OpenNavItemByName(\n 'Agent Requests',\n { requestId: config.requestId },\n aiApp.ID\n );\n return true;\n }\n\n /**\n * Handle navigation to a conversation via NavigationService.\n * Returns true if the notification was a conversation type and navigation was attempted.\n */\n private navigateToConversation(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'conversation') {\n return false;\n }\n\n const chatApp = this.appManager.GetAppByName('Chat');\n if (!chatApp) {\n return false;\n }\n\n const navConfig: Record<string, string> = {};\n if (config.conversationId) navConfig['conversationId'] = config.conversationId;\n if (config.messageId) navConfig['messageId'] = config.messageId;\n if (config.artifactId) navConfig['artifactId'] = config.artifactId;\n if (config.versionNumber) navConfig['versionNumber'] = config.versionNumber;\n if (config.taskId) navConfig['taskId'] = config.taskId;\n\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n navConfig,\n chatApp.ID\n );\n return true;\n }\n\n public getNotificationType(typeId: string | null): MJUserNotificationTypeEntity | null {\n if (!typeId) return null;\n return this.notificationTypes.find(t => UUIDsEqual(t.ID, typeId)) || null;\n }\n\n public getTypeIcon(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Icon || 'fa-bell';\n }\n\n public getTypeColor(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Color || '#999';\n }\n\n public getTypeName(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type ? type.Name : 'Notification';\n }\n\n public onTypeFilterChange(typeId: string | null): void {\n this.selectedTypeFilter = typeId;\n }\n}\n","<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <h1>Notifications</h1>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <!-- Horizontal Slider for Filters (Mobile) -->\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Stats Pills (Filter Tabs) -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <input #allRadio type=\"radio\" name=\"UnreadStatus\" value=\"All\"\n (change)=\"onReadRadioChanged($event)\" checked class=\"hidden-radio\"\n id=\"filter-all\" />\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n <input #unreadRadio type=\"radio\" name=\"UnreadStatus\" value=\"Unread\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-unread\" />\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n <input #readRadio type=\"radio\" name=\"UnreadStatus\" value=\"Read\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-read\" />\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Native Type Filter Dropdown (in slider on mobile) -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search Filter (separate, full-width on mobile) -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n <!-- Filter Info Badge -->\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-bell-slash\"></i>\n </div>\n <h3>No Notifications</h3>\n <p>You're all caught up! New notifications will appear here.</p>\n </div>\n } @else if (NotificationsToShow.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n </div>\n <h3>No Matching Notifications</h3>\n <p>Try adjusting your filters to see more notifications.</p>\n </div>\n } @else {\n <!-- Notifications List -->\n <div class=\"notifications-list\">\n @for (notification of NotificationsToShow; track notification.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"notification.Unread\"\n [class.clickable]=\"isNotificationClickable(notification)\"\n role=\"article\"\n [attr.aria-label]=\"notification.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(notification)\"\n [style.color]=\"getTypeColor(notification)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(notification)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"notification.Unread\">\n {{notification.Title}}\n </h3>\n <span class=\"card-time\">\n <i class=\"fa-regular fa-clock\" aria-hidden=\"true\"></i>\n <time [attr.datetime]=\"notification.__mj_CreatedAt\">\n {{notification.__mj_CreatedAt | date:'MMM d, h:mm a'}}\n </time>\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n [style.color]=\"getTypeColor(notification)\">\n {{getTypeName(notification)}}\n </span>\n </div>\n\n <p class=\"card-message\">{{notification.Message}}</p>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (notification.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, true, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, false, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n </div>\n }\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"user-notifications.component.js","sourceRoot":"","sources":["../../../src/lib/user-notifications/user-notifications.component.ts","../../../src/lib/user-notifications/user-notifications.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\nimport { SharedService, NavigationService } from '@memberjunction/ng-shared';\nimport { MJConversationDetailEntity, MJConversationEntity, MJUserNotificationEntity, MJUserNotificationTypeEntity, UserInfoEngine } from '@memberjunction/core-entities';\nimport { Metadata, TransactionGroupBase, TransactionVariable } from '@memberjunction/core';\nimport { Router } from '@angular/router';\nimport { SafeJSONParse , UUIDsEqual } from '@memberjunction/global';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { ApplicationManager } from '@memberjunction/ng-base-application';\n\n/**\n * Radio button filter options for notification read status\n */\ntype ReadFilterOption = 'All' | 'Unread' | 'Read';\n\n/**\n * Configuration for record-type resource navigation\n */\ninterface RecordResourceConfig {\n Entity?: string;\n}\n\n/**\n * Configuration for conversation-type resource navigation\n */\ninterface ConversationResourceConfig {\n type: 'conversation';\n conversationId?: string;\n messageId?: string;\n artifactId?: string;\n versionNumber?: string;\n taskId?: string;\n}\n\n/**\n * Configuration for agent-request-type resource navigation\n */\ninterface AgentRequestResourceConfig {\n type: 'agent-request';\n requestId: string;\n}\n\n/**\n * Result of parsing a notification URL\n */\ninterface NotificationUrlInfo {\n urlParts: string[];\n queryString: string;\n}\n\n@Component({\n standalone: false,\n selector: 'app-user-notifications',\n templateUrl: './user-notifications.component.html',\n styleUrls: ['./user-notifications.component.css']\n})\nexport class UserNotificationsComponent implements OnInit, AfterViewInit {\n @ViewChild('allRadio') allRadio!: ElementRef<HTMLInputElement>;\n @ViewChild('unreadRadio') unreadRadio!: ElementRef<HTMLInputElement>;\n @ViewChild('readRadio') readRadio!: ElementRef<HTMLInputElement>;\n\n public radioSelected: ReadFilterOption = 'All';\n public currentFilter: string = '';\n public notificationTypes: MJUserNotificationTypeEntity[] = [];\n public selectedTypeFilter: string | null = null;\n public loadingTypes: boolean = true;\n\n constructor (\n public sharedService: SharedService,\n private router: Router,\n private navigationService: NavigationService,\n private appManager: ApplicationManager\n ) {}\n\n async ngOnInit() {\n this.loadNotificationTypes();\n }\n\n ngAfterViewInit(): void {\n this.sharedService.InvokeManualResize(); // make sure the notifications component is sized correctly\n }\n\n private loadNotificationTypes() {\n // Get notification types from UserInfoEngine cache, sorted client-side\n // UserInfoEngine is auto-configured via @RegisterForStartup()\n this.notificationTypes = [...UserInfoEngine.Instance.NotificationTypes].sort((a, b) => {\n const priorityA = a.Priority ?? 999;\n const priorityB = b.Priority ?? 999;\n if (priorityA !== priorityB) {\n return priorityA - priorityB;\n }\n return a.Name.localeCompare(b.Name);\n });\n this.loadingTypes = false;\n }\n\n public get NotificationsToShow(): MJUserNotificationEntity[] {\n let temp: MJUserNotificationEntity[] = [];\n switch (this.radioSelected) {\n case 'All':\n temp = this.AllNotifications;\n break;\n case 'Unread':\n temp = this.AllNotifications.filter(n => n.Unread);\n break;\n case 'Read':\n temp = this.AllNotifications.filter(n => !n.Unread);\n break;\n }\n\n // Apply type filter if selected\n if (this.selectedTypeFilter) {\n temp = temp.filter(n => UUIDsEqual(n.NotificationTypeID, this.selectedTypeFilter));\n }\n\n // Apply text filter if it is not empty\n if (this.currentFilter.trim().length > 0) {\n // check for inclusion of filter value in title or message\n temp = temp.filter(n => n.Title?.toLowerCase().includes(this.currentFilter.trim().toLowerCase()) ||\n n.Message?.toLowerCase().includes(this.currentFilter.trim().toLowerCase())\n );\n }\n\n return temp;\n }\n\n public isNotificationClickable(notification: MJUserNotificationEntity): boolean {\n // Check for agent-request type (navigated via NavigationService, not URL)\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'agent-request' && config.requestId) {\n return true;\n }\n }\n\n const info = this.notificationUrl(notification);\n return (info !== null && info.urlParts && info.urlParts.length > 0);\n }\n\n public notificationUrl(notification: MJUserNotificationEntity): NotificationUrlInfo {\n const url: string[] = [];\n let queryString = '';\n if (notification.ResourceRecordID && notification.ResourceRecordID.length > 0 &&\n notification.ResourceTypeID && notification.ResourceTypeID.length > 0) {\n // we have a resource here, like a Report, Dashboard, etc\n // we can generate a url to navigate to it\n const rt = this.sharedService.ResourceTypeByID(notification.ResourceTypeID);\n let routeSegment: string | null | undefined;\n if (rt)\n routeSegment = this.sharedService.mapResourceTypeNameToRouteSegment(rt.Name);\n\n if (rt && routeSegment && routeSegment.trim().length > 0) {\n url.push('resource');\n url.push(routeSegment);\n url.push(notification.ResourceRecordID.toString());\n if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n if (rt.Name.trim().toLowerCase() === 'records') {\n // special handling for records\n const config = SafeJSONParse<RecordResourceConfig>(notification.ResourceConfiguration);\n if (config && config.Entity)\n queryString = `Entity=${config.Entity}`;\n }\n else\n queryString = notification.ResourceConfiguration;\n }\n }\n }\n else if (notification.ResourceConfiguration && notification.ResourceConfiguration.trim().length > 0) {\n // we do NOT have a resource type or resource record id, but we do have a ResourceConfiguration\n // string, which means we might have information on how to navigate to what we want if we parse the config\n // HOME screen stuff is done this way\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (config && config.type?.trim().toLowerCase() === 'conversation') {\n url.push('chat');\n // Build query string with conversation and artifact navigation\n const queryParams: string[] = [];\n if (config.conversationId) queryParams.push(`conversationId=${config.conversationId}`);\n if (config.messageId) queryParams.push(`messageId=${config.messageId}`);\n if (config.artifactId) queryParams.push(`artifactId=${config.artifactId}`);\n if (config.versionNumber) queryParams.push(`versionNumber=${config.versionNumber}`);\n if (config.taskId) queryParams.push(`taskId=${config.taskId}`);\n queryString = queryParams.join('&');\n }\n }\n\n return { urlParts: url, queryString };\n }\n\n public get AllNotifications(): MJUserNotificationEntity[] {\n return SharedService.UserNotifications;\n }\n\n public get UnreadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => n.Unread);\n }\n\n public get ReadNotifications(): MJUserNotificationEntity[] {\n return this.AllNotifications.filter(n => !n.Unread);\n }\n\n selectReadOption(option: ReadFilterOption): void {\n this.radioSelected = option;\n // now update the radio button group in the UI\n switch (option) {\n case 'All':\n this.allRadio.nativeElement.checked = true;\n break;\n case 'Unread':\n this.unreadRadio.nativeElement.checked = true;\n break;\n case 'Read':\n this.readRadio.nativeElement.checked = true;\n break;\n }\n }\n\n onReadRadioChanged(event: Event): void {\n if (event.target instanceof HTMLInputElement) {\n this.radioSelected = event.target.value as ReadFilterOption;\n }\n }\n\n onFilterChanged(value: string): void {\n this.currentFilter = value;\n }\n\n getItemTitleClass(notification: MJUserNotificationEntity): string {\n if (notification.Unread) {\n return 'notification-title notification-title-unread';\n }\n return 'notification-title';\n }\n\n getItemWrapperClass(notification: MJUserNotificationEntity): string {\n let classInfo = 'notification-wrap';\n\n if (this.isNotificationClickable(notification))\n classInfo += ' notification-wrap-clickable';\n\n if (notification.Unread)\n classInfo += ' notification-wrap-unread';\n\n return classInfo;\n }\n\n async markAsRead(notification: MJUserNotificationEntity, bRead: boolean, transGroup: TransactionGroupBase | null): Promise<boolean> {\n if (notification) {\n const notificationId = notification.ID;\n notification.Unread = !bRead;\n let notificationEntity: MJUserNotificationEntity;\n if (notification instanceof MJUserNotificationEntity) {\n // the passed in param truly is a MJUserNotificationEntity or subclass, so just use it, saves a DB round trip\n notificationEntity = notification;\n }\n else {\n // the passed in param is just a plain object, so we need to load the entity\n const md = new Metadata();\n notificationEntity = await md.GetEntityObject<MJUserNotificationEntity>('MJ: User Notifications');\n await notificationEntity.Load(notificationId); \n notificationEntity.Unread = !bRead; \n }\n\n // part of a transaction group, if so, add it as that will defer the actual network traffic/save\n if (transGroup) {\n notificationEntity.TransactionGroup = transGroup;\n await notificationEntity.Save()\n return true;\n }\n else {\n // Save the notification (not part of transaction group)\n await notificationEntity.Save();\n // Update the observables so badge count refreshes immediately\n MJNotificationService.UpdateNotificationObservables();\n return true;\n }\n }\n else {\n return false;\n }\n }\n\n public async markAllAsRead() {\n await this.markAll(true);\n\n // test harness for creating Conversations and Conversation Details record in a single transaction using variables\n await this.TestTransactionGroupVariables();\n }\n\n public async TestTransactionGroupVariables() {\n const md = new Metadata();\n const transGroup = await md.CreateTransactionGroup();\n\n const conversation = await md.GetEntityObject<MJConversationEntity>('MJ: Conversations');\n conversation.UserID = md.CurrentUser.ID;\n conversation.Description = 'Test Conversation';\n conversation.TransactionGroup = transGroup;\n if (!await conversation.Save()) {\n this.sharedService.CreateSimpleNotification('Unable to create conversation', 'error', 5000);\n }\n\n const tvDefine = new TransactionVariable('NewConvoID', conversation, 'ID', 'Define')\n transGroup.AddVariable(tvDefine);\n\n const conversationDetail = await md.GetEntityObject<MJConversationDetailEntity>('MJ: Conversation Details');\n conversationDetail.Message = 'Test Message';\n conversationDetail.Role = 'User';\n conversationDetail.ConversationID = 'x'; // fake UUID must be non-null to pass validation, this will be replaced by the variable, since we're part of a TG, not a real save, so doesn't validate it as a true fkey\n conversationDetail.TransactionGroup = transGroup;\n if (!await conversationDetail.Save()) {\n this.sharedService.CreateSimpleNotification('Unable to create conversation detail', 'error', 500);\n } \n const tvUse = new TransactionVariable('NewConvoID', conversationDetail, 'ConversationID', 'Use')\n transGroup.AddVariable(tvUse);\n\n if (await transGroup.Submit()) {\n this.sharedService.CreateSimpleNotification('Transaction Group with Variables worked', 'success', 5000);\n }\n else {\n this.sharedService.CreateSimpleNotification('Transaction Group with Variables failed', 'error', 5000);\n }\n }\n\n public async markAllAsUnread() {\n await this.markAll(false);\n }\n\n public async markAll(bRead: boolean) {\n // Use transaction group for batching - all saves are queued and sent in one round-trip\n const md = new Metadata();\n const transGroup = await md.CreateTransactionGroup();\n\n // Queue all saves - no need to await individual saves since transaction group queues them\n for (const notification of this.AllNotifications) {\n if (notification.Unread && bRead || !notification.Unread && !bRead) {\n // Don't await - Save() with transaction group queues the operation immediately\n this.markAsRead(notification, bRead, transGroup);\n }\n }\n\n // Submit transaction group - this is where the actual network call happens\n if (!await transGroup.Submit())\n this.sharedService.CreateSimpleNotification('Unable to mark all notifications as read', 'error', 5000);\n else\n SharedService.RefreshUserNotifications();\n }\n \n notificationClicked(notification: MJUserNotificationEntity): void {\n if (this.isNotificationClickable(notification)) {\n // also mark this as read when we click it\n this.markAsRead(notification, true, null);\n\n // Check for special navigation types that use NavigationService (not router)\n if (this.navigateToAgentRequest(notification)) {\n return;\n }\n if (this.navigateToConversation(notification)) {\n return;\n }\n\n const info = this.notificationUrl(notification);\n if (info.queryString && info.queryString.trim().length > 0) {\n const fullUrl = `${info.urlParts.join('/')}${info.queryString ? '?' + info.queryString : ''}`;\n this.router.navigateByUrl(fullUrl);\n }\n else {\n this.router.navigate(info.urlParts);\n }\n }\n }\n\n /**\n * Handle navigation to an agent request via NavigationService.\n * Returns true if the notification was an agent-request type and navigation was attempted.\n */\n private navigateToAgentRequest(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<AgentRequestResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'agent-request' || !config.requestId) {\n return false;\n }\n\n // Try the AI app first (has dedicated Agent Requests nav item)\n const aiApp = this.appManager.GetAppByName('AI');\n if (aiApp) {\n this.navigationService.OpenNavItemByName(\n 'Agent Requests',\n { requestId: config.requestId },\n aiApp.ID\n );\n return true;\n }\n\n // Fallback: navigate to Chat app's Conversations with the request context\n const chatApp = this.appManager.GetAppByName('Chat');\n if (chatApp) {\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n { requestId: config.requestId },\n chatApp.ID\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Handle navigation to a conversation via NavigationService.\n * Returns true if the notification was a conversation type and navigation was attempted.\n */\n private navigateToConversation(notification: MJUserNotificationEntity): boolean {\n if (!notification.ResourceConfiguration || notification.ResourceConfiguration.trim().length === 0) {\n return false;\n }\n\n const config = SafeJSONParse<ConversationResourceConfig>(notification.ResourceConfiguration);\n if (!config || config.type?.trim().toLowerCase() !== 'conversation') {\n return false;\n }\n\n const chatApp = this.appManager.GetAppByName('Chat');\n if (!chatApp) {\n return false;\n }\n\n const navConfig: Record<string, string> = {};\n if (config.conversationId) navConfig['conversationId'] = config.conversationId;\n if (config.messageId) navConfig['messageId'] = config.messageId;\n if (config.artifactId) navConfig['artifactId'] = config.artifactId;\n if (config.versionNumber) navConfig['versionNumber'] = config.versionNumber;\n if (config.taskId) navConfig['taskId'] = config.taskId;\n\n this.navigationService.OpenNavItemByName(\n 'Conversations',\n navConfig,\n chatApp.ID\n );\n return true;\n }\n\n public getNotificationType(typeId: string | null): MJUserNotificationTypeEntity | null {\n if (!typeId) return null;\n return this.notificationTypes.find(t => UUIDsEqual(t.ID, typeId)) || null;\n }\n\n public getTypeIcon(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Icon || 'fa-bell';\n }\n\n public getTypeColor(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type?.Color || '#999';\n }\n\n public getTypeName(notification: MJUserNotificationEntity): string {\n const type = this.getNotificationType(notification.NotificationTypeID);\n return type ? type.Name : 'Notification';\n }\n\n public onTypeFilterChange(typeId: string | null): void {\n this.selectedTypeFilter = typeId;\n }\n}\n","<div class=\"notifications-container\">\n <!-- Header Section -->\n <div class=\"notifications-header\">\n <div class=\"header-top\">\n <div class=\"header-title\">\n <div class=\"title-icon\">\n <i class=\"fa-solid fa-bell\"></i>\n </div>\n <h1>Notifications</h1>\n </div>\n\n @if (AllNotifications.length > 0) {\n <div class=\"header-actions\">\n @if (UnreadNotifications.length > 0) {\n <button class=\"action-btn action-btn-ghost\"\n type=\"button\"\n (click)=\"markAllAsRead()\"\n aria-label=\"Mark all notifications as read\">\n <i class=\"fa-solid fa-check-double\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Read</span>\n </button>\n }\n @if (ReadNotifications.length > 0) {\n <button class=\"action-btn action-btn-secondary\"\n type=\"button\"\n (click)=\"markAllAsUnread()\"\n aria-label=\"Mark all notifications as unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Mark All Unread</span>\n </button>\n }\n </div>\n }\n </div>\n\n <!-- Filters Section -->\n @if (AllNotifications.length > 0) {\n <div class=\"filters-section\">\n <!-- Horizontal Slider for Filters (Mobile) -->\n <div class=\"filters-slider\">\n <div class=\"slider-content\">\n <!-- Stats Pills (Filter Tabs) -->\n <div class=\"header-stats\" role=\"group\" aria-label=\"Filter notifications by read status\">\n <input #allRadio type=\"radio\" name=\"UnreadStatus\" value=\"All\"\n (change)=\"onReadRadioChanged($event)\" checked class=\"hidden-radio\"\n id=\"filter-all\" />\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'All'\"\n (click)=\"selectReadOption('All')\"\n [attr.aria-pressed]=\"radioSelected === 'All'\"\n aria-label=\"Show all notifications\">\n <span class=\"stat-label\">All</span>\n <span class=\"stat-count\">{{AllNotifications.length}}</span>\n </button>\n\n <input #unreadRadio type=\"radio\" name=\"UnreadStatus\" value=\"Unread\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-unread\" />\n @if (UnreadNotifications.length > 0 || ReadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Unread'\"\n [class.has-unread]=\"UnreadNotifications.length > 0\"\n (click)=\"selectReadOption('Unread')\"\n [attr.aria-pressed]=\"radioSelected === 'Unread'\"\n aria-label=\"Show unread notifications\">\n <span class=\"stat-label\">Unread</span>\n <span class=\"stat-count\" [class.unread-count]=\"UnreadNotifications.length > 0\">\n {{UnreadNotifications.length}}\n </span>\n </button>\n }\n\n <input #readRadio type=\"radio\" name=\"UnreadStatus\" value=\"Read\"\n (change)=\"onReadRadioChanged($event)\" class=\"hidden-radio\"\n id=\"filter-read\" />\n @if (ReadNotifications.length > 0 || UnreadNotifications.length === 0) {\n <button class=\"stat-pill\"\n type=\"button\"\n [class.active]=\"radioSelected === 'Read'\"\n (click)=\"selectReadOption('Read')\"\n [attr.aria-pressed]=\"radioSelected === 'Read'\"\n aria-label=\"Show read notifications\">\n <span class=\"stat-label\">Read</span>\n <span class=\"stat-count\">{{ReadNotifications.length}}</span>\n </button>\n }\n </div>\n\n <!-- Native Type Filter Dropdown (in slider on mobile) -->\n @if (notificationTypes.length > 0) {\n <div class=\"filter-item type-filter-slider\">\n <select class=\"type-select\"\n [(ngModel)]=\"selectedTypeFilter\"\n (change)=\"onTypeFilterChange(selectedTypeFilter)\"\n aria-label=\"Filter by notification type\">\n <option [value]=\"null\">All Types</option>\n @for (type of notificationTypes; track type.ID) {\n <option [value]=\"type.ID\">{{type.Name}}</option>\n }\n </select>\n </div>\n }\n </div>\n </div>\n\n <!-- Search Filter (separate, full-width on mobile) -->\n <div class=\"search-section\">\n <div class=\"search-container\">\n <i class=\"fa-solid fa-magnifying-glass search-icon\" aria-hidden=\"true\"></i>\n <input type=\"text\"\n class=\"search-input\"\n placeholder=\"Search notifications...\"\n [value]=\"currentFilter\"\n (input)=\"onFilterChanged($any($event.target).value)\"\n aria-label=\"Search notifications\" />\n </div>\n </div>\n\n <!-- Filter Info Badge -->\n @if (NotificationsToShow.length !== AllNotifications.length) {\n <div class=\"filter-info\">\n <span class=\"filter-badge\">\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n Showing {{NotificationsToShow.length}} of {{AllNotifications.length}}\n </span>\n </div>\n }\n </div>\n }\n </div>\n\n <!-- Notifications Content -->\n <div class=\"notifications-content\">\n @if (NotificationsToShow.length === 0 && AllNotifications.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-bell-slash\"></i>\n </div>\n <h3>No Notifications</h3>\n <p>You're all caught up! New notifications will appear here.</p>\n </div>\n } @else if (NotificationsToShow.length === 0) {\n <div class=\"empty-state\">\n <div class=\"empty-icon\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n </div>\n <h3>No Matching Notifications</h3>\n <p>Try adjusting your filters to see more notifications.</p>\n </div>\n } @else {\n <!-- Notifications List -->\n <div class=\"notifications-list\">\n @for (notification of NotificationsToShow; track notification.ID) {\n <article class=\"notification-card\"\n [class.unread]=\"notification.Unread\"\n [class.clickable]=\"isNotificationClickable(notification)\"\n role=\"article\"\n [attr.aria-label]=\"notification.Title\">\n\n <!-- Unread Indicator Bar -->\n <div class=\"card-indicator\" aria-hidden=\"true\"></div>\n\n <!-- Type Icon -->\n <div class=\"card-icon\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n aria-hidden=\"true\">\n <i [class]=\"'fa-solid ' + getTypeIcon(notification)\"\n [style.color]=\"getTypeColor(notification)\"></i>\n </div>\n\n <!-- Content -->\n <div class=\"card-content\" (click)=\"notificationClicked(notification)\">\n <div class=\"card-header\">\n <h3 class=\"card-title\" [class.card-title-unread]=\"notification.Unread\">\n {{notification.Title}}\n </h3>\n <span class=\"card-time\">\n <i class=\"fa-regular fa-clock\" aria-hidden=\"true\"></i>\n <time [attr.datetime]=\"notification.__mj_CreatedAt\">\n {{notification.__mj_CreatedAt | date:'MMM d, h:mm a'}}\n </time>\n </span>\n </div>\n\n <div class=\"card-meta\">\n <span class=\"card-type\"\n [style.background-color]=\"getTypeColor(notification) + '15'\"\n [style.color]=\"getTypeColor(notification)\">\n {{getTypeName(notification)}}\n </span>\n </div>\n\n <p class=\"card-message\">{{notification.Message}}</p>\n </div>\n\n <!-- Actions -->\n <div class=\"card-actions\">\n @if (notification.Unread) {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, true, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as read'\"\n title=\"Mark as Read\">\n <i class=\"fa-solid fa-check\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Read</span>\n </button>\n } @else {\n <button class=\"card-action-btn\"\n type=\"button\"\n (click)=\"markAsRead(notification, false, null)\"\n [attr.aria-label]=\"'Mark ' + notification.Title + ' as unread'\"\n title=\"Mark as Unread\">\n <i class=\"fa-solid fa-envelope\" aria-hidden=\"true\"></i>\n <span class=\"action-text\">Unread</span>\n </button>\n }\n </div>\n </article>\n }\n </div>\n }\n </div>\n</div>\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-explorer-core",
3
- "version": "5.15.0",
3
+ "version": "5.16.0",
4
4
  "description": "MemberJunction Explorer: Core Angular Components",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -30,39 +30,39 @@
30
30
  "@angular/cdk": "21.1.3",
31
31
  "@angular/platform-browser": "21.1.3",
32
32
  "@auth0/auth0-angular": "^2.6.0",
33
- "@memberjunction/ai-core-plus": "5.15.0",
34
- "@memberjunction/ai-engine-base": "5.15.0",
35
- "@memberjunction/communication-types": "5.15.0",
36
- "@memberjunction/core": "5.15.0",
37
- "@memberjunction/core-entities": "5.15.0",
38
- "@memberjunction/entity-communications-client": "5.15.0",
39
- "@memberjunction/global": "5.15.0",
40
- "@memberjunction/graphql-dataprovider": "5.15.0",
41
- "@memberjunction/ng-ai-test-harness": "5.15.0",
42
- "@memberjunction/ng-artifacts": "5.15.0",
43
- "@memberjunction/ng-auth-services": "5.15.0",
44
- "@memberjunction/ng-base-application": "5.15.0",
45
- "@memberjunction/ng-base-forms": "5.15.0",
46
- "@memberjunction/ng-container-directives": "5.15.0",
47
- "@memberjunction/ng-conversations": "5.15.0",
48
- "@memberjunction/ng-dashboards": "5.15.0",
49
- "@memberjunction/ng-entity-form-dialog": "5.15.0",
50
- "@memberjunction/ng-entity-permissions": "5.15.0",
51
- "@memberjunction/ng-dashboard-viewer": "5.15.0",
52
- "@memberjunction/ng-entity-viewer": "5.15.0",
53
- "@memberjunction/ng-list-detail-grid": "5.15.0",
54
- "@memberjunction/ng-explorer-settings": "5.15.0",
55
- "@memberjunction/ng-file-storage": "5.15.0",
56
- "@memberjunction/ng-generic-dialog": "5.15.0",
57
- "@memberjunction/ng-notifications": "5.15.0",
58
- "@memberjunction/ng-query-viewer": "5.15.0",
59
- "@memberjunction/ng-record-changes": "5.15.0",
60
- "@memberjunction/ng-record-selector": "5.15.0",
61
- "@memberjunction/ng-resource-permissions": "5.15.0",
62
- "@memberjunction/ng-shared": "5.15.0",
63
- "@memberjunction/ng-shared-generic": "5.15.0",
64
- "@memberjunction/ng-user-avatar": "5.15.0",
65
- "@memberjunction/templates-base-types": "5.15.0",
33
+ "@memberjunction/ai-core-plus": "5.16.0",
34
+ "@memberjunction/ai-engine-base": "5.16.0",
35
+ "@memberjunction/communication-types": "5.16.0",
36
+ "@memberjunction/core": "5.16.0",
37
+ "@memberjunction/core-entities": "5.16.0",
38
+ "@memberjunction/entity-communications-client": "5.16.0",
39
+ "@memberjunction/global": "5.16.0",
40
+ "@memberjunction/graphql-dataprovider": "5.16.0",
41
+ "@memberjunction/ng-ai-test-harness": "5.16.0",
42
+ "@memberjunction/ng-artifacts": "5.16.0",
43
+ "@memberjunction/ng-auth-services": "5.16.0",
44
+ "@memberjunction/ng-base-application": "5.16.0",
45
+ "@memberjunction/ng-base-forms": "5.16.0",
46
+ "@memberjunction/ng-container-directives": "5.16.0",
47
+ "@memberjunction/ng-conversations": "5.16.0",
48
+ "@memberjunction/ng-dashboards": "5.16.0",
49
+ "@memberjunction/ng-entity-form-dialog": "5.16.0",
50
+ "@memberjunction/ng-entity-permissions": "5.16.0",
51
+ "@memberjunction/ng-dashboard-viewer": "5.16.0",
52
+ "@memberjunction/ng-entity-viewer": "5.16.0",
53
+ "@memberjunction/ng-list-detail-grid": "5.16.0",
54
+ "@memberjunction/ng-explorer-settings": "5.16.0",
55
+ "@memberjunction/ng-file-storage": "5.16.0",
56
+ "@memberjunction/ng-generic-dialog": "5.16.0",
57
+ "@memberjunction/ng-notifications": "5.16.0",
58
+ "@memberjunction/ng-query-viewer": "5.16.0",
59
+ "@memberjunction/ng-record-changes": "5.16.0",
60
+ "@memberjunction/ng-record-selector": "5.16.0",
61
+ "@memberjunction/ng-resource-permissions": "5.16.0",
62
+ "@memberjunction/ng-shared": "5.16.0",
63
+ "@memberjunction/ng-shared-generic": "5.16.0",
64
+ "@memberjunction/ng-user-avatar": "5.16.0",
65
+ "@memberjunction/templates-base-types": "5.16.0",
66
66
  "@progress/kendo-angular-buttons": "22.0.1",
67
67
  "@progress/kendo-angular-dateinputs": "22.0.1",
68
68
  "@progress/kendo-angular-dialog": "22.0.1",