@memberjunction/ng-explorer-core 5.30.1 → 5.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/dist/app-routing.module.d.ts +9 -0
  2. package/dist/app-routing.module.d.ts.map +1 -1
  3. package/dist/app-routing.module.js +13 -1
  4. package/dist/app-routing.module.js.map +1 -1
  5. package/dist/generated/lazy-feature-config.d.ts +1 -1
  6. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  7. package/dist/generated/lazy-feature-config.js +5 -3
  8. package/dist/generated/lazy-feature-config.js.map +1 -1
  9. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts +2 -1
  10. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.d.ts.map +1 -1
  11. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +12 -11
  12. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  13. package/dist/lib/guards/entities.guard.d.ts +2 -1
  14. package/dist/lib/guards/entities.guard.d.ts.map +1 -1
  15. package/dist/lib/guards/entities.guard.js +14 -1
  16. package/dist/lib/guards/entities.guard.js.map +1 -1
  17. package/dist/lib/oauth/oauth-callback.component.d.ts +2 -1
  18. package/dist/lib/oauth/oauth-callback.component.d.ts.map +1 -1
  19. package/dist/lib/oauth/oauth-callback.component.js +7 -6
  20. package/dist/lib/oauth/oauth-callback.component.js.map +1 -1
  21. package/dist/lib/resource-wrappers/artifact-resource.component.js +2 -3
  22. package/dist/lib/resource-wrappers/artifact-resource.component.js.map +1 -1
  23. package/dist/lib/resource-wrappers/chat-collections-resource.component.js +3 -3
  24. package/dist/lib/resource-wrappers/chat-collections-resource.component.js.map +1 -1
  25. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +4 -4
  26. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  27. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js +1 -2
  28. package/dist/lib/resource-wrappers/chat-tasks-resource.component.js.map +1 -1
  29. package/dist/lib/resource-wrappers/dashboard-resource.component.js +5 -5
  30. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  31. package/dist/lib/resource-wrappers/list-detail-resource.component.js +2 -2
  32. package/dist/lib/resource-wrappers/list-detail-resource.component.js.map +1 -1
  33. package/dist/lib/resource-wrappers/query-resource.component.js +2 -2
  34. package/dist/lib/resource-wrappers/query-resource.component.js.map +1 -1
  35. package/dist/lib/resource-wrappers/record-resource.component.d.ts +2 -2
  36. package/dist/lib/resource-wrappers/record-resource.component.d.ts.map +1 -1
  37. package/dist/lib/resource-wrappers/record-resource.component.js +8 -7
  38. package/dist/lib/resource-wrappers/record-resource.component.js.map +1 -1
  39. package/dist/lib/resource-wrappers/search-results-resource.component.js +3 -3
  40. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  41. package/dist/lib/resource-wrappers/view-resource.component.d.ts +1 -1
  42. package/dist/lib/resource-wrappers/view-resource.component.d.ts.map +1 -1
  43. package/dist/lib/resource-wrappers/view-resource.component.js +3 -3
  44. package/dist/lib/resource-wrappers/view-resource.component.js.map +1 -1
  45. package/dist/lib/services/startup-validation.service.d.ts +9 -0
  46. package/dist/lib/services/startup-validation.service.d.ts.map +1 -1
  47. package/dist/lib/services/startup-validation.service.js +13 -1
  48. package/dist/lib/services/startup-validation.service.js.map +1 -1
  49. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +2 -1
  50. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  51. package/dist/lib/shell/components/tabs/tab-container.component.js +7 -5
  52. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  53. package/dist/lib/shell/shell.component.d.ts +5 -2
  54. package/dist/lib/shell/shell.component.d.ts.map +1 -1
  55. package/dist/lib/shell/shell.component.js +43 -27
  56. package/dist/lib/shell/shell.component.js.map +1 -1
  57. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts +3 -2
  58. package/dist/lib/single-dashboard/Components/add-item/add-item.component.d.ts.map +1 -1
  59. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +8 -6
  60. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  61. package/dist/lib/single-dashboard/single-dashboard.component.js +1 -2
  62. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  63. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +2 -1
  64. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  65. package/dist/lib/single-list-detail/single-list-detail.component.js +18 -16
  66. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  67. package/dist/lib/single-record/single-record.component.d.ts +2 -1
  68. package/dist/lib/single-record/single-record.component.d.ts.map +1 -1
  69. package/dist/lib/single-record/single-record.component.js +7 -5
  70. package/dist/lib/single-record/single-record.component.js.map +1 -1
  71. package/dist/lib/single-search-result/single-search-result.component.d.ts +2 -1
  72. package/dist/lib/single-search-result/single-search-result.component.d.ts.map +1 -1
  73. package/dist/lib/single-search-result/single-search-result.component.js +8 -6
  74. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  75. package/dist/lib/user-notifications/user-notifications.component.d.ts +2 -1
  76. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  77. package/dist/lib/user-notifications/user-notifications.component.js +9 -7
  78. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  79. package/dist/lib/user-profile/user-profile.component.d.ts +2 -1
  80. package/dist/lib/user-profile/user-profile.component.d.ts.map +1 -1
  81. package/dist/lib/user-profile/user-profile.component.js +6 -5
  82. package/dist/lib/user-profile/user-profile.component.js.map +1 -1
  83. package/package.json +42 -41
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-preferences-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.ts","../../../src/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\nimport { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';\nimport { LogError, Metadata, RunView } from '@memberjunction/core';\nimport { MJDashboardEntityExtended, MJDashboardUserPreferenceEntity, MJApplicationEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nexport interface DashboardPreferencesResult {\n saved: boolean;\n preferences?: MJDashboardUserPreferenceEntity[];\n}\n\n@Component({\n standalone: false,\n selector: 'mj-dashboard-preferences-dialog',\n templateUrl: './dashboard-preferences-dialog.component.html',\n styleUrls: ['./dashboard-preferences-dialog.component.css']\n})\nexport class DashboardPreferencesDialogComponent implements OnInit {\n @Input() public applicationId: string | null = null;\n @Input() public scope: 'Global' | 'App' = 'Global';\n @Output() public result = new EventEmitter<DashboardPreferencesResult>();\n\n public availableDashboards: MJDashboardEntityExtended[] = [];\n public configuredDashboards: MJDashboardEntityExtended[] = [];\n public applicationName: string = '';\n public loading: boolean = true;\n public saving: boolean = false;\n public error: string | null = null;\n public hasChanges: boolean = false;\n public isSysAdmin: boolean = false;\n public preferenceMode: 'personal' | 'system' = 'personal';\n\n private originalConfiguredIds: string[] = [];\n private currentUserPreferences: MJDashboardUserPreferenceEntity[] = [];\n private allAvailableDashboards: MJDashboardEntityExtended[] = [];\n\n async ngOnInit(): Promise<void> {\n try {\n await this.loadData();\n } catch (error) {\n LogError('Error initializing dashboard preferences dialog', null, error);\n this.error = 'Failed to load dashboard preferences';\n } finally {\n this.loading = false;\n }\n }\n\n private async loadData(): Promise<void> {\n const md = new Metadata();\n \n // Check if current user is sysadmin\n this.isSysAdmin = md.CurrentUser.Type.trim().toLowerCase() === 'owner';\n console.log('User is sysadmin:', this.isSysAdmin);\n \n // Default to personal preferences for all users (including sysadmin)\n this.preferenceMode = 'personal';\n \n // Load application name if we're in app scope\n if (this.scope === 'App' && this.applicationId) {\n await this.loadApplicationName();\n }\n\n // Get cached dashboards from MJ_Metadata dataset\n const ds = await md.GetAndCacheDatasetByName(\"MJ_Metadata\");\n if (!ds || !ds.Success) {\n throw new Error(ds?.Status || 'Failed to load metadata dataset');\n }\n\n const dashList = ds.Results.find(r => r.Code === 'Dashboards');\n if (!dashList) {\n throw new Error('Dashboards dataset not found');\n }\n\n // Filter dashboards by scope\n const appFilter = this.applicationId ? ` AND ApplicationID='${this.applicationId}'` : ' AND ApplicationID IS NULL';\n this.allAvailableDashboards = dashList.Results.filter((d: MJDashboardEntityExtended) => {\n if (this.scope === 'Global') {\n return d.Scope === 'Global' && !d.ApplicationID;\n } else {\n return UUIDsEqual(d.ApplicationID, this.applicationId) // ignore scope for dashboards that match app id, sometimes they have a global scope as they can be shown globally as well as app specific\n }\n });\n\n // Load current user preferences\n await this.loadCurrentPreferences();\n \n // Split dashboards into available and configured\n this.splitDashboards();\n \n // Store original state to detect changes\n this.originalConfiguredIds = this.configuredDashboards.map(d => d.ID);\n }\n\n private async loadApplicationName(): Promise<void> {\n if (!this.applicationId) return;\n \n try {\n const md = new Metadata();\n const ds = await md.GetAndCacheDatasetByName(\"MJ_Metadata\");\n const appList = ds.Results.find(r => r.Code === 'Applications');\n if (appList) {\n const app = appList.Results.find((a: MJApplicationEntity) => UUIDsEqual(a.ID, this.applicationId));\n this.applicationName = app?.Name || 'Unknown Application';\n }\n } catch (error) {\n LogError('Error loading application name', null, error);\n this.applicationName = 'Unknown Application';\n }\n }\n\n private async loadCurrentPreferences(): Promise<void> {\n const rv = new RunView();\n const md = new Metadata();\n \n const appFilter = this.applicationId ? ` AND ApplicationID='${this.applicationId}'` : '';\n const baseCondition = `Scope='${this.scope}'${appFilter}`;\n \n let filter: string;\n \n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n // Load system defaults only (UserID IS NULL)\n filter = `UserID IS NULL AND ${baseCondition}`;\n } else {\n // Load personal user preferences (including for sysadmin when in personal mode)\n // For personal mode, we ONLY load the user's specific preferences, no fallback to system defaults\n // This allows sysadmin to see their actual personal preferences vs system defaults\n filter = `UserID='${md.CurrentUser.ID}' AND ${baseCondition}`;\n }\n\n console.log('Loading preferences with filter:', filter);\n\n const prefsResult = await rv.RunView<MJDashboardUserPreferenceEntity>({\n EntityName: 'MJ: Dashboard User Preferences',\n ExtraFilter: filter,\n ResultType: 'entity_object',\n OrderBy: 'DisplayOrder',\n });\n\n this.currentUserPreferences = prefsResult?.Results || [];\n console.log('Loaded preferences:', this.currentUserPreferences.length);\n }\n\n private splitDashboards(): void {\n const configuredIds = new Set(this.currentUserPreferences.map(p => p.DashboardID));\n \n // Get configured dashboards in the right order\n this.configuredDashboards = this.currentUserPreferences\n .map(pref => this.allAvailableDashboards.find(d => UUIDsEqual(d.ID, pref.DashboardID)))\n .filter((d): d is MJDashboardEntityExtended => d !== undefined);\n \n // Get available dashboards (not configured)\n this.availableDashboards = this.allAvailableDashboards\n .filter(d => !configuredIds.has(d.ID))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n }\n\n public onDrop(event: CdkDragDrop<MJDashboardEntityExtended[]>): void {\n try {\n if (event.previousContainer === event.container) {\n // Reordering within the same list\n moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);\n } else {\n // Moving between lists\n transferArrayItem(\n event.previousContainer.data,\n event.container.data,\n event.previousIndex,\n event.currentIndex\n );\n \n // If moving to configured dashboards, sort the available list\n if (event.container.data === this.configuredDashboards) {\n this.availableDashboards.sort((a, b) => a.Name.localeCompare(b.Name));\n }\n }\n \n this.checkForChanges();\n } catch (error) {\n LogError('Error in drag drop operation', null, error);\n this.error = 'Error reordering dashboards. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public addDashboard(dashboard: MJDashboardEntityExtended): void {\n try {\n const index = this.availableDashboards.findIndex(d => UUIDsEqual(d.ID, dashboard.ID));\n if (index !== -1) {\n this.availableDashboards.splice(index, 1);\n this.configuredDashboards.push(dashboard);\n this.checkForChanges();\n }\n } catch (error) {\n LogError('Error adding dashboard', null, error);\n this.error = 'Error adding dashboard. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public removeDashboard(dashboard: MJDashboardEntityExtended): void {\n try {\n const index = this.configuredDashboards.findIndex(d => UUIDsEqual(d.ID, dashboard.ID));\n if (index !== -1) {\n this.configuredDashboards.splice(index, 1);\n this.availableDashboards.push(dashboard);\n this.availableDashboards.sort((a, b) => a.Name.localeCompare(b.Name));\n this.checkForChanges();\n }\n } catch (error) {\n LogError('Error removing dashboard', null, error);\n this.error = 'Error removing dashboard. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public async onPreferenceModeChange(): Promise<void> {\n try {\n this.loading = true;\n this.error = null;\n \n // Reload preferences with new mode\n await this.loadCurrentPreferences();\n this.splitDashboards();\n this.originalConfiguredIds = this.configuredDashboards.map(d => d.ID);\n this.hasChanges = false;\n \n } catch (error) {\n LogError('Error changing preference mode', null, error);\n this.error = 'Error loading preferences. Please try again.';\n } finally {\n this.loading = false;\n }\n }\n\n private checkForChanges(): void {\n try {\n const currentConfiguredIds = this.configuredDashboards.map(d => d.ID);\n \n // Check if the order or selection has changed\n this.hasChanges = currentConfiguredIds.length !== this.originalConfiguredIds.length ||\n currentConfiguredIds.some((id, index) => id !== this.originalConfiguredIds[index]);\n \n // Debug logging\n console.log('Dashboard preferences change check:', {\n original: this.originalConfiguredIds,\n current: currentConfiguredIds,\n hasChanges: this.hasChanges\n });\n } catch (error) {\n LogError('Error checking for changes', null, error);\n this.hasChanges = false;\n }\n }\n\n public async onSave(): Promise<void> {\n if (this.saving || !this.hasChanges) {\n console.log('Save cancelled:', { saving: this.saving, hasChanges: this.hasChanges });\n return;\n }\n\n try {\n this.saving = true;\n console.log('Starting save process with configured dashboards:', this.configuredDashboards.map(d => ({ id: d.ID, name: d.Name })));\n \n const md = new Metadata();\n const rv = new RunView();\n\n // Get existing preferences for this scope\n const baseCondition = this.scope === 'Global' \n ? `Scope='Global' AND ApplicationID IS NULL`\n : `Scope='App' AND ApplicationID='${this.applicationId}'`;\n \n let userFilter: string;\n \n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n // Managing system defaults\n userFilter = `UserID IS NULL AND ${baseCondition}`;\n } else {\n // Managing personal preferences\n userFilter = `UserID='${md.CurrentUser.ID}' AND ${baseCondition}`;\n }\n \n console.log('Loading existing preferences with filter:', userFilter);\n \n const existingPrefs = await rv.RunView<MJDashboardUserPreferenceEntity>({\n EntityName: 'MJ: Dashboard User Preferences',\n ExtraFilter: userFilter,\n ResultType: 'entity_object',\n });\n\n const existingPreferences = existingPrefs?.Results || [];\n console.log('Found existing preferences:', existingPreferences.length);\n\n // Create maps for efficient lookups\n const existingByDashboardId = new Map<string, MJDashboardUserPreferenceEntity>();\n existingPreferences.forEach(pref => {\n existingByDashboardId.set(pref.DashboardID, pref);\n });\n\n const configuredDashboardIds = new Set(this.configuredDashboards.map(d => d.ID));\n\n // Step 1: Delete preferences that are no longer configured\n const prefsToDelete = existingPreferences.filter(pref => !configuredDashboardIds.has(pref.DashboardID));\n console.log('Preferences to delete:', prefsToDelete.length);\n \n for (const pref of prefsToDelete) {\n console.log('Deleting preference for dashboard:', pref.DashboardID);\n if (!await pref.Delete()) {\n const errorMsg = pref.LatestResult?.Error || pref.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to delete preference: ${errorMsg}`);\n }\n }\n\n // Step 2: Update existing preferences or create new ones\n const newPreferences: MJDashboardUserPreferenceEntity[] = [];\n \n for (let i = 0; i < this.configuredDashboards.length; i++) {\n const dashboard = this.configuredDashboards[i];\n const newDisplayOrder = i + 1;\n \n let prefEntity = existingByDashboardId.get(dashboard.ID);\n \n if (prefEntity) {\n // Update existing preference\n console.log(`Updating existing preference for dashboard ${dashboard.Name}, new order: ${newDisplayOrder}`);\n prefEntity.DisplayOrder = newDisplayOrder;\n \n if (!await prefEntity.Save()) {\n const errorMsg = prefEntity.LatestResult?.Error || prefEntity.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to update preference for dashboard ${dashboard.Name}: ${errorMsg}`);\n }\n } else {\n // Create new preference\n console.log(`Creating new preference for dashboard ${dashboard.Name}, order: ${newDisplayOrder}`);\n prefEntity = await md.GetEntityObject<MJDashboardUserPreferenceEntity>('MJ: Dashboard User Preferences');\n \n // Set UserID based on preference mode\n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n prefEntity.UserID = null; // System default\n } else {\n prefEntity.UserID = md.CurrentUser.ID; // Personal preference\n }\n \n prefEntity.DashboardID = dashboard.ID;\n prefEntity.DisplayOrder = newDisplayOrder;\n prefEntity.Scope = this.scope;\n prefEntity.ApplicationID = this.applicationId;\n\n console.log('Creating preference entity:', {\n UserID: prefEntity.UserID,\n DashboardID: prefEntity.DashboardID,\n DisplayOrder: prefEntity.DisplayOrder,\n Scope: prefEntity.Scope,\n ApplicationID: prefEntity.ApplicationID\n });\n\n if (!await prefEntity.Save()) {\n const errorMsg = prefEntity.LatestResult?.Error || prefEntity.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to create preference for dashboard ${dashboard.Name}: ${errorMsg}`);\n }\n }\n \n newPreferences.push(prefEntity);\n }\n\n console.log('Successfully processed', newPreferences.length, 'preferences');\n\n // Emit success result\n this.result.emit({\n saved: true,\n preferences: newPreferences\n });\n\n } catch (error) {\n console.error('Save error:', error);\n LogError('Error saving dashboard preferences', null, error);\n this.error = `Failed to save preferences: ${error instanceof Error ? error.message : 'Unknown error'}`;\n \n // Clear error after 5 seconds\n setTimeout(() => {\n this.error = null;\n }, 5000);\n } finally {\n this.saving = false;\n }\n }\n\n public onCancel(): void {\n this.result.emit({ saved: false });\n }\n}","<mj-dialog [Visible]=\"true\" Title=\"Dashboard Preferences\"\n [Width]=\"800\"\n [Height]=\"600\"\n [MinWidth]=\"600\"\n (Close)=\"onCancel()\">\n<div class=\"dashboard-preferences-dialog\">\n <div class=\"dialog-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Dashboard Preferences</h3>\n <p class=\"scope-indicator\">\n @if (scope === 'Global') {\n <i class=\"fa-solid fa-globe\"></i> Global Scope\n } @else {\n <i class=\"fa-solid fa-layer-group\"></i> Application: {{ applicationName }}\n }\n </p>\n @if (isSysAdmin && scope === 'Global') {\n <div class=\"preference-mode-selector\">\n <label>\n <input type=\"radio\"\n name=\"preferenceMode\"\n value=\"personal\"\n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n Personal Preferences\n </label>\n <label>\n <input type=\"radio\"\n name=\"preferenceMode\"\n value=\"system\"\n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n System Defaults\n </label>\n </div>\n }\n </div>\n\n <div class=\"dialog-content\">\n @if (loading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading preferences...\" size=\"large\"></mj-loading>\n </div>\n }\n\n @if (error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </div>\n }\n\n @if (!loading && !error) {\n <div class=\"preferences-panels\">\n <!-- Available Dashboards Panel -->\n <div class=\"panel available-panel\">\n <h4><i class=\"fa-solid fa-list\"></i> Available Dashboards</h4>\n <div class=\"dashboard-list\"\n cdkDropList\n #availableList=\"cdkDropList\"\n [cdkDropListData]=\"availableDashboards\"\n [cdkDropListConnectedTo]=\"[configuredList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n\n @if (availableDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n All dashboards are configured\n </div>\n }\n\n @for (dashboard of availableDashboards; track dashboard.ID) {\n <div class=\"dashboard-item available-item\"\n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\"\n class=\"add-button\"\n (click)=\"addDashboard(dashboard)\"\n title=\"Add to configured dashboards\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Configured Dashboards Panel -->\n <div class=\"panel configured-panel\">\n <h4><i class=\"fa-solid fa-list-ol\"></i> Configured Dashboards</h4>\n <div class=\"dashboard-list\"\n cdkDropList\n #configuredList=\"cdkDropList\"\n [cdkDropListData]=\"configuredDashboards\"\n [cdkDropListConnectedTo]=\"[availableList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n\n @if (configuredDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No dashboards configured\n </div>\n }\n\n @for (dashboard of configuredDashboards; track dashboard.ID; let i = $index) {\n <div class=\"dashboard-item configured-item\"\n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <span class=\"order-number\">{{ i + 1 }}</span>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\"\n class=\"remove-button\"\n (click)=\"removeDashboard(dashboard)\"\n title=\"Remove from configured dashboards\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button type=\"button\"\n class=\"btn btn-secondary\"\n (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i> Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [disabled]=\"!hasChanges || saving\"\n (click)=\"onSave()\">\n @if (saving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Save Changes\n }\n </button>\n </mj-dialog-actions>\n</div>\n</mj-dialog>\n"]}
1
+ {"version":3,"file":"dashboard-preferences-dialog.component.js","sourceRoot":"","sources":["../../../src/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.ts","../../../src/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\nimport { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';\nimport { LogError, Metadata, RunView } from '@memberjunction/core';\nimport { MJDashboardEntityExtended, MJDashboardUserPreferenceEntity, MJApplicationEntity } from '@memberjunction/core-entities';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\nexport interface DashboardPreferencesResult {\n saved: boolean;\n preferences?: MJDashboardUserPreferenceEntity[];\n}\n\n@Component({\n standalone: false,\n selector: 'mj-dashboard-preferences-dialog',\n templateUrl: './dashboard-preferences-dialog.component.html',\n styleUrls: ['./dashboard-preferences-dialog.component.css']\n})\nexport class DashboardPreferencesDialogComponent extends BaseAngularComponent implements OnInit {\n @Input() public applicationId: string | null = null;\n @Input() public scope: 'Global' | 'App' = 'Global';\n @Output() public result = new EventEmitter<DashboardPreferencesResult>();\n\n public availableDashboards: MJDashboardEntityExtended[] = [];\n public configuredDashboards: MJDashboardEntityExtended[] = [];\n public applicationName: string = '';\n public loading: boolean = true;\n public saving: boolean = false;\n public error: string | null = null;\n public hasChanges: boolean = false;\n public isSysAdmin: boolean = false;\n public preferenceMode: 'personal' | 'system' = 'personal';\n\n private originalConfiguredIds: string[] = [];\n private currentUserPreferences: MJDashboardUserPreferenceEntity[] = [];\n private allAvailableDashboards: MJDashboardEntityExtended[] = [];\n\n async ngOnInit(): Promise<void> {\n try {\n await this.loadData();\n } catch (error) {\n LogError('Error initializing dashboard preferences dialog', null, error);\n this.error = 'Failed to load dashboard preferences';\n } finally {\n this.loading = false;\n }\n }\n\n private async loadData(): Promise<void> {\n const md = this.ProviderToUse;\n \n // Check if current user is sysadmin\n this.isSysAdmin = md.CurrentUser.Type.trim().toLowerCase() === 'owner';\n console.log('User is sysadmin:', this.isSysAdmin);\n \n // Default to personal preferences for all users (including sysadmin)\n this.preferenceMode = 'personal';\n \n // Load application name if we're in app scope\n if (this.scope === 'App' && this.applicationId) {\n await this.loadApplicationName();\n }\n\n // Get cached dashboards from MJ_Metadata dataset\n const ds = await md.GetAndCacheDatasetByName(\"MJ_Metadata\");\n if (!ds || !ds.Success) {\n throw new Error(ds?.Status || 'Failed to load metadata dataset');\n }\n\n const dashList = ds.Results.find(r => r.Code === 'Dashboards');\n if (!dashList) {\n throw new Error('Dashboards dataset not found');\n }\n\n // Filter dashboards by scope\n const appFilter = this.applicationId ? ` AND ApplicationID='${this.applicationId}'` : ' AND ApplicationID IS NULL';\n this.allAvailableDashboards = dashList.Results.filter((d: MJDashboardEntityExtended) => {\n if (this.scope === 'Global') {\n return d.Scope === 'Global' && !d.ApplicationID;\n } else {\n return UUIDsEqual(d.ApplicationID, this.applicationId) // ignore scope for dashboards that match app id, sometimes they have a global scope as they can be shown globally as well as app specific\n }\n });\n\n // Load current user preferences\n await this.loadCurrentPreferences();\n \n // Split dashboards into available and configured\n this.splitDashboards();\n \n // Store original state to detect changes\n this.originalConfiguredIds = this.configuredDashboards.map(d => d.ID);\n }\n\n private async loadApplicationName(): Promise<void> {\n if (!this.applicationId) return;\n \n try {\n const md = this.ProviderToUse;\n const ds = await md.GetAndCacheDatasetByName(\"MJ_Metadata\");\n const appList = ds.Results.find(r => r.Code === 'Applications');\n if (appList) {\n const app = appList.Results.find((a: MJApplicationEntity) => UUIDsEqual(a.ID, this.applicationId));\n this.applicationName = app?.Name || 'Unknown Application';\n }\n } catch (error) {\n LogError('Error loading application name', null, error);\n this.applicationName = 'Unknown Application';\n }\n }\n\n private async loadCurrentPreferences(): Promise<void> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const md = this.ProviderToUse;\n \n const appFilter = this.applicationId ? ` AND ApplicationID='${this.applicationId}'` : '';\n const baseCondition = `Scope='${this.scope}'${appFilter}`;\n \n let filter: string;\n \n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n // Load system defaults only (UserID IS NULL)\n filter = `UserID IS NULL AND ${baseCondition}`;\n } else {\n // Load personal user preferences (including for sysadmin when in personal mode)\n // For personal mode, we ONLY load the user's specific preferences, no fallback to system defaults\n // This allows sysadmin to see their actual personal preferences vs system defaults\n filter = `UserID='${md.CurrentUser.ID}' AND ${baseCondition}`;\n }\n\n console.log('Loading preferences with filter:', filter);\n\n const prefsResult = await rv.RunView<MJDashboardUserPreferenceEntity>({\n EntityName: 'MJ: Dashboard User Preferences',\n ExtraFilter: filter,\n ResultType: 'entity_object',\n OrderBy: 'DisplayOrder',\n });\n\n this.currentUserPreferences = prefsResult?.Results || [];\n console.log('Loaded preferences:', this.currentUserPreferences.length);\n }\n\n private splitDashboards(): void {\n const configuredIds = new Set(this.currentUserPreferences.map(p => p.DashboardID));\n \n // Get configured dashboards in the right order\n this.configuredDashboards = this.currentUserPreferences\n .map(pref => this.allAvailableDashboards.find(d => UUIDsEqual(d.ID, pref.DashboardID)))\n .filter((d): d is MJDashboardEntityExtended => d !== undefined);\n \n // Get available dashboards (not configured)\n this.availableDashboards = this.allAvailableDashboards\n .filter(d => !configuredIds.has(d.ID))\n .sort((a, b) => a.Name.localeCompare(b.Name));\n }\n\n public onDrop(event: CdkDragDrop<MJDashboardEntityExtended[]>): void {\n try {\n if (event.previousContainer === event.container) {\n // Reordering within the same list\n moveItemInArray(event.container.data, event.previousIndex, event.currentIndex);\n } else {\n // Moving between lists\n transferArrayItem(\n event.previousContainer.data,\n event.container.data,\n event.previousIndex,\n event.currentIndex\n );\n \n // If moving to configured dashboards, sort the available list\n if (event.container.data === this.configuredDashboards) {\n this.availableDashboards.sort((a, b) => a.Name.localeCompare(b.Name));\n }\n }\n \n this.checkForChanges();\n } catch (error) {\n LogError('Error in drag drop operation', null, error);\n this.error = 'Error reordering dashboards. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public addDashboard(dashboard: MJDashboardEntityExtended): void {\n try {\n const index = this.availableDashboards.findIndex(d => UUIDsEqual(d.ID, dashboard.ID));\n if (index !== -1) {\n this.availableDashboards.splice(index, 1);\n this.configuredDashboards.push(dashboard);\n this.checkForChanges();\n }\n } catch (error) {\n LogError('Error adding dashboard', null, error);\n this.error = 'Error adding dashboard. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public removeDashboard(dashboard: MJDashboardEntityExtended): void {\n try {\n const index = this.configuredDashboards.findIndex(d => UUIDsEqual(d.ID, dashboard.ID));\n if (index !== -1) {\n this.configuredDashboards.splice(index, 1);\n this.availableDashboards.push(dashboard);\n this.availableDashboards.sort((a, b) => a.Name.localeCompare(b.Name));\n this.checkForChanges();\n }\n } catch (error) {\n LogError('Error removing dashboard', null, error);\n this.error = 'Error removing dashboard. Please try again.';\n \n // Clear error after 3 seconds\n setTimeout(() => {\n this.error = null;\n }, 3000);\n }\n }\n\n public async onPreferenceModeChange(): Promise<void> {\n try {\n this.loading = true;\n this.error = null;\n \n // Reload preferences with new mode\n await this.loadCurrentPreferences();\n this.splitDashboards();\n this.originalConfiguredIds = this.configuredDashboards.map(d => d.ID);\n this.hasChanges = false;\n \n } catch (error) {\n LogError('Error changing preference mode', null, error);\n this.error = 'Error loading preferences. Please try again.';\n } finally {\n this.loading = false;\n }\n }\n\n private checkForChanges(): void {\n try {\n const currentConfiguredIds = this.configuredDashboards.map(d => d.ID);\n \n // Check if the order or selection has changed\n this.hasChanges = currentConfiguredIds.length !== this.originalConfiguredIds.length ||\n currentConfiguredIds.some((id, index) => id !== this.originalConfiguredIds[index]);\n \n // Debug logging\n console.log('Dashboard preferences change check:', {\n original: this.originalConfiguredIds,\n current: currentConfiguredIds,\n hasChanges: this.hasChanges\n });\n } catch (error) {\n LogError('Error checking for changes', null, error);\n this.hasChanges = false;\n }\n }\n\n public async onSave(): Promise<void> {\n if (this.saving || !this.hasChanges) {\n console.log('Save cancelled:', { saving: this.saving, hasChanges: this.hasChanges });\n return;\n }\n\n try {\n this.saving = true;\n console.log('Starting save process with configured dashboards:', this.configuredDashboards.map(d => ({ id: d.ID, name: d.Name })));\n \n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Get existing preferences for this scope\n const baseCondition = this.scope === 'Global' \n ? `Scope='Global' AND ApplicationID IS NULL`\n : `Scope='App' AND ApplicationID='${this.applicationId}'`;\n \n let userFilter: string;\n \n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n // Managing system defaults\n userFilter = `UserID IS NULL AND ${baseCondition}`;\n } else {\n // Managing personal preferences\n userFilter = `UserID='${md.CurrentUser.ID}' AND ${baseCondition}`;\n }\n \n console.log('Loading existing preferences with filter:', userFilter);\n \n const existingPrefs = await rv.RunView<MJDashboardUserPreferenceEntity>({\n EntityName: 'MJ: Dashboard User Preferences',\n ExtraFilter: userFilter,\n ResultType: 'entity_object',\n });\n\n const existingPreferences = existingPrefs?.Results || [];\n console.log('Found existing preferences:', existingPreferences.length);\n\n // Create maps for efficient lookups\n const existingByDashboardId = new Map<string, MJDashboardUserPreferenceEntity>();\n existingPreferences.forEach(pref => {\n existingByDashboardId.set(pref.DashboardID, pref);\n });\n\n const configuredDashboardIds = new Set(this.configuredDashboards.map(d => d.ID));\n\n // Step 1: Delete preferences that are no longer configured\n const prefsToDelete = existingPreferences.filter(pref => !configuredDashboardIds.has(pref.DashboardID));\n console.log('Preferences to delete:', prefsToDelete.length);\n \n for (const pref of prefsToDelete) {\n console.log('Deleting preference for dashboard:', pref.DashboardID);\n if (!await pref.Delete()) {\n const errorMsg = pref.LatestResult?.Error || pref.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to delete preference: ${errorMsg}`);\n }\n }\n\n // Step 2: Update existing preferences or create new ones\n const newPreferences: MJDashboardUserPreferenceEntity[] = [];\n \n for (let i = 0; i < this.configuredDashboards.length; i++) {\n const dashboard = this.configuredDashboards[i];\n const newDisplayOrder = i + 1;\n \n let prefEntity = existingByDashboardId.get(dashboard.ID);\n \n if (prefEntity) {\n // Update existing preference\n console.log(`Updating existing preference for dashboard ${dashboard.Name}, new order: ${newDisplayOrder}`);\n prefEntity.DisplayOrder = newDisplayOrder;\n \n if (!await prefEntity.Save()) {\n const errorMsg = prefEntity.LatestResult?.Error || prefEntity.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to update preference for dashboard ${dashboard.Name}: ${errorMsg}`);\n }\n } else {\n // Create new preference\n console.log(`Creating new preference for dashboard ${dashboard.Name}, order: ${newDisplayOrder}`);\n prefEntity = await md.GetEntityObject<MJDashboardUserPreferenceEntity>('MJ: Dashboard User Preferences');\n \n // Set UserID based on preference mode\n if (this.isSysAdmin && this.scope === 'Global' && this.preferenceMode === 'system') {\n prefEntity.UserID = null; // System default\n } else {\n prefEntity.UserID = md.CurrentUser.ID; // Personal preference\n }\n \n prefEntity.DashboardID = dashboard.ID;\n prefEntity.DisplayOrder = newDisplayOrder;\n prefEntity.Scope = this.scope;\n prefEntity.ApplicationID = this.applicationId;\n\n console.log('Creating preference entity:', {\n UserID: prefEntity.UserID,\n DashboardID: prefEntity.DashboardID,\n DisplayOrder: prefEntity.DisplayOrder,\n Scope: prefEntity.Scope,\n ApplicationID: prefEntity.ApplicationID\n });\n\n if (!await prefEntity.Save()) {\n const errorMsg = prefEntity.LatestResult?.Error || prefEntity.LatestResult?.Message || 'Unknown error';\n throw new Error(`Failed to create preference for dashboard ${dashboard.Name}: ${errorMsg}`);\n }\n }\n \n newPreferences.push(prefEntity);\n }\n\n console.log('Successfully processed', newPreferences.length, 'preferences');\n\n // Emit success result\n this.result.emit({\n saved: true,\n preferences: newPreferences\n });\n\n } catch (error) {\n console.error('Save error:', error);\n LogError('Error saving dashboard preferences', null, error);\n this.error = `Failed to save preferences: ${error instanceof Error ? error.message : 'Unknown error'}`;\n \n // Clear error after 5 seconds\n setTimeout(() => {\n this.error = null;\n }, 5000);\n } finally {\n this.saving = false;\n }\n }\n\n public onCancel(): void {\n this.result.emit({ saved: false });\n }\n}","<mj-dialog [Visible]=\"true\" Title=\"Dashboard Preferences\"\n [Width]=\"800\"\n [Height]=\"600\"\n [MinWidth]=\"600\"\n (Close)=\"onCancel()\">\n<div class=\"dashboard-preferences-dialog\">\n <div class=\"dialog-header\">\n <h3><i class=\"fa-solid fa-sliders\"></i> Dashboard Preferences</h3>\n <p class=\"scope-indicator\">\n @if (scope === 'Global') {\n <i class=\"fa-solid fa-globe\"></i> Global Scope\n } @else {\n <i class=\"fa-solid fa-layer-group\"></i> Application: {{ applicationName }}\n }\n </p>\n @if (isSysAdmin && scope === 'Global') {\n <div class=\"preference-mode-selector\">\n <label>\n <input type=\"radio\"\n name=\"preferenceMode\"\n value=\"personal\"\n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n Personal Preferences\n </label>\n <label>\n <input type=\"radio\"\n name=\"preferenceMode\"\n value=\"system\"\n [(ngModel)]=\"preferenceMode\"\n (change)=\"onPreferenceModeChange()\">\n System Defaults\n </label>\n </div>\n }\n </div>\n\n <div class=\"dialog-content\">\n @if (loading) {\n <div class=\"loading-overlay\">\n <mj-loading text=\"Loading preferences...\" size=\"large\"></mj-loading>\n </div>\n }\n\n @if (error) {\n <div class=\"error-container\">\n <i class=\"fa-solid fa-exclamation-triangle\"></i>\n {{ error }}\n </div>\n }\n\n @if (!loading && !error) {\n <div class=\"preferences-panels\">\n <!-- Available Dashboards Panel -->\n <div class=\"panel available-panel\">\n <h4><i class=\"fa-solid fa-list\"></i> Available Dashboards</h4>\n <div class=\"dashboard-list\"\n cdkDropList\n #availableList=\"cdkDropList\"\n [cdkDropListData]=\"availableDashboards\"\n [cdkDropListConnectedTo]=\"[configuredList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n\n @if (availableDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n All dashboards are configured\n </div>\n }\n\n @for (dashboard of availableDashboards; track dashboard.ID) {\n <div class=\"dashboard-item available-item\"\n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\"\n class=\"add-button\"\n (click)=\"addDashboard(dashboard)\"\n title=\"Add to configured dashboards\">\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n\n <!-- Configured Dashboards Panel -->\n <div class=\"panel configured-panel\">\n <h4><i class=\"fa-solid fa-list-ol\"></i> Configured Dashboards</h4>\n <div class=\"dashboard-list\"\n cdkDropList\n #configuredList=\"cdkDropList\"\n [cdkDropListData]=\"configuredDashboards\"\n [cdkDropListConnectedTo]=\"[availableList]\"\n (cdkDropListDropped)=\"onDrop($event)\">\n\n @if (configuredDashboards.length === 0) {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-info-circle\"></i>\n No dashboards configured\n </div>\n }\n\n @for (dashboard of configuredDashboards; track dashboard.ID; let i = $index) {\n <div class=\"dashboard-item configured-item\"\n cdkDrag\n [cdkDragData]=\"dashboard\">\n <div class=\"dashboard-item-content\">\n <i class=\"fa-solid fa-grip-vertical drag-handle\"></i>\n <span class=\"order-number\">{{ i + 1 }}</span>\n <div class=\"dashboard-info\">\n <span class=\"dashboard-name\">{{ dashboard.Name }}</span>\n @if (dashboard.Description) {\n <span class=\"dashboard-description\">{{ dashboard.Description }}</span>\n }\n </div>\n <button type=\"button\"\n class=\"remove-button\"\n (click)=\"removeDashboard(dashboard)\"\n title=\"Remove from configured dashboards\">\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n }\n </div>\n\n <mj-dialog-actions>\n <button type=\"button\"\n class=\"btn btn-secondary\"\n (click)=\"onCancel()\">\n <i class=\"fa-solid fa-times\"></i> Cancel\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n [disabled]=\"!hasChanges || saving\"\n (click)=\"onSave()\">\n @if (saving) {\n <mj-loading [showText]=\"false\" size=\"small\"></mj-loading>\n Saving...\n } @else {\n <i class=\"fa-solid fa-check\"></i> Save Changes\n }\n </button>\n </mj-dialog-actions>\n</div>\n</mj-dialog>\n"]}
@@ -1,4 +1,5 @@
1
1
  import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
2
- import { EntityPermissionType } from "@memberjunction/core";
2
+ import { EntityPermissionType, IMetadataProvider } from "@memberjunction/core";
3
+ export declare function setEntitiesGuardProvider(p: IMetadataProvider): void;
3
4
  export declare function checkUserEntityPermissions(type: EntityPermissionType): (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => any;
4
5
  //# sourceMappingURL=entities.guard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entities.guard.d.ts","sourceRoot":"","sources":["../../../src/lib/guards/entities.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,oBAAoB,EAAW,MAAM,sBAAsB,CAAC;AAEpE,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,oBAAoB,GAAG,CAAC,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,mBAAmB,KAAK,GAAG,CAuCvI"}
1
+ {"version":3,"file":"entities.guard.d.ts","sourceRoot":"","sources":["../../../src/lib/guards/entities.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAC,oBAAoB,EAAY,iBAAiB,EAAC,MAAM,sBAAsB,CAAC;AAUvF,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAEnE;AAMD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,oBAAoB,GAAG,CAAC,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,mBAAmB,KAAK,GAAG,CAuCvI"}
@@ -1,7 +1,20 @@
1
1
  import { EntityPermissionType, Metadata } from "@memberjunction/core";
2
+ /**
3
+ * Module-level provider for the route guard. Set via `setEntitiesGuardProvider()`
4
+ * from app-init / shell. Falls back to `Metadata.Provider` when not set, which
5
+ * is fine for single-provider apps — guards are constructed by Angular DI and
6
+ * don't have a natural per-component provider context.
7
+ */
8
+ let _guardProvider = null;
9
+ export function setEntitiesGuardProvider(p) {
10
+ _guardProvider = p;
11
+ }
12
+ function getGuardProvider() {
13
+ return _guardProvider ?? Metadata.Provider;
14
+ }
2
15
  export function checkUserEntityPermissions(type) {
3
16
  return (route, state) => {
4
- const md = new Metadata();
17
+ const md = getGuardProvider();
5
18
  const appName = route.params['appName'];
6
19
  const entityName = route.params['entityName'];
7
20
  if (md && md.Entities) {
@@ -1 +1 @@
1
- {"version":3,"file":"entities.guard.js","sourceRoot":"","sources":["../../../src/lib/guards/entities.guard.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,oBAAoB,EAAE,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAEpE,MAAM,UAAU,0BAA0B,CAAC,IAA0B;IACjE,OAAO,CAAC,KAA6B,EAAE,KAA0B,EAAE,EAAE;QACnE,MAAM,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAE9C,IAAI,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;gBAClC,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAA;YAC9B,CAAC,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,MAAM,EAAE,iBAAiB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;YAE9D,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,QAAQ,GAAY,KAAK,CAAC;gBAC9B,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;oBACR,KAAK,oBAAoB,CAAC,IAAI;wBAC5B,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC;wBAC/B,MAAM;oBACR,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;oBACR,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;gBACV,CAAC;gBACD,OAAO,QAAQ,CAAA;YACjB,CAAC;iBACI,CAAC;gBACJ,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;aACI,CAAC;YACJ,OAAO,KAAK,CAAC,CAAC,iCAAiC;QACjD,CAAC;IACH,CAAC,CAAA;AACH,CAAC","sourcesContent":["import {\n ActivatedRouteSnapshot,\n RouterStateSnapshot,\n} from '@angular/router';\nimport {EntityPermissionType, Metadata} from \"@memberjunction/core\";\n \nexport function checkUserEntityPermissions(type: EntityPermissionType): (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => any {\n return (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n const md = new Metadata();\n const appName = route.params['appName'];\n const entityName = route.params['entityName'];\n \n if (md && md.Entities) {\n const entity = md.Entities.find(e => {\n return e.Name === entityName \n });\n \n const permissions = entity?.GetUserPermisions(md.CurrentUser);\n \n if (permissions) {\n let bAllowed: boolean = false;\n switch (type) {\n case EntityPermissionType.Create:\n bAllowed = permissions.CanCreate;\n break;\n case EntityPermissionType.Read:\n bAllowed = permissions.CanRead;\n break;\n case EntityPermissionType.Update:\n bAllowed = permissions.CanUpdate;\n break;\n case EntityPermissionType.Delete:\n bAllowed = permissions.CanDelete;\n break;\n }\n return bAllowed\n }\n else {\n return false;\n }\n }\n else {\n return false; // entity metadata not loaded yet\n }\n }\n }\n "]}
1
+ {"version":3,"file":"entities.guard.js","sourceRoot":"","sources":["../../../src/lib/guards/entities.guard.ts"],"names":[],"mappings":"AAIA,OAAO,EAAC,oBAAoB,EAAE,QAAQ,EAAoB,MAAM,sBAAsB,CAAC;AAEvF;;;;;GAKG;AACH,IAAI,cAAc,GAA6B,IAAI,CAAC;AAEpD,MAAM,UAAU,wBAAwB,CAAC,CAAoB;IAC3D,cAAc,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,cAAc,IAAI,QAAQ,CAAC,QAAQ,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,IAA0B;IACjE,OAAO,CAAC,KAA6B,EAAE,KAA0B,EAAE,EAAE;QACnE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAE9C,IAAI,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC;YACtB,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;gBAClC,OAAO,CAAC,CAAC,IAAI,KAAK,UAAU,CAAA;YAC9B,CAAC,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,MAAM,EAAE,iBAAiB,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;YAE9D,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,QAAQ,GAAY,KAAK,CAAC;gBAC9B,QAAQ,IAAI,EAAE,CAAC;oBACb,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;oBACR,KAAK,oBAAoB,CAAC,IAAI;wBAC5B,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC;wBAC/B,MAAM;oBACR,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;oBACR,KAAK,oBAAoB,CAAC,MAAM;wBAC9B,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC;wBACjC,MAAM;gBACV,CAAC;gBACD,OAAO,QAAQ,CAAA;YACjB,CAAC;iBACI,CAAC;gBACJ,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;aACI,CAAC;YACJ,OAAO,KAAK,CAAC,CAAC,iCAAiC;QACjD,CAAC;IACH,CAAC,CAAA;AACH,CAAC","sourcesContent":["import {\n ActivatedRouteSnapshot,\n RouterStateSnapshot,\n} from '@angular/router';\nimport {EntityPermissionType, Metadata, IMetadataProvider} from \"@memberjunction/core\";\n\n/**\n * Module-level provider for the route guard. Set via `setEntitiesGuardProvider()`\n * from app-init / shell. Falls back to `Metadata.Provider` when not set, which\n * is fine for single-provider apps — guards are constructed by Angular DI and\n * don't have a natural per-component provider context.\n */\nlet _guardProvider: IMetadataProvider | null = null;\n\nexport function setEntitiesGuardProvider(p: IMetadataProvider): void {\n _guardProvider = p;\n}\n\nfunction getGuardProvider(): IMetadataProvider {\n return _guardProvider ?? Metadata.Provider;\n}\n\nexport function checkUserEntityPermissions(type: EntityPermissionType): (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => any {\n return (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n const md = getGuardProvider();\n const appName = route.params['appName'];\n const entityName = route.params['entityName'];\n \n if (md && md.Entities) {\n const entity = md.Entities.find(e => {\n return e.Name === entityName \n });\n \n const permissions = entity?.GetUserPermisions(md.CurrentUser);\n \n if (permissions) {\n let bAllowed: boolean = false;\n switch (type) {\n case EntityPermissionType.Create:\n bAllowed = permissions.CanCreate;\n break;\n case EntityPermissionType.Read:\n bAllowed = permissions.CanRead;\n break;\n case EntityPermissionType.Update:\n bAllowed = permissions.CanUpdate;\n break;\n case EntityPermissionType.Delete:\n bAllowed = permissions.CanDelete;\n break;\n }\n return bAllowed\n }\n else {\n return false;\n }\n }\n else {\n return false; // entity metadata not loaded yet\n }\n }\n }\n "]}
@@ -12,6 +12,7 @@
12
12
  */
13
13
  import { OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';
14
14
  import { ActivatedRoute, Router } from '@angular/router';
15
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
15
16
  import * as i0 from "@angular/core";
16
17
  /**
17
18
  * OAuth Callback Component
@@ -23,7 +24,7 @@ import * as i0 from "@angular/core";
23
24
  * The component waits for authentication to complete before attempting
24
25
  * the code exchange, since the user's session needs to be restored first.
25
26
  */
26
- export declare class OAuthCallbackComponent implements OnInit, OnDestroy {
27
+ export declare class OAuthCallbackComponent extends BaseAngularComponent implements OnInit, OnDestroy {
27
28
  private route;
28
29
  private router;
29
30
  private cdr;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-callback.component.d.ts","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;;AAoBzD;;;;;;;;;GASG;AACH,qBAMa,sBAAuB,YAAW,MAAM,EAAE,SAAS;IA0BxD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IA3Bf,oDAAoD;IAC7C,SAAS,UAAQ;IAExB,kBAAkB;IACX,QAAQ,UAAS;IAExB,+BAA+B;IACxB,YAAY,SAAM;IAEzB,iDAAiD;IAC1C,SAAS,SAAM;IAEtB,qCAAqC;IAC9B,WAAW,UAAS;IAE3B,6CAA6C;IACtC,aAAa,SAA0B;IAE9C,2CAA2C;IAC3C,OAAO,CAAC,SAAS,CAA+C;IAEhE,wCAAwC;IACxC,OAAO,CAAC,YAAY,CAAS;gBAGjB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,iBAAiB;IAG5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,WAAW,IAAI,IAAI;IAQnB;;;OAGG;YACW,yBAAyB;IAiDvC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;YACW,oBAAoB;IAgDlC;;OAEG;YACW,YAAY;IAqC1B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB;;OAEG;IACI,OAAO,IAAI,IAAI;yCAvUb,sBAAsB;2CAAtB,sBAAsB;CA2UlC"}
1
+ {"version":3,"file":"oauth-callback.component.d.ts","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AAiBrE;;;;;;;;;GASG;AACH,qBAMa,sBAAuB,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IA0BrF,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,GAAG;IA3Bf,oDAAoD;IAC7C,SAAS,UAAQ;IAExB,kBAAkB;IACX,QAAQ,UAAS;IAExB,+BAA+B;IACxB,YAAY,SAAM;IAEzB,iDAAiD;IAC1C,SAAS,SAAM;IAEtB,qCAAqC;IAC9B,WAAW,UAAS;IAE3B,6CAA6C;IACtC,aAAa,SAA0B;IAE9C,2CAA2C;IAC3C,OAAO,CAAC,SAAS,CAA+C;IAEhE,wCAAwC;IACxC,OAAO,CAAC,YAAY,CAAS;gBAGjB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,iBAAiB;IAI5B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAK/B,WAAW,IAAI,IAAI;IAQnB;;;OAGG;YACW,yBAAyB;IAiDvC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;OAEG;YACW,mBAAmB;IAcjC;;OAEG;YACW,oBAAoB;IAgDlC;;OAEG;YACW,YAAY;IAqC1B;;OAEG;IACH,OAAO,CAAC,aAAa;IA+BrB;;OAEG;IACH,OAAO,CAAC,cAAc;IA+BtB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAO7B;;OAEG;IACH,OAAO,CAAC,SAAS;IASjB;;OAEG;IACI,OAAO,IAAI,IAAI;IAOtB;;OAEG;IACI,OAAO,IAAI,IAAI;yCAxUb,sBAAsB;2CAAtB,sBAAsB;CA4UlC"}
@@ -11,7 +11,7 @@
11
11
  * @module OAuth Callback
12
12
  */
13
13
  import { Component } from '@angular/core';
14
- import { Metadata } from '@memberjunction/core';
14
+ import { BaseAngularComponent } from '@memberjunction/ng-base-types';
15
15
  import * as i0 from "@angular/core";
16
16
  import * as i1 from "@angular/router";
17
17
  import * as i2 from "@memberjunction/ng-shared-generic";
@@ -101,7 +101,7 @@ const POLL_INTERVAL_MS = 500;
101
101
  * The component waits for authentication to complete before attempting
102
102
  * the code exchange, since the user's session needs to be restored first.
103
103
  */
104
- export class OAuthCallbackComponent {
104
+ export class OAuthCallbackComponent extends BaseAngularComponent {
105
105
  route;
106
106
  router;
107
107
  cdr;
@@ -122,6 +122,7 @@ export class OAuthCallbackComponent {
122
122
  /** Flag to prevent double processing */
123
123
  isProcessing = false;
124
124
  constructor(route, router, cdr) {
125
+ super();
125
126
  this.route = route;
126
127
  this.router = router;
127
128
  this.cdr = cdr;
@@ -184,7 +185,7 @@ export class OAuthCallbackComponent {
184
185
  */
185
186
  isProviderReady() {
186
187
  try {
187
- const provider = Metadata.Provider;
188
+ const provider = this.ProviderToUse;
188
189
  if (!provider) {
189
190
  return false;
190
191
  }
@@ -257,7 +258,7 @@ export class OAuthCallbackComponent {
257
258
  */
258
259
  async exchangeCode(code, state) {
259
260
  // Get the GraphQL provider - we know it's ready at this point
260
- const gqlProvider = Metadata.Provider;
261
+ const gqlProvider = this.ProviderToUse;
261
262
  const configData = gqlProvider.ConfigData;
262
263
  // Build the exchange endpoint URL from the GraphQL URL
263
264
  // Handle both cases: URL with /graphql suffix and URL without
@@ -385,7 +386,7 @@ export class OAuthCallbackComponent {
385
386
  this.router.navigate(['/app/admin/MCP']);
386
387
  }
387
388
  static ɵfac = function OAuthCallbackComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || OAuthCallbackComponent)(i0.ɵɵdirectiveInject(i1.ActivatedRoute), i0.ɵɵdirectiveInject(i1.Router), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef)); };
388
- static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: OAuthCallbackComponent, selectors: [["mj-oauth-callback"]], standalone: false, decls: 5, vars: 3, consts: [[1, "oauth-callback-container"], [1, "oauth-callback-card"], [1, "oauth-status", "loading"], [1, "oauth-status", "error"], [1, "oauth-status", "success"], [3, "text"], [1, "icon-container", "error-icon"], [1, "fa-solid", "fa-circle-exclamation"], [1, "error-code"], [1, "error-message"], [1, "button-group"], ["mjButton", "", "variant", "secondary"], ["mjButton", "", 3, "click", "variant"], [1, "fa-solid", "fa-arrow-left"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "icon-container", "success-icon"], [1, "fa-solid", "fa-circle-check"]], template: function OAuthCallbackComponent_Template(rf, ctx) { if (rf & 1) {
389
+ static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: OAuthCallbackComponent, selectors: [["mj-oauth-callback"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 5, vars: 3, consts: [[1, "oauth-callback-container"], [1, "oauth-callback-card"], [1, "oauth-status", "loading"], [1, "oauth-status", "error"], [1, "oauth-status", "success"], [3, "text"], [1, "icon-container", "error-icon"], [1, "fa-solid", "fa-circle-exclamation"], [1, "error-code"], [1, "error-message"], [1, "button-group"], ["mjButton", "", "variant", "secondary"], ["mjButton", "", 3, "click", "variant"], [1, "fa-solid", "fa-arrow-left"], ["mjButton", "", "variant", "secondary", 3, "click"], [1, "fa-solid", "fa-rotate-right"], [1, "icon-container", "success-icon"], [1, "fa-solid", "fa-circle-check"]], template: function OAuthCallbackComponent_Template(rf, ctx) { if (rf & 1) {
389
390
  i0.ɵɵelementStart(0, "div", 0)(1, "div", 1);
390
391
  i0.ɵɵconditionalCreate(2, OAuthCallbackComponent_Conditional_2_Template, 2, 2, "div", 2);
391
392
  i0.ɵɵconditionalCreate(3, OAuthCallbackComponent_Conditional_3_Template, 13, 4, "div", 3);
@@ -404,5 +405,5 @@ export class OAuthCallbackComponent {
404
405
  type: Component,
405
406
  args: [{ standalone: false, selector: 'mj-oauth-callback', template: "<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"IsRetryable ? 'outline' : 'secondary'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n", styles: [".oauth-callback-container {\n display: flex;\n justify-content: center;\n align-items: center;\n min-height: 100vh;\n background: var(--mj-brand-primary);\n padding: 1rem;\n}\n\n.oauth-callback-card {\n background: var(--mj-bg-surface);\n padding: 3rem;\n border-radius: 1rem;\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);\n text-align: center;\n max-width: 450px;\n width: 100%;\n}\n\n.oauth-status {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.oauth-status h2 {\n margin: 0;\n font-size: 1.5rem;\n font-weight: 600;\n}\n\n.oauth-status p {\n margin: 0;\n color: var(--mj-text-muted);\n line-height: 1.6;\n}\n\n/* Icon containers */\n.icon-container {\n width: 80px;\n height: 80px;\n border-radius: 50%;\n display: flex;\n justify-content: center;\n align-items: center;\n margin-bottom: 0.5rem;\n}\n\n.icon-container i {\n font-size: 3rem;\n}\n\n.success-icon {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n}\n\n.success-icon i {\n color: var(--mj-status-success);\n}\n\n.error-icon {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.error-icon i {\n color: var(--mj-status-error);\n}\n\n/* Success state */\n.oauth-status.success h2 {\n color: var(--mj-status-success);\n}\n\n/* Error state */\n.oauth-status.error h2 {\n color: var(--mj-status-error);\n}\n\n.error-code {\n background: color-mix(in srgb, var(--mj-status-error) 5%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n padding: 0.5rem 1rem;\n border-radius: 0.5rem;\n font-family: monospace;\n font-size: 0.875rem;\n}\n\n.error-message {\n background: var(--mj-bg-surface-sunken);\n padding: 1rem;\n border-radius: 0.5rem;\n font-size: 0.9rem;\n color: var(--mj-text-secondary);\n width: 100%;\n}\n\n/* Buttons */\n.button-group {\n display: flex;\n gap: 0.75rem;\n margin-top: 1rem;\n}\n\n.button-group button {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n/* Loading state */\n.oauth-status.loading {\n padding: 2rem 0;\n}\n\n/* Responsive */\n@media (max-width: 480px) {\n .oauth-callback-card {\n padding: 2rem 1.5rem;\n }\n\n .button-group {\n flex-direction: column;\n width: 100%;\n }\n\n .button-group button {\n width: 100%;\n justify-content: center;\n }\n}\n"] }]
406
407
  }], () => [{ type: i1.ActivatedRoute }, { type: i1.Router }, { type: i0.ChangeDetectorRef }], null); })();
407
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OAuthCallbackComponent, { className: "OAuthCallbackComponent", filePath: "src/lib/oauth/oauth-callback.component.ts", lineNumber: 51 }); })();
408
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(OAuthCallbackComponent, { className: "OAuthCallbackComponent", filePath: "src/lib/oauth/oauth-callback.component.ts", lineNumber: 52 }); })();
408
409
  //# sourceMappingURL=oauth-callback.component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth-callback.component.js","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts","../../../src/lib/oauth/oauth-callback.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview OAuth Callback Component\n *\n * Handles OAuth provider redirects in the frontend. When an OAuth provider\n * redirects back to the application after user authorization, this component:\n * 1. Waits for the user's session to be restored (authentication)\n * 2. Extracts the code and state from URL query parameters\n * 3. Calls the backend /oauth/exchange endpoint to complete the token exchange\n * 4. Redirects to the original page with success/error notification\n *\n * @module OAuth Callback\n */\n\nimport { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Metadata } from '@memberjunction/core';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\n/**\n * Response from the OAuth exchange endpoint\n */\ninterface OAuthExchangeResponse {\n success: boolean;\n connectionId?: string;\n errorCode?: string;\n errorMessage?: string;\n isRetryable?: boolean;\n}\n\n/** Maximum time to wait for provider initialization (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\n/**\n * OAuth Callback Component\n *\n * Handles the redirect from OAuth providers after user authorization.\n * This component is loaded at /oauth/callback and processes the\n * authorization code to complete the OAuth flow.\n *\n * The component waits for authentication to complete before attempting\n * the code exchange, since the user's session needs to be restored first.\n */\n@Component({\n standalone: false,\n selector: 'mj-oauth-callback',\n templateUrl: './oauth-callback.component.html',\n styleUrls: ['./oauth-callback.component.css']\n})\nexport class OAuthCallbackComponent implements OnInit, OnDestroy {\n /** Loading state while processing OAuth callback */\n public IsLoading = true;\n\n /** Error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** Error code from OAuth provider or exchange */\n public ErrorCode = '';\n\n /** Whether the error is retryable */\n public IsRetryable = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {}\n\n async ngOnInit(): Promise<void> {\n // Wait for the GraphQL provider to be ready, then process the callback\n await this.waitForProviderAndProcess();\n }\n\n ngOnDestroy(): void {\n // Clean up the polling timer\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete)\n * then processes the OAuth callback.\n */\n private async waitForProviderAndProcess(): Promise<void> {\n const startTime = Date.now();\n\n // Check if provider is already ready\n if (this.isProviderReady()) {\n await this.safeProcessCallback();\n return;\n }\n\n // Poll for provider readiness\n this.StatusMessage = 'Waiting for authentication...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeProcessCallback();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.showError(\n 'timeout',\n 'Timed out waiting for authentication. Please try logging in again.',\n true\n );\n resolve();\n return;\n }\n\n // Update status message with progress\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for authentication... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /**\n * Checks if the GraphQL provider is initialized and has a valid token\n */\n private isProviderReady(): boolean {\n try {\n const provider = Metadata.Provider as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n if (!configData || !configData.Token || !configData.URL) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Safely processes the callback, preventing double execution\n */\n private async safeProcessCallback(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.processOAuthCallback();\n } catch (error) {\n console.error('[OAuth Callback] Error in processOAuthCallback:', error);\n this.showError('component_error', error instanceof Error ? error.message : String(error), true);\n }\n }\n\n /**\n * Process the OAuth callback by extracting params and exchanging the code\n */\n private async processOAuthCallback(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n\n // Check for error from OAuth provider\n if (params['error']) {\n this.showError(\n params['error'] as string,\n params['error_description'] as string || 'Authorization was denied or failed'\n );\n return;\n }\n\n const code = params['code'] as string;\n const state = params['state'] as string;\n\n // Validate required parameters\n if (!code) {\n this.showError('missing_code', 'No authorization code received from the OAuth provider');\n return;\n }\n\n if (!state) {\n this.showError('missing_state', 'No state parameter received from the OAuth provider');\n return;\n }\n\n // Exchange the code for tokens\n this.StatusMessage = 'Exchanging authorization code...';\n this.cdr.detectChanges();\n\n try {\n const result = await this.exchangeCode(code, state);\n\n if (result.success) {\n this.handleSuccess(result.connectionId);\n } else {\n this.showError(\n result.errorCode || 'exchange_failed',\n result.errorMessage || 'Failed to complete authorization',\n result.isRetryable\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.showError('network_error', message, true);\n }\n }\n\n /**\n * Call the backend to exchange the authorization code for tokens\n */\n private async exchangeCode(code: string, state: string): Promise<OAuthExchangeResponse> {\n // Get the GraphQL provider - we know it's ready at this point\n const gqlProvider = Metadata.Provider as GraphQLDataProvider;\n const configData = gqlProvider.ConfigData;\n\n // Build the exchange endpoint URL from the GraphQL URL\n // Handle both cases: URL with /graphql suffix and URL without\n let apiUrl = configData.URL;\n if (apiUrl.includes('/graphql')) {\n apiUrl = apiUrl.replace('/graphql', '/oauth/exchange');\n } else {\n // URL doesn't have /graphql, append /oauth/exchange\n apiUrl = apiUrl.replace(/\\/$/, '') + '/oauth/exchange';\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${configData.Token}`\n },\n body: JSON.stringify({ code, state })\n });\n\n // Parse response regardless of status code\n const data = await response.json();\n return data as OAuthExchangeResponse;\n } catch (fetchError) {\n return {\n success: false,\n errorCode: 'fetch_error',\n errorMessage: fetchError instanceof Error ? fetchError.message : 'Network error during token exchange'\n };\n }\n }\n\n /**\n * Handle successful OAuth completion\n */\n private handleSuccess(connectionId?: string): void {\n this.IsLoading = false;\n this.StatusMessage = 'Authorization successful! Redirecting...';\n this.cdr.detectChanges();\n\n // Get the stored return URL - try both localStorage and sessionStorage\n const storedUrl = localStorage.getItem('oauth_return_url');\n const storedPath = localStorage.getItem('oauth_return_path');\n const sessionUrl = sessionStorage.getItem('oauth_return_url');\n const sessionPath = sessionStorage.getItem('oauth_return_path');\n\n let returnUrl = storedUrl || sessionUrl || storedPath || sessionPath;\n\n // Clean up all possible storage locations\n this.clearStoredReturnUrls();\n\n // Default to MCP dashboard if no return URL found\n const defaultPath = '/app/admin/MCP';\n if (!returnUrl || returnUrl.trim() === '' || returnUrl === '/') {\n returnUrl = defaultPath;\n }\n\n // Build the final navigation path\n const finalPath = this.buildFinalPath(returnUrl, connectionId, defaultPath);\n\n // Use window.location for reliable navigation after OAuth\n setTimeout(() => {\n window.location.href = finalPath;\n }, 500);\n }\n\n /**\n * Builds the final navigation path with success query params\n */\n private buildFinalPath(returnUrl: string, connectionId: string | undefined, defaultPath: string): string {\n try {\n let finalPath: string;\n\n // If it's a full URL, extract just the path and search\n if (returnUrl.startsWith('http://') || returnUrl.startsWith('https://')) {\n const url = new URL(returnUrl);\n finalPath = url.pathname + url.search;\n } else {\n finalPath = returnUrl;\n }\n\n // Ensure we have a valid path (not empty or just \"/\")\n if (!finalPath || finalPath.trim() === '' || finalPath === '/') {\n finalPath = defaultPath;\n }\n\n // Add success query params\n const separator = finalPath.includes('?') ? '&' : '?';\n finalPath = `${finalPath}${separator}oauth=success`;\n if (connectionId) {\n finalPath += `&connectionId=${connectionId}`;\n }\n\n return finalPath;\n } catch (e) {\n console.error('[OAuth Callback] Error parsing return URL:', e);\n return `${defaultPath}?oauth=success${connectionId ? `&connectionId=${connectionId}` : ''}`;\n }\n }\n\n /**\n * Clears all stored return URLs from storage\n */\n private clearStoredReturnUrls(): void {\n localStorage.removeItem('oauth_return_url');\n localStorage.removeItem('oauth_return_path');\n sessionStorage.removeItem('oauth_return_url');\n sessionStorage.removeItem('oauth_return_path');\n }\n\n /**\n * Show error state\n */\n private showError(errorCode: string, message: string, isRetryable = false): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorCode = errorCode;\n this.ErrorMessage = message;\n this.IsRetryable = isRetryable;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle retry button click\n */\n public onRetry(): void {\n // Get the stored return URL and redirect there to start fresh\n const returnUrl = localStorage.getItem('oauth_return_url') || '/app/admin/MCP';\n this.clearStoredReturnUrls();\n this.router.navigateByUrl(returnUrl);\n }\n\n /**\n * Handle close button click (return to MCP dashboard)\n */\n public onClose(): void {\n this.clearStoredReturnUrls();\n this.router.navigate(['/app/admin/MCP']);\n }\n}\n","<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"IsRetryable ? 'outline' : 'secondary'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n"]}
1
+ {"version":3,"file":"oauth-callback.component.js","sourceRoot":"","sources":["../../../src/lib/oauth/oauth-callback.component.ts","../../../src/lib/oauth/oauth-callback.component.html"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview OAuth Callback Component\n *\n * Handles OAuth provider redirects in the frontend. When an OAuth provider\n * redirects back to the application after user authorization, this component:\n * 1. Waits for the user's session to be restored (authentication)\n * 2. Extracts the code and state from URL query parameters\n * 3. Calls the backend /oauth/exchange endpoint to complete the token exchange\n * 4. Redirects to the original page with success/error notification\n *\n * @module OAuth Callback\n */\n\nimport { Component, OnInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { Metadata } from '@memberjunction/core';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n/**\n * Response from the OAuth exchange endpoint\n */\ninterface OAuthExchangeResponse {\n success: boolean;\n connectionId?: string;\n errorCode?: string;\n errorMessage?: string;\n isRetryable?: boolean;\n}\n\n/** Maximum time to wait for provider initialization (30 seconds) */\nconst MAX_WAIT_TIME_MS = 30000;\n/** Polling interval for checking provider readiness (500ms) */\nconst POLL_INTERVAL_MS = 500;\n\n/**\n * OAuth Callback Component\n *\n * Handles the redirect from OAuth providers after user authorization.\n * This component is loaded at /oauth/callback and processes the\n * authorization code to complete the OAuth flow.\n *\n * The component waits for authentication to complete before attempting\n * the code exchange, since the user's session needs to be restored first.\n */\n@Component({\n standalone: false,\n selector: 'mj-oauth-callback',\n templateUrl: './oauth-callback.component.html',\n styleUrls: ['./oauth-callback.component.css']\n})\nexport class OAuthCallbackComponent extends BaseAngularComponent implements OnInit, OnDestroy {\n /** Loading state while processing OAuth callback */\n public IsLoading = true;\n\n /** Error state */\n public HasError = false;\n\n /** Error message to display */\n public ErrorMessage = '';\n\n /** Error code from OAuth provider or exchange */\n public ErrorCode = '';\n\n /** Whether the error is retryable */\n public IsRetryable = false;\n\n /** Status message shown during processing */\n public StatusMessage = 'Restoring session...';\n\n /** Timer for polling provider readiness */\n private pollTimer: ReturnType<typeof setInterval> | null = null;\n\n /** Flag to prevent double processing */\n private isProcessing = false;\n\n constructor(\n private route: ActivatedRoute,\n private router: Router,\n private cdr: ChangeDetectorRef\n ) {\n super();}\n\n async ngOnInit(): Promise<void> {\n // Wait for the GraphQL provider to be ready, then process the callback\n await this.waitForProviderAndProcess();\n }\n\n ngOnDestroy(): void {\n // Clean up the polling timer\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n }\n\n /**\n * Waits for the GraphQL provider to be initialized (indicating auth is complete)\n * then processes the OAuth callback.\n */\n private async waitForProviderAndProcess(): Promise<void> {\n const startTime = Date.now();\n\n // Check if provider is already ready\n if (this.isProviderReady()) {\n await this.safeProcessCallback();\n return;\n }\n\n // Poll for provider readiness\n this.StatusMessage = 'Waiting for authentication...';\n this.cdr.detectChanges();\n\n return new Promise<void>((resolve) => {\n this.pollTimer = setInterval(async () => {\n const elapsed = Date.now() - startTime;\n\n if (this.isProviderReady()) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n await this.safeProcessCallback();\n resolve();\n return;\n }\n\n if (elapsed >= MAX_WAIT_TIME_MS) {\n if (this.pollTimer) {\n clearInterval(this.pollTimer);\n this.pollTimer = null;\n }\n this.showError(\n 'timeout',\n 'Timed out waiting for authentication. Please try logging in again.',\n true\n );\n resolve();\n return;\n }\n\n // Update status message with progress\n const secondsRemaining = Math.ceil((MAX_WAIT_TIME_MS - elapsed) / 1000);\n this.StatusMessage = `Waiting for authentication... (${secondsRemaining}s)`;\n this.cdr.detectChanges();\n }, POLL_INTERVAL_MS);\n });\n }\n\n /**\n * Checks if the GraphQL provider is initialized and has a valid token\n */\n private isProviderReady(): boolean {\n try {\n const provider = this.ProviderToUse as GraphQLDataProvider;\n if (!provider) {\n return false;\n }\n const configData = provider.ConfigData;\n if (!configData || !configData.Token || !configData.URL) {\n return false;\n }\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Safely processes the callback, preventing double execution\n */\n private async safeProcessCallback(): Promise<void> {\n if (this.isProcessing) {\n return;\n }\n this.isProcessing = true;\n\n try {\n await this.processOAuthCallback();\n } catch (error) {\n console.error('[OAuth Callback] Error in processOAuthCallback:', error);\n this.showError('component_error', error instanceof Error ? error.message : String(error), true);\n }\n }\n\n /**\n * Process the OAuth callback by extracting params and exchanging the code\n */\n private async processOAuthCallback(): Promise<void> {\n const params = this.route.snapshot.queryParams;\n\n // Check for error from OAuth provider\n if (params['error']) {\n this.showError(\n params['error'] as string,\n params['error_description'] as string || 'Authorization was denied or failed'\n );\n return;\n }\n\n const code = params['code'] as string;\n const state = params['state'] as string;\n\n // Validate required parameters\n if (!code) {\n this.showError('missing_code', 'No authorization code received from the OAuth provider');\n return;\n }\n\n if (!state) {\n this.showError('missing_state', 'No state parameter received from the OAuth provider');\n return;\n }\n\n // Exchange the code for tokens\n this.StatusMessage = 'Exchanging authorization code...';\n this.cdr.detectChanges();\n\n try {\n const result = await this.exchangeCode(code, state);\n\n if (result.success) {\n this.handleSuccess(result.connectionId);\n } else {\n this.showError(\n result.errorCode || 'exchange_failed',\n result.errorMessage || 'Failed to complete authorization',\n result.isRetryable\n );\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : 'An unexpected error occurred';\n this.showError('network_error', message, true);\n }\n }\n\n /**\n * Call the backend to exchange the authorization code for tokens\n */\n private async exchangeCode(code: string, state: string): Promise<OAuthExchangeResponse> {\n // Get the GraphQL provider - we know it's ready at this point\n const gqlProvider = this.ProviderToUse as GraphQLDataProvider;\n const configData = gqlProvider.ConfigData;\n\n // Build the exchange endpoint URL from the GraphQL URL\n // Handle both cases: URL with /graphql suffix and URL without\n let apiUrl = configData.URL;\n if (apiUrl.includes('/graphql')) {\n apiUrl = apiUrl.replace('/graphql', '/oauth/exchange');\n } else {\n // URL doesn't have /graphql, append /oauth/exchange\n apiUrl = apiUrl.replace(/\\/$/, '') + '/oauth/exchange';\n }\n\n try {\n const response = await fetch(apiUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${configData.Token}`\n },\n body: JSON.stringify({ code, state })\n });\n\n // Parse response regardless of status code\n const data = await response.json();\n return data as OAuthExchangeResponse;\n } catch (fetchError) {\n return {\n success: false,\n errorCode: 'fetch_error',\n errorMessage: fetchError instanceof Error ? fetchError.message : 'Network error during token exchange'\n };\n }\n }\n\n /**\n * Handle successful OAuth completion\n */\n private handleSuccess(connectionId?: string): void {\n this.IsLoading = false;\n this.StatusMessage = 'Authorization successful! Redirecting...';\n this.cdr.detectChanges();\n\n // Get the stored return URL - try both localStorage and sessionStorage\n const storedUrl = localStorage.getItem('oauth_return_url');\n const storedPath = localStorage.getItem('oauth_return_path');\n const sessionUrl = sessionStorage.getItem('oauth_return_url');\n const sessionPath = sessionStorage.getItem('oauth_return_path');\n\n let returnUrl = storedUrl || sessionUrl || storedPath || sessionPath;\n\n // Clean up all possible storage locations\n this.clearStoredReturnUrls();\n\n // Default to MCP dashboard if no return URL found\n const defaultPath = '/app/admin/MCP';\n if (!returnUrl || returnUrl.trim() === '' || returnUrl === '/') {\n returnUrl = defaultPath;\n }\n\n // Build the final navigation path\n const finalPath = this.buildFinalPath(returnUrl, connectionId, defaultPath);\n\n // Use window.location for reliable navigation after OAuth\n setTimeout(() => {\n window.location.href = finalPath;\n }, 500);\n }\n\n /**\n * Builds the final navigation path with success query params\n */\n private buildFinalPath(returnUrl: string, connectionId: string | undefined, defaultPath: string): string {\n try {\n let finalPath: string;\n\n // If it's a full URL, extract just the path and search\n if (returnUrl.startsWith('http://') || returnUrl.startsWith('https://')) {\n const url = new URL(returnUrl);\n finalPath = url.pathname + url.search;\n } else {\n finalPath = returnUrl;\n }\n\n // Ensure we have a valid path (not empty or just \"/\")\n if (!finalPath || finalPath.trim() === '' || finalPath === '/') {\n finalPath = defaultPath;\n }\n\n // Add success query params\n const separator = finalPath.includes('?') ? '&' : '?';\n finalPath = `${finalPath}${separator}oauth=success`;\n if (connectionId) {\n finalPath += `&connectionId=${connectionId}`;\n }\n\n return finalPath;\n } catch (e) {\n console.error('[OAuth Callback] Error parsing return URL:', e);\n return `${defaultPath}?oauth=success${connectionId ? `&connectionId=${connectionId}` : ''}`;\n }\n }\n\n /**\n * Clears all stored return URLs from storage\n */\n private clearStoredReturnUrls(): void {\n localStorage.removeItem('oauth_return_url');\n localStorage.removeItem('oauth_return_path');\n sessionStorage.removeItem('oauth_return_url');\n sessionStorage.removeItem('oauth_return_path');\n }\n\n /**\n * Show error state\n */\n private showError(errorCode: string, message: string, isRetryable = false): void {\n this.IsLoading = false;\n this.HasError = true;\n this.ErrorCode = errorCode;\n this.ErrorMessage = message;\n this.IsRetryable = isRetryable;\n this.cdr.detectChanges();\n }\n\n /**\n * Handle retry button click\n */\n public onRetry(): void {\n // Get the stored return URL and redirect there to start fresh\n const returnUrl = localStorage.getItem('oauth_return_url') || '/app/admin/MCP';\n this.clearStoredReturnUrls();\n this.router.navigateByUrl(returnUrl);\n }\n\n /**\n * Handle close button click (return to MCP dashboard)\n */\n public onClose(): void {\n this.clearStoredReturnUrls();\n this.router.navigate(['/app/admin/MCP']);\n }\n}\n","<div class=\"oauth-callback-container\">\n <div class=\"oauth-callback-card\">\n <!-- Loading State -->\n @if (IsLoading) {\n <div class=\"oauth-status loading\">\n <mj-loading text=\"{{ StatusMessage }}\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (HasError) {\n <div class=\"oauth-status error\">\n <div class=\"icon-container error-icon\">\n <i class=\"fa-solid fa-circle-exclamation\"></i>\n </div>\n <h2>Authorization Failed</h2>\n @if (ErrorCode) {\n <div class=\"error-code\">{{ ErrorCode }}</div>\n }\n <p class=\"error-message\">{{ ErrorMessage }}</p>\n <div class=\"button-group\">\n @if (IsRetryable) {\n <button mjButton variant=\"secondary\" (click)=\"onRetry()\">\n <i class=\"fa-solid fa-rotate-right\"></i>\n Try Again\n </button>\n }\n <button mjButton [variant]=\"IsRetryable ? 'outline' : 'secondary'\" (click)=\"onClose()\">\n <i class=\"fa-solid fa-arrow-left\"></i>\n Return to Dashboard\n </button>\n </div>\n </div>\n }\n\n <!-- Success State (brief - redirects quickly) -->\n @if (!IsLoading && !HasError) {\n <div class=\"oauth-status success\">\n <div class=\"icon-container success-icon\">\n <i class=\"fa-solid fa-circle-check\"></i>\n </div>\n <h2>Authorization Successful</h2>\n <p>{{ StatusMessage }}</p>\n </div>\n }\n </div>\n</div>\n"]}
@@ -5,7 +5,6 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { Component, ViewEncapsulation, inject } from '@angular/core';
8
- import { Metadata } from '@memberjunction/core';
9
8
  import { RegisterClass } from '@memberjunction/global';
10
9
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
11
10
  import { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';
@@ -34,7 +33,7 @@ let ArtifactResource = class ArtifactResource extends BaseResourceComponent {
34
33
  environmentId = '';
35
34
  ngOnInit() {
36
35
  super.ngOnInit();
37
- const md = new Metadata();
36
+ const md = this.ProviderToUse;
38
37
  this.currentUser = md.CurrentUser;
39
38
  // Get artifact ID from resource data
40
39
  if (this.Data && this.Data.ResourceRecordID) {
@@ -76,7 +75,7 @@ let ArtifactResource = class ArtifactResource extends BaseResourceComponent {
76
75
  // Try to load artifact name from database
77
76
  if (data.ResourceRecordID) {
78
77
  try {
79
- const md = new Metadata();
78
+ const md = this.ProviderToUse;
80
79
  const artifact = await md.GetEntityObject('MJ: Conversation Artifacts');
81
80
  await artifact.Load(data.ResourceRecordID);
82
81
  return artifact.Name || `Artifact - ${data.ResourceRecordID}`;
@@ -1 +1 @@
1
- {"version":3,"file":"artifact-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewEncapsulation, inject } from '@angular/core';\nimport { DataSnapshot, Metadata, UserInfo } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { AnalyzeArtifactService } from '@memberjunction/ng-artifacts';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\n/**\n * Artifact Resource - displays versioned content artifacts\n * Wraps the artifact-viewer-panel component for tab-based display\n * Supports reports, dashboards, forms, and other artifact types\n */\n@RegisterClass(BaseResourceComponent, 'ArtifactResource')\n@Component({\n standalone: false,\n selector: 'mj-artifact-resource',\n template: `\n <div class=\"artifact-container\">\n @if (currentUser && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [showSaveToCollection]=\"true\"\n [canShare]=\"true\"\n [canEdit]=\"true\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n .artifact-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ArtifactResource extends BaseResourceComponent {\n private readonly analyzeService = inject(AnalyzeArtifactService);\n\n public currentUser: UserInfo | null = null;\n public artifactId: string = '';\n public environmentId: string = '';\n\n ngOnInit() {\n super.ngOnInit();\n const md = new Metadata();\n this.currentUser = md.CurrentUser;\n\n // Get artifact ID from resource data\n if (this.Data && this.Data.ResourceRecordID) {\n this.artifactId = this.Data.ResourceRecordID;\n }\n\n // Environment ID — use the configured environment if present, otherwise\n // fall back to the default environment. Must be a valid UUID since\n // downstream saves (e.g. AnalyzeArtifactService creating artifacts)\n // require a non-empty EnvironmentID.\n this.environmentId = (this.Data?.Configuration?.['environmentId'] as string | undefined)\n || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n\n setTimeout(() => this.NotifyLoadComplete(), 100);\n }\n\n /**\n * Handler for the Analyze button on the artifact viewer panel.\n * Creates a Data Snapshot artifact from the live viewer state, opens a\n * new conversation with it attached as input, and routes the user there.\n */\n async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n if (!this.currentUser) return;\n\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n // Route to the new conversation in the Conversations nav item\n await this.navigationService.OpenNavItemByName('Conversations', {\n conversationId: result.conversationId,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to start analysis conversation';\n MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 5000);\n }\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n // Try to load artifact name from database\n if (data.ResourceRecordID) {\n try {\n const md = new Metadata();\n const artifact = await md.GetEntityObject<any>('MJ: Conversation Artifacts');\n await artifact.Load(data.ResourceRecordID);\n return artifact.Name || `Artifact - ${data.ResourceRecordID}`;\n } catch (error) {\n console.error('Error loading artifact name:', error);\n }\n }\n return 'Artifact';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-file-code';\n }\n}\n"]}
1
+ {"version":3,"file":"artifact-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/artifact-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ViewEncapsulation, inject } from '@angular/core';\nimport { DataSnapshot, Metadata, UserInfo } from '@memberjunction/core';\nimport { RegisterClass } from '@memberjunction/global';\nimport { BaseResourceComponent } from '@memberjunction/ng-shared';\nimport { ResourceData, MJEnvironmentEntityExtended } from '@memberjunction/core-entities';\nimport { AnalyzeArtifactService } from '@memberjunction/ng-artifacts';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\n\n/**\n * Artifact Resource - displays versioned content artifacts\n * Wraps the artifact-viewer-panel component for tab-based display\n * Supports reports, dashboards, forms, and other artifact types\n */\n@RegisterClass(BaseResourceComponent, 'ArtifactResource')\n@Component({\n standalone: false,\n selector: 'mj-artifact-resource',\n template: `\n <div class=\"artifact-container\">\n @if (currentUser && artifactId) {\n <mj-artifact-viewer-panel\n [artifactId]=\"artifactId\"\n [currentUser]=\"currentUser\"\n [environmentId]=\"environmentId\"\n [showSaveToCollection]=\"true\"\n [canShare]=\"true\"\n [canEdit]=\"true\"\n (analyzeRequested)=\"onAnalyzeRequested($event)\">\n </mj-artifact-viewer-panel>\n }\n </div>\n `,\n styles: [`\n .artifact-container {\n display: flex;\n width: 100%;\n height: 100%;\n overflow: hidden;\n }\n `],\n encapsulation: ViewEncapsulation.None\n})\nexport class ArtifactResource extends BaseResourceComponent {\n private readonly analyzeService = inject(AnalyzeArtifactService);\n\n public currentUser: UserInfo | null = null;\n public artifactId: string = '';\n public environmentId: string = '';\n\n ngOnInit() {\n super.ngOnInit();\n const md = this.ProviderToUse;\n this.currentUser = md.CurrentUser;\n\n // Get artifact ID from resource data\n if (this.Data && this.Data.ResourceRecordID) {\n this.artifactId = this.Data.ResourceRecordID;\n }\n\n // Environment ID — use the configured environment if present, otherwise\n // fall back to the default environment. Must be a valid UUID since\n // downstream saves (e.g. AnalyzeArtifactService creating artifacts)\n // require a non-empty EnvironmentID.\n this.environmentId = (this.Data?.Configuration?.['environmentId'] as string | undefined)\n || MJEnvironmentEntityExtended.DefaultEnvironmentID;\n\n setTimeout(() => this.NotifyLoadComplete(), 100);\n }\n\n /**\n * Handler for the Analyze button on the artifact viewer panel.\n * Creates a Data Snapshot artifact from the live viewer state, opens a\n * new conversation with it attached as input, and routes the user there.\n */\n async onAnalyzeRequested(event: { artifactId: string; snapshot: DataSnapshot }): Promise<void> {\n if (!this.currentUser) return;\n\n try {\n const result = await this.analyzeService.StartAnalysisConversation({\n snapshot: event.snapshot,\n currentUser: this.currentUser,\n environmentId: this.environmentId,\n });\n\n // Route to the new conversation in the Conversations nav item\n await this.navigationService.OpenNavItemByName('Conversations', {\n conversationId: result.conversationId,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Failed to start analysis conversation';\n MJNotificationService.Instance.CreateSimpleNotification(message, 'error', 5000);\n }\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n // Try to load artifact name from database\n if (data.ResourceRecordID) {\n try {\n const md = this.ProviderToUse;\n const artifact = await md.GetEntityObject<any>('MJ: Conversation Artifacts');\n await artifact.Load(data.ResourceRecordID);\n return artifact.Name || `Artifact - ${data.ResourceRecordID}`;\n } catch (error) {\n console.error('Error loading artifact name:', error);\n }\n }\n return 'Artifact';\n }\n\n async GetResourceIconClass(data: ResourceData): Promise<string> {\n return 'fa-solid fa-file-code';\n }\n}\n"]}
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  import { Component, ViewEncapsulation, ChangeDetectorRef, inject } from '@angular/core';
8
- import { Metadata, RunView } from '@memberjunction/core';
8
+ import { RunView } from '@memberjunction/core';
9
9
  import { RegisterClass } from '@memberjunction/global';
10
10
  import { BaseResourceComponent } from '@memberjunction/ng-shared';
11
11
  import { MJEnvironmentEntityExtended } from '@memberjunction/core-entities';
@@ -73,7 +73,7 @@ let ChatCollectionsResource = class ChatCollectionsResource extends BaseResource
73
73
  analyzeService = inject(AnalyzeArtifactService);
74
74
  ngOnInit() {
75
75
  super.ngOnInit();
76
- const md = new Metadata();
76
+ const md = this.ProviderToUse;
77
77
  this.currentUser = md.CurrentUser;
78
78
  // Subscribe to artifact state changes
79
79
  this.subscribeToArtifactState();
@@ -193,7 +193,7 @@ let ChatCollectionsResource = class ChatCollectionsResource extends BaseResource
193
193
  return;
194
194
  }
195
195
  try {
196
- const rv = new RunView();
196
+ const rv = RunView.FromMetadataProvider(this.ProviderToUse);
197
197
  const result = await rv.RunView({
198
198
  EntityName: 'MJ: Collections',
199
199
  Fields: ['Name'],