@memberjunction/ng-explorer-core 6.2.0-edge.0 → 6.2.0-edge.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app-routing.module.d.ts +23 -1
- package/dist/app-routing.module.d.ts.map +1 -1
- package/dist/app-routing.module.js +50 -14
- package/dist/app-routing.module.js.map +1 -1
- package/dist/generated/lazy-feature-config.d.ts +1 -1
- package/dist/generated/lazy-feature-config.d.ts.map +1 -1
- package/dist/generated/lazy-feature-config.js +12 -1
- package/dist/generated/lazy-feature-config.js.map +1 -1
- package/dist/lib/command-palette/command-palette.component.d.ts +7 -1
- package/dist/lib/command-palette/command-palette.component.d.ts.map +1 -1
- package/dist/lib/command-palette/command-palette.component.js +28 -14
- package/dist/lib/command-palette/command-palette.component.js.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts +103 -13
- package/dist/lib/conversation-feedback/conversation-feedback.d.ts.map +1 -1
- package/dist/lib/conversation-feedback/conversation-feedback.js +219 -67
- package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +64 -10
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +172 -66
- package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
- package/dist/lib/generic/resource-container-component.d.ts +19 -5
- package/dist/lib/generic/resource-container-component.d.ts.map +1 -1
- package/dist/lib/generic/resource-container-component.js +43 -13
- package/dist/lib/generic/resource-container-component.js.map +1 -1
- package/dist/lib/guards/entities.guard.d.ts +4 -0
- package/dist/lib/guards/entities.guard.d.ts.map +1 -1
- package/dist/lib/guards/entities.guard.js +10 -2
- package/dist/lib/guards/entities.guard.js.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.d.ts +4 -0
- package/dist/lib/identity-claims/claim-redeem.component.d.ts.map +1 -1
- package/dist/lib/identity-claims/claim-redeem.component.js +10 -2
- package/dist/lib/identity-claims/claim-redeem.component.js.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.d.ts +4 -0
- package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
- package/dist/lib/oauth/oauth-callback.component.js +10 -2
- package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
- package/dist/lib/profile/profile-dialog.component.d.ts.map +1 -1
- package/dist/lib/profile/profile-dialog.component.js +194 -191
- package/dist/lib/profile/profile-dialog.component.js.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts +20 -2
- package/dist/lib/resource-wrappers/artifact-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/artifact-resource.component.js +33 -9
- package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts +80 -10
- package/dist/lib/resource-wrappers/chat-collections-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js +168 -56
- package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +199 -25
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +534 -182
- package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts +2 -0
- package/dist/lib/resource-wrappers/chat-deeplink-params.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js +5 -1
- package/dist/lib/resource-wrappers/chat-deeplink-params.js.map +1 -1
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts +25 -0
- package/dist/lib/resource-wrappers/chat-search-routing.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js +24 -0
- package/dist/lib/resource-wrappers/chat-search-routing.js.map +1 -0
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts +14 -2
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +32 -8
- package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts +46 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.d.ts.map +1 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js +62 -0
- package/dist/lib/resource-wrappers/compose-email-fallback.js.map +1 -0
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts +54 -8
- package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/dashboard-resource.component.js +138 -46
- package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts +223 -30
- package/dist/lib/resource-wrappers/livekit-room-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js +438 -118
- package/dist/lib/resource-wrappers/livekit-room-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts +7 -3
- package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/search-results-resource.component.js +23 -15
- package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.d.ts +74 -11
- package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
- package/dist/lib/resource-wrappers/view-resource.component.js +214 -68
- package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
- package/dist/lib/services/server-connectivity.service.d.ts +9 -4
- package/dist/lib/services/server-connectivity.service.d.ts.map +1 -1
- package/dist/lib/services/server-connectivity.service.js +56 -12
- package/dist/lib/services/server-connectivity.service.js.map +1 -1
- package/dist/lib/services/startup-validation.service.d.ts +4 -0
- package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
- package/dist/lib/services/startup-validation.service.js +10 -2
- package/dist/lib/services/startup-validation.service.js.map +1 -1
- package/dist/lib/services/system-validation.service.d.ts +13 -1
- package/dist/lib/services/system-validation.service.d.ts.map +1 -1
- package/dist/lib/services/system-validation.service.js +29 -5
- package/dist/lib/services/system-validation.service.js.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts +54 -4
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.d.ts.map +1 -1
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js +130 -40
- package/dist/lib/shell/components/dialogs/app-access-dialog.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts +29 -1
- package/dist/lib/shell/components/header/app-nav.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-nav.component.js +56 -12
- package/dist/lib/shell/components/header/app-nav.component.js.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.d.ts +33 -5
- package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -1
- package/dist/lib/shell/components/header/app-switcher.component.js +85 -29
- package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js +1 -1
- package/dist/lib/shell/components/record-open/record-origin-crumb.component.js.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +50 -6
- package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/component-cache-manager.js +95 -22
- package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts +91 -9
- package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
- package/dist/lib/shell/components/tabs/tab-container.component.js +257 -101
- package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
- package/dist/lib/shell/loading-themes.d.ts +16 -12
- package/dist/lib/shell/loading-themes.d.ts.map +1 -1
- package/dist/lib/shell/loading-themes.js +145 -137
- package/dist/lib/shell/loading-themes.js.map +1 -1
- package/dist/lib/shell/readiness-beacon.d.ts +2 -0
- package/dist/lib/shell/readiness-beacon.d.ts.map +1 -1
- package/dist/lib/shell/readiness-beacon.js +5 -1
- package/dist/lib/shell/readiness-beacon.js.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/about-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/about-dialog.service.js +16 -4
- package/dist/lib/shell/services/about-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/profile-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/profile-dialog.service.js +16 -4
- package/dist/lib/shell/services/profile-dialog.service.js.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts +6 -0
- package/dist/lib/shell/services/user-sharing-center-dialog.service.d.ts.map +1 -1
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js +15 -3
- package/dist/lib/shell/services/user-sharing-center-dialog.service.js.map +1 -1
- package/dist/lib/shell/shell.component.d.ts +264 -39
- package/dist/lib/shell/shell.component.d.ts.map +1 -1
- package/dist/lib/shell/shell.component.js +697 -294
- package/dist/lib/shell/shell.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +64 -8
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +129 -37
- package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts +26 -2
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js +48 -10
- package/dist/lib/single-dashboard/Components/delete-item/delete-item.component.js.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts +84 -6
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js +133 -29
- package/dist/lib/single-dashboard/Components/edit-dashboard/edit-dashboard.component.js.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts +173 -23
- package/dist/lib/single-dashboard/single-dashboard.component.d.ts.map +1 -1
- package/dist/lib/single-dashboard/single-dashboard.component.js +383 -109
- package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts +383 -55
- package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
- package/dist/lib/single-list-detail/single-list-detail.component.js +962 -326
- package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
- package/dist/lib/single-query/single-query.component.d.ts +22 -2
- package/dist/lib/single-query/single-query.component.d.ts.map +1 -1
- package/dist/lib/single-query/single-query.component.js +40 -10
- package/dist/lib/single-query/single-query.component.js.map +1 -1
- package/dist/lib/single-record/single-record.component.d.ts +41 -3
- package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
- package/dist/lib/single-record/single-record.component.js +71 -11
- package/dist/lib/single-record/single-record.component.js.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.d.ts +23 -3
- package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
- package/dist/lib/single-search-result/single-search-result.component.js +42 -12
- package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.d.ts +12 -2
- package/dist/lib/system-validation/system-validation-banner.component.d.ts.map +1 -1
- package/dist/lib/system-validation/system-validation-banner.component.js +25 -5
- package/dist/lib/system-validation/system-validation-banner.component.js.map +1 -1
- package/dist/lib/user-menu/user-menu.types.d.ts +4 -0
- package/dist/lib/user-menu/user-menu.types.d.ts.map +1 -1
- package/dist/lib/user-menu/user-menu.types.js +10 -2
- package/dist/lib/user-menu/user-menu.types.js.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.d.ts +59 -7
- package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
- package/dist/lib/user-notifications/user-notifications.component.js +151 -47
- package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
- package/dist/lib/user-profile/user-profile.component.d.ts +3 -2
- package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
- package/dist/lib/user-profile/user-profile.component.js +5 -4
- package/dist/lib/user-profile/user-profile.component.js.map +1 -1
- package/package.json +52 -52
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-access-dialog.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.ts","../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, HostListener } from '@angular/core';\n\n/**\n * Type of app access issue\n */\nexport type AppAccessDialogType =\n | 'not_installed' // User can install the app\n | 'disabled' // User has disabled the app, can re-enable\n | 'no_access' // User doesn't have permission\n | 'not_found' // App doesn't exist\n | 'inactive' // App is inactive/disabled by admin\n | 'no_apps' // User has no apps configured at all\n | 'layout_error'; // Golden Layout failed to initialize\n\n/**\n * Configuration for the app access dialog\n */\nexport interface AppAccessDialogConfig {\n type: AppAccessDialogType;\n appName?: string;\n appId?: string;\n}\n\n/**\n * Result from the dialog\n */\nexport interface AppAccessDialogResult {\n action: 'install' | 'enable' | 'redirect' | 'dismissed';\n appId?: string;\n}\n\n/**\n * Dialog component for handling app access errors.\n * Shows appropriate messages and actions based on the type of access issue.\n * Features auto-dismiss with countdown timer for certain dialog types.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-access-dialog',\n templateUrl: './app-access-dialog.component.html',\n styleUrls: ['./app-access-dialog.component.css']\n})\nexport class AppAccessDialogComponent implements OnDestroy {\n @Input() visible = false;\n @Output() visibleChange = new EventEmitter<boolean>();\n @Output() result = new EventEmitter<AppAccessDialogResult>();\n\n config: AppAccessDialogConfig | null = null;\n isProcessing = false;\n\n // Auto-dismiss countdown\n private countdownInterval: ReturnType<typeof setInterval> | null = null;\n countdownSeconds = 0;\n private readonly AUTO_DISMISS_SECONDS = 5;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n /**\n * Show the dialog with the specified configuration\n */\n show(config: AppAccessDialogConfig): void {\n this.config = config;\n this.visible = true;\n this.isProcessing = false;\n this.visibleChange.emit(true);\n\n // Start countdown for types that auto-dismiss\n if (this.shouldAutoDismiss()) {\n this.startCountdown();\n }\n\n this.cdr.detectChanges();\n }\n\n /**\n * Hide the dialog\n */\n hide(): void {\n this.stopCountdown();\n this.visible = false;\n this.visibleChange.emit(false);\n this.cdr.detectChanges();\n }\n\n ngOnDestroy(): void {\n this.stopCountdown();\n }\n\n /**\n * Get the dialog title based on type\n */\n get title(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n return 'Add Application?';\n case 'disabled':\n return 'Add Application?';\n case 'no_access':\n return 'Access Denied';\n case 'not_found':\n return 'Application Not Found';\n case 'inactive':\n return 'Application Unavailable';\n case 'no_apps':\n return 'No Applications Available';\n case 'layout_error':\n return 'Display Error';\n default:\n return 'Application Error';\n }\n }\n\n /**\n * Get the dialog icon based on type\n */\n get icon(): string {\n if (!this.config) return 'fa-circle-info';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return 'fa-circle-question';\n case 'no_access':\n return 'fa-lock';\n case 'not_found':\n return 'fa-circle-xmark';\n case 'inactive':\n return 'fa-circle-pause';\n case 'no_apps':\n return 'fa-folder-open';\n case 'layout_error':\n return 'fa-triangle-exclamation';\n default:\n return 'fa-circle-info';\n }\n }\n\n /**\n * Get the dialog icon color based on type\n */\n get iconColor(): string {\n if (!this.config) return 'var(--mj-text-secondary)';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return '#2196F3'; // Blue for actionable\n case 'no_access':\n case 'inactive':\n return '#FF9800'; // Orange for warning\n case 'not_found':\n case 'layout_error':\n return '#F44336'; // Red for error\n case 'no_apps':\n return '#9E9E9E'; // Gray for info\n default:\n return 'var(--mj-text-secondary)';\n }\n }\n\n /**\n * Get the main message based on type\n */\n get message(): string {\n if (!this.config) return '';\n\n const appName = this.config.appName || 'this application';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return `Would you like to add \"${appName}\" to your applications?`;\n case 'no_access':\n return `You don't have permission to access \"${appName}\".`;\n case 'not_found':\n return `The application \"${appName}\" doesn't exist in this system.`;\n case 'inactive':\n return `The application \"${appName}\" is currently inactive and unavailable.`;\n case 'no_apps':\n return `You don't have any applications configured. Your system administrator needs to set up your application access.`;\n case 'layout_error':\n return `There was an error displaying the application interface. The system will redirect you to an available application.`;\n default:\n return 'An error occurred while loading the application.';\n }\n }\n\n /**\n * Get the secondary/help message based on type\n */\n get helpMessage(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return '';\n case 'no_access':\n case 'not_found':\n case 'inactive':\n return 'If you believe this is an error, please contact your system administrator.';\n case 'no_apps':\n return 'Please contact your system administrator to configure your application access.';\n case 'layout_error':\n return 'If this error persists, try clearing your browser cache or contact your system administrator.';\n default:\n return '';\n }\n }\n\n /**\n * Check if the primary action button should be shown\n */\n get showPrimaryAction(): boolean {\n if (!this.config) return false;\n return this.config.type === 'not_installed' || this.config.type === 'disabled';\n }\n\n /**\n * Get the primary action button text\n */\n get primaryActionText(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return 'Add';\n default:\n return 'OK';\n }\n }\n\n /**\n * Get the secondary/dismiss button text with countdown if applicable\n * For actionable dialogs (install/enable), show \"Cancel\"\n * For non-actionable dialogs (errors), show \"OK\" with countdown\n */\n get dismissButtonText(): string {\n // For actionable dialogs, use \"Cancel\"\n if (this.showPrimaryAction) {\n return 'Cancel';\n }\n\n // For non-actionable dialogs, show countdown if active\n if (this.countdownSeconds > 0) {\n return `OK (${this.countdownSeconds})`;\n }\n return 'OK';\n }\n\n /**\n * Check if this dialog type should auto-dismiss\n */\n private shouldAutoDismiss(): boolean {\n if (!this.config) return false;\n return ['no_access', 'not_found', 'inactive', 'layout_error'].includes(this.config.type);\n }\n\n /**\n * Start the countdown timer for auto-dismiss\n */\n private startCountdown(): void {\n this.stopCountdown();\n this.countdownSeconds = this.AUTO_DISMISS_SECONDS;\n\n this.countdownInterval = setInterval(() => {\n this.countdownSeconds--;\n this.cdr.detectChanges();\n\n if (this.countdownSeconds <= 0) {\n this.onDismiss();\n }\n }, 1000);\n }\n\n /**\n * Stop the countdown timer\n */\n private stopCountdown(): void {\n if (this.countdownInterval) {\n clearInterval(this.countdownInterval);\n this.countdownInterval = null;\n }\n this.countdownSeconds = 0;\n }\n\n /**\n * Handle primary action (install/enable)\n */\n async onPrimaryAction(): Promise<void> {\n if (!this.config) return;\n\n this.isProcessing = true;\n this.cdr.detectChanges();\n\n const action = this.config.type === 'not_installed' ? 'install' : 'enable';\n\n this.result.emit({\n action,\n appId: this.config.appId\n });\n\n // Don't hide yet - let the parent component handle the result and close when ready\n }\n\n /**\n * Handle dismiss/redirect action\n */\n onDismiss(): void {\n this.stopCountdown();\n this.result.emit({ action: 'redirect' });\n this.hide();\n }\n\n /**\n * Mark processing as complete (called by parent after install/enable)\n */\n completeProcessing(): void {\n this.isProcessing = false;\n this.hide();\n }\n\n /**\n * Handle keyboard events for the dialog\n * Enter key triggers primary action (Install/Enable)\n * Escape key dismisses the dialog\n */\n @HostListener('document:keydown', ['$event'])\n handleKeyDown(event: KeyboardEvent): void {\n if (!this.visible || this.isProcessing) return;\n\n if (event.key === 'Enter') {\n // Enter triggers primary action if available\n if (this.showPrimaryAction) {\n event.preventDefault();\n event.stopPropagation();\n this.onPrimaryAction();\n }\n } else if (event.key === 'Escape') {\n // Escape dismisses the dialog\n event.preventDefault();\n event.stopPropagation();\n this.onDismiss();\n }\n }\n}\n","@if (visible) {\n <div class=\"dialog-overlay\" (click)=\"onDismiss()\">\n <div class=\"dialog-container\" (click)=\"$event.stopPropagation()\">\n <!-- Icon -->\n <div class=\"dialog-icon\" [style.color]=\"iconColor\">\n <i class=\"fa-solid\" [ngClass]=\"icon\"></i>\n </div>\n <!-- Title -->\n <h2 class=\"dialog-title\">{{ title }}</h2>\n <!-- Message -->\n <p class=\"dialog-message\">{{ message }}</p>\n <!-- Help message -->\n @if (helpMessage) {\n <p class=\"dialog-help\">{{ helpMessage }}</p>\n }\n <!-- Actions -->\n <div class=\"dialog-actions\">\n @if (showPrimaryAction) {\n <button\n class=\"dialog-btn primary\"\n [disabled]=\"isProcessing\"\n (click)=\"onPrimaryAction()\">\n @if (isProcessing) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!isProcessing) {\n <span>{{ primaryActionText }}</span>\n }\n @if (isProcessing) {\n <span>Processing...</span>\n }\n </button>\n }\n <button\n class=\"dialog-btn\"\n [class.secondary]=\"showPrimaryAction\"\n [disabled]=\"isProcessing\"\n (click)=\"onDismiss()\">\n {{ dismissButtonText }}\n </button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"app-access-dialog.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.ts","../../../../../src/lib/shell/components/dialogs/app-access-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnDestroy, ChangeDetectorRef, HostListener } from '@angular/core';\n\n/**\n * Type of app access issue\n */\nexport type AppAccessDialogType =\n | 'not_installed' // User can install the app\n | 'disabled' // User has disabled the app, can re-enable\n | 'no_access' // User doesn't have permission\n | 'not_found' // App doesn't exist\n | 'inactive' // App is inactive/disabled by admin\n | 'no_apps' // User has no apps configured at all\n | 'layout_error'; // Golden Layout failed to initialize\n\n/**\n * Configuration for the app access dialog\n */\nexport interface AppAccessDialogConfig {\n type: AppAccessDialogType; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n appName?: string; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n appId?: string; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n}\n\n/**\n * Result from the dialog\n */\nexport interface AppAccessDialogResult {\n action: 'install' | 'enable' | 'redirect' | 'dismissed'; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n appId?: string; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n}\n\n/**\n * Dialog component for handling app access errors.\n * Shows appropriate messages and actions based on the type of access issue.\n * Features auto-dismiss with countdown timer for certain dialog types.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-access-dialog',\n templateUrl: './app-access-dialog.component.html',\n styleUrls: ['./app-access-dialog.component.css']\n})\nexport class AppAccessDialogComponent implements OnDestroy {\n @Input() Visible = false;\n\n /** @deprecated Use {@link Visible}. */\n @Input() set visible(value: AppAccessDialogComponent['Visible']) {\n this.Visible = value;\n }\n /** @deprecated Use {@link Visible}. */\n get visible(): AppAccessDialogComponent['Visible'] {\n return this.Visible;\n }\n @Output() VisibleChange = new EventEmitter<boolean>();\n\n /**\n * @deprecated Use {@link VisibleChange}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (visibleChange) keeps working. Must stay AFTER VisibleChange: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() visibleChange = this.VisibleChange;\n @Output() Result = new EventEmitter<AppAccessDialogResult>();\n\n /**\n * @deprecated Use {@link Result}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (result) keeps working. Must stay AFTER Result: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() result = this.Result;\n\n config: AppAccessDialogConfig | null = null;\n IsProcessing = false;\n\n /** @deprecated Use {@link IsProcessing}. */\n get isProcessing() {\n return this.IsProcessing;\n }\n /** @deprecated Use {@link IsProcessing}. */\n set isProcessing(value) {\n this.IsProcessing = value;\n }\n\n // Auto-dismiss countdown\n private countdownInterval: ReturnType<typeof setInterval> | null = null;\n CountdownSeconds = 0;\n\n /** @deprecated Use {@link CountdownSeconds}. */\n get countdownSeconds() {\n return this.CountdownSeconds;\n }\n /** @deprecated Use {@link CountdownSeconds}. */\n set countdownSeconds(value) {\n this.CountdownSeconds = value;\n }\n private readonly AUTO_DISMISS_SECONDS = 5;\n\n constructor(private cdr: ChangeDetectorRef) {}\n\n /**\n * Show the dialog with the specified configuration\n */\n Show(config: AppAccessDialogConfig): void {\n this.config = config;\n this.Visible = true;\n this.IsProcessing = false;\n this.VisibleChange.emit(true);\n\n // Start countdown for types that auto-dismiss\n if (this.shouldAutoDismiss()) {\n this.startCountdown();\n }\n\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link Show}. */\n show(config: AppAccessDialogConfig): void {\n return this.Show(config);\n }\n\n /**\n * Hide the dialog\n */\n Hide(): void {\n this.stopCountdown();\n this.Visible = false;\n this.VisibleChange.emit(false);\n this.cdr.detectChanges();\n }\n\n /** @deprecated Use {@link Hide}. */\n hide(): void {\n return this.Hide();\n }\n\n ngOnDestroy(): void {\n this.stopCountdown();\n }\n\n /**\n * Get the dialog title based on type\n */\n get title(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n return 'Add Application?';\n case 'disabled':\n return 'Add Application?';\n case 'no_access':\n return 'Access Denied';\n case 'not_found':\n return 'Application Not Found';\n case 'inactive':\n return 'Application Unavailable';\n case 'no_apps':\n return 'No Applications Available';\n case 'layout_error':\n return 'Display Error';\n default:\n return 'Application Error';\n }\n }\n\n /**\n * Get the dialog icon based on type\n */\n get Icon(): string {\n if (!this.config) return 'fa-circle-info';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return 'fa-circle-question';\n case 'no_access':\n return 'fa-lock';\n case 'not_found':\n return 'fa-circle-xmark';\n case 'inactive':\n return 'fa-circle-pause';\n case 'no_apps':\n return 'fa-folder-open';\n case 'layout_error':\n return 'fa-triangle-exclamation';\n default:\n return 'fa-circle-info';\n }\n }\n\n /** @deprecated Use {@link Icon}. */\n get icon(): string {\n return this.Icon;\n }\n\n /**\n * Get the dialog icon color based on type\n */\n get IconColor(): string {\n if (!this.config) return 'var(--mj-text-secondary)';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return '#2196F3'; // Blue for actionable\n case 'no_access':\n case 'inactive':\n return '#FF9800'; // Orange for warning\n case 'not_found':\n case 'layout_error':\n return '#F44336'; // Red for error\n case 'no_apps':\n return '#9E9E9E'; // Gray for info\n default:\n return 'var(--mj-text-secondary)';\n }\n }\n\n /** @deprecated Use {@link IconColor}. */\n get iconColor(): string {\n return this.IconColor;\n }\n\n /**\n * Get the main message based on type\n */\n get message(): string {\n if (!this.config) return '';\n\n const appName = this.config.appName || 'this application';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return `Would you like to add \"${appName}\" to your applications?`;\n case 'no_access':\n return `You don't have permission to access \"${appName}\".`;\n case 'not_found':\n return `The application \"${appName}\" doesn't exist in this system.`;\n case 'inactive':\n return `The application \"${appName}\" is currently inactive and unavailable.`;\n case 'no_apps':\n return `You don't have any applications configured. Your system administrator needs to set up your application access.`;\n case 'layout_error':\n return `There was an error displaying the application interface. The system will redirect you to an available application.`;\n default:\n return 'An error occurred while loading the application.';\n }\n }\n\n /**\n * Get the secondary/help message based on type\n */\n get HelpMessage(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return '';\n case 'no_access':\n case 'not_found':\n case 'inactive':\n return 'If you believe this is an error, please contact your system administrator.';\n case 'no_apps':\n return 'Please contact your system administrator to configure your application access.';\n case 'layout_error':\n return 'If this error persists, try clearing your browser cache or contact your system administrator.';\n default:\n return '';\n }\n }\n\n /** @deprecated Use {@link HelpMessage}. */\n get helpMessage(): string {\n return this.HelpMessage;\n }\n\n /**\n * Check if the primary action button should be shown\n */\n get ShowPrimaryAction(): boolean {\n if (!this.config) return false;\n return this.config.type === 'not_installed' || this.config.type === 'disabled';\n }\n\n /** @deprecated Use {@link ShowPrimaryAction}. */\n get showPrimaryAction(): boolean {\n return this.ShowPrimaryAction;\n }\n\n /**\n * Get the primary action button text\n */\n get PrimaryActionText(): string {\n if (!this.config) return '';\n\n switch (this.config.type) {\n case 'not_installed':\n case 'disabled':\n return 'Add';\n default:\n return 'OK';\n }\n }\n\n /** @deprecated Use {@link PrimaryActionText}. */\n get primaryActionText(): string {\n return this.PrimaryActionText;\n }\n\n /**\n * Get the secondary/dismiss button text with countdown if applicable\n * For actionable dialogs (install/enable), show \"Cancel\"\n * For non-actionable dialogs (errors), show \"OK\" with countdown\n */\n get DismissButtonText(): string {\n // For actionable dialogs, use \"Cancel\"\n if (this.ShowPrimaryAction) {\n return 'Cancel';\n }\n\n // For non-actionable dialogs, show countdown if active\n if (this.CountdownSeconds > 0) {\n return `OK (${this.CountdownSeconds})`;\n }\n return 'OK';\n }\n\n /** @deprecated Use {@link DismissButtonText}. */\n get dismissButtonText(): string {\n return this.DismissButtonText;\n }\n\n /**\n * Check if this dialog type should auto-dismiss\n */\n private shouldAutoDismiss(): boolean {\n if (!this.config) return false;\n return ['no_access', 'not_found', 'inactive', 'layout_error'].includes(this.config.type);\n }\n\n /**\n * Start the countdown timer for auto-dismiss\n */\n private startCountdown(): void {\n this.stopCountdown();\n this.CountdownSeconds = this.AUTO_DISMISS_SECONDS;\n\n this.countdownInterval = setInterval(() => {\n this.CountdownSeconds--;\n this.cdr.detectChanges();\n\n if (this.CountdownSeconds <= 0) {\n this.OnDismiss();\n }\n }, 1000);\n }\n\n /**\n * Stop the countdown timer\n */\n private stopCountdown(): void {\n if (this.countdownInterval) {\n clearInterval(this.countdownInterval);\n this.countdownInterval = null;\n }\n this.CountdownSeconds = 0;\n }\n\n /**\n * Handle primary action (install/enable)\n */\n async OnPrimaryAction(): Promise<void> {\n if (!this.config) return;\n\n this.IsProcessing = true;\n this.cdr.detectChanges();\n\n const action = this.config.type === 'not_installed' ? 'install' : 'enable';\n\n this.Result.emit({\n action,\n appId: this.config.appId\n });\n\n // Don't hide yet - let the parent component handle the result and close when ready\n }\n\n /** @deprecated Use {@link OnPrimaryAction}. */\n async onPrimaryAction(): Promise<void> {\n return this.OnPrimaryAction();\n }\n\n /**\n * Handle dismiss/redirect action\n */\n OnDismiss(): void {\n this.stopCountdown();\n this.Result.emit({ action: 'redirect' });\n this.Hide();\n }\n\n /** @deprecated Use {@link OnDismiss}. */\n onDismiss(): void {\n return this.OnDismiss();\n }\n\n /**\n * Mark processing as complete (called by parent after install/enable)\n */\n CompleteProcessing(): void {\n this.IsProcessing = false;\n this.Hide();\n }\n\n /** @deprecated Use {@link CompleteProcessing}. */\n completeProcessing(): void {\n return this.CompleteProcessing();\n }\n\n /**\n * Handle keyboard events for the dialog\n * Enter key triggers primary action (Install/Enable)\n * Escape key dismisses the dialog\n */\n @HostListener('document:keydown', ['$event'])\n handleKeyDown(event: KeyboardEvent): void {\n if (!this.Visible || this.IsProcessing) return;\n\n if (event.key === 'Enter') {\n // Enter triggers primary action if available\n if (this.ShowPrimaryAction) {\n event.preventDefault();\n event.stopPropagation();\n this.OnPrimaryAction();\n }\n } else if (event.key === 'Escape') {\n // Escape dismisses the dialog\n event.preventDefault();\n event.stopPropagation();\n this.OnDismiss();\n }\n }\n}\n","@if (visible) {\n <div class=\"dialog-overlay\" (click)=\"onDismiss()\">\n <div class=\"dialog-container\" (click)=\"$event.stopPropagation()\">\n <!-- Icon -->\n <div class=\"dialog-icon\" [style.color]=\"iconColor\">\n <i class=\"fa-solid\" [ngClass]=\"icon\"></i>\n </div>\n <!-- Title -->\n <h2 class=\"dialog-title\">{{ title }}</h2>\n <!-- Message -->\n <p class=\"dialog-message\">{{ message }}</p>\n <!-- Help message -->\n @if (helpMessage) {\n <p class=\"dialog-help\">{{ helpMessage }}</p>\n }\n <!-- Actions -->\n <div class=\"dialog-actions\">\n @if (showPrimaryAction) {\n <button\n class=\"dialog-btn primary\"\n [disabled]=\"isProcessing\"\n (click)=\"onPrimaryAction()\">\n @if (isProcessing) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!isProcessing) {\n <span>{{ primaryActionText }}</span>\n }\n @if (isProcessing) {\n <span>Processing...</span>\n }\n </button>\n }\n <button\n class=\"dialog-btn\"\n [class.secondary]=\"showPrimaryAction\"\n [disabled]=\"isProcessing\"\n (click)=\"onDismiss()\">\n {{ dismissButtonText }}\n </button>\n </div>\n </div>\n </div>\n}\n"]}
|
|
@@ -67,7 +67,23 @@ export declare class AppNavComponent implements OnInit, OnDestroy, AfterViewInit
|
|
|
67
67
|
private navListRef?;
|
|
68
68
|
private moreBtnRef?;
|
|
69
69
|
private trailingSlotRef?;
|
|
70
|
+
NavItemClick: EventEmitter<NavItemClickEvent>;
|
|
71
|
+
/**
|
|
72
|
+
* @deprecated Use {@link NavItemClick}.
|
|
73
|
+
*
|
|
74
|
+
* The same emitter under the old binding name, so a template still binding
|
|
75
|
+
* (navItemClick) keeps working. Must stay AFTER NavItemClick: class fields
|
|
76
|
+
* initialise in order, and the other way round this captures undefined.
|
|
77
|
+
*/
|
|
70
78
|
navItemClick: EventEmitter<NavItemClickEvent>;
|
|
79
|
+
NavItemDismiss: EventEmitter<NavItem>;
|
|
80
|
+
/**
|
|
81
|
+
* @deprecated Use {@link NavItemDismiss}.
|
|
82
|
+
*
|
|
83
|
+
* The same emitter under the old binding name, so a template still binding
|
|
84
|
+
* (navItemDismiss) keeps working. Must stay AFTER NavItemDismiss: class fields
|
|
85
|
+
* initialise in order, and the other way round this captures undefined.
|
|
86
|
+
*/
|
|
71
87
|
navItemDismiss: EventEmitter<NavItem>;
|
|
72
88
|
/**
|
|
73
89
|
* Disable the priority+ overflow behavior. Used by the mobile drawer instance,
|
|
@@ -144,6 +160,8 @@ export declare class AppNavComponent implements OnInit, OnDestroy, AfterViewInit
|
|
|
144
160
|
/**
|
|
145
161
|
* Check if a nav item is dynamic (generated from recent orphan resources)
|
|
146
162
|
*/
|
|
163
|
+
IsDynamic(item: NavItem): boolean;
|
|
164
|
+
/** @deprecated Use {@link IsDynamic}. */
|
|
147
165
|
isDynamic(item: NavItem): boolean;
|
|
148
166
|
/**
|
|
149
167
|
* Compute if nav item is active based on active tab
|
|
@@ -152,26 +170,36 @@ export declare class AppNavComponent implements OnInit, OnDestroy, AfterViewInit
|
|
|
152
170
|
/**
|
|
153
171
|
* Get cached navigation items (no computation in getter)
|
|
154
172
|
*/
|
|
173
|
+
get NavItems(): NavItem[];
|
|
174
|
+
/** @deprecated Use {@link NavItems}. */
|
|
155
175
|
get navItems(): NavItem[];
|
|
156
176
|
/**
|
|
157
177
|
* Check if nav item is active (uses cached state from Map)
|
|
158
178
|
*/
|
|
179
|
+
IsActive(item: NavItem): boolean;
|
|
180
|
+
/** @deprecated Use {@link IsActive}. */
|
|
159
181
|
isActive(item: NavItem): boolean;
|
|
160
182
|
/**
|
|
161
183
|
* Track function for @for to optimize rendering
|
|
162
184
|
*/
|
|
185
|
+
TrackByNavItem(_index: number, item: NavItem): string;
|
|
186
|
+
/** @deprecated Use {@link TrackByNavItem}. */
|
|
163
187
|
trackByNavItem(_index: number, item: NavItem): string;
|
|
164
188
|
/**
|
|
165
189
|
* Handle nav item click
|
|
166
190
|
*/
|
|
191
|
+
OnNavClick(item: NavItem, event?: MouseEvent): void;
|
|
192
|
+
/** @deprecated Use {@link OnNavClick}. */
|
|
167
193
|
onNavClick(item: NavItem, event?: MouseEvent): void;
|
|
168
194
|
/**
|
|
169
195
|
* Handle dismiss click on a dynamic nav item.
|
|
170
196
|
* Removes from the app's recent stack and refreshes nav items immediately.
|
|
171
197
|
* Stops propagation so the nav click handler doesn't fire.
|
|
172
198
|
*/
|
|
199
|
+
OnDismiss(item: NavItem, event: MouseEvent): void;
|
|
200
|
+
/** @deprecated Use {@link OnDismiss}. */
|
|
173
201
|
onDismiss(item: NavItem, event: MouseEvent): void;
|
|
174
202
|
static ɵfac: i0.ɵɵFactoryDeclaration<AppNavComponent, never>;
|
|
175
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AppNavComponent, "mj-app-nav", never, { "OverflowEnabled": { "alias": "OverflowEnabled"; "required": false; }; "app": { "alias": "app"; "required": false; }; }, { "navItemClick": "navItemClick"; "navItemDismiss": "navItemDismiss"; }, never, ["*"], false, never>;
|
|
203
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AppNavComponent, "mj-app-nav", never, { "OverflowEnabled": { "alias": "OverflowEnabled"; "required": false; }; "app": { "alias": "app"; "required": false; }; }, { "NavItemClick": "NavItemClick"; "navItemClick": "navItemClick"; "NavItemDismiss": "NavItemDismiss"; "navItemDismiss": "navItemDismiss"; }, never, ["*"], false, never>;
|
|
176
204
|
}
|
|
177
205
|
//# sourceMappingURL=app-nav.component.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-nav.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,iBAAiB,EAA2B,UAAU,EAA2B,MAAM,eAAe,CAAC;AAC1L,OAAO,EAAE,eAAe,EAAkB,OAAO,EAAE,qBAAqB,EAA0B,MAAM,qCAAqC,CAAC;AAC9I,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;;AAG1D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,qBAOa,eAAgB,YAAW,MAAM,EAAE,SAAS,EAAE,aAAa;
|
|
1
|
+
{"version":3,"file":"app-nav.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts"],"names":[],"mappings":"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"}
|
|
@@ -197,8 +197,24 @@ export class AppNavComponent {
|
|
|
197
197
|
navListRef;
|
|
198
198
|
moreBtnRef;
|
|
199
199
|
trailingSlotRef;
|
|
200
|
-
|
|
201
|
-
|
|
200
|
+
NavItemClick = new EventEmitter();
|
|
201
|
+
/**
|
|
202
|
+
* @deprecated Use {@link NavItemClick}.
|
|
203
|
+
*
|
|
204
|
+
* The same emitter under the old binding name, so a template still binding
|
|
205
|
+
* (navItemClick) keeps working. Must stay AFTER NavItemClick: class fields
|
|
206
|
+
* initialise in order, and the other way round this captures undefined.
|
|
207
|
+
*/
|
|
208
|
+
navItemClick = this.NavItemClick;
|
|
209
|
+
NavItemDismiss = new EventEmitter();
|
|
210
|
+
/**
|
|
211
|
+
* @deprecated Use {@link NavItemDismiss}.
|
|
212
|
+
*
|
|
213
|
+
* The same emitter under the old binding name, so a template still binding
|
|
214
|
+
* (navItemDismiss) keeps working. Must stay AFTER NavItemDismiss: class fields
|
|
215
|
+
* initialise in order, and the other way round this captures undefined.
|
|
216
|
+
*/
|
|
217
|
+
navItemDismiss = this.NavItemDismiss;
|
|
202
218
|
/**
|
|
203
219
|
* Disable the priority+ overflow behavior. Used by the mobile drawer instance,
|
|
204
220
|
* where items stack vertically and can never overflow horizontally.
|
|
@@ -452,7 +468,7 @@ export class AppNavComponent {
|
|
|
452
468
|
}
|
|
453
469
|
/** True when any overflowed item is the active one (More button shows active tint) */
|
|
454
470
|
get OverflowHasActive() {
|
|
455
|
-
return this.OverflowItems.some(item => this.
|
|
471
|
+
return this.OverflowItems.some(item => this.IsActive(item));
|
|
456
472
|
}
|
|
457
473
|
/** Open/close the More dropdown, anchoring it under the More button and clamping it inside the host */
|
|
458
474
|
ToggleMore(event) {
|
|
@@ -522,9 +538,13 @@ export class AppNavComponent {
|
|
|
522
538
|
/**
|
|
523
539
|
* Check if a nav item is dynamic (generated from recent orphan resources)
|
|
524
540
|
*/
|
|
525
|
-
|
|
541
|
+
IsDynamic(item) {
|
|
526
542
|
return item.isDynamic === true;
|
|
527
543
|
}
|
|
544
|
+
/** @deprecated Use {@link IsDynamic}. */
|
|
545
|
+
isDynamic(item) {
|
|
546
|
+
return this.IsDynamic(item);
|
|
547
|
+
}
|
|
528
548
|
/**
|
|
529
549
|
* Compute if nav item is active based on active tab
|
|
530
550
|
*/
|
|
@@ -556,38 +576,54 @@ export class AppNavComponent {
|
|
|
556
576
|
/**
|
|
557
577
|
* Get cached navigation items (no computation in getter)
|
|
558
578
|
*/
|
|
559
|
-
get
|
|
579
|
+
get NavItems() {
|
|
560
580
|
return this._cachedNavItems;
|
|
561
581
|
}
|
|
582
|
+
/** @deprecated Use {@link NavItems}. */
|
|
583
|
+
get navItems() {
|
|
584
|
+
return this.NavItems;
|
|
585
|
+
}
|
|
562
586
|
/**
|
|
563
587
|
* Check if nav item is active (uses cached state from Map)
|
|
564
588
|
*/
|
|
565
|
-
|
|
589
|
+
IsActive(item) {
|
|
566
590
|
const key = this.getItemKey(item);
|
|
567
591
|
return this.activeStateMap.get(key) || false;
|
|
568
592
|
}
|
|
593
|
+
/** @deprecated Use {@link IsActive}. */
|
|
594
|
+
isActive(item) {
|
|
595
|
+
return this.IsActive(item);
|
|
596
|
+
}
|
|
569
597
|
/**
|
|
570
598
|
* Track function for @for to optimize rendering
|
|
571
599
|
*/
|
|
572
|
-
|
|
600
|
+
TrackByNavItem(_index, item) {
|
|
573
601
|
return this.getItemKey(item);
|
|
574
602
|
}
|
|
603
|
+
/** @deprecated Use {@link TrackByNavItem}. */
|
|
604
|
+
trackByNavItem(_index, item) {
|
|
605
|
+
return this.TrackByNavItem(_index, item);
|
|
606
|
+
}
|
|
575
607
|
/**
|
|
576
608
|
* Handle nav item click
|
|
577
609
|
*/
|
|
578
|
-
|
|
610
|
+
OnNavClick(item, event) {
|
|
579
611
|
this.MoreOpen = false;
|
|
580
|
-
this.
|
|
612
|
+
this.NavItemClick.emit({
|
|
581
613
|
item,
|
|
582
614
|
shiftKey: event?.shiftKey || false
|
|
583
615
|
});
|
|
584
616
|
}
|
|
617
|
+
/** @deprecated Use {@link OnNavClick}. */
|
|
618
|
+
onNavClick(item, event) {
|
|
619
|
+
return this.OnNavClick(item, event);
|
|
620
|
+
}
|
|
585
621
|
/**
|
|
586
622
|
* Handle dismiss click on a dynamic nav item.
|
|
587
623
|
* Removes from the app's recent stack and refreshes nav items immediately.
|
|
588
624
|
* Stops propagation so the nav click handler doesn't fire.
|
|
589
625
|
*/
|
|
590
|
-
|
|
626
|
+
OnDismiss(item, event) {
|
|
591
627
|
event.stopPropagation();
|
|
592
628
|
// Remove from the app's recent stack directly so we can refresh immediately
|
|
593
629
|
if (this._app) {
|
|
@@ -597,7 +633,11 @@ export class AppNavComponent {
|
|
|
597
633
|
this.updateCachedData();
|
|
598
634
|
}
|
|
599
635
|
}
|
|
600
|
-
this.
|
|
636
|
+
this.NavItemDismiss.emit(item);
|
|
637
|
+
}
|
|
638
|
+
/** @deprecated Use {@link OnDismiss}. */
|
|
639
|
+
onDismiss(item, event) {
|
|
640
|
+
return this.OnDismiss(item, event);
|
|
601
641
|
}
|
|
602
642
|
static ɵfac = function AppNavComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AppNavComponent)(i0.ɵɵdirectiveInject(i1.WorkspaceStateManager), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.ElementRef)); };
|
|
603
643
|
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: AppNavComponent, selectors: [["mj-app-nav"]], viewQuery: function AppNavComponent_Query(rf, ctx) { if (rf & 1) {
|
|
@@ -609,7 +649,7 @@ export class AppNavComponent {
|
|
|
609
649
|
i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.trailingSlotRef = _t.first);
|
|
610
650
|
} }, hostBindings: function AppNavComponent_HostBindings(rf, ctx) { if (rf & 1) {
|
|
611
651
|
i0.ɵɵlistener("click", function AppNavComponent_click_HostBindingHandler($event) { return ctx.onDocumentClick($event); }, i0.ɵɵresolveDocument)("keydown.escape", function AppNavComponent_keydown_escape_HostBindingHandler() { return ctx.onEscape(); }, i0.ɵɵresolveDocument);
|
|
612
|
-
} }, inputs: { OverflowEnabled: "OverflowEnabled", app: "app" }, outputs: { navItemClick: "navItemClick", navItemDismiss: "navItemDismiss" }, standalone: false, ngContentSelectors: _c3, decls: 10, vars: 5, consts: [["navList", ""], ["trailingSlot", ""], ["moreBtn", ""], [1, "nav-list"], ["aria-hidden", "true", 1, "nav-skeleton"], ["role", "link", 1, "nav-item", 3, "mjClickable", "testId", "active", "dynamic", "no-icon"], ["mjClickable", "More navigation items", "testId", "nav-more-btn", 1, "nav-item", "nav-more-btn", 3, "active"], [1, "nav-trailing"], [1, "nav-more-dropdown", 3, "left"], [1, "nav-skeleton-pill", 2, "width", "88px"], [1, "nav-skeleton-pill", 2, "width", "72px"], [1, "nav-skeleton-pill", 2, "width", "96px"], ["role", "link", 1, "nav-item", 3, "click", "mjClickable", "testId"], [3, "class"], [1, "badge"], ["title", "Remove", 1, "dismiss-btn"], ["title", "Remove", 1, "dismiss-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], ["mjClickable", "More navigation items", "testId", "nav-more-btn", 1, "nav-item", "nav-more-btn", 3, "click"], [1, "fa-solid", "fa-ellipsis"], [1, "more-count"], [1, "nav-more-dropdown"], ["role", "link", 1, "nav-more-item", 3, "mjClickable", "testId", "active", "dynamic"], ["role", "link", 1, "nav-more-item", 3, "click", "mjClickable", "testId"], [1, "more-item-label"]], template: function AppNavComponent_Template(rf, ctx) { if (rf & 1) {
|
|
652
|
+
} }, inputs: { OverflowEnabled: "OverflowEnabled", app: "app" }, outputs: { NavItemClick: "NavItemClick", navItemClick: "navItemClick", NavItemDismiss: "NavItemDismiss", navItemDismiss: "navItemDismiss" }, standalone: false, ngContentSelectors: _c3, decls: 10, vars: 5, consts: [["navList", ""], ["trailingSlot", ""], ["moreBtn", ""], [1, "nav-list"], ["aria-hidden", "true", 1, "nav-skeleton"], ["role", "link", 1, "nav-item", 3, "mjClickable", "testId", "active", "dynamic", "no-icon"], ["mjClickable", "More navigation items", "testId", "nav-more-btn", 1, "nav-item", "nav-more-btn", 3, "active"], [1, "nav-trailing"], [1, "nav-more-dropdown", 3, "left"], [1, "nav-skeleton-pill", 2, "width", "88px"], [1, "nav-skeleton-pill", 2, "width", "72px"], [1, "nav-skeleton-pill", 2, "width", "96px"], ["role", "link", 1, "nav-item", 3, "click", "mjClickable", "testId"], [3, "class"], [1, "badge"], ["title", "Remove", 1, "dismiss-btn"], ["title", "Remove", 1, "dismiss-btn", 3, "click"], [1, "fa-solid", "fa-xmark"], ["mjClickable", "More navigation items", "testId", "nav-more-btn", 1, "nav-item", "nav-more-btn", 3, "click"], [1, "fa-solid", "fa-ellipsis"], [1, "more-count"], [1, "nav-more-dropdown"], ["role", "link", 1, "nav-more-item", 3, "mjClickable", "testId", "active", "dynamic"], ["role", "link", 1, "nav-more-item", 3, "click", "mjClickable", "testId"], [1, "more-item-label"]], template: function AppNavComponent_Template(rf, ctx) { if (rf & 1) {
|
|
613
653
|
i0.ɵɵprojectionDef();
|
|
614
654
|
i0.ɵɵelementStart(0, "nav", 3, 0);
|
|
615
655
|
i0.ɵɵconditionalCreate(2, AppNavComponent_Conditional_2_Template, 4, 0, "div", 4);
|
|
@@ -643,8 +683,12 @@ export class AppNavComponent {
|
|
|
643
683
|
}], trailingSlotRef: [{
|
|
644
684
|
type: ViewChild,
|
|
645
685
|
args: ['trailingSlot']
|
|
686
|
+
}], NavItemClick: [{
|
|
687
|
+
type: Output
|
|
646
688
|
}], navItemClick: [{
|
|
647
689
|
type: Output
|
|
690
|
+
}], NavItemDismiss: [{
|
|
691
|
+
type: Output
|
|
648
692
|
}], navItemDismiss: [{
|
|
649
693
|
type: Output
|
|
650
694
|
}], OverflowEnabled: [{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-nav.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts","../../../../../src/lib/shell/components/header/app-nav.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, AfterViewInit, ChangeDetectorRef, ChangeDetectionStrategy, ElementRef, ViewChild, HostListener } from '@angular/core';\nimport { BaseApplication, DynamicNavItem, NavItem, WorkspaceStateManager, WorkspaceConfiguration } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Subject, takeUntil } from 'rxjs';\n\n/**\n * Event emitted when a nav item is clicked\n */\nexport interface NavItemClickEvent {\n item: NavItem;\n shiftKey: boolean;\n}\n\n/**\n * Horizontal navigation items for the current app.\n * Uses OnPush change detection and reactive state management for optimal performance.\n *\n * Overflow behavior (priority+ pattern): when the header can't fit every nav item,\n * trailing items collapse into a \"More\" dropdown instead of squeezing the header's\n * action cluster off-screen. Item widths are measured once per nav-items change\n * (all items render for one frame, widths are cached), then every resize recomputes\n * the fit from the cache — no re-measure, no layout thrash.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-nav',\n templateUrl: './app-nav.component.html',\n styleUrls: ['./app-nav.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppNavComponent implements OnInit, OnDestroy, AfterViewInit {\n private destroy$ = new Subject<void>();\n private _app: BaseApplication | null = null;\n private _cachedNavItems: NavItem[] = [];\n private _servicesInjected = false;\n\n /**\n * Monotonically increasing counter used to detect and discard stale async results.\n *\n * Because GetNavItems() is async (HomeApplication does a DB lookup for record names),\n * and RxJS subscribe() does NOT serialize async callbacks, multiple calls to\n * updateCachedData() can overlap. Without this guard, a slow call (e.g., Home app\n * doing a DB lookup) that started BEFORE a fast call (e.g., switching to App B)\n * could resolve AFTER the fast call and overwrite the correct nav items with stale ones.\n *\n * How it works:\n * 1. Each updateCachedData() call increments this counter and captures it as `gen`\n * 2. After the await, it checks: does `gen` still match `_updateGeneration`?\n * 3. If not, a newer call started while we were waiting — discard our stale results\n */\n private _updateGeneration = 0;\n\n // Map of nav item key (Route or Label) to active state\n private activeStateMap = new Map<string, boolean>();\n\n // ---- Overflow (priority+) state ----\n /** Cached natural pixel width of each nav item, parallel to navItems order */\n private itemWidths: number[] = [];\n /** Measured width of the More button (fallback used until first render) */\n private moreBtnWidth = 120;\n /** Left offset (px, relative to host) where the More dropdown anchors */\n public MoreDropdownLeft = 0;\n /** True when even one item + More can't fit — the lone visible pill\n * shrinks with an ellipsis instead of clipping the More button. */\n public Tight = false;\n /** Flex gap between nav items — measured from the rendered row (falls back\n * to --mj-space-1's default of 4px until first measurement) */\n private itemGap = 4;\n /** How many leading nav items are currently visible inline */\n public VisibleCount = Number.MAX_SAFE_INTEGER;\n /** Whether the More dropdown is open */\n public MoreOpen = false;\n /** True while nav items are being (re)loaded for skeleton display */\n public Loading = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private _overflowEnabled = true;\n\n @ViewChild('navList') private navListRef?: ElementRef<HTMLElement>;\n @ViewChild('moreBtn') private moreBtnRef?: ElementRef<HTMLElement>;\n @ViewChild('trailingSlot') private trailingSlotRef?: ElementRef<HTMLElement>;\n\n @Output() navItemClick = new EventEmitter<NavItemClickEvent>();\n @Output() navItemDismiss = new EventEmitter<NavItem>();\n\n /**\n * Disable the priority+ overflow behavior. Used by the mobile drawer instance,\n * where items stack vertically and can never overflow horizontally.\n */\n @Input()\n set OverflowEnabled(value: boolean) {\n this._overflowEnabled = value;\n if (!value) {\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n }\n }\n get OverflowEnabled(): boolean {\n return this._overflowEnabled;\n }\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef,\n private host: ElementRef<HTMLElement>\n ) {}\n\n /**\n * Input setter for app - triggers cache update when app changes\n */\n @Input()\n set app(value: BaseApplication | null) {\n if (this._app !== value) {\n this._app = value;\n this._cachedNavItems = []; // Clear stale items immediately so previous app's items don't flash\n this.activeStateMap.clear();\n this._servicesInjected = false; // Reset injection flag\n this.Loading = value != null; // Skeleton until GetNavItems resolves\n this.updateCachedData();\n this.cdr.markForCheck();\n }\n }\n\n get app(): BaseApplication | null {\n return this._app;\n }\n\n ngOnInit(): void {\n // Subscribe to workspace configuration changes.\n // Must rebuild nav items (not just active states) because dynamic nav items\n // are generated based on the currently active tab - when a user navigates\n // from one record to another (e.g., via OpenEntityRecord), the active tab\n // changes and the dynamic nav item needs to reflect the new record.\n this.workspaceManager.Configuration\n .pipe(takeUntil(this.destroy$))\n .subscribe(async () => {\n await this.updateCachedData();\n });\n }\n\n ngAfterViewInit(): void {\n if (this._overflowEnabled && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.recomputeFit());\n this.resizeObserver.observe(this.host.nativeElement);\n }\n // Widths measured before webfonts arrive are stale (Explorer's Montserrat\n // loads late over the fallback stack) — invalidate the cache once fonts\n // settle so the fit is computed against real glyph metrics.\n if (this._overflowEnabled && typeof document !== 'undefined' && document.fonts?.ready) {\n document.fonts.ready.then(() => {\n this.itemWidths = [];\n this.recomputeFit();\n });\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Update cached nav items and app color when app changes\n */\n private async updateCachedData(): Promise<void> {\n // Capture the current generation before any async work.\n // See _updateGeneration JSDoc for full explanation of the race condition this prevents.\n const gen = ++this._updateGeneration;\n\n if (this._app) {\n // Inject services once for apps that need them (e.g., HomeApplication for dynamic nav items)\n if (!this._servicesInjected) {\n const appWithServices = this._app as BaseApplication & {\n SetWorkspaceManager?: (manager: WorkspaceStateManager) => void;\n SetSharedService?: (service: SharedService) => void;\n };\n\n if (typeof appWithServices.SetWorkspaceManager === 'function') {\n appWithServices.SetWorkspaceManager(this.workspaceManager);\n }\n if (typeof appWithServices.SetSharedService === 'function') {\n appWithServices.SetSharedService(this.sharedService);\n }\n this._servicesInjected = true;\n }\n\n const items = await this._app.GetNavItems() || [];\n\n // If a newer call started while we were awaiting, our results are stale — bail out\n // so we don't overwrite the newer call's (correct) results.\n if (gen !== this._updateGeneration) {\n return;\n }\n\n // Only show items with Status 'Active' or undefined (default to Active)\n this._cachedNavItems = items.filter(item => !item.Status || item.Status === 'Active');\n } else {\n this._cachedNavItems = [];\n }\n\n this.Loading = false;\n\n // Update active states after nav items change\n const config = this.workspaceManager.GetConfiguration();\n this.updateActiveStates(config);\n\n // New item set: show everything for one frame so natural widths can be\n // measured (the row clips, so the temporary full row is invisible),\n // then collapse to fit. Tight mode MUST be off during measurement — its\n // flex-shrink would record squeezed widths and poison the fit arithmetic.\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n this.MoreOpen = false;\n this.Tight = false;\n this.syncChangeDetection();\n\n if (this._overflowEnabled) {\n requestAnimationFrame(() => {\n this.measureItemWidths();\n this.recomputeFit();\n });\n }\n }\n\n /**\n * Cache the natural width of every nav item. Called in the frame after a new\n * item set renders (all items visible, flex-shrink: 0, so widths are natural\n * even if the row is clipped by overflow: hidden).\n */\n private measureItemWidths(): void {\n const list = this.navListRef?.nativeElement;\n if (!list) {\n return;\n }\n const els = Array.from(list.querySelectorAll<HTMLElement>('.nav-item:not(.nav-more-btn)'));\n if (els.length !== this._cachedNavItems.length) {\n return; // View out of sync (mid-CD) — the next update cycle re-measures\n }\n this.itemWidths = els.map(el => el.offsetWidth);\n // Measure the real flex gap (rem-based tokens can differ from the 4px\n // fallback if the root font-size changes)\n const gap = parseFloat(getComputedStyle(list).columnGap);\n if (!Number.isNaN(gap)) {\n this.itemGap = gap;\n }\n }\n\n /**\n * Decide how many items fit in the host's current width; the rest collapse\n * into the More dropdown. Pure arithmetic over cached widths — safe to call\n * on every resize.\n */\n private recomputeFit(): void {\n if (!this._overflowEnabled || this._cachedNavItems.length === 0) {\n return;\n }\n const hostWidth = this.host.nativeElement.clientWidth;\n if (hostWidth === 0) {\n return; // Hidden (mobile breakpoint) — leave state alone\n }\n if (!this.ensureFreshWidthCache()) {\n return; // Cache still stale — a retry frame is already scheduled\n }\n if (this.moreBtnRef?.nativeElement) {\n this.moreBtnWidth = this.moreBtnRef.nativeElement.offsetWidth || this.moreBtnWidth;\n }\n // Reserve the trailing slot's width (projected shell items, e.g. the\n // Records pill) so nav items yield to More before painting under it.\n // Measured fresh each pass — the slot appears/disappears with open records,\n // and every such change arrives via a configuration$ emission that re-runs\n // this fit anyway.\n const trailingWidth = this.trailingSlotRef?.nativeElement?.offsetWidth ?? 0;\n const fit = this.computeFitCount(hostWidth - trailingWidth);\n this.applyFit(fit.count, fit.tight);\n }\n\n /**\n * Self-heal for the item-width cache: if it's stale or missing (the\n * measurement frame can race the first render after a reload/app switch),\n * expand to the full item set, re-measure, and retry next frame until it\n * converges. Returns true when the cache matches the current item set.\n */\n private ensureFreshWidthCache(): boolean {\n if (this.itemWidths.length === this._cachedNavItems.length) {\n return true;\n }\n if (this.VisibleCount < this._cachedNavItems.length || this.Tight) {\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n this.Tight = false; // Never measure with tight-mode shrink applied\n this.syncChangeDetection();\n }\n this.measureItemWidths();\n if (this.itemWidths.length !== this._cachedNavItems.length) {\n requestAnimationFrame(() => this.recomputeFit());\n return false;\n }\n return true;\n }\n\n /** Pure fit arithmetic: how many leading items fit beside the More button */\n private computeFitCount(hostWidth: number): { count: number; tight: boolean } {\n const gap = this.itemGap;\n const n = this.itemWidths.length;\n const totalAll = this.itemWidths.reduce((a, b) => a + b, 0) + gap * (n - 1);\n if (totalAll <= hostWidth) {\n return { count: Number.MAX_SAFE_INTEGER, tight: false }; // Everything fits\n }\n // Reserve room for the More button, then fit as many leading items as possible\n let used = this.moreBtnWidth;\n let fit = 0;\n for (let i = 0; i < n; i++) {\n const next = used + gap + this.itemWidths[i];\n if (next > hostWidth) {\n break;\n }\n used = next;\n fit++;\n }\n // Never collapse below one visible item; tight = even the lone item + More overflows\n return { count: Math.max(1, fit), tight: fit === 0 };\n }\n\n /** Commit a fit result, closing More if nothing overflows; CD only on change */\n private applyFit(count: number, tight: boolean): void {\n if (count === this.VisibleCount && tight === this.Tight) {\n return;\n }\n this.VisibleCount = count;\n this.Tight = tight;\n if (this.OverflowItems.length === 0) {\n this.MoreOpen = false;\n }\n this.syncChangeDetection();\n }\n\n /**\n * markForCheck + synchronous detectChanges. In Angular 21 zoneless mode,\n * markForCheck() alone is unreliable when the trigger is an RxJS\n * subscription or rAF callback not tracked by the zoneless scheduler — the\n * dirty flag is set but no follow-up tick is scheduled. detectChanges()\n * throws if invoked re-entrantly during an in-flight CD pass; that's\n * harmless (the in-flight pass picks up our markForCheck), hence the catch.\n */\n private syncChangeDetection(): void {\n this.cdr.markForCheck();\n try {\n this.cdr.detectChanges();\n } catch {\n // Re-entrant CD — harmless.\n }\n }\n\n /** Items rendered inline in the header row */\n get InlineItems(): NavItem[] {\n return this._cachedNavItems.slice(0, this.VisibleCount);\n }\n\n /** Items collapsed into the More dropdown */\n get OverflowItems(): NavItem[] {\n return this.VisibleCount >= this._cachedNavItems.length\n ? []\n : this._cachedNavItems.slice(this.VisibleCount);\n }\n\n /** True when any overflowed item is the active one (More button shows active tint) */\n get OverflowHasActive(): boolean {\n return this.OverflowItems.some(item => this.isActive(item));\n }\n\n /** Open/close the More dropdown, anchoring it under the More button and clamping it inside the host */\n ToggleMore(event: MouseEvent): void {\n event.stopPropagation();\n this.MoreOpen = !this.MoreOpen;\n if (this.MoreOpen) {\n // Anchor the dropdown under the More button; once the dropdown has\n // rendered, clamp it so its right edge stays inside the host.\n this.MoreDropdownLeft = this.moreBtnRef?.nativeElement?.offsetLeft ?? 0;\n requestAnimationFrame(() => {\n const dropdown = this.host.nativeElement.querySelector<HTMLElement>('.nav-more-dropdown');\n if (dropdown) {\n const maxLeft = this.host.nativeElement.clientWidth - dropdown.offsetWidth;\n this.MoreDropdownLeft = Math.max(0, Math.min(this.MoreDropdownLeft, maxLeft));\n this.cdr.markForCheck();\n try {\n this.cdr.detectChanges();\n } catch {\n // Re-entrant CD — harmless.\n }\n }\n });\n }\n this.cdr.markForCheck();\n }\n\n /** Close the More dropdown on any outside click or Escape */\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.MoreOpen && !this.host.nativeElement.contains(event.target as Node)) {\n this.MoreOpen = false;\n this.cdr.markForCheck();\n }\n }\n\n /** Close the More dropdown on Escape */\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.MoreOpen) {\n this.MoreOpen = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Update active state map based on current workspace configuration\n */\n private updateActiveStates(config: WorkspaceConfiguration | null): void {\n this.activeStateMap.clear();\n\n if (!config || !this._app) {\n return;\n }\n\n const activeTab = config.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || activeTab.applicationId !== this._app.ID) {\n return;\n }\n\n // Compute active state for each nav item once\n for (const item of this._cachedNavItems) {\n const key = this.getItemKey(item);\n const isActive = this.computeIsActive(item, activeTab);\n this.activeStateMap.set(key, isActive);\n }\n }\n\n /**\n * Get unique key for nav item (used for tracking and active state).\n * Prefers RecordID for dynamic items to avoid label collisions.\n */\n private getItemKey(item: NavItem): string {\n return item.RecordID || item.Route || item.Label || '';\n }\n\n /**\n * Check if a nav item is dynamic (generated from recent orphan resources)\n */\n isDynamic(item: NavItem): boolean {\n return (item as DynamicNavItem).isDynamic === true;\n }\n\n /**\n * Compute if nav item is active based on active tab\n */\n private computeIsActive(item: NavItem, activeTab: any): boolean {\n // Check if nav item has a custom matching function (for dynamic items)\n const dynamicItem = item as NavItem & { isActiveMatch?: (tab: unknown) => boolean };\n if (dynamicItem.isActiveMatch && typeof dynamicItem.isActiveMatch === 'function') {\n return dynamicItem.isActiveMatch(activeTab);\n }\n\n const config = activeTab.configuration || {};\n\n // Match by DriverClass (most reliable for Custom resource types — always set correctly)\n if (item.DriverClass && (config['driverClass'] === item.DriverClass || config['resourceTypeDriverClass'] === item.DriverClass)) {\n return true;\n }\n\n // Match by navItemName from config (reliable — set when nav item opens)\n if (config['navItemName'] && config['navItemName'] === item.Label) {\n return true;\n }\n\n // Match by route (for route-based nav items)\n if (item.Route && config['route'] === item.Route) {\n return true;\n }\n\n // NOTE: We intentionally do NOT match by activeTab.title here.\n // Tab titles can be stale (updated asynchronously by DisplayNameChangedEvent\n // from cached components) and cause double-matches where two nav items\n // both appear active. DriverClass and navItemName are sufficient.\n return false;\n }\n\n /**\n * Get cached navigation items (no computation in getter)\n */\n get navItems(): NavItem[] {\n return this._cachedNavItems;\n }\n\n /**\n * Check if nav item is active (uses cached state from Map)\n */\n isActive(item: NavItem): boolean {\n const key = this.getItemKey(item);\n return this.activeStateMap.get(key) || false;\n }\n\n /**\n * Track function for @for to optimize rendering\n */\n trackByNavItem(_index: number, item: NavItem): string {\n return this.getItemKey(item);\n }\n\n /**\n * Handle nav item click\n */\n onNavClick(item: NavItem, event?: MouseEvent): void {\n this.MoreOpen = false;\n this.navItemClick.emit({\n item,\n shiftKey: event?.shiftKey || false\n });\n }\n\n /**\n * Handle dismiss click on a dynamic nav item.\n * Removes from the app's recent stack and refreshes nav items immediately.\n * Stops propagation so the nav click handler doesn't fire.\n */\n onDismiss(item: NavItem, event: MouseEvent): void {\n event.stopPropagation();\n\n // Remove from the app's recent stack directly so we can refresh immediately\n if (this._app) {\n const appWithRemove = this._app as BaseApplication & {\n RemoveDynamicNavItem?: (navItem: NavItem) => void;\n };\n if (typeof appWithRemove.RemoveDynamicNavItem === 'function') {\n appWithRemove.RemoveDynamicNavItem(item);\n this.updateCachedData();\n }\n }\n\n this.navItemDismiss.emit(item);\n }\n\n}\n","<nav class=\"nav-list\" #navList [class.tight]=\"Tight\">\n @if (Loading && navItems.length === 0) {\n <!-- Skeleton pills while GetNavItems() resolves — prevents header pop-in -->\n <div class=\"nav-skeleton\" aria-hidden=\"true\">\n <span class=\"nav-skeleton-pill\" style=\"width: 88px\"></span>\n <span class=\"nav-skeleton-pill\" style=\"width: 72px\"></span>\n <span class=\"nav-skeleton-pill\" style=\"width: 96px\"></span>\n </div>\n }\n @for (item of InlineItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-item\"\n [mjClickable]=\"item.Label\"\n role=\"link\"\n [testId]=\"'nav-item-' + item.Label\"\n [attr.aria-current]=\"isActive(item) ? 'page' : null\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n [class.no-icon]=\"!item.Icon\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span>{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n @if (OverflowItems.length > 0) {\n <div\n #moreBtn\n class=\"nav-item nav-more-btn\"\n mjClickable=\"More navigation items\"\n testId=\"nav-more-btn\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"MoreOpen\"\n [class.active]=\"OverflowHasActive\"\n (click)=\"ToggleMore($event)\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n <span>More</span>\n <span class=\"more-count\">{{ OverflowItems.length }}</span>\n </div>\n }\n <!-- Trailing slot: shell-level items that sit AFTER the app's own nav\n (the Records pill). Its width is reserved by\n recomputeFit so the priority+ arithmetic never lets nav items paint\n under it. -->\n <span class=\"nav-trailing\" #trailingSlot>\n <ng-content></ng-content>\n </span>\n</nav>\n\n<!-- The dropdown lives OUTSIDE the clipped nav row (the row keeps\n overflow: hidden so fit-arithmetic slack can never paint over the\n header's action cluster). Anchored to the More button by measurement. -->\n@if (MoreOpen && OverflowItems.length > 0) {\n <div class=\"nav-more-dropdown\" [style.left.px]=\"MoreDropdownLeft\">\n @for (item of OverflowItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-more-item\"\n [mjClickable]=\"item.Label\"\n role=\"link\"\n [testId]=\"'nav-more-item-' + item.Label\"\n [attr.aria-current]=\"isActive(item) ? 'page' : null\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span class=\"more-item-label\">{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n </div>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"app-nav.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-nav.component.ts","../../../../../src/lib/shell/components/header/app-nav.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnDestroy, AfterViewInit, ChangeDetectorRef, ChangeDetectionStrategy, ElementRef, ViewChild, HostListener } from '@angular/core';\nimport { BaseApplication, DynamicNavItem, NavItem, WorkspaceStateManager, WorkspaceConfiguration } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { Subject, takeUntil } from 'rxjs';\n\n/**\n * Event emitted when a nav item is clicked\n */\nexport interface NavItemClickEvent {\n item: NavItem; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n shiftKey: boolean; // case-violation-ok-legacy-back-compat: the type is named in an exported signature, so consumers build object literals against it; an interface has no runtime carrier for a stub\n}\n\n/**\n * Horizontal navigation items for the current app.\n * Uses OnPush change detection and reactive state management for optimal performance.\n *\n * Overflow behavior (priority+ pattern): when the header can't fit every nav item,\n * trailing items collapse into a \"More\" dropdown instead of squeezing the header's\n * action cluster off-screen. Item widths are measured once per nav-items change\n * (all items render for one frame, widths are cached), then every resize recomputes\n * the fit from the cache — no re-measure, no layout thrash.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-nav',\n templateUrl: './app-nav.component.html',\n styleUrls: ['./app-nav.component.css'],\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class AppNavComponent implements OnInit, OnDestroy, AfterViewInit {\n private destroy$ = new Subject<void>();\n private _app: BaseApplication | null = null;\n private _cachedNavItems: NavItem[] = [];\n private _servicesInjected = false;\n\n /**\n * Monotonically increasing counter used to detect and discard stale async results.\n *\n * Because GetNavItems() is async (HomeApplication does a DB lookup for record names),\n * and RxJS subscribe() does NOT serialize async callbacks, multiple calls to\n * updateCachedData() can overlap. Without this guard, a slow call (e.g., Home app\n * doing a DB lookup) that started BEFORE a fast call (e.g., switching to App B)\n * could resolve AFTER the fast call and overwrite the correct nav items with stale ones.\n *\n * How it works:\n * 1. Each updateCachedData() call increments this counter and captures it as `gen`\n * 2. After the await, it checks: does `gen` still match `_updateGeneration`?\n * 3. If not, a newer call started while we were waiting — discard our stale results\n */\n private _updateGeneration = 0;\n\n // Map of nav item key (Route or Label) to active state\n private activeStateMap = new Map<string, boolean>();\n\n // ---- Overflow (priority+) state ----\n /** Cached natural pixel width of each nav item, parallel to navItems order */\n private itemWidths: number[] = [];\n /** Measured width of the More button (fallback used until first render) */\n private moreBtnWidth = 120;\n /** Left offset (px, relative to host) where the More dropdown anchors */\n public MoreDropdownLeft = 0;\n /** True when even one item + More can't fit — the lone visible pill\n * shrinks with an ellipsis instead of clipping the More button. */\n public Tight = false;\n /** Flex gap between nav items — measured from the rendered row (falls back\n * to --mj-space-1's default of 4px until first measurement) */\n private itemGap = 4;\n /** How many leading nav items are currently visible inline */\n public VisibleCount = Number.MAX_SAFE_INTEGER;\n /** Whether the More dropdown is open */\n public MoreOpen = false;\n /** True while nav items are being (re)loaded for skeleton display */\n public Loading = false;\n\n private resizeObserver: ResizeObserver | null = null;\n private _overflowEnabled = true;\n\n @ViewChild('navList') private navListRef?: ElementRef<HTMLElement>;\n @ViewChild('moreBtn') private moreBtnRef?: ElementRef<HTMLElement>;\n @ViewChild('trailingSlot') private trailingSlotRef?: ElementRef<HTMLElement>;\n\n @Output() NavItemClick = new EventEmitter<NavItemClickEvent>();\n\n /**\n * @deprecated Use {@link NavItemClick}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (navItemClick) keeps working. Must stay AFTER NavItemClick: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() navItemClick = this.NavItemClick;\n @Output() NavItemDismiss = new EventEmitter<NavItem>();\n\n /**\n * @deprecated Use {@link NavItemDismiss}.\n *\n * The same emitter under the old binding name, so a template still binding\n * (navItemDismiss) keeps working. Must stay AFTER NavItemDismiss: class fields\n * initialise in order, and the other way round this captures undefined.\n */\n @Output() navItemDismiss = this.NavItemDismiss;\n\n /**\n * Disable the priority+ overflow behavior. Used by the mobile drawer instance,\n * where items stack vertically and can never overflow horizontally.\n */\n @Input()\n set OverflowEnabled(value: boolean) {\n this._overflowEnabled = value;\n if (!value) {\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n }\n }\n get OverflowEnabled(): boolean {\n return this._overflowEnabled;\n }\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef,\n private host: ElementRef<HTMLElement>\n ) {}\n\n /**\n * Input setter for app - triggers cache update when app changes\n */\n @Input()\n set app(value: BaseApplication | null) {\n if (this._app !== value) {\n this._app = value;\n this._cachedNavItems = []; // Clear stale items immediately so previous app's items don't flash\n this.activeStateMap.clear();\n this._servicesInjected = false; // Reset injection flag\n this.Loading = value != null; // Skeleton until GetNavItems resolves\n this.updateCachedData();\n this.cdr.markForCheck();\n }\n }\n\n get app(): BaseApplication | null {\n return this._app;\n }\n\n ngOnInit(): void {\n // Subscribe to workspace configuration changes.\n // Must rebuild nav items (not just active states) because dynamic nav items\n // are generated based on the currently active tab - when a user navigates\n // from one record to another (e.g., via OpenEntityRecord), the active tab\n // changes and the dynamic nav item needs to reflect the new record.\n this.workspaceManager.Configuration\n .pipe(takeUntil(this.destroy$))\n .subscribe(async () => {\n await this.updateCachedData();\n });\n }\n\n ngAfterViewInit(): void {\n if (this._overflowEnabled && typeof ResizeObserver !== 'undefined') {\n this.resizeObserver = new ResizeObserver(() => this.recomputeFit());\n this.resizeObserver.observe(this.host.nativeElement);\n }\n // Widths measured before webfonts arrive are stale (Explorer's Montserrat\n // loads late over the fallback stack) — invalidate the cache once fonts\n // settle so the fit is computed against real glyph metrics.\n if (this._overflowEnabled && typeof document !== 'undefined' && document.fonts?.ready) {\n document.fonts.ready.then(() => {\n this.itemWidths = [];\n this.recomputeFit();\n });\n }\n }\n\n ngOnDestroy(): void {\n this.resizeObserver?.disconnect();\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n /**\n * Update cached nav items and app color when app changes\n */\n private async updateCachedData(): Promise<void> {\n // Capture the current generation before any async work.\n // See _updateGeneration JSDoc for full explanation of the race condition this prevents.\n const gen = ++this._updateGeneration;\n\n if (this._app) {\n // Inject services once for apps that need them (e.g., HomeApplication for dynamic nav items)\n if (!this._servicesInjected) {\n const appWithServices = this._app as BaseApplication & {\n SetWorkspaceManager?: (manager: WorkspaceStateManager) => void;\n SetSharedService?: (service: SharedService) => void;\n };\n\n if (typeof appWithServices.SetWorkspaceManager === 'function') {\n appWithServices.SetWorkspaceManager(this.workspaceManager);\n }\n if (typeof appWithServices.SetSharedService === 'function') {\n appWithServices.SetSharedService(this.sharedService);\n }\n this._servicesInjected = true;\n }\n\n const items = await this._app.GetNavItems() || [];\n\n // If a newer call started while we were awaiting, our results are stale — bail out\n // so we don't overwrite the newer call's (correct) results.\n if (gen !== this._updateGeneration) {\n return;\n }\n\n // Only show items with Status 'Active' or undefined (default to Active)\n this._cachedNavItems = items.filter(item => !item.Status || item.Status === 'Active');\n } else {\n this._cachedNavItems = [];\n }\n\n this.Loading = false;\n\n // Update active states after nav items change\n const config = this.workspaceManager.GetConfiguration();\n this.updateActiveStates(config);\n\n // New item set: show everything for one frame so natural widths can be\n // measured (the row clips, so the temporary full row is invisible),\n // then collapse to fit. Tight mode MUST be off during measurement — its\n // flex-shrink would record squeezed widths and poison the fit arithmetic.\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n this.MoreOpen = false;\n this.Tight = false;\n this.syncChangeDetection();\n\n if (this._overflowEnabled) {\n requestAnimationFrame(() => {\n this.measureItemWidths();\n this.recomputeFit();\n });\n }\n }\n\n /**\n * Cache the natural width of every nav item. Called in the frame after a new\n * item set renders (all items visible, flex-shrink: 0, so widths are natural\n * even if the row is clipped by overflow: hidden).\n */\n private measureItemWidths(): void {\n const list = this.navListRef?.nativeElement;\n if (!list) {\n return;\n }\n const els = Array.from(list.querySelectorAll<HTMLElement>('.nav-item:not(.nav-more-btn)'));\n if (els.length !== this._cachedNavItems.length) {\n return; // View out of sync (mid-CD) — the next update cycle re-measures\n }\n this.itemWidths = els.map(el => el.offsetWidth);\n // Measure the real flex gap (rem-based tokens can differ from the 4px\n // fallback if the root font-size changes)\n const gap = parseFloat(getComputedStyle(list).columnGap);\n if (!Number.isNaN(gap)) {\n this.itemGap = gap;\n }\n }\n\n /**\n * Decide how many items fit in the host's current width; the rest collapse\n * into the More dropdown. Pure arithmetic over cached widths — safe to call\n * on every resize.\n */\n private recomputeFit(): void {\n if (!this._overflowEnabled || this._cachedNavItems.length === 0) {\n return;\n }\n const hostWidth = this.host.nativeElement.clientWidth;\n if (hostWidth === 0) {\n return; // Hidden (mobile breakpoint) — leave state alone\n }\n if (!this.ensureFreshWidthCache()) {\n return; // Cache still stale — a retry frame is already scheduled\n }\n if (this.moreBtnRef?.nativeElement) {\n this.moreBtnWidth = this.moreBtnRef.nativeElement.offsetWidth || this.moreBtnWidth;\n }\n // Reserve the trailing slot's width (projected shell items, e.g. the\n // Records pill) so nav items yield to More before painting under it.\n // Measured fresh each pass — the slot appears/disappears with open records,\n // and every such change arrives via a configuration$ emission that re-runs\n // this fit anyway.\n const trailingWidth = this.trailingSlotRef?.nativeElement?.offsetWidth ?? 0;\n const fit = this.computeFitCount(hostWidth - trailingWidth);\n this.applyFit(fit.count, fit.tight);\n }\n\n /**\n * Self-heal for the item-width cache: if it's stale or missing (the\n * measurement frame can race the first render after a reload/app switch),\n * expand to the full item set, re-measure, and retry next frame until it\n * converges. Returns true when the cache matches the current item set.\n */\n private ensureFreshWidthCache(): boolean {\n if (this.itemWidths.length === this._cachedNavItems.length) {\n return true;\n }\n if (this.VisibleCount < this._cachedNavItems.length || this.Tight) {\n this.VisibleCount = Number.MAX_SAFE_INTEGER;\n this.Tight = false; // Never measure with tight-mode shrink applied\n this.syncChangeDetection();\n }\n this.measureItemWidths();\n if (this.itemWidths.length !== this._cachedNavItems.length) {\n requestAnimationFrame(() => this.recomputeFit());\n return false;\n }\n return true;\n }\n\n /** Pure fit arithmetic: how many leading items fit beside the More button */\n private computeFitCount(hostWidth: number): { count: number; tight: boolean } {\n const gap = this.itemGap;\n const n = this.itemWidths.length;\n const totalAll = this.itemWidths.reduce((a, b) => a + b, 0) + gap * (n - 1);\n if (totalAll <= hostWidth) {\n return { count: Number.MAX_SAFE_INTEGER, tight: false }; // Everything fits\n }\n // Reserve room for the More button, then fit as many leading items as possible\n let used = this.moreBtnWidth;\n let fit = 0;\n for (let i = 0; i < n; i++) {\n const next = used + gap + this.itemWidths[i];\n if (next > hostWidth) {\n break;\n }\n used = next;\n fit++;\n }\n // Never collapse below one visible item; tight = even the lone item + More overflows\n return { count: Math.max(1, fit), tight: fit === 0 };\n }\n\n /** Commit a fit result, closing More if nothing overflows; CD only on change */\n private applyFit(count: number, tight: boolean): void {\n if (count === this.VisibleCount && tight === this.Tight) {\n return;\n }\n this.VisibleCount = count;\n this.Tight = tight;\n if (this.OverflowItems.length === 0) {\n this.MoreOpen = false;\n }\n this.syncChangeDetection();\n }\n\n /**\n * markForCheck + synchronous detectChanges. In Angular 21 zoneless mode,\n * markForCheck() alone is unreliable when the trigger is an RxJS\n * subscription or rAF callback not tracked by the zoneless scheduler — the\n * dirty flag is set but no follow-up tick is scheduled. detectChanges()\n * throws if invoked re-entrantly during an in-flight CD pass; that's\n * harmless (the in-flight pass picks up our markForCheck), hence the catch.\n */\n private syncChangeDetection(): void {\n this.cdr.markForCheck();\n try {\n this.cdr.detectChanges();\n } catch {\n // Re-entrant CD — harmless.\n }\n }\n\n /** Items rendered inline in the header row */\n get InlineItems(): NavItem[] {\n return this._cachedNavItems.slice(0, this.VisibleCount);\n }\n\n /** Items collapsed into the More dropdown */\n get OverflowItems(): NavItem[] {\n return this.VisibleCount >= this._cachedNavItems.length\n ? []\n : this._cachedNavItems.slice(this.VisibleCount);\n }\n\n /** True when any overflowed item is the active one (More button shows active tint) */\n get OverflowHasActive(): boolean {\n return this.OverflowItems.some(item => this.IsActive(item));\n }\n\n /** Open/close the More dropdown, anchoring it under the More button and clamping it inside the host */\n ToggleMore(event: MouseEvent): void {\n event.stopPropagation();\n this.MoreOpen = !this.MoreOpen;\n if (this.MoreOpen) {\n // Anchor the dropdown under the More button; once the dropdown has\n // rendered, clamp it so its right edge stays inside the host.\n this.MoreDropdownLeft = this.moreBtnRef?.nativeElement?.offsetLeft ?? 0;\n requestAnimationFrame(() => {\n const dropdown = this.host.nativeElement.querySelector<HTMLElement>('.nav-more-dropdown');\n if (dropdown) {\n const maxLeft = this.host.nativeElement.clientWidth - dropdown.offsetWidth;\n this.MoreDropdownLeft = Math.max(0, Math.min(this.MoreDropdownLeft, maxLeft));\n this.cdr.markForCheck();\n try {\n this.cdr.detectChanges();\n } catch {\n // Re-entrant CD — harmless.\n }\n }\n });\n }\n this.cdr.markForCheck();\n }\n\n /** Close the More dropdown on any outside click or Escape */\n @HostListener('document:click', ['$event'])\n onDocumentClick(event: MouseEvent): void {\n if (this.MoreOpen && !this.host.nativeElement.contains(event.target as Node)) {\n this.MoreOpen = false;\n this.cdr.markForCheck();\n }\n }\n\n /** Close the More dropdown on Escape */\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.MoreOpen) {\n this.MoreOpen = false;\n this.cdr.markForCheck();\n }\n }\n\n /**\n * Update active state map based on current workspace configuration\n */\n private updateActiveStates(config: WorkspaceConfiguration | null): void {\n this.activeStateMap.clear();\n\n if (!config || !this._app) {\n return;\n }\n\n const activeTab = config.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || activeTab.applicationId !== this._app.ID) {\n return;\n }\n\n // Compute active state for each nav item once\n for (const item of this._cachedNavItems) {\n const key = this.getItemKey(item);\n const isActive = this.computeIsActive(item, activeTab);\n this.activeStateMap.set(key, isActive);\n }\n }\n\n /**\n * Get unique key for nav item (used for tracking and active state).\n * Prefers RecordID for dynamic items to avoid label collisions.\n */\n private getItemKey(item: NavItem): string {\n return item.RecordID || item.Route || item.Label || '';\n }\n\n /**\n * Check if a nav item is dynamic (generated from recent orphan resources)\n */\n IsDynamic(item: NavItem): boolean {\n return (item as DynamicNavItem).isDynamic === true;\n }\n\n /** @deprecated Use {@link IsDynamic}. */\n isDynamic(item: NavItem): boolean {\n return this.IsDynamic(item);\n }\n\n /**\n * Compute if nav item is active based on active tab\n */\n private computeIsActive(item: NavItem, activeTab: any): boolean {\n // Check if nav item has a custom matching function (for dynamic items)\n const dynamicItem = item as NavItem & { isActiveMatch?: (tab: unknown) => boolean };\n if (dynamicItem.isActiveMatch && typeof dynamicItem.isActiveMatch === 'function') {\n return dynamicItem.isActiveMatch(activeTab);\n }\n\n const config = activeTab.configuration || {};\n\n // Match by DriverClass (most reliable for Custom resource types — always set correctly)\n if (item.DriverClass && (config['driverClass'] === item.DriverClass || config['resourceTypeDriverClass'] === item.DriverClass)) {\n return true;\n }\n\n // Match by navItemName from config (reliable — set when nav item opens)\n if (config['navItemName'] && config['navItemName'] === item.Label) {\n return true;\n }\n\n // Match by route (for route-based nav items)\n if (item.Route && config['route'] === item.Route) {\n return true;\n }\n\n // NOTE: We intentionally do NOT match by activeTab.title here.\n // Tab titles can be stale (updated asynchronously by DisplayNameChangedEvent\n // from cached components) and cause double-matches where two nav items\n // both appear active. DriverClass and navItemName are sufficient.\n return false;\n }\n\n /**\n * Get cached navigation items (no computation in getter)\n */\n get NavItems(): NavItem[] {\n return this._cachedNavItems;\n }\n\n /** @deprecated Use {@link NavItems}. */\n get navItems(): NavItem[] {\n return this.NavItems;\n }\n\n /**\n * Check if nav item is active (uses cached state from Map)\n */\n IsActive(item: NavItem): boolean {\n const key = this.getItemKey(item);\n return this.activeStateMap.get(key) || false;\n }\n\n /** @deprecated Use {@link IsActive}. */\n isActive(item: NavItem): boolean {\n return this.IsActive(item);\n }\n\n /**\n * Track function for @for to optimize rendering\n */\n TrackByNavItem(_index: number, item: NavItem): string {\n return this.getItemKey(item);\n }\n\n /** @deprecated Use {@link TrackByNavItem}. */\n trackByNavItem(_index: number, item: NavItem): string {\n return this.TrackByNavItem(_index, item);\n }\n\n /**\n * Handle nav item click\n */\n OnNavClick(item: NavItem, event?: MouseEvent): void {\n this.MoreOpen = false;\n this.NavItemClick.emit({\n item,\n shiftKey: event?.shiftKey || false\n });\n }\n\n /** @deprecated Use {@link OnNavClick}. */\n onNavClick(item: NavItem, event?: MouseEvent): void {\n return this.OnNavClick(item, event);\n }\n\n /**\n * Handle dismiss click on a dynamic nav item.\n * Removes from the app's recent stack and refreshes nav items immediately.\n * Stops propagation so the nav click handler doesn't fire.\n */\n OnDismiss(item: NavItem, event: MouseEvent): void {\n event.stopPropagation();\n\n // Remove from the app's recent stack directly so we can refresh immediately\n if (this._app) {\n const appWithRemove = this._app as BaseApplication & {\n RemoveDynamicNavItem?: (navItem: NavItem) => void;\n };\n if (typeof appWithRemove.RemoveDynamicNavItem === 'function') {\n appWithRemove.RemoveDynamicNavItem(item);\n this.updateCachedData();\n }\n }\n\n this.NavItemDismiss.emit(item);\n }\n\n /** @deprecated Use {@link OnDismiss}. */\n onDismiss(item: NavItem, event: MouseEvent): void {\n return this.OnDismiss(item, event);\n }\n\n}\n","<nav class=\"nav-list\" #navList [class.tight]=\"Tight\">\n @if (Loading && navItems.length === 0) {\n <!-- Skeleton pills while GetNavItems() resolves — prevents header pop-in -->\n <div class=\"nav-skeleton\" aria-hidden=\"true\">\n <span class=\"nav-skeleton-pill\" style=\"width: 88px\"></span>\n <span class=\"nav-skeleton-pill\" style=\"width: 72px\"></span>\n <span class=\"nav-skeleton-pill\" style=\"width: 96px\"></span>\n </div>\n }\n @for (item of InlineItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-item\"\n [mjClickable]=\"item.Label\"\n role=\"link\"\n [testId]=\"'nav-item-' + item.Label\"\n [attr.aria-current]=\"isActive(item) ? 'page' : null\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n [class.no-icon]=\"!item.Icon\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span>{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n @if (OverflowItems.length > 0) {\n <div\n #moreBtn\n class=\"nav-item nav-more-btn\"\n mjClickable=\"More navigation items\"\n testId=\"nav-more-btn\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"MoreOpen\"\n [class.active]=\"OverflowHasActive\"\n (click)=\"ToggleMore($event)\">\n <i class=\"fa-solid fa-ellipsis\"></i>\n <span>More</span>\n <span class=\"more-count\">{{ OverflowItems.length }}</span>\n </div>\n }\n <!-- Trailing slot: shell-level items that sit AFTER the app's own nav\n (the Records pill). Its width is reserved by\n recomputeFit so the priority+ arithmetic never lets nav items paint\n under it. -->\n <span class=\"nav-trailing\" #trailingSlot>\n <ng-content></ng-content>\n </span>\n</nav>\n\n<!-- The dropdown lives OUTSIDE the clipped nav row (the row keeps\n overflow: hidden so fit-arithmetic slack can never paint over the\n header's action cluster). Anchored to the More button by measurement. -->\n@if (MoreOpen && OverflowItems.length > 0) {\n <div class=\"nav-more-dropdown\" [style.left.px]=\"MoreDropdownLeft\">\n @for (item of OverflowItems; track trackByNavItem($index, item)) {\n <div\n class=\"nav-more-item\"\n [mjClickable]=\"item.Label\"\n role=\"link\"\n [testId]=\"'nav-more-item-' + item.Label\"\n [attr.aria-current]=\"isActive(item) ? 'page' : null\"\n [class.active]=\"isActive(item)\"\n [class.dynamic]=\"isDynamic(item)\"\n (click)=\"onNavClick(item, $event)\">\n @if (item.Icon) {\n <i [class]=\"item.Icon\"></i>\n }\n <span class=\"more-item-label\">{{ item.Label }}</span>\n @if (item.Badge) {\n <span class=\"badge\">{{ item.Badge }}</span>\n }\n @if (isDynamic(item)) {\n <button class=\"dismiss-btn\" title=\"Remove\" (click)=\"onDismiss(item, $event)\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n }\n </div>\n}\n"]}
|
|
@@ -35,18 +35,42 @@ export declare class AppSwitcherComponent extends BaseAngularComponent implement
|
|
|
35
35
|
private appManager;
|
|
36
36
|
private cdr;
|
|
37
37
|
private destroy$;
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
ActiveApp: BaseApplication | null;
|
|
39
|
+
/** @deprecated Use {@link ActiveApp}. */
|
|
40
|
+
set activeApp(value: BaseApplication | null);
|
|
41
|
+
/** @deprecated Use {@link ActiveApp}. */
|
|
42
|
+
get activeApp(): BaseApplication | null;
|
|
43
|
+
IsViewingSystemTab: boolean;
|
|
44
|
+
/** @deprecated Use {@link IsViewingSystemTab}. */
|
|
45
|
+
set isViewingSystemTab(value: AppSwitcherComponent['IsViewingSystemTab']);
|
|
46
|
+
/** @deprecated Use {@link IsViewingSystemTab}. */
|
|
47
|
+
get isViewingSystemTab(): AppSwitcherComponent['IsViewingSystemTab'];
|
|
40
48
|
/** ID of the app currently being loaded (shows loading indicator) */
|
|
41
|
-
|
|
49
|
+
LoadingAppId: string | null;
|
|
50
|
+
/** @deprecated Use {@link LoadingAppId}. */
|
|
51
|
+
set loadingAppId(value: string | null);
|
|
52
|
+
/** @deprecated Use {@link LoadingAppId}. */
|
|
53
|
+
get loadingAppId(): string | null;
|
|
42
54
|
/** Presentation style (from Shell.AppSwitcher.Style instance config) */
|
|
43
55
|
SwitcherStyle: AppSwitcherStyle;
|
|
56
|
+
AppSelected: EventEmitter<string>;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated Use {@link AppSelected}.
|
|
59
|
+
*
|
|
60
|
+
* The same emitter under the old binding name, so a template still binding
|
|
61
|
+
* (appSelected) keeps working. Must stay AFTER AppSelected: class fields
|
|
62
|
+
* initialise in order, and the other way round this captures undefined.
|
|
63
|
+
*/
|
|
44
64
|
appSelected: EventEmitter<string>;
|
|
45
65
|
private filterInputRef?;
|
|
46
66
|
private triggerRef?;
|
|
47
67
|
private panelRef?;
|
|
48
68
|
private configContent?;
|
|
49
|
-
|
|
69
|
+
ShowDropdown: boolean;
|
|
70
|
+
/** @deprecated Use {@link ShowDropdown}. */
|
|
71
|
+
get showDropdown(): boolean;
|
|
72
|
+
/** @deprecated Use {@link ShowDropdown}. */
|
|
73
|
+
set showDropdown(value: boolean);
|
|
50
74
|
/** When true, the launcher body shows the app-configuration view instead of the card grid */
|
|
51
75
|
ConfigMode: boolean;
|
|
52
76
|
/** Pending action awaiting the inline unsaved-changes discard bar ('exit' = back to grid, 'close' = close launcher) */
|
|
@@ -97,6 +121,8 @@ export declare class AppSwitcherComponent extends BaseAngularComponent implement
|
|
|
97
121
|
* Get applications that should appear in the app switcher
|
|
98
122
|
* (NavigationStyle = 'App Switcher' or 'Both')
|
|
99
123
|
*/
|
|
124
|
+
get Apps(): BaseApplication[];
|
|
125
|
+
/** @deprecated Use {@link Apps}. */
|
|
100
126
|
get apps(): BaseApplication[];
|
|
101
127
|
/** Recently-used apps (persisted per user), newest first, capped for display.
|
|
102
128
|
* Compact mode skips the Recent section — with a handful of apps it's noise. */
|
|
@@ -162,6 +188,8 @@ export declare class AppSwitcherComponent extends BaseAngularComponent implement
|
|
|
162
188
|
* Select an application.
|
|
163
189
|
* When viewing a system tab, always emit to allow returning to the app.
|
|
164
190
|
*/
|
|
191
|
+
SelectApp(app: BaseApplication): void;
|
|
192
|
+
/** @deprecated Use {@link SelectApp}. */
|
|
165
193
|
selectApp(app: BaseApplication): void;
|
|
166
194
|
/** Case-insensitive UUID check whether an app is the currently active app. */
|
|
167
195
|
IsActiveApp(app: BaseApplication): boolean;
|
|
@@ -187,6 +215,6 @@ export declare class AppSwitcherComponent extends BaseAngularComponent implement
|
|
|
187
215
|
*/
|
|
188
216
|
ExitConfigMode(): void;
|
|
189
217
|
static ɵfac: i0.ɵɵFactoryDeclaration<AppSwitcherComponent, never>;
|
|
190
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<AppSwitcherComponent, "mj-app-switcher", never, { "activeApp": { "alias": "activeApp"; "required": false; }; "isViewingSystemTab": { "alias": "isViewingSystemTab"; "required": false; }; "loadingAppId": { "alias": "loadingAppId"; "required": false; }; "SwitcherStyle": { "alias": "SwitcherStyle"; "required": false; }; }, { "appSelected": "appSelected"; }, never, never, false, never>;
|
|
218
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<AppSwitcherComponent, "mj-app-switcher", never, { "ActiveApp": { "alias": "ActiveApp"; "required": false; }; "activeApp": { "alias": "activeApp"; "required": false; }; "IsViewingSystemTab": { "alias": "IsViewingSystemTab"; "required": false; }; "isViewingSystemTab": { "alias": "isViewingSystemTab"; "required": false; }; "LoadingAppId": { "alias": "LoadingAppId"; "required": false; }; "loadingAppId": { "alias": "loadingAppId"; "required": false; }; "SwitcherStyle": { "alias": "SwitcherStyle"; "required": false; }; }, { "AppSelected": "AppSelected"; "appSelected": "appSelected"; }, never, never, false, never>;
|
|
191
219
|
}
|
|
192
220
|
//# sourceMappingURL=app-switcher.component.d.ts.map
|