@memberjunction/ng-explorer-settings 6.2.0-edge.0 → 6.2.0-edge.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/account-info/account-info.component.d.ts +1 -1
- package/dist/lib/account-info/account-info.component.js +2 -2
- package/dist/lib/account-info/account-info.component.js.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +92 -10
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.js +222 -76
- package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
- package/dist/lib/application-management/application-management.component.d.ts +92 -10
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-management.component.js +229 -65
- package/dist/lib/application-management/application-management.component.js.map +1 -1
- package/dist/lib/application-settings/application-settings.component.d.ts +4 -4
- package/dist/lib/application-settings/application-settings.component.js +10 -10
- package/dist/lib/application-settings/application-settings.component.js.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +88 -10
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.js +219 -63
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts +44 -6
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js +117 -43
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts +25 -3
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.js +62 -18
- package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts +32 -4
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.js +84 -30
- package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
- package/dist/lib/role-management/role-management-agent-context.d.ts +12 -4
- package/dist/lib/role-management/role-management-agent-context.d.ts.map +1 -1
- package/dist/lib/role-management/role-management-agent-context.js +26 -10
- package/dist/lib/role-management/role-management-agent-context.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +95 -11
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-management.component.js +259 -91
- package/dist/lib/role-management/role-management.component.js.map +1 -1
- package/dist/lib/settings/settings.component.d.ts +87 -11
- package/dist/lib/settings/settings.component.d.ts.map +1 -1
- package/dist/lib/settings/settings.component.js +211 -65
- package/dist/lib/settings/settings.component.js.map +1 -1
- package/dist/lib/shared/settings-card.component.d.ts +24 -4
- package/dist/lib/shared/settings-card.component.d.ts.map +1 -1
- package/dist/lib/shared/settings-card.component.js +46 -6
- package/dist/lib/shared/settings-card.component.js.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.d.ts +172 -18
- package/dist/lib/sql-logging/sql-logging.component.d.ts.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.js +320 -108
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config-content.component.js +3 -3
- package/dist/lib/user-app-config/user-app-config-content.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config-reorder.d.ts +4 -0
- package/dist/lib/user-app-config/user-app-config-reorder.d.ts.map +1 -1
- package/dist/lib/user-app-config/user-app-config-reorder.js +11 -3
- package/dist/lib/user-app-config/user-app-config-reorder.js.map +1 -1
- package/dist/lib/user-management/transaction-group-refusals.d.ts +4 -2
- package/dist/lib/user-management/transaction-group-refusals.d.ts.map +1 -1
- package/dist/lib/user-management/transaction-group-refusals.js +7 -3
- package/dist/lib/user-management/transaction-group-refusals.js.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +44 -6
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.js +121 -47
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management-agent-context.d.ts +10 -0
- package/dist/lib/user-management/user-management-agent-context.d.ts.map +1 -1
- package/dist/lib/user-management/user-management-agent-context.js +26 -6
- package/dist/lib/user-management/user-management-agent-context.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +174 -16
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +480 -171
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +97 -15
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.js +280 -116
- package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
- package/package.json +20 -20
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-management.component.js","sourceRoot":"","sources":["../../../src/lib/application-management/application-management.component.ts","../../../src/lib/application-management/application-management.component.html"],"names":[],"mappings":"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","sourcesContent":["import { ChangeDetectorRef, Component, NgZone, OnDestroy } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata, EntityInfo } from '@memberjunction/core';\nimport { MJApplicationEntity, MJApplicationEntityEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { ApplicationDialogData, ApplicationDialogResult } from './application-dialog/application-dialog.component';\n\ninterface AppStats {\n totalApplications: number;\n activeApplications: number;\n totalEntities: number;\n publicEntities: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-application-management',\n templateUrl: './application-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './application-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'ApplicationManagement')\nexport class ApplicationManagementComponent extends BaseDashboard implements OnDestroy {\n // State management\n public applications: MJApplicationEntity[] = [];\n public filteredApplications: MJApplicationEntity[] = [];\n public selectedApp: MJApplicationEntity | null = null;\n public isLoading = false;\n public error: string | null = null;\n\n // Application entities mapping\n public appEntities: Map<string, MJApplicationEntityEntity[]> = new Map();\n\n // Stats\n public stats: AppStats = {\n totalApplications: 0,\n activeApplications: 0,\n totalEntities: 0,\n publicEntities: 0\n };\n\n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n search: ''\n });\n\n // UI State\n public showApplicationDialog = false;\n public applicationDialogData: ApplicationDialogData | null = null;\n public showDeleteConfirm = false;\n public expandedAppId: string | null = null;\n\n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Application Management\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n }\n\n protected loadData(): void {\n this.loadInitialData();\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async loadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load applications and their entities\n const [apps, appEntities] = await Promise.all([\n this.loadApplications(),\n this.loadApplicationEntities()\n ]);\n \n this.applications = apps;\n this.processApplicationEntities(appEntities);\n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading application data:', error);\n this.error = 'Failed to load application data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async loadApplications(): Promise<MJApplicationEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJApplicationEntity>({\n EntityName: 'MJ: Applications',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadApplicationEntities(): Promise<MJApplicationEntityEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJApplicationEntityEntity>({\n EntityName: 'MJ: Application Entities',\n ResultType: 'entity_object',\n OrderBy: 'ApplicationID, Sequence'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private processApplicationEntities(appEntities: MJApplicationEntityEntity[]): void {\n this.appEntities.clear();\n \n for (const appEntity of appEntities) {\n const appId = appEntity.ApplicationID;\n if (!this.appEntities.has(appId)) {\n this.appEntities.set(appId, []);\n }\n this.appEntities.get(appId)!.push(appEntity);\n }\n }\n \n private setupFilterSubscription(): void {\n this.filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n });\n }\n \n private applyFilters(): void {\n const filters = this.filters$.value;\n let filtered = [...this.applications];\n \n // Apply status filter - for now, all applications are considered active\n // In the future, we might add an IsActive field to the Applications table\n if (filters.status === 'inactive') {\n // Currently no way to determine inactive apps\n filtered = [];\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(app =>\n app.Name?.toLowerCase().includes(searchLower) ||\n app.Description?.toLowerCase().includes(searchLower)\n );\n }\n \n this.filteredApplications = filtered;\n this.cdr.detectChanges();\n }\n \n private calculateStats(): void {\n // For now, consider all applications as active\n const activeApps = this.applications;\n let totalEntities = 0;\n let publicEntities = 0;\n \n for (const [, entities] of this.appEntities) {\n totalEntities += entities.length;\n publicEntities += entities.filter(e => e.DefaultForNewUser).length;\n }\n \n this.stats = {\n totalApplications: this.applications.length,\n activeApplications: activeApps.length,\n totalEntities,\n publicEntities\n };\n }\n \n // Public methods for template\n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.updateFilter({ status });\n }\n \n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n // Discrete changes (chips) apply immediately. Text search still goes\n // through the 300ms debounce in setupFilterSubscription.\n if (!('search' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n\n // -- Concise chrome: one Filter popover (Status) + applied-filter chips -----\n\n public get filterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Active', value: 'active' },\n { text: 'Inactive', value: 'inactive' },\n ],\n },\n ];\n }\n\n public get filterValues(): Record<string, unknown> {\n return { status: this.filters$.value.status };\n }\n\n /** Total active filters (Status) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n return this.filters$.value.status !== 'all' ? 1 : 0;\n }\n\n public onFilterPanelChange(values: Record<string, unknown>): void {\n if ('status' in values) {\n this.updateFilter({ status: (values['status'] as FilterOptions['status']) || 'all' });\n }\n }\n\n /** Clear all filters (Status); search persists. */\n public clearAllAppliedFilters(): void {\n this.updateFilter({ status: 'all' });\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.filters$.value.search !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Status) and refresh\n * immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public resetAllFiltersAndSearch(): void {\n this.filters$.next({ status: 'all', search: '' });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n \n public toggleAppExpansion(appId: string): void {\n this.expandedAppId = this.expandedAppId === appId ? null : appId;\n }\n \n public isAppExpanded(appId: string): boolean {\n return this.expandedAppId === appId;\n }\n \n public getAppEntities(appId: string): MJApplicationEntityEntity[] {\n return this.appEntities.get(appId) || [];\n }\n \n public getEntityInfo(entityId: string): EntityInfo | undefined {\n return this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n }\n \n public createNewApplication(): void {\n this.applicationDialogData = {\n mode: 'create'\n };\n this.showApplicationDialog = true;\n }\n \n public editApplication(app: MJApplicationEntity): void {\n this.applicationDialogData = {\n application: app,\n mode: 'edit'\n };\n this.showApplicationDialog = true;\n }\n \n public confirmDeleteApplication(app: MJApplicationEntity): void {\n this.selectedApp = app;\n this.showDeleteConfirm = true;\n }\n \n public async deleteApplication(): Promise<void> {\n if (!this.selectedApp) return;\n \n try {\n this.isLoading = true;\n this.error = null;\n\n // Delete the application\n const deleteResult = await this.selectedApp.Delete();\n if (!deleteResult) {\n throw new Error(this.selectedApp.LatestResult?.Message || 'Failed to delete application');\n }\n\n this.showDeleteConfirm = false;\n this.selectedApp = null;\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Error deleting application:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete application';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n public onApplicationDialogResult(result: ApplicationDialogResult): void {\n this.showApplicationDialog = false;\n this.applicationDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the application list after save\n this.loadInitialData();\n }\n }\n \n public getAppIcon(app: MJApplicationEntity): string {\n // Map application names to appropriate icons based on their purpose\n const name = (app.Name || '').toLowerCase();\n\n // Common application type mappings\n if (name.includes('admin') || name.includes('management')) {\n return 'fa-cog';\n }\n if (name.includes('report') || name.includes('analytics') || name.includes('dashboard')) {\n return 'fa-chart-line';\n }\n if (name.includes('user') || name.includes('people') || name.includes('employee')) {\n return 'fa-users';\n }\n if (name.includes('settings') || name.includes('config')) {\n return 'fa-sliders';\n }\n if (name.includes('data') || name.includes('database')) {\n return 'fa-database';\n }\n if (name.includes('file') || name.includes('document')) {\n return 'fa-file-alt';\n }\n if (name.includes('mail') || name.includes('email') || name.includes('message')) {\n return 'fa-envelope';\n }\n if (name.includes('search') || name.includes('explorer')) {\n return 'fa-search';\n }\n if (name.includes('calendar') || name.includes('schedule') || name.includes('event')) {\n return 'fa-calendar';\n }\n if (name.includes('security') || name.includes('auth') || name.includes('permission')) {\n return 'fa-shield-alt';\n }\n if (name.includes('integration') || name.includes('api') || name.includes('connect')) {\n return 'fa-plug';\n }\n if (name.includes('workflow') || name.includes('process') || name.includes('automation')) {\n return 'fa-project-diagram';\n }\n if (name.includes('ai') || name.includes('intelligence') || name.includes('machine')) {\n return 'fa-brain';\n }\n if (name.includes('home') || name.includes('main') || name.includes('default')) {\n return 'fa-home';\n }\n\n // Default icon for applications\n return 'fa-grid-2';\n }\n \n public getAppStatusClass(app: MJApplicationEntity): string {\n // For now, all apps are considered active\n return 'status-active';\n }\n \n public getAppStatusLabel(app: MJApplicationEntity): string {\n // For now, all apps are considered active\n return 'Active';\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n}","<!--\n Interior chrome — see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter applications\"\n Title=\"Applications\"\n Subtitle=\"Configure applications and their entity associations\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n Partition badges (entities/public) stay dropped — Active/Inactive\n chips in [toolbar] handle the partition signal. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredApplications.length\"\n [Total]=\"applications.length\"\n Label=\"applications\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter. Status lives behind the\n one Filter button; applied filters show as removable chips below the\n card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search applications by name or description...\"\n [Value]=\"filters$.value.search\"\n (ValueChange)=\"updateFilter({ search: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"createNewApplication()\" aria-label=\"Add new application\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"mj-action-label\">Add Application</span>\n </button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\n <mj-loading text=\"Loading applications...\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button mjButton variant=\"primary\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Applications List -->\n @if (!isLoading && !error) {\n <div class=\"applications-list\" role=\"list\">\n @for (app of filteredApplications; track app.ID) {\n <div class=\"app-card\" [class.expanded]=\"isAppExpanded(app.ID)\" role=\"listitem\">\n <div class=\"app-header\" (click)=\"toggleAppExpansion(app.ID)\" role=\"button\" [attr.aria-expanded]=\"isAppExpanded(app.ID)\">\n <div class=\"app-info\">\n <div class=\"app-icon-wrapper\">\n <i [class]=\"'fa-solid ' + getAppIcon(app)\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"app-details\">\n <h3 class=\"app-name\">{{ app.Name }}</h3>\n <p class=\"app-description\">{{ app.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"app-meta\">\n <span class=\"status-badge\" [class]=\"getAppStatusClass(app)\">\n {{ getAppStatusLabel(app) }}\n </span>\n <div class=\"app-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editApplication(app)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + app.Name\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteApplication(app)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + app.Name\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isAppExpanded(app.ID)) {\n <div class=\"app-content\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getAppStatusClass(app)\">\n {{ getAppStatusLabel(app) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editApplication(app)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + app.Name\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteApplication(app)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + app.Name\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <div class=\"app-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Entities:</span>\n <span class=\"stat-value\">{{ getAppEntities(app.ID).length }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ app.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ app.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <div class=\"entities-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n Application Entities\n </h4>\n\n @if (getAppEntities(app.ID).length > 0) {\n <div class=\"entities-grid\">\n @for (appEntity of getAppEntities(app.ID); track appEntity.ID) {\n @if (getEntityInfo(appEntity.EntityID); as entity) {\n <div class=\"entity-item\">\n <div class=\"entity-name\">{{ entity.DisplayNameOrName }}</div>\n <div class=\"entity-meta\">\n @if (appEntity.DefaultForNewUser) {\n <span class=\"entity-badge public\">Public</span>\n }\n <span class=\"entity-sequence\">Order: {{ appEntity.Sequence }}</span>\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <p class=\"no-entities\">No entities configured for this application</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredApplications.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-cubes\"\n Title=\"No applications found\"\n Message=\"Try adjusting your filters or create a new application\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : ''\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"resetAllFiltersAndSearch()\" />\n }\n </div>\n }\n </mj-page-body-interior>\n\n <!-- Application Dialog -->\n <mj-application-dialog\n [visible]=\"showApplicationDialog\"\n [data]=\"applicationDialogData\"\n (result)=\"onApplicationDialogResult($event)\"\n ></mj-application-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedApp) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\" role=\"presentation\">\n <div\n class=\"modal-dialog\"\n (click)=\"$event.stopPropagation()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-description\"\n >\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-description\">\n <p>Are you sure you want to delete the application <strong>{{ selectedApp.Name }}</strong>?</p>\n <mj-alert Variant=\"warning\" Message=\"This will remove all entity associations for this application.\" />\n </div>\n <div class=\"modal-footer\">\n <!-- Primary action (Delete) on LEFT per MD3 design guide -->\n <button mjButton variant=\"danger\" (click)=\"deleteApplication()\" [disabled]=\"isLoading\">\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Deleting...\n } @else {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete Application\n }\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n"]}
|
|
1
|
+
{"version":3,"file":"application-management.component.js","sourceRoot":"","sources":["../../../src/lib/application-management/application-management.component.ts","../../../src/lib/application-management/application-management.component.html"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAqB,SAAS,EAAqB,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,OAAO,EAAwB,MAAM,sBAAsB,CAAC;AAErE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAG,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;;;;;;IC8ChE,+BAAgE;IAC9D,iCAAwD;IAC1D,iBAAM;;;;IAMJ,AADF,+BAA0C,cACb;IACzB,wBAA8E;IAC9E,6BAAyB;IAAA,YAAW;IAAA,iBAAI;IACxC,kCAA+D;IAA5B,mMAAS,wBAAiB,KAAC;IAC5D,wBAAmC;IACnC,2BACF;IAEJ,AADE,AADE,iBAAS,EACL,EACF;;;IANuB,eAAW;IAAX,kCAAW;;;IAkHZ,gCAAkC;IAAA,sBAAM;IAAA,iBAAO;;;IAHnD,AADF,+BAAyB,cACE;IAAA,YAA8B;IAAA,iBAAM;IAC7D,+BAAyB;IACvB,yKAAmC;IAGnC,gCAA8B;IAAA,YAA+B;IAEjE,AADE,AAD+D,iBAAO,EAChE,EACF;;;IAPqB,eAA8B;IAA9B,2CAA8B;IAErD,eAEC;IAFD,yDAEC;IAC6B,eAA+B;IAA/B,uDAA+B;;;IAPnE,0JAAoD;;;;;IAApD,6FAUC;;;IAZL,+BAA2B;IACzB,sJAYC;IACH,iBAAM;;;;IAbJ,cAYC;IAZD,cAAA,gCAAsB,CAYrB;;;IAGH,6BAAuB;IAAA,2DAA2C;IAAA,iBAAI;;;;IAnE1E,AAFF,+BAAyB,cAE4C;IAAnC,kJAAS,wBAAwB,IAAC;IAChE,gCAA4D;IAC1D,YACF;IAAA,iBAAO;IAEL,AADF,+BAAmC,iBAMhC;IAHC,sQAAS,8BAAoB,KAAC;IAI9B,wBAAgC;IAChC,gCAAwB;IAAA,oBAAI;IAC9B,AAD8B,iBAAO,EAC5B;IACT,kCAKC;IAHC,sQAAS,uCAA6B,KAAC;IAIvC,yBAAiC;IACjC,iCAAwB;IAAA,uBAAM;IAGpC,AADE,AADE,AADgC,iBAAO,EAC9B,EACL,EACF;IAGJ,AADF,gCAAuB,eACE;IACrB,yBAAuD;IACvD,iCAAyB;IAAA,0BAAS;IAAA,iBAAO;IACzC,iCAAyB;IAAA,aAAmC;IAC9D,AAD8D,iBAAO,EAC/D;IACN,gCAAuB;IACrB,yBAAuD;IACvD,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAuC;;IAClE,AADkE,iBAAO,EACnE;IACN,gCAAuB;IACrB,yBAAoD;IACpD,iCAAyB;IAAA,yBAAQ;IAAA,iBAAO;IACxC,iCAAyB;IAAA,aAAuC;;IAEpE,AADE,AADkE,iBAAO,EACnE,EACF;IAGJ,AADF,gCAA8B,cACF;IACxB,yBAAuD;IACvD,uCACF;IAAA,iBAAK;IAkBH,AAhBF,uIAAyC,+GAgBhC;IAIb,AADE,iBAAM,EACF;;;;IArEyB,eAAgC;IAAhC,+CAAgC;IACzD,cACF;IADE,iEACF;IAMI,eAAsC;;IAStC,eAAwC;;IAYjB,gBAAmC;IAAnC,6DAAmC;IAKnC,eAAuC;IAAvC,2EAAuC;IAKvC,eAAuC;IAAvC,4EAAuC;IAUlE,eAkBC;IAlBD,uEAkBC;;;;IA9GP,AADF,+BAA+E,cAC2C;IAAhG,gOAAS,oCAA0B,KAAC;IAExD,AADF,+BAAsB,cACU;IAC5B,wBAAkE;IACpE,iBAAM;IAEJ,AADF,+BAAyB,aACF;IAAA,YAAc;IAAA,iBAAK;IACxC,6BAA2B;IAAA,YAAmD;IAElF,AADE,AADgF,iBAAI,EAC9E,EACF;IAGJ,AADF,gCAAsB,gBACwC;IAC1D,aACF;IAAA,iBAAO;IACP,gCAA4D;IAAnC,oIAAS,wBAAwB,IAAC;IACzD,mCAKC;IAHC,oOAAS,8BAAoB,KAAC;IAI9B,yBAAgC;IAClC,iBAAS;IACT,mCAKC;IAHC,oOAAS,uCAA6B,KAAC;IAIvC,yBAAiC;IAErC,AADE,iBAAS,EACL;IACN,mCAAuD;IACrD,yBAA2D;IAGjE,AADE,AADE,iBAAS,EACL,EACF;IAEN,0HAA6B;IA2E/B,iBAAM;;;;IAnHgB,2DAAwC;IACe,cAA4C;;IAG9G,eAAuC;IAAvC,sDAAuC;IAGrB,eAAc;IAAd,iCAAc;IACR,eAAmD;IAAnD,sEAAmD;IAKrD,eAAgC;IAAhC,+CAAgC;IACzD,cACF;IADE,iEACF;IAMI,eAAsC;;IAQtC,eAAwC;;IAWhD,eA0EC;IA1ED,2DA0EC;;;;IAKH,0CAO0C;IAAxC,4NAAU,iCAA0B,KAAC;IAPvC,iBAO0C;;;IAFxC,AAJA,wEAAmD,4DAIC;;;IA9H5D,+BAA2C;IACvC,mHAqHC;IAED,2HAAyC;IAU7C,iBAAM;;;IAjIF,cAqHC;IArHD,0CAqHC;IAED,eASC;IATD,mEASC;;;IA4CK,wBAA8D;IAC9D,6BACF;;;IACE,wBAAoD;IACpD,oCACF;;;;IAnCR,+BAAoF;IAAxD,2NAA6B,KAAK,KAAC;IAC7D,+BAOC;IALC,6HAAS,wBAAwB,IAAC;IAOhC,AADF,+BAA0B,aACyB;IAC/C,wBAA+E;IAC/E,gCACF;IAAA,iBAAK;IACL,kCAIC;IAFC,8NAA6B,KAAK,KAAC;IAGnC,wBAAoD;IAExD,AADE,iBAAS,EACL;IAEJ,AADF,+BAAuD,QAClD;IAAA,iEAAgD;IAAA,+BAAQ;IAAA,aAAsB;IAAA,iBAAS;IAAA,kBAAC;IAAA,iBAAI;IAC/F,gCAAuG;IACzG,iBAAM;IAGJ,AAFF,gCAA0B,kBAE+D;IAArD,oMAAS,0BAAmB,KAAC;IAI3D,AAHF,uGAAiB,iFAGR;IAIX,iBAAS;IACT,mCAAqD;IAApC,+NAA6B,KAAK,KAAC;IAClD,yBACF;IAGN,AADE,AADE,AADE,iBAAS,EACL,EACF,EACF;;;IAnB2D,gBAAsB;IAAtB,6CAAsB;IAKjB,eAAsB;IAAtB,2CAAsB;IACpF,cAMC;IAND,4CAMC;;AD9NN,IAAM,8BAA8B,GAApC,MAAM,8BAA+B,SAAQ,aAAa;IA2H3C;IAAgC;IA1HpD,mBAAmB;IACZ,YAAY,GAA0B,EAAE,CAAC;IAEhD,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IACD,4CAA4C;IAC5C,IAAW,YAAY,CAAC,KAA4B;QAClD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC5B,CAAC;IACM,oBAAoB,GAA0B,EAAE,CAAC;IAExD,oDAAoD;IACpD,IAAW,oBAAoB;QAC7B,OAAO,IAAI,CAAC,oBAAoB,CAAC;IACnC,CAAC;IACD,oDAAoD;IACpD,IAAW,oBAAoB,CAAC,KAA4B;QAC1D,IAAI,CAAC,oBAAoB,GAAG,KAAK,CAAC;IACpC,CAAC;IACM,WAAW,GAA+B,IAAI,CAAC;IAEtD,2CAA2C;IAC3C,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IACD,2CAA2C;IAC3C,IAAW,WAAW,CAAC,KAAiC;QACtD,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IACM,SAAS,GAAG,KAAK,CAAC;IAClB,KAAK,GAAkB,IAAI,CAAC;IAEnC,+BAA+B;IACxB,WAAW,GAA6C,IAAI,GAAG,EAAE,CAAC;IAEzE,2CAA2C;IAC3C,IAAW,WAAW;QACpB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IACD,2CAA2C;IAC3C,IAAW,WAAW,CAAC,KAA+C;QACpE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED,QAAQ;IACD,KAAK,GAAa;QACvB,iBAAiB,EAAE,CAAC;QACpB,kBAAkB,EAAE,CAAC;QACrB,aAAa,EAAE,CAAC;QAChB,cAAc,EAAE,CAAC;KAClB,CAAC;IAEF,qCAAqC;IACrC,IAAW,KAAK;QACd,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IACD,qCAAqC;IACrC,IAAW,KAAK,CAAC,KAAe;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,UAAU;IACH,QAAQ,GAAG,IAAI,eAAe,CAAgB;QACnD,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,EAAE;KACX,CAAC,CAAC;IAEH,wCAAwC;IACxC,IAAW,QAAQ;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IACD,wCAAwC;IACxC,IAAW,QAAQ,CAAC,KAAK;QACvB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED,WAAW;IACJ,qBAAqB,GAAG,KAAK,CAAC;IAErC,qDAAqD;IACrD,IAAW,qBAAqB;QAC9B,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IACD,qDAAqD;IACrD,IAAW,qBAAqB,CAAC,KAAK;QACpC,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;IACrC,CAAC;IACM,qBAAqB,GAAiC,IAAI,CAAC;IAElE,qDAAqD;IACrD,IAAW,qBAAqB;QAC9B,OAAO,IAAI,CAAC,qBAAqB,CAAC;IACpC,CAAC;IACD,qDAAqD;IACrD,IAAW,qBAAqB,CAAC,KAAmC;QAClE,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;IACrC,CAAC;IACM,iBAAiB,GAAG,KAAK,CAAC;IAEjC,iDAAiD;IACjD,IAAW,iBAAiB;QAC1B,OAAO,IAAI,CAAC,iBAAiB,CAAC;IAChC,CAAC;IACD,iDAAiD;IACjD,IAAW,iBAAiB,CAAC,KAAK;QAChC,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;IACjC,CAAC;IACM,aAAa,GAAkB,IAAI,CAAC;IAE3C,6CAA6C;IAC7C,IAAW,aAAa;QACtB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IACD,6CAA6C;IAC7C,IAAW,aAAa,CAAC,KAAoB;QAC3C,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;IAC7B,CAAC;IAEkB,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;IAClD,IAAY,QAAQ,KAAK,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,YAAoB,GAAsB,EAAU,MAAc;QAChE,KAAK,EAAE,CAAC;QADU,QAAG,GAAH,GAAG,CAAmB;QAAU,WAAM,GAAN,MAAM,CAAQ;IAElE,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC7C,OAAO,wBAAwB,CAAA;IACjC,CAAC;IAES,aAAa;QACrB,IAAI,CAAC,uBAAuB,EAAE,CAAC;IACjC,CAAC;IAES,QAAQ;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAEQ,WAAW;QAClB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACzB,KAAK,CAAC,WAAW,EAAE,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,eAAe;QAC1B,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAElB,uCAAuC;YACvC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC5C,IAAI,CAAC,gBAAgB,EAAE;gBACvB,IAAI,CAAC,uBAAuB,EAAE;aAC/B,CAAC,CAAC;YAEH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,IAAI,CAAC,0BAA0B,CAAC,WAAW,CAAC,CAAC;YAC7C,IAAI,CAAC,cAAc,EAAE,CAAC;YACtB,IAAI,CAAC,YAAY,EAAE,CAAC;QAEtB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;YACxD,IAAI,CAAC,KAAK,GAAG,oDAAoD,CAAC;QACpE,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+CAA+C;IACxC,KAAK,CAAC,eAAe;QAC1B,OAAO,IAAI,CAAC,eAAe,EAAE,CAAC;IAChC,CAAC;IAEO,KAAK,CAAC,gBAAgB;QAC5B,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAsB;YACnD,UAAU,EAAE,kBAAkB;YAC9B,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,UAAU;SACpB,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,KAAK,CAAC,uBAAuB;QACnC,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAA4B;YACzD,UAAU,EAAE,0BAA0B;YACtC,UAAU,EAAE,eAAe;YAC3B,OAAO,EAAE,yBAAyB;SACnC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9C,CAAC;IAEO,0BAA0B,CAAC,WAAwC;QACzE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAEzB,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,SAAS,CAAC,aAAa,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,QAAQ;aACV,IAAI,CACH,YAAY,CAAC,GAAG,CAAC,EACjB,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EACvE,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CACzB;aACA,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,YAAY;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,IAAI,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;QAEtC,wEAAwE;QACxE,0EAA0E;QAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAClC,8CAA8C;YAC9C,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;QAED,sBAAsB;QACtB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACjD,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC/B,GAAG,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC;gBAC7C,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CACrD,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,oBAAoB,GAAG,QAAQ,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAEO,cAAc;QACpB,+CAA+C;QAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC;QACrC,IAAI,aAAa,GAAG,CAAC,CAAC;QACtB,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,CAAC,EAAE,QAAQ,CAAC,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5C,aAAa,IAAI,QAAQ,CAAC,MAAM,CAAC;YACjC,cAAc,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC;QACrE,CAAC;QAED,IAAI,CAAC,KAAK,GAAG;YACX,iBAAiB,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM;YAC3C,kBAAkB,EAAE,UAAU,CAAC,MAAM;YACrC,aAAa;YACb,cAAc;SACf,CAAC;IACJ,CAAC;IAED,8BAA8B;IACvB,oBAAoB,CAAC,MAAqC;QAC/D,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,oDAAoD;IAC7C,oBAAoB,CAAC,MAAqC;QAC/D,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAEM,YAAY,CAAC,OAA+B;QACjD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;YACjB,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK;YACtB,GAAG,OAAO;SACX,CAAC,CAAC;QACH,qEAAqE;QACrE,yDAAyD;QACzD,IAAI,CAAC,CAAC,QAAQ,IAAI,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,4CAA4C;IACrC,YAAY,CAAC,OAA+B;QACjD,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,8EAA8E;IAE9E,IAAW,YAAY;QACrB,OAAO;YACL;gBACE,GAAG,EAAE,QAAQ;gBACb,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,QAAQ;gBACf,WAAW,EAAE;oBACX,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE;oBAC7B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;oBACnC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;iBACxC;aACF;SACF,CAAC;IACJ,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,IAAW,YAAY;QACrB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IAChD,CAAC;IAED,4CAA4C;IAC5C,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,sEAAsE;IACtE,IAAW,sBAAsB;QAC/B,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,CAAC;IAEM,mBAAmB,CAAC,MAA+B;QACxD,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;YACvB,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAG,MAAM,CAAC,QAAQ,CAA6B,IAAI,KAAK,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,mDAAmD;IAC5C,mBAAmB,CAAC,MAA+B;QACxD,OAAO,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,mDAAmD;IAC5C,sBAAsB;QAC3B,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,sDAAsD;IAC/C,sBAAsB;QAC3B,OAAO,IAAI,CAAC,sBAAsB,EAAE,CAAC;IACvC,CAAC;IAED;sDACkD;IAClD,IAAW,cAAc;QACvB,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,KAAK,EAAE,IAAI,IAAI,CAAC,sBAAsB,GAAG,CAAC,CAAC;IAC9E,CAAC;IAED;;qEAEiE;IAC1D,wBAAwB;QAC7B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,YAAY,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;IAC1B,CAAC;IAED,wDAAwD;IACjD,wBAAwB;QAC7B,OAAO,IAAI,CAAC,wBAAwB,EAAE,CAAC;IACzC,CAAC;IAEM,kBAAkB,CAAC,KAAa;QACrC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IACnE,CAAC;IAED,kDAAkD;IAC3C,kBAAkB,CAAC,KAAa;QACrC,OAAO,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAEM,aAAa,CAAC,KAAa;QAChC,OAAO,IAAI,CAAC,aAAa,KAAK,KAAK,CAAC;IACtC,CAAC;IAED,6CAA6C;IACtC,aAAa,CAAC,KAAa;QAChC,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IAEM,cAAc,CAAC,KAAa;QACjC,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC;IAED,8CAA8C;IACvC,cAAc,CAAC,KAAa;QACjC,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAEM,aAAa,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,6CAA6C;IACtC,aAAa,CAAC,QAAgB;QACnC,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAEM,oBAAoB;QACzB,IAAI,CAAC,qBAAqB,GAAG;YAC3B,IAAI,EAAE,QAAQ;SACf,CAAC;QACF,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,oDAAoD;IAC7C,oBAAoB;QACzB,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC;IACrC,CAAC;IAEM,eAAe,CAAC,GAAwB;QAC7C,IAAI,CAAC,qBAAqB,GAAG;YAC3B,WAAW,EAAE,GAAG;YAChB,IAAI,EAAE,MAAM;SACb,CAAC;QACF,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,+CAA+C;IACxC,eAAe,CAAC,GAAwB;QAC7C,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IACnC,CAAC;IAEM,wBAAwB,CAAC,GAAwB;QACtD,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;QACvB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAChC,CAAC;IAED,wDAAwD;IACjD,wBAAwB,CAAC,GAAwB;QACtD,OAAO,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC;IAEM,KAAK,CAAC,iBAAiB;QAC5B,IAAI,CAAC,IAAI,CAAC,WAAW;YAAE,OAAO;QAE9B,IAAI,CAAC;YACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAElB,yBAAyB;YACzB,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC;YACrD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,OAAO,IAAI,8BAA8B,CAAC,CAAC;YAC5F,CAAC;YAED,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,KAAK,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC;gBACrF,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;gBACvB,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC;YAC1B,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,iDAAiD;IAC1C,KAAK,CAAC,iBAAiB;QAC5B,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC;IAClC,CAAC;IAEM,yBAAyB,CAAC,MAA+B;QAC9D,IAAI,CAAC,qBAAqB,GAAG,KAAK,CAAC;QACnC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QAElC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAC7B,0CAA0C;YAC1C,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,CAAC;IACH,CAAC;IAED,yDAAyD;IAClD,yBAAyB,CAAC,MAA+B;QAC9D,OAAO,IAAI,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAEM,UAAU,CAAC,GAAwB;QACxC,oEAAoE;QACpE,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAE5C,mCAAmC;QACnC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAC1D,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACxF,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAClF,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACzD,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAChF,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACzD,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACrF,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACtF,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrF,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YACzF,OAAO,oBAAoB,CAAC;QAC9B,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrF,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC/E,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,gCAAgC;QAChC,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,0CAA0C;IACnC,UAAU,CAAC,GAAwB;QACxC,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAEM,iBAAiB,CAAC,GAAwB;QAC/C,0CAA0C;QAC1C,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,iDAAiD;IAC1C,iBAAiB,CAAC,GAAwB;QAC/C,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IAEM,iBAAiB,CAAC,GAAwB;QAC/C,0CAA0C;QAC1C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,iDAAiD;IAC1C,iBAAiB,CAAC,GAAwB;QAC/C,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrC,CAAC;IAEM,WAAW;QAChB,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,2CAA2C;IACpC,WAAW;QAChB,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAC5B,CAAC;wHAhkBU,8BAA8B;6DAA9B,8BAA8B;YCnBzC,AAPF,kDAGkE,aAItD;YACR,mCAIgB;YAClB,iBAAM;YAKJ,AAJF,8BAAa,wBAOwC;YAAjD,qIAAe,iBAAa,kBAAkB,CAAC,IAAC;YAClD,iBAAiB;YACjB,4CAKiD;YAA/C,8IAAqB,4BAAwB,IAAC;YAC9C,0CAIqC;YAAnC,AADA,wIAAgB,+BAA2B,IAAC,uGACnC,4BAAwB,IAAC;YAGxC,AADE,AADE,iBAAkB,EACA,EAChB;YAEJ,AADF,8BAAa,2BACwD;YAA1B,0HAAW,iBAAa,IAAC;YAAC,iBAAoB;YACvF,iCAA+G;YAAlE,2GAAS,0BAAsB,IAAC;YAC3E,yBAAgC;YAAC,iCAA8B;YAAA,gCAAe;YAGpF,AADE,AADE,AADgF,iBAAO,EAC9E,EACL,EACkB;YAG1B,8CAAuB;YAErB,mGAAiB;YAOjB,mGAA2B;YAc3B,mGAA4B;YAqI5B,iBAAwB;YAGxB,kDAIC;YADC,mIAAU,qCAAiC,IAAC;YAC7C,iBAAwB;YAGzB,oGAAwC;;YA3MpC,eAAqC;YACrC,AADA,uDAAqC,kCACR;YAU7B,eAA+B;YAA/B,iDAA+B;YAM/B,cAAsC;YACtC,AADA,wDAAsC,gDACK;YAGzC,cAAuB;YACvB,AADA,yCAAuB,4BACA;YAOR,eAAqB;YAArB,uCAAqB;YAU1C,eAIC;YAJD,yCAIC;YAGD,cAWC;YAXD,uDAWC;YAGD,cAoIC;YApID,wDAoIC;YAKC,cAAiC;YACjC,AADA,mDAAiC,mCACH;YAKhC,cA4CC;YA5CD,oEA4CC;;;ADtOU,8BAA8B;IAD1C,aAAa,CAAC,aAAa,EAAE,uBAAuB,CAAC;GACzC,8BAA8B,CAikB1C;;iFAjkBY,8BAA8B;cAP1C,SAAS;6BACI,KAAK,YACP,2BAA2B;;kFAK1B,8BAA8B","sourcesContent":["import { ChangeDetectorRef, Component, NgZone, OnDestroy } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata, EntityInfo } from '@memberjunction/core';\nimport { MJApplicationEntity, MJApplicationEntityEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass , UUIDsEqual } from '@memberjunction/global';\nimport { FilterFieldConfig } from '@memberjunction/ng-ui-components';\nimport { ApplicationDialogData, ApplicationDialogResult } from './application-dialog/application-dialog.component';\n\ninterface AppStats {\n totalApplications: number;\n activeApplications: number;\n totalEntities: number;\n publicEntities: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-application-management',\n templateUrl: './application-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './application-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'ApplicationManagement')\nexport class ApplicationManagementComponent extends BaseDashboard implements OnDestroy {\n // State management\n public Applications: MJApplicationEntity[] = [];\n\n /** @deprecated Use {@link Applications}. */\n public get applications(): MJApplicationEntity[] {\n return this.Applications;\n }\n /** @deprecated Use {@link Applications}. */\n public set applications(value: MJApplicationEntity[]) {\n this.Applications = value;\n }\n public FilteredApplications: MJApplicationEntity[] = [];\n\n /** @deprecated Use {@link FilteredApplications}. */\n public get filteredApplications(): MJApplicationEntity[] {\n return this.FilteredApplications;\n }\n /** @deprecated Use {@link FilteredApplications}. */\n public set filteredApplications(value: MJApplicationEntity[]) {\n this.FilteredApplications = value;\n }\n public SelectedApp: MJApplicationEntity | null = null;\n\n /** @deprecated Use {@link SelectedApp}. */\n public get selectedApp(): MJApplicationEntity | null {\n return this.SelectedApp;\n }\n /** @deprecated Use {@link SelectedApp}. */\n public set selectedApp(value: MJApplicationEntity | null) {\n this.SelectedApp = value;\n }\n public isLoading = false;\n public error: string | null = null;\n\n // Application entities mapping\n public AppEntities: Map<string, MJApplicationEntityEntity[]> = new Map();\n\n /** @deprecated Use {@link AppEntities}. */\n public get appEntities(): Map<string, MJApplicationEntityEntity[]> {\n return this.AppEntities;\n }\n /** @deprecated Use {@link AppEntities}. */\n public set appEntities(value: Map<string, MJApplicationEntityEntity[]>) {\n this.AppEntities = value;\n }\n\n // Stats\n public Stats: AppStats = {\n totalApplications: 0,\n activeApplications: 0,\n totalEntities: 0,\n publicEntities: 0\n };\n\n /** @deprecated Use {@link Stats}. */\n public get stats(): AppStats {\n return this.Stats;\n }\n /** @deprecated Use {@link Stats}. */\n public set stats(value: AppStats) {\n this.Stats = value;\n }\n\n // Filters\n public Filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n search: ''\n });\n\n /** @deprecated Use {@link Filters$}. */\n public get filters$() {\n return this.Filters$;\n }\n /** @deprecated Use {@link Filters$}. */\n public set filters$(value) {\n this.Filters$ = value;\n }\n\n // UI State\n public ShowApplicationDialog = false;\n\n /** @deprecated Use {@link ShowApplicationDialog}. */\n public get showApplicationDialog() {\n return this.ShowApplicationDialog;\n }\n /** @deprecated Use {@link ShowApplicationDialog}. */\n public set showApplicationDialog(value) {\n this.ShowApplicationDialog = value;\n }\n public ApplicationDialogData: ApplicationDialogData | null = null;\n\n /** @deprecated Use {@link ApplicationDialogData}. */\n public get applicationDialogData(): ApplicationDialogData | null {\n return this.ApplicationDialogData;\n }\n /** @deprecated Use {@link ApplicationDialogData}. */\n public set applicationDialogData(value: ApplicationDialogData | null) {\n this.ApplicationDialogData = value;\n }\n public ShowDeleteConfirm = false;\n\n /** @deprecated Use {@link ShowDeleteConfirm}. */\n public get showDeleteConfirm() {\n return this.ShowDeleteConfirm;\n }\n /** @deprecated Use {@link ShowDeleteConfirm}. */\n public set showDeleteConfirm(value) {\n this.ShowDeleteConfirm = value;\n }\n public ExpandedAppId: string | null = null;\n\n /** @deprecated Use {@link ExpandedAppId}. */\n public get expandedAppId(): string | null {\n return this.ExpandedAppId;\n }\n /** @deprecated Use {@link ExpandedAppId}. */\n public set expandedAppId(value: string | null) {\n this.ExpandedAppId = value;\n }\n\n protected override destroy$ = new Subject<void>();\n private get metadata() { return this.ProviderToUse; }\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"Application Management\"\n }\n\n protected initDashboard(): void {\n this.setupFilterSubscription();\n }\n\n protected loadData(): void {\n this.LoadInitialData();\n }\n\n override ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n super.ngOnDestroy();\n }\n \n public async LoadInitialData(): Promise<void> {\n try {\n this.isLoading = true;\n this.error = null;\n \n // Load applications and their entities\n const [apps, appEntities] = await Promise.all([\n this.loadApplications(),\n this.loadApplicationEntities()\n ]);\n \n this.Applications = apps;\n this.processApplicationEntities(appEntities);\n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading application data:', error);\n this.error = 'Failed to load application data. Please try again.';\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n /** @deprecated Use {@link LoadInitialData}. */\n public async loadInitialData(): Promise<void> {\n return this.LoadInitialData();\n }\n\n private async loadApplications(): Promise<MJApplicationEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJApplicationEntity>({\n EntityName: 'MJ: Applications',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadApplicationEntities(): Promise<MJApplicationEntityEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJApplicationEntityEntity>({\n EntityName: 'MJ: Application Entities',\n ResultType: 'entity_object',\n OrderBy: 'ApplicationID, Sequence'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private processApplicationEntities(appEntities: MJApplicationEntityEntity[]): void {\n this.AppEntities.clear();\n \n for (const appEntity of appEntities) {\n const appId = appEntity.ApplicationID;\n if (!this.AppEntities.has(appId)) {\n this.AppEntities.set(appId, []);\n }\n this.AppEntities.get(appId)!.push(appEntity);\n }\n }\n \n private setupFilterSubscription(): void {\n this.Filters$\n .pipe(\n debounceTime(300),\n distinctUntilChanged((a, b) => JSON.stringify(a) === JSON.stringify(b)),\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.applyFilters();\n });\n }\n \n private applyFilters(): void {\n const filters = this.Filters$.value;\n let filtered = [...this.Applications];\n \n // Apply status filter - for now, all applications are considered active\n // In the future, we might add an IsActive field to the Applications table\n if (filters.status === 'inactive') {\n // Currently no way to determine inactive apps\n filtered = [];\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(app =>\n app.Name?.toLowerCase().includes(searchLower) ||\n app.Description?.toLowerCase().includes(searchLower)\n );\n }\n \n this.FilteredApplications = filtered;\n this.cdr.detectChanges();\n }\n \n private calculateStats(): void {\n // For now, consider all applications as active\n const activeApps = this.Applications;\n let totalEntities = 0;\n let publicEntities = 0;\n \n for (const [, entities] of this.AppEntities) {\n totalEntities += entities.length;\n publicEntities += entities.filter(e => e.DefaultForNewUser).length;\n }\n \n this.Stats = {\n totalApplications: this.Applications.length,\n activeApplications: activeApps.length,\n totalEntities,\n publicEntities\n };\n }\n \n // Public methods for template\n public OnStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.UpdateFilter({ status });\n }\n\n /** @deprecated Use {@link OnStatusFilterChange}. */\n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n return this.OnStatusFilterChange(status);\n }\n \n public UpdateFilter(partial: Partial<FilterOptions>): void {\n this.Filters$.next({\n ...this.Filters$.value,\n ...partial\n });\n // Discrete changes (chips) apply immediately. Text search still goes\n // through the 300ms debounce in setupFilterSubscription.\n if (!('search' in partial)) {\n this.applyFilters();\n this.cdr.markForCheck();\n }\n }\n\n /** @deprecated Use {@link UpdateFilter}. */\n public updateFilter(partial: Partial<FilterOptions>): void {\n return this.UpdateFilter(partial);\n }\n\n // -- Concise chrome: one Filter popover (Status) + applied-filter chips -----\n\n public get FilterFields(): FilterFieldConfig[] {\n return [\n {\n key: 'status',\n type: 'chips',\n label: 'Status',\n chipOptions: [\n { text: 'All', value: 'all' },\n { text: 'Active', value: 'active' },\n { text: 'Inactive', value: 'inactive' },\n ],\n },\n ];\n }\n\n /** @deprecated Use {@link FilterFields}. */\n public get filterFields(): FilterFieldConfig[] {\n return this.FilterFields;\n }\n\n public get FilterValues(): Record<string, unknown> {\n return { status: this.Filters$.value.status };\n }\n\n /** @deprecated Use {@link FilterValues}. */\n public get filterValues(): Record<string, unknown> {\n return this.FilterValues;\n }\n\n /** Total active filters (Status) — drives the Filter button badge. */\n public get TotalActiveFilterCount(): number {\n return this.Filters$.value.status !== 'all' ? 1 : 0;\n }\n\n public OnFilterPanelChange(values: Record<string, unknown>): void {\n if ('status' in values) {\n this.UpdateFilter({ status: (values['status'] as FilterOptions['status']) || 'all' });\n }\n }\n\n /** @deprecated Use {@link OnFilterPanelChange}. */\n public onFilterPanelChange(values: Record<string, unknown>): void {\n return this.OnFilterPanelChange(values);\n }\n\n /** Clear all filters (Status); search persists. */\n public ClearAllAppliedFilters(): void {\n this.UpdateFilter({ status: 'all' });\n }\n\n /** @deprecated Use {@link ClearAllAppliedFilters}. */\n public clearAllAppliedFilters(): void {\n return this.ClearAllAppliedFilters();\n }\n\n /** True when search and/or panel filters are narrowing the list — gates the\n * no-results empty-state \"Reset filters\" CTA. */\n public get IsListNarrowed(): boolean {\n return this.Filters$.value.search !== '' || this.TotalActiveFilterCount > 0;\n }\n\n /** Reset everything narrowing the list (search + Status) and refresh\n * immediately. Wired to the no-results empty-state CTA. Unlike\n * clearAllAppliedFilters(), this also clears the search box. */\n public ResetAllFiltersAndSearch(): void {\n this.Filters$.next({ status: 'all', search: '' });\n this.applyFilters();\n this.cdr.markForCheck();\n }\n\n /** @deprecated Use {@link ResetAllFiltersAndSearch}. */\n public resetAllFiltersAndSearch(): void {\n return this.ResetAllFiltersAndSearch();\n }\n \n public ToggleAppExpansion(appId: string): void {\n this.ExpandedAppId = this.ExpandedAppId === appId ? null : appId;\n }\n\n /** @deprecated Use {@link ToggleAppExpansion}. */\n public toggleAppExpansion(appId: string): void {\n return this.ToggleAppExpansion(appId);\n }\n \n public IsAppExpanded(appId: string): boolean {\n return this.ExpandedAppId === appId;\n }\n\n /** @deprecated Use {@link IsAppExpanded}. */\n public isAppExpanded(appId: string): boolean {\n return this.IsAppExpanded(appId);\n }\n \n public GetAppEntities(appId: string): MJApplicationEntityEntity[] {\n return this.AppEntities.get(appId) || [];\n }\n\n /** @deprecated Use {@link GetAppEntities}. */\n public getAppEntities(appId: string): MJApplicationEntityEntity[] {\n return this.GetAppEntities(appId);\n }\n \n public GetEntityInfo(entityId: string): EntityInfo | undefined {\n return this.metadata.Entities.find(e => UUIDsEqual(e.ID, entityId));\n }\n\n /** @deprecated Use {@link GetEntityInfo}. */\n public getEntityInfo(entityId: string): EntityInfo | undefined {\n return this.GetEntityInfo(entityId);\n }\n \n public CreateNewApplication(): void {\n this.ApplicationDialogData = {\n mode: 'create'\n };\n this.ShowApplicationDialog = true;\n }\n\n /** @deprecated Use {@link CreateNewApplication}. */\n public createNewApplication(): void {\n return this.CreateNewApplication();\n }\n \n public EditApplication(app: MJApplicationEntity): void {\n this.ApplicationDialogData = {\n application: app,\n mode: 'edit'\n };\n this.ShowApplicationDialog = true;\n }\n\n /** @deprecated Use {@link EditApplication}. */\n public editApplication(app: MJApplicationEntity): void {\n return this.EditApplication(app);\n }\n \n public ConfirmDeleteApplication(app: MJApplicationEntity): void {\n this.SelectedApp = app;\n this.ShowDeleteConfirm = true;\n }\n\n /** @deprecated Use {@link ConfirmDeleteApplication}. */\n public confirmDeleteApplication(app: MJApplicationEntity): void {\n return this.ConfirmDeleteApplication(app);\n }\n \n public async DeleteApplication(): Promise<void> {\n if (!this.SelectedApp) return;\n \n try {\n this.isLoading = true;\n this.error = null;\n\n // Delete the application\n const deleteResult = await this.SelectedApp.Delete();\n if (!deleteResult) {\n throw new Error(this.SelectedApp.LatestResult?.Message || 'Failed to delete application');\n }\n\n this.ShowDeleteConfirm = false;\n this.SelectedApp = null;\n await this.LoadInitialData();\n } catch (error: unknown) {\n console.error('Error deleting application:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete application';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n /** @deprecated Use {@link DeleteApplication}. */\n public async deleteApplication(): Promise<void> {\n return this.DeleteApplication();\n }\n\n public OnApplicationDialogResult(result: ApplicationDialogResult): void {\n this.ShowApplicationDialog = false;\n this.ApplicationDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the application list after save\n this.LoadInitialData();\n }\n }\n\n /** @deprecated Use {@link OnApplicationDialogResult}. */\n public onApplicationDialogResult(result: ApplicationDialogResult): void {\n return this.OnApplicationDialogResult(result);\n }\n \n public GetAppIcon(app: MJApplicationEntity): string {\n // Map application names to appropriate icons based on their purpose\n const name = (app.Name || '').toLowerCase();\n\n // Common application type mappings\n if (name.includes('admin') || name.includes('management')) {\n return 'fa-cog';\n }\n if (name.includes('report') || name.includes('analytics') || name.includes('dashboard')) {\n return 'fa-chart-line';\n }\n if (name.includes('user') || name.includes('people') || name.includes('employee')) {\n return 'fa-users';\n }\n if (name.includes('settings') || name.includes('config')) {\n return 'fa-sliders';\n }\n if (name.includes('data') || name.includes('database')) {\n return 'fa-database';\n }\n if (name.includes('file') || name.includes('document')) {\n return 'fa-file-alt';\n }\n if (name.includes('mail') || name.includes('email') || name.includes('message')) {\n return 'fa-envelope';\n }\n if (name.includes('search') || name.includes('explorer')) {\n return 'fa-search';\n }\n if (name.includes('calendar') || name.includes('schedule') || name.includes('event')) {\n return 'fa-calendar';\n }\n if (name.includes('security') || name.includes('auth') || name.includes('permission')) {\n return 'fa-shield-alt';\n }\n if (name.includes('integration') || name.includes('api') || name.includes('connect')) {\n return 'fa-plug';\n }\n if (name.includes('workflow') || name.includes('process') || name.includes('automation')) {\n return 'fa-project-diagram';\n }\n if (name.includes('ai') || name.includes('intelligence') || name.includes('machine')) {\n return 'fa-brain';\n }\n if (name.includes('home') || name.includes('main') || name.includes('default')) {\n return 'fa-home';\n }\n\n // Default icon for applications\n return 'fa-grid-2';\n }\n\n /** @deprecated Use {@link GetAppIcon}. */\n public getAppIcon(app: MJApplicationEntity): string {\n return this.GetAppIcon(app);\n }\n \n public GetAppStatusClass(app: MJApplicationEntity): string {\n // For now, all apps are considered active\n return 'status-active';\n }\n\n /** @deprecated Use {@link GetAppStatusClass}. */\n public getAppStatusClass(app: MJApplicationEntity): string {\n return this.GetAppStatusClass(app);\n }\n \n public GetAppStatusLabel(app: MJApplicationEntity): string {\n // For now, all apps are considered active\n return 'Active';\n }\n\n /** @deprecated Use {@link GetAppStatusLabel}. */\n public getAppStatusLabel(app: MJApplicationEntity): string {\n return this.GetAppStatusLabel(app);\n }\n \n public RefreshData(): void {\n this.LoadInitialData();\n }\n\n /** @deprecated Use {@link RefreshData}. */\n public refreshData(): void {\n return this.RefreshData();\n }\n}","<!--\n Interior chrome — see Section 10 of explorer-chrome-conventions.\n-->\n<mj-page-header-interior\n AriaLabel=\"Filter applications\"\n Title=\"Applications\"\n Subtitle=\"Configure applications and their entity associations\">\n <!-- X-of-Y filtered count earns its meta spot per chrome conventions §2.\n Partition badges (entities/public) stay dropped — Active/Inactive\n chips in [toolbar] handle the partition signal. -->\n <div meta>\n <mj-stat-badge\n [Count]=\"filteredApplications.length\"\n [Total]=\"applications.length\"\n Label=\"applications\">\n </mj-stat-badge>\n </div>\n <div toolbar>\n <!-- Concise-chrome control bar: search · Filter. Status lives behind the\n one Filter button; applied filters show as removable chips below the\n card. On mobile the popover docks as a bottom sheet. -->\n <mj-page-search\n Placeholder=\"Search applications by name or description...\"\n [Value]=\"filters$.value.search\"\n (ValueChange)=\"updateFilter({ search: $event })\">\n </mj-page-search>\n <mj-filter-popover\n Label=\"Filters\"\n Icon=\"fa-solid fa-filter\"\n [ActiveCount]=\"TotalActiveFilterCount\"\n [ShowClearAll]=\"TotalActiveFilterCount > 0\"\n (ClearAllRequested)=\"clearAllAppliedFilters()\">\n <mj-filter-panel\n [Fields]=\"filterFields\"\n [Values]=\"filterValues\"\n (ValuesChange)=\"onFilterPanelChange($event)\"\n (Reset)=\"clearAllAppliedFilters()\">\n </mj-filter-panel>\n </mj-filter-popover>\n </div>\n <div actions>\n <mj-refresh-button [Loading]=\"isLoading\" (Clicked)=\"refreshData()\"></mj-refresh-button>\n <button mjButton variant=\"primary\" size=\"sm\" (click)=\"createNewApplication()\" aria-label=\"Add new application\">\n <i class=\"fa-solid fa-plus\"></i> <span class=\"mj-action-label\">Add Application</span>\n </button>\n </div>\n</mj-page-header-interior>\n\n<!-- Scrollable Content Section — owned by <mj-page-body-interior>. -->\n<mj-page-body-interior>\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\">\n <mj-loading text=\"Loading applications...\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\">\n <div class=\"error-content\">\n <i class=\"fa-solid fa-exclamation-triangle error-icon\" aria-hidden=\"true\"></i>\n <p class=\"error-message\">{{ error }}</p>\n <button mjButton variant=\"primary\" (click)=\"loadInitialData()\">\n <i class=\"fa-solid fa-refresh\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Applications List -->\n @if (!isLoading && !error) {\n <div class=\"applications-list\" role=\"list\">\n @for (app of filteredApplications; track app.ID) {\n <div class=\"app-card\" [class.expanded]=\"isAppExpanded(app.ID)\" role=\"listitem\">\n <div class=\"app-header\" (click)=\"toggleAppExpansion(app.ID)\" role=\"button\" [attr.aria-expanded]=\"isAppExpanded(app.ID)\">\n <div class=\"app-info\">\n <div class=\"app-icon-wrapper\">\n <i [class]=\"'fa-solid ' + getAppIcon(app)\" aria-hidden=\"true\"></i>\n </div>\n <div class=\"app-details\">\n <h3 class=\"app-name\">{{ app.Name }}</h3>\n <p class=\"app-description\">{{ app.Description || 'No description available' }}</p>\n </div>\n </div>\n\n <div class=\"app-meta\">\n <span class=\"status-badge\" [class]=\"getAppStatusClass(app)\">\n {{ getAppStatusLabel(app) }}\n </span>\n <div class=\"app-actions\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editApplication(app)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + app.Name\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteApplication(app)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + app.Name\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n @if (isAppExpanded(app.ID)) {\n <div class=\"app-content\">\n <!-- Mobile-only actions bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getAppStatusClass(app)\">\n {{ getAppStatusLabel(app) }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editApplication(app)\"\n title=\"Edit\"\n [attr.aria-label]=\"'Edit ' + app.Name\"\n >\n <i class=\"fa-solid fa-edit\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteApplication(app)\"\n title=\"Delete\"\n [attr.aria-label]=\"'Delete ' + app.Name\"\n >\n <i class=\"fa-solid fa-trash\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <div class=\"app-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Entities:</span>\n <span class=\"stat-value\">{{ getAppEntities(app.ID).length }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-calendar\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Created:</span>\n <span class=\"stat-value\">{{ app.__mj_CreatedAt | date:'short' }}</span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-clock\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Updated:</span>\n <span class=\"stat-value\">{{ app.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <div class=\"entities-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-database\" aria-hidden=\"true\"></i>\n Application Entities\n </h4>\n\n @if (getAppEntities(app.ID).length > 0) {\n <div class=\"entities-grid\">\n @for (appEntity of getAppEntities(app.ID); track appEntity.ID) {\n @if (getEntityInfo(appEntity.EntityID); as entity) {\n <div class=\"entity-item\">\n <div class=\"entity-name\">{{ entity.DisplayNameOrName }}</div>\n <div class=\"entity-meta\">\n @if (appEntity.DefaultForNewUser) {\n <span class=\"entity-badge public\">Public</span>\n }\n <span class=\"entity-sequence\">Order: {{ appEntity.Sequence }}</span>\n </div>\n </div>\n }\n }\n </div>\n } @else {\n <p class=\"no-entities\">No entities configured for this application</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredApplications.length === 0) {\n <mj-empty-state\n [Variant]=\"IsListNarrowed ? 'no-results' : 'empty'\"\n Icon=\"fa-solid fa-cubes\"\n Title=\"No applications found\"\n Message=\"Try adjusting your filters or create a new application\"\n [ActionText]=\"IsListNarrowed ? 'Reset filters' : ''\"\n ActionIcon=\"fa-solid fa-rotate-left\"\n (Action)=\"resetAllFiltersAndSearch()\" />\n }\n </div>\n }\n </mj-page-body-interior>\n\n <!-- Application Dialog -->\n <mj-application-dialog\n [visible]=\"showApplicationDialog\"\n [data]=\"applicationDialogData\"\n (result)=\"onApplicationDialogResult($event)\"\n ></mj-application-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedApp) {\n <div class=\"modal-backdrop\" (click)=\"showDeleteConfirm = false\" role=\"presentation\">\n <div\n class=\"modal-dialog\"\n (click)=\"$event.stopPropagation()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-description\"\n >\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"delete-dialog-title\">\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n Confirm Delete\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"showDeleteConfirm = false\"\n aria-label=\"Close dialog\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <div class=\"modal-body\" id=\"delete-dialog-description\">\n <p>Are you sure you want to delete the application <strong>{{ selectedApp.Name }}</strong>?</p>\n <mj-alert Variant=\"warning\" Message=\"This will remove all entity associations for this application.\" />\n </div>\n <div class=\"modal-footer\">\n <!-- Primary action (Delete) on LEFT per MD3 design guide -->\n <button mjButton variant=\"danger\" (click)=\"deleteApplication()\" [disabled]=\"isLoading\">\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Deleting...\n } @else {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete Application\n }\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n"]}
|
|
@@ -43,11 +43,11 @@ export declare class ApplicationSettingsComponent extends BaseAngularComponent i
|
|
|
43
43
|
/**
|
|
44
44
|
* Builds app config items by matching system apps with user's UserApplication records
|
|
45
45
|
*/
|
|
46
|
-
private
|
|
46
|
+
private buildAppConfigItems;
|
|
47
47
|
/**
|
|
48
48
|
* Separates apps into active and available lists based on IsActive state
|
|
49
49
|
*/
|
|
50
|
-
private
|
|
50
|
+
private refreshAppLists;
|
|
51
51
|
/**
|
|
52
52
|
* Native drag start handler
|
|
53
53
|
*/
|
|
@@ -95,11 +95,11 @@ export declare class ApplicationSettingsComponent extends BaseAngularComponent i
|
|
|
95
95
|
/**
|
|
96
96
|
* Updates an existing UserApplication record
|
|
97
97
|
*/
|
|
98
|
-
private
|
|
98
|
+
private updateUserApplication;
|
|
99
99
|
/**
|
|
100
100
|
* Creates a new UserApplication record
|
|
101
101
|
*/
|
|
102
|
-
private
|
|
102
|
+
private createUserApplication;
|
|
103
103
|
/**
|
|
104
104
|
* Resets all changes and reloads the configuration
|
|
105
105
|
*/
|
|
@@ -234,9 +234,9 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
234
234
|
});
|
|
235
235
|
const userApps = userAppsResult.Success ? userAppsResult.Results : [];
|
|
236
236
|
// Build app config items
|
|
237
|
-
this.AllApps = this.
|
|
237
|
+
this.AllApps = this.buildAppConfigItems(systemApps, userApps);
|
|
238
238
|
// Separate into active (selected) and available (unselected)
|
|
239
|
-
this.
|
|
239
|
+
this.refreshAppLists();
|
|
240
240
|
}
|
|
241
241
|
catch (error) {
|
|
242
242
|
this.ErrorMessage = 'Failed to load app configuration. Please try again.';
|
|
@@ -252,7 +252,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
252
252
|
/**
|
|
253
253
|
* Builds app config items by matching system apps with user's UserApplication records
|
|
254
254
|
*/
|
|
255
|
-
|
|
255
|
+
buildAppConfigItems(systemApps, userApps) {
|
|
256
256
|
const items = [];
|
|
257
257
|
for (const app of systemApps) {
|
|
258
258
|
const userApp = userApps.find(ua => UUIDsEqual(ua.ApplicationID, app.ID));
|
|
@@ -269,7 +269,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
269
269
|
/**
|
|
270
270
|
* Separates apps into active and available lists based on IsActive state
|
|
271
271
|
*/
|
|
272
|
-
|
|
272
|
+
refreshAppLists() {
|
|
273
273
|
this.ActiveApps = this.AllApps
|
|
274
274
|
.filter(item => item.IsActive)
|
|
275
275
|
.sort((a, b) => a.Sequence - b.Sequence);
|
|
@@ -341,7 +341,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
341
341
|
item.IsActive = true;
|
|
342
342
|
item.Sequence = this.ActiveApps.length;
|
|
343
343
|
item.IsDirty = true;
|
|
344
|
-
this.
|
|
344
|
+
this.refreshAppLists();
|
|
345
345
|
}
|
|
346
346
|
/**
|
|
347
347
|
* Removes an app from the user's active list
|
|
@@ -350,7 +350,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
350
350
|
item.IsActive = false;
|
|
351
351
|
item.Sequence = 999;
|
|
352
352
|
item.IsDirty = true;
|
|
353
|
-
this.
|
|
353
|
+
this.refreshAppLists();
|
|
354
354
|
// Resequence remaining active apps
|
|
355
355
|
this.ActiveApps.forEach((activeItem, index) => {
|
|
356
356
|
if (activeItem.Sequence !== index) {
|
|
@@ -417,11 +417,11 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
417
417
|
continue;
|
|
418
418
|
if (item.UserAppId) {
|
|
419
419
|
// Update existing UserApplication record
|
|
420
|
-
await this.
|
|
420
|
+
await this.updateUserApplication(md, item);
|
|
421
421
|
}
|
|
422
422
|
else if (item.IsActive) {
|
|
423
423
|
// Create new UserApplication record (only if active)
|
|
424
|
-
await this.
|
|
424
|
+
await this.createUserApplication(md, item);
|
|
425
425
|
}
|
|
426
426
|
}
|
|
427
427
|
// Reload the ApplicationManager to reflect changes
|
|
@@ -446,7 +446,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
446
446
|
/**
|
|
447
447
|
* Updates an existing UserApplication record
|
|
448
448
|
*/
|
|
449
|
-
async
|
|
449
|
+
async updateUserApplication(md, item) {
|
|
450
450
|
const userApp = await md.GetEntityObject('MJ: User Applications');
|
|
451
451
|
await userApp.Load(item.UserAppId);
|
|
452
452
|
userApp.Sequence = item.Sequence;
|
|
@@ -461,7 +461,7 @@ export class ApplicationSettingsComponent extends BaseAngularComponent {
|
|
|
461
461
|
/**
|
|
462
462
|
* Creates a new UserApplication record
|
|
463
463
|
*/
|
|
464
|
-
async
|
|
464
|
+
async createUserApplication(md, item) {
|
|
465
465
|
const userApp = await md.GetEntityObject('MJ: User Applications');
|
|
466
466
|
userApp.NewRecord();
|
|
467
467
|
userApp.UserID = md.CurrentUser.ID;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-settings.component.js","sourceRoot":"","sources":["../../../src/lib/application-settings/application-settings.component.ts","../../../src/lib/application-settings/application-settings.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, LogError, LogStatus } from '@memberjunction/core';\nimport { MJUserApplicationEntity } from '@memberjunction/core-entities';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n/**\n * Represents an app item in the configuration UI\n */\ninterface AppConfigItem {\n App: BaseApplication;\n UserAppId: string | null;\n Sequence: number;\n IsActive: boolean;\n IsDirty: boolean;\n}\n\n/**\n * Inline component for configuring user's application visibility and order.\n * Allows users to:\n * - Select which applications to show in the app switcher\n * - Reorder applications via drag-and-drop\n */\n@Component({\n standalone: false,\n selector: 'mj-application-settings',\n templateUrl: './application-settings.component.html',\n styleUrls: ['./application-settings.component.css']\n})\nexport class ApplicationSettingsComponent extends BaseAngularComponent implements OnInit {\n // All available apps from the system\n AllApps: AppConfigItem[] = [];\n\n // User's selected apps (active and ordered)\n ActiveApps: AppConfigItem[] = [];\n\n // Available apps not yet selected\n AvailableApps: AppConfigItem[] = [];\n\n IsLoading = false;\n IsSaving = false;\n ErrorMessage = '';\n SuccessMessage = '';\n\n // Native drag-and-drop state\n private draggedItem: AppConfigItem | null = null;\n private draggedIndex = -1;\n private dropTargetIndex = -1;\n\n constructor(\n private appManager: ApplicationManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone\n ) {\n super();}\n\n async ngOnInit(): Promise<void> {\n await this.LoadConfiguration();\n }\n\n /**\n * Loads the user's current app configuration\n */\n async LoadConfiguration(): Promise<void> {\n this.IsLoading = true;\n this.ErrorMessage = '';\n\n try {\n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Load all system apps from ApplicationManager\n const systemApps = this.appManager.GetAuthorizedSystemApps();\n\n // Load user's UserApplication records\n const userAppsResult = await rv.RunView<MJUserApplicationEntity>({\n EntityName: 'MJ: User Applications',\n ExtraFilter: `UserID = '${md.CurrentUser.ID}'`,\n OrderBy: 'Sequence, Application',\n ResultType: 'entity_object'\n });\n\n const userApps: MJUserApplicationEntity[] = userAppsResult.Success ? userAppsResult.Results : [];\n\n // Build app config items\n this.AllApps = this.BuildAppConfigItems(systemApps, userApps);\n\n // Separate into active (selected) and available (unselected)\n this.RefreshAppLists();\n\n } catch (error) {\n this.ErrorMessage = 'Failed to load app configuration. Please try again.';\n LogError('Error loading app configuration:', undefined, error instanceof Error ? error.message : String(error));\n } finally {\n this.ngZone.run(() => {\n this.IsLoading = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Builds app config items by matching system apps with user's UserApplication records\n */\n private BuildAppConfigItems(systemApps: BaseApplication[], userApps: MJUserApplicationEntity[]): AppConfigItem[] {\n const items: AppConfigItem[] = [];\n\n for (const app of systemApps) {\n const userApp = userApps.find(ua => UUIDsEqual(ua.ApplicationID, app.ID));\n\n items.push({\n App: app,\n UserAppId: userApp?.ID || null,\n Sequence: userApp?.Sequence ?? 999,\n IsActive: userApp?.IsActive ?? false,\n IsDirty: false\n });\n }\n\n return items;\n }\n\n /**\n * Separates apps into active and available lists based on IsActive state\n */\n private RefreshAppLists(): void {\n this.ActiveApps = this.AllApps\n .filter(item => item.IsActive)\n .sort((a, b) => a.Sequence - b.Sequence);\n\n this.AvailableApps = this.AllApps\n .filter(item => !item.IsActive)\n .sort((a, b) => a.App.Name.localeCompare(b.App.Name));\n }\n\n /**\n * Native drag start handler\n */\n OnDragStart(event: DragEvent, item: AppConfigItem, index: number): void {\n this.draggedItem = item;\n this.draggedIndex = index;\n\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', index.toString());\n }\n }\n\n /**\n * Native drag over handler - allows drop\n */\n OnDragOver(event: DragEvent): void {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n }\n\n /**\n * Native drag enter handler - tracks drop target\n */\n OnDragEnter(event: DragEvent, index: number): void {\n event.preventDefault();\n this.dropTargetIndex = index;\n }\n\n /**\n * Native drag end handler - cleanup\n */\n OnDragEnd(): void {\n this.draggedItem = null;\n this.draggedIndex = -1;\n this.dropTargetIndex = -1;\n }\n\n /**\n * Native drop handler - reorder items\n */\n OnDrop(event: DragEvent): void {\n event.preventDefault();\n\n if (this.draggedIndex >= 0 && this.dropTargetIndex >= 0 && this.draggedIndex !== this.dropTargetIndex) {\n // Remove item from old position\n const [movedItem] = this.ActiveApps.splice(this.draggedIndex, 1);\n\n // Insert at new position\n this.ActiveApps.splice(this.dropTargetIndex, 0, movedItem);\n\n // Update sequences based on new order\n this.ActiveApps.forEach((item, idx) => {\n if (item.Sequence !== idx) {\n item.Sequence = idx;\n item.IsDirty = true;\n }\n });\n\n this.cdr.detectChanges();\n }\n\n // Reset drag state\n this.OnDragEnd();\n }\n\n /**\n * Adds an app to the user's active list\n */\n AddApp(item: AppConfigItem): void {\n item.IsActive = true;\n item.Sequence = this.ActiveApps.length;\n item.IsDirty = true;\n this.RefreshAppLists();\n }\n\n /**\n * Removes an app from the user's active list\n */\n RemoveApp(item: AppConfigItem): void {\n item.IsActive = false;\n item.Sequence = 999;\n item.IsDirty = true;\n this.RefreshAppLists();\n\n // Resequence remaining active apps\n this.ActiveApps.forEach((activeItem, index) => {\n if (activeItem.Sequence !== index) {\n activeItem.Sequence = index;\n activeItem.IsDirty = true;\n }\n });\n }\n\n /**\n * Moves an app up in the order\n */\n MoveUp(item: AppConfigItem): void {\n const index = this.ActiveApps.indexOf(item);\n if (index > 0) {\n const prevItem = this.ActiveApps[index - 1];\n\n // Swap sequences\n const tempSeq = item.Sequence;\n item.Sequence = prevItem.Sequence;\n prevItem.Sequence = tempSeq;\n\n item.IsDirty = true;\n prevItem.IsDirty = true;\n\n // Re-sort\n this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.Sequence - b.Sequence);\n }\n }\n\n /**\n * Moves an app down in the order\n */\n MoveDown(item: AppConfigItem): void {\n const index = this.ActiveApps.indexOf(item);\n if (index < this.ActiveApps.length - 1) {\n const nextItem = this.ActiveApps[index + 1];\n\n // Swap sequences\n const tempSeq = item.Sequence;\n item.Sequence = nextItem.Sequence;\n nextItem.Sequence = tempSeq;\n\n item.IsDirty = true;\n nextItem.IsDirty = true;\n\n // Re-sort\n this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.Sequence - b.Sequence);\n }\n }\n\n /**\n * Checks if there are any unsaved changes\n */\n HasChanges(): boolean {\n return this.AllApps.some(item => item.IsDirty);\n }\n\n /**\n * Saves the user's app configuration\n */\n async Save(): Promise<void> {\n if (!this.HasChanges()) {\n return;\n }\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n this.SuccessMessage = '';\n\n try {\n const md = this.ProviderToUse;\n\n // Process each app config item\n for (const item of this.AllApps) {\n if (!item.IsDirty) continue;\n\n if (item.UserAppId) {\n // Update existing UserApplication record\n await this.UpdateUserApplication(md, item);\n } else if (item.IsActive) {\n // Create new UserApplication record (only if active)\n await this.CreateUserApplication(md, item);\n }\n }\n\n // Reload the ApplicationManager to reflect changes\n LogStatus('User app configuration saved, reloading ApplicationManager...');\n await this.appManager.ReloadUserApplications();\n\n this.SuccessMessage = 'App configuration saved successfully!';\n this.sharedService.CreateSimpleNotification(this.SuccessMessage, 'success', 3000);\n\n // Clear dirty flags\n this.AllApps.forEach(item => item.IsDirty = false);\n\n } catch (error) {\n this.ErrorMessage = 'Failed to save configuration. Please try again.';\n LogError('Error saving app configuration:', undefined, error instanceof Error ? error.message : String(error));\n } finally {\n this.ngZone.run(() => {\n this.IsSaving = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Updates an existing UserApplication record\n */\n private async UpdateUserApplication(md: IMetadataProvider, item: AppConfigItem): Promise<void> {\n const userApp = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications');\n await userApp.Load(item.UserAppId!);\n\n userApp.Sequence = item.Sequence;\n userApp.IsActive = item.IsActive;\n\n const saved = await userApp.Save();\n if (!saved) {\n throw new Error(`Failed to update UserApplication for ${item.App.Name}: ${userApp.LatestResult}`);\n }\n\n item.IsDirty = false;\n LogStatus(`Updated UserApplication for ${item.App.Name}: sequence=${item.Sequence}, isActive=${item.IsActive}`);\n }\n\n /**\n * Creates a new UserApplication record\n */\n private async CreateUserApplication(md: IMetadataProvider, item: AppConfigItem): Promise<void> {\n const userApp = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications');\n userApp.NewRecord();\n\n userApp.UserID = md.CurrentUser.ID;\n userApp.ApplicationID = item.App.ID;\n userApp.Sequence = item.Sequence;\n userApp.IsActive = item.IsActive;\n\n const saved = await userApp.Save();\n if (!saved) {\n throw new Error(`Failed to create UserApplication for ${item.App.Name}: ${userApp.LatestResult}`);\n }\n\n item.UserAppId = userApp.ID;\n item.IsDirty = false;\n LogStatus(`Created UserApplication for ${item.App.Name}: sequence=${item.Sequence}`);\n }\n\n /**\n * Resets all changes and reloads the configuration\n */\n async Reset(): Promise<void> {\n await this.LoadConfiguration();\n this.SuccessMessage = '';\n }\n\n /**\n * Check if drop target is active\n */\n IsDropTarget(index: number): boolean {\n return this.dropTargetIndex === index;\n }\n}\n","<div class=\"application-settings\">\n <h2 class=\"section-title\">Applications</h2>\n <p class=\"section-description\">Choose which applications appear in your app switcher and set their order</p>\n\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading applications...\"></mj-loading>\n </div>\n }\n\n @if (ErrorMessage && !IsLoading) {\n <mj-alert Variant=\"error\">{{ ErrorMessage }}</mj-alert>\n }\n\n @if (SuccessMessage && !IsLoading) {\n <mj-alert Variant=\"success\">{{ SuccessMessage }}</mj-alert>\n }\n\n @if (!IsLoading && !ErrorMessage) {\n <div class=\"app-config-layout\">\n <!-- Available Apps Panel -->\n <div class=\"app-panel available-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Available Applications\n </h3>\n <span class=\"panel-count\">{{ AvailableApps.length }}</span>\n </div>\n <div class=\"panel-content\">\n @if (AvailableApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-check\"\n Title=\"All applications are selected\" />\n }\n @for (item of AvailableApps; track item.App.ID) {\n <div class=\"app-item\" (click)=\"AddApp(item)\">\n <div class=\"app-icon\">\n <i [class]=\"item.App.Icon || 'fa-solid fa-window-maximize'\"></i>\n </div>\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.App.Name }}</span>\n @if (item.App.Description) {\n <span class=\"app-desc\">{{ item.App.Description }}</span>\n }\n </div>\n <button\n class=\"app-action add-btn\"\n (click)=\"AddApp(item); $event.stopPropagation()\"\n title=\"Add to selected\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Apps Panel -->\n <div class=\"app-panel selected-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-star\"></i>\n Your Applications\n </h3>\n <span class=\"panel-count\">{{ ActiveApps.length }}</span>\n </div>\n <div class=\"panel-content\" (dragover)=\"OnDragOver($event)\">\n @if (ActiveApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-arrow-left\"\n Title=\"Add applications from the list\" />\n }\n @for (item of ActiveApps; track item.App.ID; let i = $index; let first = $first; let last = $last) {\n <div\n class=\"app-item selected\"\n [class.drop-target]=\"IsDropTarget(i)\"\n [class.dirty]=\"item.IsDirty\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, item, i)\"\n (dragenter)=\"OnDragEnter($event, i)\"\n (dragend)=\"OnDragEnd()\"\n (drop)=\"OnDrop($event)\"\n >\n <div class=\"drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <div class=\"app-icon\">\n <i [class]=\"item.App.Icon || 'fa-solid fa-window-maximize'\"></i>\n </div>\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.App.Name }}</span>\n <span class=\"app-sequence\">Position {{ i + 1 }}</span>\n </div>\n <div class=\"app-actions\">\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n [disabled]=\"first\"\n (click)=\"MoveUp(item)\"\n title=\"Move up\"\n >\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n [disabled]=\"last\"\n (click)=\"MoveDown(item)\"\n title=\"Move down\"\n >\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button mjButton\n variant=\"danger\"\n size=\"sm\"\n (click)=\"RemoveApp(item)\"\n title=\"Remove\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-bar\">\n <button\n class=\"btn btn-secondary\"\n (click)=\"Reset()\"\n [disabled]=\"!HasChanges() || IsSaving\"\n >\n <i class=\"fa-solid fa-undo\"></i>\n Reset\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"Save()\"\n [disabled]=\"!HasChanges() || IsSaving\"\n >\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n }\n </button>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"application-settings.component.js","sourceRoot":"","sources":["../../../src/lib/application-settings/application-settings.component.ts","../../../src/lib/application-settings/application-settings.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnInit, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { IMetadataProvider, Metadata, RunView, LogError, LogStatus } from '@memberjunction/core';\nimport { MJUserApplicationEntity } from '@memberjunction/core-entities';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { SharedService } from '@memberjunction/ng-shared';\nimport { UUIDsEqual } from '@memberjunction/global';\n\nimport { BaseAngularComponent } from '@memberjunction/ng-base-types';\n/**\n * Represents an app item in the configuration UI\n */\ninterface AppConfigItem {\n App: BaseApplication;\n UserAppId: string | null;\n Sequence: number;\n IsActive: boolean;\n IsDirty: boolean;\n}\n\n/**\n * Inline component for configuring user's application visibility and order.\n * Allows users to:\n * - Select which applications to show in the app switcher\n * - Reorder applications via drag-and-drop\n */\n@Component({\n standalone: false,\n selector: 'mj-application-settings',\n templateUrl: './application-settings.component.html',\n styleUrls: ['./application-settings.component.css']\n})\nexport class ApplicationSettingsComponent extends BaseAngularComponent implements OnInit {\n // All available apps from the system\n AllApps: AppConfigItem[] = [];\n\n // User's selected apps (active and ordered)\n ActiveApps: AppConfigItem[] = [];\n\n // Available apps not yet selected\n AvailableApps: AppConfigItem[] = [];\n\n IsLoading = false;\n IsSaving = false;\n ErrorMessage = '';\n SuccessMessage = '';\n\n // Native drag-and-drop state\n private draggedItem: AppConfigItem | null = null;\n private draggedIndex = -1;\n private dropTargetIndex = -1;\n\n constructor(\n private appManager: ApplicationManager,\n private sharedService: SharedService,\n private cdr: ChangeDetectorRef,\n private ngZone: NgZone\n ) {\n super();}\n\n async ngOnInit(): Promise<void> {\n await this.LoadConfiguration();\n }\n\n /**\n * Loads the user's current app configuration\n */\n async LoadConfiguration(): Promise<void> {\n this.IsLoading = true;\n this.ErrorMessage = '';\n\n try {\n const md = this.ProviderToUse;\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n // Load all system apps from ApplicationManager\n const systemApps = this.appManager.GetAuthorizedSystemApps();\n\n // Load user's UserApplication records\n const userAppsResult = await rv.RunView<MJUserApplicationEntity>({\n EntityName: 'MJ: User Applications',\n ExtraFilter: `UserID = '${md.CurrentUser.ID}'`,\n OrderBy: 'Sequence, Application',\n ResultType: 'entity_object'\n });\n\n const userApps: MJUserApplicationEntity[] = userAppsResult.Success ? userAppsResult.Results : [];\n\n // Build app config items\n this.AllApps = this.buildAppConfigItems(systemApps, userApps);\n\n // Separate into active (selected) and available (unselected)\n this.refreshAppLists();\n\n } catch (error) {\n this.ErrorMessage = 'Failed to load app configuration. Please try again.';\n LogError('Error loading app configuration:', undefined, error instanceof Error ? error.message : String(error));\n } finally {\n this.ngZone.run(() => {\n this.IsLoading = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Builds app config items by matching system apps with user's UserApplication records\n */\n private buildAppConfigItems(systemApps: BaseApplication[], userApps: MJUserApplicationEntity[]): AppConfigItem[] {\n const items: AppConfigItem[] = [];\n\n for (const app of systemApps) {\n const userApp = userApps.find(ua => UUIDsEqual(ua.ApplicationID, app.ID));\n\n items.push({\n App: app,\n UserAppId: userApp?.ID || null,\n Sequence: userApp?.Sequence ?? 999,\n IsActive: userApp?.IsActive ?? false,\n IsDirty: false\n });\n }\n\n return items;\n }\n\n /**\n * Separates apps into active and available lists based on IsActive state\n */\n private refreshAppLists(): void {\n this.ActiveApps = this.AllApps\n .filter(item => item.IsActive)\n .sort((a, b) => a.Sequence - b.Sequence);\n\n this.AvailableApps = this.AllApps\n .filter(item => !item.IsActive)\n .sort((a, b) => a.App.Name.localeCompare(b.App.Name));\n }\n\n /**\n * Native drag start handler\n */\n OnDragStart(event: DragEvent, item: AppConfigItem, index: number): void {\n this.draggedItem = item;\n this.draggedIndex = index;\n\n if (event.dataTransfer) {\n event.dataTransfer.effectAllowed = 'move';\n event.dataTransfer.setData('text/plain', index.toString());\n }\n }\n\n /**\n * Native drag over handler - allows drop\n */\n OnDragOver(event: DragEvent): void {\n event.preventDefault();\n if (event.dataTransfer) {\n event.dataTransfer.dropEffect = 'move';\n }\n }\n\n /**\n * Native drag enter handler - tracks drop target\n */\n OnDragEnter(event: DragEvent, index: number): void {\n event.preventDefault();\n this.dropTargetIndex = index;\n }\n\n /**\n * Native drag end handler - cleanup\n */\n OnDragEnd(): void {\n this.draggedItem = null;\n this.draggedIndex = -1;\n this.dropTargetIndex = -1;\n }\n\n /**\n * Native drop handler - reorder items\n */\n OnDrop(event: DragEvent): void {\n event.preventDefault();\n\n if (this.draggedIndex >= 0 && this.dropTargetIndex >= 0 && this.draggedIndex !== this.dropTargetIndex) {\n // Remove item from old position\n const [movedItem] = this.ActiveApps.splice(this.draggedIndex, 1);\n\n // Insert at new position\n this.ActiveApps.splice(this.dropTargetIndex, 0, movedItem);\n\n // Update sequences based on new order\n this.ActiveApps.forEach((item, idx) => {\n if (item.Sequence !== idx) {\n item.Sequence = idx;\n item.IsDirty = true;\n }\n });\n\n this.cdr.detectChanges();\n }\n\n // Reset drag state\n this.OnDragEnd();\n }\n\n /**\n * Adds an app to the user's active list\n */\n AddApp(item: AppConfigItem): void {\n item.IsActive = true;\n item.Sequence = this.ActiveApps.length;\n item.IsDirty = true;\n this.refreshAppLists();\n }\n\n /**\n * Removes an app from the user's active list\n */\n RemoveApp(item: AppConfigItem): void {\n item.IsActive = false;\n item.Sequence = 999;\n item.IsDirty = true;\n this.refreshAppLists();\n\n // Resequence remaining active apps\n this.ActiveApps.forEach((activeItem, index) => {\n if (activeItem.Sequence !== index) {\n activeItem.Sequence = index;\n activeItem.IsDirty = true;\n }\n });\n }\n\n /**\n * Moves an app up in the order\n */\n MoveUp(item: AppConfigItem): void {\n const index = this.ActiveApps.indexOf(item);\n if (index > 0) {\n const prevItem = this.ActiveApps[index - 1];\n\n // Swap sequences\n const tempSeq = item.Sequence;\n item.Sequence = prevItem.Sequence;\n prevItem.Sequence = tempSeq;\n\n item.IsDirty = true;\n prevItem.IsDirty = true;\n\n // Re-sort\n this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.Sequence - b.Sequence);\n }\n }\n\n /**\n * Moves an app down in the order\n */\n MoveDown(item: AppConfigItem): void {\n const index = this.ActiveApps.indexOf(item);\n if (index < this.ActiveApps.length - 1) {\n const nextItem = this.ActiveApps[index + 1];\n\n // Swap sequences\n const tempSeq = item.Sequence;\n item.Sequence = nextItem.Sequence;\n nextItem.Sequence = tempSeq;\n\n item.IsDirty = true;\n nextItem.IsDirty = true;\n\n // Re-sort\n this.ActiveApps = [...this.ActiveApps].sort((a, b) => a.Sequence - b.Sequence);\n }\n }\n\n /**\n * Checks if there are any unsaved changes\n */\n HasChanges(): boolean {\n return this.AllApps.some(item => item.IsDirty);\n }\n\n /**\n * Saves the user's app configuration\n */\n async Save(): Promise<void> {\n if (!this.HasChanges()) {\n return;\n }\n\n this.IsSaving = true;\n this.ErrorMessage = '';\n this.SuccessMessage = '';\n\n try {\n const md = this.ProviderToUse;\n\n // Process each app config item\n for (const item of this.AllApps) {\n if (!item.IsDirty) continue;\n\n if (item.UserAppId) {\n // Update existing UserApplication record\n await this.updateUserApplication(md, item);\n } else if (item.IsActive) {\n // Create new UserApplication record (only if active)\n await this.createUserApplication(md, item);\n }\n }\n\n // Reload the ApplicationManager to reflect changes\n LogStatus('User app configuration saved, reloading ApplicationManager...');\n await this.appManager.ReloadUserApplications();\n\n this.SuccessMessage = 'App configuration saved successfully!';\n this.sharedService.CreateSimpleNotification(this.SuccessMessage, 'success', 3000);\n\n // Clear dirty flags\n this.AllApps.forEach(item => item.IsDirty = false);\n\n } catch (error) {\n this.ErrorMessage = 'Failed to save configuration. Please try again.';\n LogError('Error saving app configuration:', undefined, error instanceof Error ? error.message : String(error));\n } finally {\n this.ngZone.run(() => {\n this.IsSaving = false;\n this.cdr.detectChanges();\n });\n }\n }\n\n /**\n * Updates an existing UserApplication record\n */\n private async updateUserApplication(md: IMetadataProvider, item: AppConfigItem): Promise<void> {\n const userApp = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications');\n await userApp.Load(item.UserAppId!);\n\n userApp.Sequence = item.Sequence;\n userApp.IsActive = item.IsActive;\n\n const saved = await userApp.Save();\n if (!saved) {\n throw new Error(`Failed to update UserApplication for ${item.App.Name}: ${userApp.LatestResult}`);\n }\n\n item.IsDirty = false;\n LogStatus(`Updated UserApplication for ${item.App.Name}: sequence=${item.Sequence}, isActive=${item.IsActive}`);\n }\n\n /**\n * Creates a new UserApplication record\n */\n private async createUserApplication(md: IMetadataProvider, item: AppConfigItem): Promise<void> {\n const userApp = await md.GetEntityObject<MJUserApplicationEntity>('MJ: User Applications');\n userApp.NewRecord();\n\n userApp.UserID = md.CurrentUser.ID;\n userApp.ApplicationID = item.App.ID;\n userApp.Sequence = item.Sequence;\n userApp.IsActive = item.IsActive;\n\n const saved = await userApp.Save();\n if (!saved) {\n throw new Error(`Failed to create UserApplication for ${item.App.Name}: ${userApp.LatestResult}`);\n }\n\n item.UserAppId = userApp.ID;\n item.IsDirty = false;\n LogStatus(`Created UserApplication for ${item.App.Name}: sequence=${item.Sequence}`);\n }\n\n /**\n * Resets all changes and reloads the configuration\n */\n async Reset(): Promise<void> {\n await this.LoadConfiguration();\n this.SuccessMessage = '';\n }\n\n /**\n * Check if drop target is active\n */\n IsDropTarget(index: number): boolean {\n return this.dropTargetIndex === index;\n }\n}\n","<div class=\"application-settings\">\n <h2 class=\"section-title\">Applications</h2>\n <p class=\"section-description\">Choose which applications appear in your app switcher and set their order</p>\n\n @if (IsLoading) {\n <div class=\"loading-container\">\n <mj-loading text=\"Loading applications...\"></mj-loading>\n </div>\n }\n\n @if (ErrorMessage && !IsLoading) {\n <mj-alert Variant=\"error\">{{ ErrorMessage }}</mj-alert>\n }\n\n @if (SuccessMessage && !IsLoading) {\n <mj-alert Variant=\"success\">{{ SuccessMessage }}</mj-alert>\n }\n\n @if (!IsLoading && !ErrorMessage) {\n <div class=\"app-config-layout\">\n <!-- Available Apps Panel -->\n <div class=\"app-panel available-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-grid-2\"></i>\n Available Applications\n </h3>\n <span class=\"panel-count\">{{ AvailableApps.length }}</span>\n </div>\n <div class=\"panel-content\">\n @if (AvailableApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-circle-check\"\n Title=\"All applications are selected\" />\n }\n @for (item of AvailableApps; track item.App.ID) {\n <div class=\"app-item\" (click)=\"AddApp(item)\">\n <div class=\"app-icon\">\n <i [class]=\"item.App.Icon || 'fa-solid fa-window-maximize'\"></i>\n </div>\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.App.Name }}</span>\n @if (item.App.Description) {\n <span class=\"app-desc\">{{ item.App.Description }}</span>\n }\n </div>\n <button\n class=\"app-action add-btn\"\n (click)=\"AddApp(item); $event.stopPropagation()\"\n title=\"Add to selected\"\n >\n <i class=\"fa-solid fa-plus\"></i>\n </button>\n </div>\n }\n </div>\n </div>\n\n <!-- Selected Apps Panel -->\n <div class=\"app-panel selected-panel\">\n <div class=\"panel-header\">\n <h3 class=\"panel-title\">\n <i class=\"fa-solid fa-star\"></i>\n Your Applications\n </h3>\n <span class=\"panel-count\">{{ ActiveApps.length }}</span>\n </div>\n <div class=\"panel-content\" (dragover)=\"OnDragOver($event)\">\n @if (ActiveApps.length === 0) {\n <mj-empty-state\n Size=\"compact\"\n Icon=\"fa-solid fa-arrow-left\"\n Title=\"Add applications from the list\" />\n }\n @for (item of ActiveApps; track item.App.ID; let i = $index; let first = $first; let last = $last) {\n <div\n class=\"app-item selected\"\n [class.drop-target]=\"IsDropTarget(i)\"\n [class.dirty]=\"item.IsDirty\"\n draggable=\"true\"\n (dragstart)=\"OnDragStart($event, item, i)\"\n (dragenter)=\"OnDragEnter($event, i)\"\n (dragend)=\"OnDragEnd()\"\n (drop)=\"OnDrop($event)\"\n >\n <div class=\"drag-handle\" title=\"Drag to reorder\">\n <i class=\"fa-solid fa-grip-vertical\"></i>\n </div>\n <div class=\"app-icon\">\n <i [class]=\"item.App.Icon || 'fa-solid fa-window-maximize'\"></i>\n </div>\n <div class=\"app-info\">\n <span class=\"app-name\">{{ item.App.Name }}</span>\n <span class=\"app-sequence\">Position {{ i + 1 }}</span>\n </div>\n <div class=\"app-actions\">\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n [disabled]=\"first\"\n (click)=\"MoveUp(item)\"\n title=\"Move up\"\n >\n <i class=\"fa-solid fa-chevron-up\"></i>\n </button>\n <button mjButton\n variant=\"flat\"\n size=\"sm\"\n [disabled]=\"last\"\n (click)=\"MoveDown(item)\"\n title=\"Move down\"\n >\n <i class=\"fa-solid fa-chevron-down\"></i>\n </button>\n <button mjButton\n variant=\"danger\"\n size=\"sm\"\n (click)=\"RemoveApp(item)\"\n title=\"Remove\"\n >\n <i class=\"fa-solid fa-times\"></i>\n </button>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-bar\">\n <button\n class=\"btn btn-secondary\"\n (click)=\"Reset()\"\n [disabled]=\"!HasChanges() || IsSaving\"\n >\n <i class=\"fa-solid fa-undo\"></i>\n Reset\n </button>\n <button\n class=\"btn btn-primary\"\n (click)=\"Save()\"\n [disabled]=\"!HasChanges() || IsSaving\"\n >\n @if (IsSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n Saving...\n } @else {\n <i class=\"fa-solid fa-save\"></i>\n Save Changes\n }\n </button>\n </div>\n }\n</div>\n"]}
|