@memberjunction/ng-explorer-settings 5.30.1 → 5.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/account-info/account-info.component.d.ts +2 -1
- package/dist/lib/account-info/account-info.component.d.ts.map +1 -1
- package/dist/lib/account-info/account-info.component.js +6 -5
- package/dist/lib/account-info/account-info.component.js.map +1 -1
- package/dist/lib/application-management/application-dialog/application-dialog.component.d.ts +3 -2
- 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 +9 -7
- package/dist/lib/application-management/application-dialog/application-dialog.component.js.map +1 -1
- package/dist/lib/application-management/application-management.component.d.ts +1 -1
- package/dist/lib/application-management/application-management.component.d.ts.map +1 -1
- package/dist/lib/application-management/application-management.component.js +4 -4
- package/dist/lib/application-management/application-management.component.js.map +1 -1
- package/dist/lib/application-settings/application-settings.component.d.ts +2 -1
- package/dist/lib/application-settings/application-settings.component.d.ts.map +1 -1
- package/dist/lib/application-settings/application-settings.component.js +9 -7
- package/dist/lib/application-settings/application-settings.component.js.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.d.ts.map +1 -1
- package/dist/lib/entity-permissions/entity-permissions.component.js +5 -5
- package/dist/lib/entity-permissions/entity-permissions.component.js.map +1 -1
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.d.ts +3 -2
- 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 +6 -5
- package/dist/lib/entity-permissions/permission-dialog/permission-dialog.component.js.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts +2 -1
- package/dist/lib/notification-preferences/notification-preferences.component.d.ts.map +1 -1
- package/dist/lib/notification-preferences/notification-preferences.component.js +6 -5
- package/dist/lib/notification-preferences/notification-preferences.component.js.map +1 -1
- package/dist/lib/role-management/role-dialog/role-dialog.component.d.ts +3 -2
- 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 +6 -5
- package/dist/lib/role-management/role-dialog/role-dialog.component.js.map +1 -1
- package/dist/lib/role-management/role-management.component.d.ts +1 -1
- package/dist/lib/role-management/role-management.component.d.ts.map +1 -1
- package/dist/lib/role-management/role-management.component.js +3 -3
- package/dist/lib/role-management/role-management.component.js.map +1 -1
- package/dist/lib/sql-logging/sql-logging.component.js +9 -10
- package/dist/lib/sql-logging/sql-logging.component.js.map +1 -1
- package/dist/lib/user-app-config/user-app-config.component.d.ts +2 -1
- package/dist/lib/user-app-config/user-app-config.component.d.ts.map +1 -1
- package/dist/lib/user-app-config/user-app-config.component.js +25 -21
- package/dist/lib/user-app-config/user-app-config.component.js.map +1 -1
- package/dist/lib/user-management/user-dialog/user-dialog.component.d.ts +3 -2
- 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 +8 -6
- package/dist/lib/user-management/user-dialog/user-dialog.component.js.map +1 -1
- package/dist/lib/user-management/user-management.component.d.ts +1 -1
- package/dist/lib/user-management/user-management.component.d.ts.map +1 -1
- package/dist/lib/user-management/user-management.component.js +7 -7
- package/dist/lib/user-management/user-management.component.js.map +1 -1
- package/dist/lib/user-profile-settings/user-profile-settings.component.d.ts +2 -1
- 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 +6 -5
- package/dist/lib/user-profile-settings/user-profile-settings.component.js.map +1 -1
- package/package.json +19 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-management.component.js","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts","../../../src/lib/user-management/user-management.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { UserDialogData, UserDialogResult } from './user-dialog/user-dialog.component';\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n inactiveUsers: number;\n adminUsers: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n role: string;\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-management',\n templateUrl: './user-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './user-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'UserManagement')\nexport class UserManagementComponent extends BaseDashboard implements OnDestroy {\n \n // State management\n public users: MJUserEntity[] = [];\n public filteredUsers: MJUserEntity[] = [];\n public roles: MJRoleEntity[] = [];\n public selectedUser: MJUserEntity | null = null;\n public isLoading = false;\n public error: string | null = null;\n\n // Selection state for bulk actions\n public selectedUserIds = new Set<string>();\n\n // Dialog state\n public showUserDialog = false;\n public userDialogData: UserDialogData | null = null;\n\n // Bulk action dialog state\n public showBulkActionConfirm = false;\n public bulkActionType: 'enable' | 'disable' | 'delete' | null = null;\n public showBulkRoleAssign = false;\n public bulkRoleId: string = '';\n \n // Stats\n public stats: UserStats = {\n totalUsers: 0,\n activeUsers: 0,\n inactiveUsers: 0,\n adminUsers: 0 // This will be based on roles, not Type\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n role: '',\n search: ''\n });\n \n // UI State\n public showCreateDialog = false;\n public showEditDialog = false;\n public showDeleteConfirm = false;\n public showMobileFilters = false;\n\n // Mobile expansion state\n private expandedUserIds = new Set<string>();\n\n // User-Role mapping\n private userRoleMap = new Map<string, string[]>(); // userId -> roleIds[]\n \n // Grid configuration\n public gridConfig = {\n pageSize: 20,\n sortField: 'Name',\n sortDirection: 'asc'\n };\n \n protected override destroy$ = new Subject<void>();\n private metadata = new Metadata();\n\n constructor(private cdr: ChangeDetectorRef, private ngZone: NgZone) {\n super();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n return \"User 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 users, roles, and user-role relationships in parallel\n const [users, roles, userRoles] = await Promise.all([\n this.loadUsers(),\n this.loadRoles(),\n this.loadUserRoles()\n ]);\n \n this.users = users;\n this.roles = roles;\n \n // Build user-role mapping\n this.buildUserRoleMapping(userRoles);\n \n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading user data:', error);\n this.error = 'Failed to load user 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 loadUsers(): Promise<MJUserEntity[]> {\n const rv = new RunView();\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = new RunView();\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private async loadUserRoles(): Promise<MJUserRoleEntity[]> {\n const rv = new RunView();\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private buildUserRoleMapping(userRoles: MJUserRoleEntity[]): void {\n this.userRoleMap.clear();\n \n userRoles.forEach(userRole => {\n const userId = userRole.UserID;\n const roleId = userRole.RoleID;\n \n if (!this.userRoleMap.has(userId)) {\n this.userRoleMap.set(userId, []);\n }\n \n this.userRoleMap.get(userId)!.push(roleId);\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.users];\n \n // Apply status filter\n if (filters.status !== 'all') {\n filtered = filtered.filter(user => \n filters.status === 'active' ? user.IsActive : !user.IsActive\n );\n }\n \n // Apply role filter\n if (filters.role) {\n filtered = filtered.filter(user => {\n const userRoles = this.userRoleMap.get(user.ID) || [];\n return userRoles.includes(filters.role);\n });\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(user =>\n user.Name?.toLowerCase().includes(searchLower) ||\n user.Email?.toLowerCase().includes(searchLower) ||\n user.FirstName?.toLowerCase().includes(searchLower) ||\n user.LastName?.toLowerCase().includes(searchLower)\n );\n }\n \n this.filteredUsers = filtered;\n }\n \n private calculateStats(): void {\n this.stats = {\n totalUsers: this.users.length,\n activeUsers: this.users.filter(u => u.IsActive).length,\n inactiveUsers: this.users.filter(u => !u.IsActive).length,\n adminUsers: this.users.filter(u => u.Type === 'Owner').length // Using Owner as admin type\n };\n }\n \n // Public methods for template\n public onSearchChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.updateFilter({ search: value });\n }\n \n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.updateFilter({ status });\n }\n \n public onRoleFilterChange(role: string): void {\n this.updateFilter({ role });\n }\n \n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n }\n \n public selectUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showEditDialog = true;\n }\n \n public createNewUser(): void {\n this.userDialogData = {\n mode: 'create',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public editUser(user: MJUserEntity): void {\n this.userDialogData = {\n user: user,\n mode: 'edit',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public confirmDeleteUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showDeleteConfirm = true;\n }\n \n public async deleteUser(): Promise<void> {\n if (!this.selectedUser) return;\n \n try {\n // Load user entity to delete\n const user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n const loadResult = await user.Load(this.selectedUser.ID);\n \n if (loadResult) {\n const deleteResult = await user.Delete();\n if (deleteResult) {\n this.showDeleteConfirm = false;\n this.selectedUser = null;\n await this.loadInitialData();\n } else {\n throw new Error(user.LatestResult?.Message || 'Failed to delete user');\n }\n } else {\n throw new Error('User not found or permission denied');\n }\n } catch (error: unknown) {\n console.error('Error deleting user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete user';\n this.cdr.markForCheck();\n });\n }\n }\n \n public async toggleUserStatus(user: MJUserEntity): Promise<void> {\n try {\n user.IsActive = !user.IsActive;\n await user.Save();\n this.ngZone.run(() => {\n this.calculateStats();\n this.cdr.markForCheck();\n });\n } catch (error) {\n console.error('Error updating user status:', error);\n this.ngZone.run(() => {\n user.IsActive = !user.IsActive; // Revert on error\n this.cdr.markForCheck();\n });\n }\n }\n \n public exportUsers(): void {\n if (this.filteredUsers.length === 0) {\n this.error = 'No users to export';\n return;\n }\n\n try {\n // Create CSV content\n const headers = ['Name', 'First Name', 'Last Name', 'Email', 'Type', 'Status', 'Created', 'Updated'];\n const csvRows = [headers.join(',')];\n\n // Add user data\n this.filteredUsers.forEach(user => {\n const row = [\n this.escapeCSV(user.Name || ''),\n this.escapeCSV(user.FirstName || ''),\n this.escapeCSV(user.LastName || ''),\n this.escapeCSV(user.Email || ''),\n this.escapeCSV(user.Type || ''),\n user.IsActive ? 'Active' : 'Inactive',\n user.__mj_CreatedAt ? new Date(user.__mj_CreatedAt).toLocaleDateString() : '',\n user.__mj_UpdatedAt ? new Date(user.__mj_UpdatedAt).toLocaleDateString() : ''\n ];\n csvRows.push(row.join(','));\n });\n\n // Create and download file\n const csvContent = csvRows.join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const link = document.createElement('a');\n \n if (link.download !== undefined) {\n const url = URL.createObjectURL(blob);\n link.setAttribute('href', url);\n link.setAttribute('download', `users_export_${new Date().toISOString().split('T')[0]}.csv`);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error('Error exporting users:', error);\n this.error = 'Failed to export users';\n }\n }\n\n private escapeCSV(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public getStatusIcon(user: MJUserEntity): string {\n return user.IsActive ? 'fa-check-circle' : 'fa-times-circle';\n }\n \n public getStatusClass(user: MJUserEntity): string {\n return user.IsActive ? 'status-active' : 'status-inactive';\n }\n \n public getUserTypeIcon(user: MJUserEntity): string {\n switch (user.Type) {\n case 'Owner':\n return 'fa-shield-halved';\n case 'User':\n return 'fa-user';\n default:\n return 'fa-user';\n }\n }\n \n public getUserInitials(user: MJUserEntity): string {\n const first = user.FirstName?.charAt(0) || '';\n const last = user.LastName?.charAt(0) || '';\n return (first + last).toUpperCase() || user.Name?.charAt(0).toUpperCase() || 'U';\n }\n\n public onUserDialogResult(result: UserDialogResult): void {\n this.showUserDialog = false;\n this.userDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the user list to show changes\n this.loadInitialData();\n }\n }\n\n // Selection methods for bulk actions\n public get isAllSelected(): boolean {\n return this.filteredUsers.length > 0 &&\n this.filteredUsers.every(user => this.selectedUserIds.has(user.ID));\n }\n\n public get isIndeterminate(): boolean {\n const selectedCount = this.filteredUsers.filter(user => this.selectedUserIds.has(user.ID)).length;\n return selectedCount > 0 && selectedCount < this.filteredUsers.length;\n }\n\n public get hasSelection(): boolean {\n return this.selectedUserIds.size > 0;\n }\n\n public get selectedCount(): number {\n return this.selectedUserIds.size;\n }\n\n public get hasActiveFilters(): boolean {\n const filters = this.filters$.value;\n return filters.status !== 'all' || filters.role !== '';\n }\n\n public get activeFilterCount(): number {\n let count = 0;\n const filters = this.filters$.value;\n if (filters.status !== 'all') count++;\n if (filters.role !== '') count++;\n return count;\n }\n\n public clearFilters(): void {\n this.filters$.next({\n ...this.filters$.value,\n status: 'all',\n role: ''\n });\n this.showMobileFilters = false;\n }\n\n public toggleSelectAll(): void {\n if (this.isAllSelected) {\n // Deselect all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.delete(user.ID));\n } else {\n // Select all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.add(user.ID));\n }\n }\n\n public toggleUserSelection(userId: string, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.selectedUserIds.has(userId)) {\n this.selectedUserIds.delete(userId);\n } else {\n this.selectedUserIds.add(userId);\n }\n }\n\n public isUserSelected(userId: string): boolean {\n return this.selectedUserIds.has(userId);\n }\n\n public clearSelection(): void {\n this.selectedUserIds.clear();\n }\n\n // Bulk action methods\n public confirmBulkAction(action: 'enable' | 'disable' | 'delete'): void {\n if (!this.hasSelection) return;\n this.bulkActionType = action;\n this.showBulkActionConfirm = true;\n }\n\n public cancelBulkAction(): void {\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n }\n\n public async executeBulkAction(): Promise<void> {\n if (!this.bulkActionType || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUsers = this.users.filter(user => this.selectedUserIds.has(user.ID));\n\n switch (this.bulkActionType) {\n case 'enable':\n await this.bulkSetUserStatus(selectedUsers, true);\n break;\n case 'disable':\n await this.bulkSetUserStatus(selectedUsers, false);\n break;\n case 'delete':\n await this.bulkDeleteUsers(selectedUsers);\n break;\n }\n\n this.clearSelection();\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk action failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk action failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async bulkSetUserStatus(users: MJUserEntity[], isActive: boolean): Promise<void> {\n if (users.length === 0) return;\n\n const md = new Metadata();\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.IsActive = isActive;\n user.TransactionGroup = tg;\n await user.Save();\n }\n if (!await tg.Submit()) {\n // Server rolled back — restore in-memory flags to their prior state\n for (const user of users) {\n user.IsActive = !isActive;\n }\n throw new Error('Failed to update users — all changes have been rolled back');\n }\n }\n\n private async bulkDeleteUsers(users: MJUserEntity[]): Promise<void> {\n if (users.length === 0) return;\n\n const md = new Metadata();\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.TransactionGroup = tg;\n await user.Delete();\n }\n if (!await tg.Submit()) {\n throw new Error('Failed to delete users — all changes have been rolled back');\n }\n }\n\n // Bulk role assignment\n public openBulkRoleAssign(): void {\n if (!this.hasSelection) return;\n this.bulkRoleId = '';\n this.showBulkRoleAssign = true;\n }\n\n public cancelBulkRoleAssign(): void {\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n }\n\n public async executeBulkRoleAssign(): Promise<void> {\n if (!this.bulkRoleId || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUserIds = Array.from(this.selectedUserIds);\n\n // Collect only the users that don't already have the role\n const usersNeedingRole = selectedUserIds.filter(userId => {\n const existingRoles = this.userRoleMap.get(userId) || [];\n return !existingRoles.includes(this.bulkRoleId);\n });\n\n if (usersNeedingRole.length > 0) {\n const tg = await this.metadata.CreateTransactionGroup();\n for (const userId of usersNeedingRole) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = this.bulkRoleId;\n userRole.TransactionGroup = tg;\n await userRole.Save();\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to assign roles — all changes have been rolled back');\n }\n }\n\n this.clearSelection();\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk role assignment failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk role assignment failed';\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 getBulkActionMessage(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Are you sure you want to enable ${count} user${count > 1 ? 's' : ''}?`;\n case 'disable':\n return `Are you sure you want to disable ${count} user${count > 1 ? 's' : ''}?`;\n case 'delete':\n return `Are you sure you want to delete ${count} user${count > 1 ? 's' : ''}? This action cannot be undone.`;\n default:\n return '';\n }\n }\n\n public getBulkActionTitle(): string {\n switch (this.bulkActionType) {\n case 'enable':\n return 'Enable Users';\n case 'disable':\n return 'Disable Users';\n case 'delete':\n return 'Delete Users';\n default:\n return 'Confirm Action';\n }\n }\n\n public getBulkActionButtonText(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Enable ${count} User${count > 1 ? 's' : ''}`;\n case 'disable':\n return `Disable ${count} User${count > 1 ? 's' : ''}`;\n case 'delete':\n return `Delete ${count} User${count > 1 ? 's' : ''}`;\n default:\n return 'Confirm';\n }\n }\n\n // Expansion methods\n public toggleUserExpansion(userId: string): void {\n if (this.expandedUserIds.has(userId)) {\n this.expandedUserIds.delete(userId);\n } else {\n this.expandedUserIds.add(userId);\n }\n }\n\n public isUserExpanded(userId: string): boolean {\n return this.expandedUserIds.has(userId);\n }\n\n // Get roles for a specific user\n public getUserRoles(userId: string): MJRoleEntity[] {\n const roleIds = this.userRoleMap.get(userId) || [];\n return this.roles.filter(role => roleIds.some(id => UUIDsEqual(id, role.ID)));\n }\n}","<div class=\"user-management-container\">\n <!-- Sticky Header Section -->\n <div class=\"sticky-header\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"User management actions\">\n <button\n mjButton variant=\"secondary\" class=\"mj-btn-icon-mobile\"\n (click)=\"refreshData()\"\n [disabled]=\"isLoading\"\n aria-label=\"Refresh user list\"\n >\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n <button\n mjButton variant=\"secondary\" class=\"mj-btn-icon-mobile\"\n (click)=\"exportUsers()\"\n aria-label=\"Export users to file\"\n >\n <i class=\"fa-solid fa-download\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Export</span>\n </button>\n <button\n mjButton variant=\"primary\" class=\"mj-btn-icon-mobile\"\n (click)=\"createNewUser()\"\n aria-label=\"Add new user\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Add User</span>\n </button>\n </div>\n\n <!-- Bulk Action Toolbar -->\n @if (hasSelection) {\n <div class=\"bulk-action-toolbar\" role=\"toolbar\" aria-label=\"Bulk actions\">\n <div class=\"bulk-selection-info\">\n <i class=\"fa-solid fa-check-square\" aria-hidden=\"true\"></i>\n <span>{{ selectedCount }} user{{ selectedCount > 1 ? 's' : '' }} selected</span>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear selection\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear\n </button>\n </div>\n <div class=\"bulk-action-buttons\">\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"confirmBulkAction('enable')\"\n aria-label=\"Enable selected users\"\n >\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Enable</span>\n </button>\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"confirmBulkAction('disable')\"\n aria-label=\"Disable selected users\"\n >\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Disable</span>\n </button>\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"openBulkRoleAssign()\"\n aria-label=\"Assign role to selected users\"\n >\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Assign Role</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmBulkAction('delete')\"\n aria-label=\"Delete selected users\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Delete</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Stats Cards -->\n <div class=\"mj-grid-4\" role=\"region\" aria-label=\"User statistics\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total users count\">{{ stats.totalUsers }}</div>\n <div class=\"stat-label\">Total Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-check\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Active users count\">{{ stats.activeUsers }}</div>\n <div class=\"stat-label\">Active Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-inactive\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-xmark\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Inactive users count\">{{ stats.inactiveUsers }}</div>\n <div class=\"stat-label\">Inactive Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-admin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Owner users count\">{{ stats.adminUsers }}</div>\n <div class=\"stat-label\">Owners</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\" role=\"search\" aria-label=\"Filter users\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search users by name or email...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n aria-label=\"Search users by name or email\"\n />\n </div>\n\n <!-- Mobile: Filter Toggle Button -->\n <button\n class=\"mobile-filter-toggle\"\n (click)=\"showMobileFilters = !showMobileFilters\"\n [class.active]=\"showMobileFilters\"\n [attr.aria-expanded]=\"showMobileFilters\"\n aria-label=\"Toggle filters\"\n >\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n @if (hasActiveFilters) {\n <span class=\"filter-badge\">{{ activeFilterCount }}</span>\n }\n </button>\n\n <!-- Desktop: Status Filter - Button group -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label\">Status</label>\n <div class=\"mj-filter-buttons\" role=\"group\" aria-labelledby=\"status-filter-label\">\n <button mjButton\n [variant]=\"filters$.value.status === 'all' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('all')\"\n [attr.aria-pressed]=\"filters$.value.status === 'all'\"\n >\n All\n </button>\n <button mjButton\n [variant]=\"filters$.value.status === 'active' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('active')\"\n [attr.aria-pressed]=\"filters$.value.status === 'active'\"\n >\n Active\n </button>\n <button mjButton\n [variant]=\"filters$.value.status === 'inactive' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('inactive')\"\n [attr.aria-pressed]=\"filters$.value.status === 'inactive'\"\n >\n Inactive\n </button>\n </div>\n </div>\n\n <!-- Desktop: Role Filter -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter\">Role</label>\n <select\n id=\"role-filter\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Mobile: Filter Dropdown Panel -->\n @if (showMobileFilters) {\n <div class=\"mobile-filter-dropdown\">\n <div class=\"mobile-filter-content\">\n <!-- Status Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label-mobile\">Status</label>\n <select\n class=\"mj-filter-select\"\n [value]=\"filters$.value.status\"\n (change)=\"onStatusFilterChange($any($event.target).value)\"\n aria-labelledby=\"status-filter-label-mobile\"\n >\n <option value=\"all\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter-mobile\">Role</label>\n <select\n id=\"role-filter-mobile\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Clear Filters Button -->\n @if (hasActiveFilters) {\n <button mjButton variant=\"flat\" size=\"sm\" class=\"clear-filters-btn\" (click)=\"clearFilters()\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear Filters\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div><!-- End Sticky Header -->\n\n <!-- Scrollable Content Section -->\n <div class=\"scrollable-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading users...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\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 class=\"retry-button\" (click)=\"loadInitialData()\" aria-label=\"Retry loading users\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <!-- Users List -->\n <div class=\"users-list\" role=\"list\" aria-label=\"Users list\">\n <!-- List Header with Select All -->\n <div class=\"list-header\">\n <label class=\"select-all-label\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isAllSelected\"\n [indeterminate]=\"isIndeterminate\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all users\"\n />\n <span class=\"select-all-text\">Select All ({{ filteredUsers.length }})</span>\n </label>\n @if (hasSelection) {\n <span class=\"selection-count\">{{ selectedCount }} selected</span>\n }\n </div>\n\n @for (user of filteredUsers; track user.ID) {\n <div\n class=\"user-card\"\n [class.expanded]=\"isUserExpanded(user.ID)\"\n [class.selected]=\"isUserSelected(user.ID)\"\n role=\"listitem\"\n >\n <!-- User Card Header - Always Visible -->\n <div\n class=\"user-header\"\n (click)=\"toggleUserExpansion(user.ID)\"\n role=\"button\"\n [attr.aria-expanded]=\"isUserExpanded(user.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleUserExpansion(user.ID)\"\n >\n <!-- Selection Checkbox -->\n <div class=\"user-selection\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isUserSelected(user.ID)\"\n (change)=\"toggleUserSelection(user.ID, $event)\"\n [attr.aria-label]=\"'Select ' + user.Name\"\n />\n </div>\n\n <!-- User Info -->\n <div class=\"user-info\">\n <div class=\"user-avatar\" aria-hidden=\"true\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-details\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-email\">{{ user.Email }}</p>\n </div>\n </div>\n\n <!-- User Meta -->\n <div class=\"user-meta\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"user-actions desktop-only\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n title=\"Edit\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n title=\"Delete\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle user details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- User Card Content - Expanded -->\n @if (isUserExpanded(user.ID)) {\n <div class=\"user-content\">\n <!-- Mobile Actions Bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">{{ user.IsActive ? 'Disable' : 'Enable' }}</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <!-- User Stats -->\n <div class=\"user-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Type:</span>\n <span class=\"stat-value\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.Type }}\n </span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-id-card\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Full Name:</span>\n <span class=\"stat-value\">{{ user.FirstName }} {{ user.LastName }}</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\">{{ user.__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\">{{ user.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <!-- User Roles Section -->\n <div class=\"roles-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-user-shield\" aria-hidden=\"true\"></i>\n Assigned Roles\n </h4>\n @if (getUserRoles(user.ID).length > 0) {\n <div class=\"roles-grid\">\n @for (role of getUserRoles(user.ID); track role.ID) {\n <div class=\"role-item\">\n <i class=\"fa-solid fa-shield\" aria-hidden=\"true\"></i>\n {{ role.Name }}\n </div>\n }\n </div>\n } @else {\n <p class=\"no-roles\">No roles assigned to this user</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-users-slash empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n </div>\n }\n </div><!-- End Scrollable Content -->\n\n <!-- User Create/Edit Dialog -->\n <mj-user-dialog\n [data]=\"userDialogData\"\n [visible]=\"showUserDialog\"\n (result)=\"onUserDialogResult($event)\">\n </mj-user-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedUser) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\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-desc\">\n <p>Are you sure you want to delete user <strong>{{ selectedUser.Name }}</strong>?</p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal-footer\">\n <button mjButton variant=\"danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete User\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Action Confirmation Dialog -->\n @if (showBulkActionConfirm) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkAction()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-action-dialog-title\"\n aria-describedby=\"bulk-action-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-action-dialog-title\">\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on text-success\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off text-warning\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionTitle() }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkAction()\"\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=\"bulk-action-dialog-desc\">\n <p>{{ getBulkActionMessage() }}</p>\n @if (bulkActionType === 'delete') {\n <p class=\"text-muted\">This action cannot be undone.</p>\n }\n </div>\n <div class=\"modal-footer\">\n <button mjButton\n [variant]=\"bulkActionType === 'delete' ? 'danger' : 'primary'\"\n (click)=\"executeBulkAction()\"\n [disabled]=\"isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Processing...\n } @else {\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionButtonText() }}\n }\n </button>\n <button mjButton (click)=\"cancelBulkAction()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Role Assignment Dialog -->\n @if (showBulkRoleAssign) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkRoleAssign()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-role-dialog-title\"\n aria-describedby=\"bulk-role-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-role-dialog-title\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role to {{ selectedCount }} User{{ selectedCount > 1 ? 's' : '' }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkRoleAssign()\"\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=\"bulk-role-dialog-desc\">\n <p>Select a role to assign to the selected users:</p>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"bulk-role-select\">Role</label>\n <select\n id=\"bulk-role-select\"\n class=\"field-select\"\n [(ngModel)]=\"bulkRoleId\"\n aria-label=\"Select role to assign\"\n >\n <option value=\"\">Select a role...</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n mjButton variant=\"primary\"\n (click)=\"executeBulkRoleAssign()\"\n [disabled]=\"!bulkRoleId || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Assigning...\n } @else {\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role\n }\n </button>\n <button mjButton (click)=\"cancelBulkRoleAssign()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n"]}
|
|
1
|
+
{"version":3,"file":"user-management.component.js","sourceRoot":"","sources":["../../../src/lib/user-management/user-management.component.ts","../../../src/lib/user-management/user-management.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, OnDestroy, ChangeDetectorRef, NgZone } from '@angular/core';\nimport { Subject, BehaviorSubject } from 'rxjs';\nimport { takeUntil, debounceTime, distinctUntilChanged } from 'rxjs/operators';\nimport { RunView, Metadata } from '@memberjunction/core';\nimport { MJUserEntity, MJRoleEntity, MJUserRoleEntity, ResourceData } from '@memberjunction/core-entities';\nimport { BaseDashboard } from '@memberjunction/ng-shared';\nimport { RegisterClass, UUIDsEqual } from '@memberjunction/global';\nimport { UserDialogData, UserDialogResult } from './user-dialog/user-dialog.component';\n\ninterface UserStats {\n totalUsers: number;\n activeUsers: number;\n inactiveUsers: number;\n adminUsers: number;\n}\n\ninterface FilterOptions {\n status: 'all' | 'active' | 'inactive';\n role: string;\n search: string;\n}\n\n@Component({\n standalone: false,\n selector: 'mj-user-management',\n templateUrl: './user-management.component.html',\n styleUrls: ['../shared/styles/_admin-patterns.css', './user-management.component.css']\n})\n@RegisterClass(BaseDashboard, 'UserManagement')\nexport class UserManagementComponent extends BaseDashboard implements OnDestroy {\n \n // State management\n public users: MJUserEntity[] = [];\n public filteredUsers: MJUserEntity[] = [];\n public roles: MJRoleEntity[] = [];\n public selectedUser: MJUserEntity | null = null;\n public isLoading = false;\n public error: string | null = null;\n\n // Selection state for bulk actions\n public selectedUserIds = new Set<string>();\n\n // Dialog state\n public showUserDialog = false;\n public userDialogData: UserDialogData | null = null;\n\n // Bulk action dialog state\n public showBulkActionConfirm = false;\n public bulkActionType: 'enable' | 'disable' | 'delete' | null = null;\n public showBulkRoleAssign = false;\n public bulkRoleId: string = '';\n \n // Stats\n public stats: UserStats = {\n totalUsers: 0,\n activeUsers: 0,\n inactiveUsers: 0,\n adminUsers: 0 // This will be based on roles, not Type\n };\n \n // Filters\n public filters$ = new BehaviorSubject<FilterOptions>({\n status: 'all',\n role: '',\n search: ''\n });\n \n // UI State\n public showCreateDialog = false;\n public showEditDialog = false;\n public showDeleteConfirm = false;\n public showMobileFilters = false;\n\n // Mobile expansion state\n private expandedUserIds = new Set<string>();\n\n // User-Role mapping\n private userRoleMap = new Map<string, string[]>(); // userId -> roleIds[]\n \n // Grid configuration\n public gridConfig = {\n pageSize: 20,\n sortField: 'Name',\n sortDirection: 'asc'\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 \"User 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 users, roles, and user-role relationships in parallel\n const [users, roles, userRoles] = await Promise.all([\n this.loadUsers(),\n this.loadRoles(),\n this.loadUserRoles()\n ]);\n \n this.users = users;\n this.roles = roles;\n \n // Build user-role mapping\n this.buildUserRoleMapping(userRoles);\n \n this.calculateStats();\n this.applyFilters();\n \n } catch (error) {\n console.error('Error loading user data:', error);\n this.error = 'Failed to load user 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 loadUsers(): Promise<MJUserEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserEntity>({\n EntityName: 'MJ: Users',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n \n private async loadRoles(): Promise<MJRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJRoleEntity>({\n EntityName: 'MJ: Roles',\n ResultType: 'entity_object',\n OrderBy: 'Name ASC'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private async loadUserRoles(): Promise<MJUserRoleEntity[]> {\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n const result = await rv.RunView<MJUserRoleEntity>({\n EntityName: 'MJ: User Roles',\n ResultType: 'entity_object'\n });\n \n return result.Success ? result.Results : [];\n }\n\n private buildUserRoleMapping(userRoles: MJUserRoleEntity[]): void {\n this.userRoleMap.clear();\n \n userRoles.forEach(userRole => {\n const userId = userRole.UserID;\n const roleId = userRole.RoleID;\n \n if (!this.userRoleMap.has(userId)) {\n this.userRoleMap.set(userId, []);\n }\n \n this.userRoleMap.get(userId)!.push(roleId);\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.users];\n \n // Apply status filter\n if (filters.status !== 'all') {\n filtered = filtered.filter(user => \n filters.status === 'active' ? user.IsActive : !user.IsActive\n );\n }\n \n // Apply role filter\n if (filters.role) {\n filtered = filtered.filter(user => {\n const userRoles = this.userRoleMap.get(user.ID) || [];\n return userRoles.includes(filters.role);\n });\n }\n \n // Apply search filter\n if (filters.search) {\n const searchLower = filters.search.toLowerCase();\n filtered = filtered.filter(user =>\n user.Name?.toLowerCase().includes(searchLower) ||\n user.Email?.toLowerCase().includes(searchLower) ||\n user.FirstName?.toLowerCase().includes(searchLower) ||\n user.LastName?.toLowerCase().includes(searchLower)\n );\n }\n \n this.filteredUsers = filtered;\n }\n \n private calculateStats(): void {\n this.stats = {\n totalUsers: this.users.length,\n activeUsers: this.users.filter(u => u.IsActive).length,\n inactiveUsers: this.users.filter(u => !u.IsActive).length,\n adminUsers: this.users.filter(u => u.Type === 'Owner').length // Using Owner as admin type\n };\n }\n \n // Public methods for template\n public onSearchChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.updateFilter({ search: value });\n }\n \n public onStatusFilterChange(status: 'all' | 'active' | 'inactive'): void {\n this.updateFilter({ status });\n }\n \n public onRoleFilterChange(role: string): void {\n this.updateFilter({ role });\n }\n \n public updateFilter(partial: Partial<FilterOptions>): void {\n this.filters$.next({\n ...this.filters$.value,\n ...partial\n });\n }\n \n public selectUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showEditDialog = true;\n }\n \n public createNewUser(): void {\n this.userDialogData = {\n mode: 'create',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public editUser(user: MJUserEntity): void {\n this.userDialogData = {\n user: user,\n mode: 'edit',\n availableRoles: this.roles\n };\n this.showUserDialog = true;\n }\n \n public confirmDeleteUser(user: MJUserEntity): void {\n this.selectedUser = user;\n this.showDeleteConfirm = true;\n }\n \n public async deleteUser(): Promise<void> {\n if (!this.selectedUser) return;\n \n try {\n // Load user entity to delete\n const user = await this.metadata.GetEntityObject<MJUserEntity>('MJ: Users');\n const loadResult = await user.Load(this.selectedUser.ID);\n \n if (loadResult) {\n const deleteResult = await user.Delete();\n if (deleteResult) {\n this.showDeleteConfirm = false;\n this.selectedUser = null;\n await this.loadInitialData();\n } else {\n throw new Error(user.LatestResult?.Message || 'Failed to delete user');\n }\n } else {\n throw new Error('User not found or permission denied');\n }\n } catch (error: unknown) {\n console.error('Error deleting user:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Failed to delete user';\n this.cdr.markForCheck();\n });\n }\n }\n \n public async toggleUserStatus(user: MJUserEntity): Promise<void> {\n try {\n user.IsActive = !user.IsActive;\n await user.Save();\n this.ngZone.run(() => {\n this.calculateStats();\n this.cdr.markForCheck();\n });\n } catch (error) {\n console.error('Error updating user status:', error);\n this.ngZone.run(() => {\n user.IsActive = !user.IsActive; // Revert on error\n this.cdr.markForCheck();\n });\n }\n }\n \n public exportUsers(): void {\n if (this.filteredUsers.length === 0) {\n this.error = 'No users to export';\n return;\n }\n\n try {\n // Create CSV content\n const headers = ['Name', 'First Name', 'Last Name', 'Email', 'Type', 'Status', 'Created', 'Updated'];\n const csvRows = [headers.join(',')];\n\n // Add user data\n this.filteredUsers.forEach(user => {\n const row = [\n this.escapeCSV(user.Name || ''),\n this.escapeCSV(user.FirstName || ''),\n this.escapeCSV(user.LastName || ''),\n this.escapeCSV(user.Email || ''),\n this.escapeCSV(user.Type || ''),\n user.IsActive ? 'Active' : 'Inactive',\n user.__mj_CreatedAt ? new Date(user.__mj_CreatedAt).toLocaleDateString() : '',\n user.__mj_UpdatedAt ? new Date(user.__mj_UpdatedAt).toLocaleDateString() : ''\n ];\n csvRows.push(row.join(','));\n });\n\n // Create and download file\n const csvContent = csvRows.join('\\n');\n const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });\n const link = document.createElement('a');\n \n if (link.download !== undefined) {\n const url = URL.createObjectURL(blob);\n link.setAttribute('href', url);\n link.setAttribute('download', `users_export_${new Date().toISOString().split('T')[0]}.csv`);\n link.style.visibility = 'hidden';\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n }\n } catch (error) {\n console.error('Error exporting users:', error);\n this.error = 'Failed to export users';\n }\n }\n\n private escapeCSV(value: string): string {\n if (value.includes(',') || value.includes('\"') || value.includes('\\n')) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n }\n \n public refreshData(): void {\n this.loadInitialData();\n }\n \n public getStatusIcon(user: MJUserEntity): string {\n return user.IsActive ? 'fa-check-circle' : 'fa-times-circle';\n }\n \n public getStatusClass(user: MJUserEntity): string {\n return user.IsActive ? 'status-active' : 'status-inactive';\n }\n \n public getUserTypeIcon(user: MJUserEntity): string {\n switch (user.Type) {\n case 'Owner':\n return 'fa-shield-halved';\n case 'User':\n return 'fa-user';\n default:\n return 'fa-user';\n }\n }\n \n public getUserInitials(user: MJUserEntity): string {\n const first = user.FirstName?.charAt(0) || '';\n const last = user.LastName?.charAt(0) || '';\n return (first + last).toUpperCase() || user.Name?.charAt(0).toUpperCase() || 'U';\n }\n\n public onUserDialogResult(result: UserDialogResult): void {\n this.showUserDialog = false;\n this.userDialogData = null;\n\n if (result.action === 'save') {\n // Refresh the user list to show changes\n this.loadInitialData();\n }\n }\n\n // Selection methods for bulk actions\n public get isAllSelected(): boolean {\n return this.filteredUsers.length > 0 &&\n this.filteredUsers.every(user => this.selectedUserIds.has(user.ID));\n }\n\n public get isIndeterminate(): boolean {\n const selectedCount = this.filteredUsers.filter(user => this.selectedUserIds.has(user.ID)).length;\n return selectedCount > 0 && selectedCount < this.filteredUsers.length;\n }\n\n public get hasSelection(): boolean {\n return this.selectedUserIds.size > 0;\n }\n\n public get selectedCount(): number {\n return this.selectedUserIds.size;\n }\n\n public get hasActiveFilters(): boolean {\n const filters = this.filters$.value;\n return filters.status !== 'all' || filters.role !== '';\n }\n\n public get activeFilterCount(): number {\n let count = 0;\n const filters = this.filters$.value;\n if (filters.status !== 'all') count++;\n if (filters.role !== '') count++;\n return count;\n }\n\n public clearFilters(): void {\n this.filters$.next({\n ...this.filters$.value,\n status: 'all',\n role: ''\n });\n this.showMobileFilters = false;\n }\n\n public toggleSelectAll(): void {\n if (this.isAllSelected) {\n // Deselect all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.delete(user.ID));\n } else {\n // Select all filtered users\n this.filteredUsers.forEach(user => this.selectedUserIds.add(user.ID));\n }\n }\n\n public toggleUserSelection(userId: string, event?: Event): void {\n if (event) {\n event.stopPropagation();\n }\n if (this.selectedUserIds.has(userId)) {\n this.selectedUserIds.delete(userId);\n } else {\n this.selectedUserIds.add(userId);\n }\n }\n\n public isUserSelected(userId: string): boolean {\n return this.selectedUserIds.has(userId);\n }\n\n public clearSelection(): void {\n this.selectedUserIds.clear();\n }\n\n // Bulk action methods\n public confirmBulkAction(action: 'enable' | 'disable' | 'delete'): void {\n if (!this.hasSelection) return;\n this.bulkActionType = action;\n this.showBulkActionConfirm = true;\n }\n\n public cancelBulkAction(): void {\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n }\n\n public async executeBulkAction(): Promise<void> {\n if (!this.bulkActionType || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUsers = this.users.filter(user => this.selectedUserIds.has(user.ID));\n\n switch (this.bulkActionType) {\n case 'enable':\n await this.bulkSetUserStatus(selectedUsers, true);\n break;\n case 'disable':\n await this.bulkSetUserStatus(selectedUsers, false);\n break;\n case 'delete':\n await this.bulkDeleteUsers(selectedUsers);\n break;\n }\n\n this.clearSelection();\n this.showBulkActionConfirm = false;\n this.bulkActionType = null;\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk action failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk action failed';\n this.cdr.markForCheck();\n });\n } finally {\n this.ngZone.run(() => {\n this.isLoading = false;\n this.cdr.markForCheck();\n });\n }\n }\n\n private async bulkSetUserStatus(users: MJUserEntity[], isActive: boolean): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.IsActive = isActive;\n user.TransactionGroup = tg;\n await user.Save();\n }\n if (!await tg.Submit()) {\n // Server rolled back — restore in-memory flags to their prior state\n for (const user of users) {\n user.IsActive = !isActive;\n }\n throw new Error('Failed to update users — all changes have been rolled back');\n }\n }\n\n private async bulkDeleteUsers(users: MJUserEntity[]): Promise<void> {\n if (users.length === 0) return;\n\n const md = this.ProviderToUse;\n const tg = await md.CreateTransactionGroup();\n for (const user of users) {\n user.TransactionGroup = tg;\n await user.Delete();\n }\n if (!await tg.Submit()) {\n throw new Error('Failed to delete users — all changes have been rolled back');\n }\n }\n\n // Bulk role assignment\n public openBulkRoleAssign(): void {\n if (!this.hasSelection) return;\n this.bulkRoleId = '';\n this.showBulkRoleAssign = true;\n }\n\n public cancelBulkRoleAssign(): void {\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n }\n\n public async executeBulkRoleAssign(): Promise<void> {\n if (!this.bulkRoleId || !this.hasSelection) return;\n\n try {\n this.isLoading = true;\n const selectedUserIds = Array.from(this.selectedUserIds);\n\n // Collect only the users that don't already have the role\n const usersNeedingRole = selectedUserIds.filter(userId => {\n const existingRoles = this.userRoleMap.get(userId) || [];\n return !existingRoles.includes(this.bulkRoleId);\n });\n\n if (usersNeedingRole.length > 0) {\n const tg = await this.metadata.CreateTransactionGroup();\n for (const userId of usersNeedingRole) {\n const userRole = await this.metadata.GetEntityObject<MJUserRoleEntity>('MJ: User Roles');\n userRole.NewRecord();\n userRole.UserID = userId;\n userRole.RoleID = this.bulkRoleId;\n userRole.TransactionGroup = tg;\n await userRole.Save();\n }\n\n if (!await tg.Submit()) {\n throw new Error('Failed to assign roles — all changes have been rolled back');\n }\n }\n\n this.clearSelection();\n this.showBulkRoleAssign = false;\n this.bulkRoleId = '';\n await this.loadInitialData();\n } catch (error: unknown) {\n console.error('Bulk role assignment failed:', error);\n this.ngZone.run(() => {\n this.error = error instanceof Error ? error.message : 'Bulk role assignment failed';\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 getBulkActionMessage(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Are you sure you want to enable ${count} user${count > 1 ? 's' : ''}?`;\n case 'disable':\n return `Are you sure you want to disable ${count} user${count > 1 ? 's' : ''}?`;\n case 'delete':\n return `Are you sure you want to delete ${count} user${count > 1 ? 's' : ''}? This action cannot be undone.`;\n default:\n return '';\n }\n }\n\n public getBulkActionTitle(): string {\n switch (this.bulkActionType) {\n case 'enable':\n return 'Enable Users';\n case 'disable':\n return 'Disable Users';\n case 'delete':\n return 'Delete Users';\n default:\n return 'Confirm Action';\n }\n }\n\n public getBulkActionButtonText(): string {\n const count = this.selectedCount;\n switch (this.bulkActionType) {\n case 'enable':\n return `Enable ${count} User${count > 1 ? 's' : ''}`;\n case 'disable':\n return `Disable ${count} User${count > 1 ? 's' : ''}`;\n case 'delete':\n return `Delete ${count} User${count > 1 ? 's' : ''}`;\n default:\n return 'Confirm';\n }\n }\n\n // Expansion methods\n public toggleUserExpansion(userId: string): void {\n if (this.expandedUserIds.has(userId)) {\n this.expandedUserIds.delete(userId);\n } else {\n this.expandedUserIds.add(userId);\n }\n }\n\n public isUserExpanded(userId: string): boolean {\n return this.expandedUserIds.has(userId);\n }\n\n // Get roles for a specific user\n public getUserRoles(userId: string): MJRoleEntity[] {\n const roleIds = this.userRoleMap.get(userId) || [];\n return this.roles.filter(role => roleIds.some(id => UUIDsEqual(id, role.ID)));\n }\n}","<div class=\"user-management-container\">\n <!-- Sticky Header Section -->\n <div class=\"sticky-header\">\n <!-- Action Buttons -->\n <div class=\"action-buttons\" role=\"toolbar\" aria-label=\"User management actions\">\n <button\n mjButton variant=\"secondary\" class=\"mj-btn-icon-mobile\"\n (click)=\"refreshData()\"\n [disabled]=\"isLoading\"\n aria-label=\"Refresh user list\"\n >\n <i class=\"fa-solid fa-refresh\" [class.fa-spin]=\"isLoading\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Refresh</span>\n </button>\n <button\n mjButton variant=\"secondary\" class=\"mj-btn-icon-mobile\"\n (click)=\"exportUsers()\"\n aria-label=\"Export users to file\"\n >\n <i class=\"fa-solid fa-download\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Export</span>\n </button>\n <button\n mjButton variant=\"primary\" class=\"mj-btn-icon-mobile\"\n (click)=\"createNewUser()\"\n aria-label=\"Add new user\"\n >\n <i class=\"fa-solid fa-plus\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Add User</span>\n </button>\n </div>\n\n <!-- Bulk Action Toolbar -->\n @if (hasSelection) {\n <div class=\"bulk-action-toolbar\" role=\"toolbar\" aria-label=\"Bulk actions\">\n <div class=\"bulk-selection-info\">\n <i class=\"fa-solid fa-check-square\" aria-hidden=\"true\"></i>\n <span>{{ selectedCount }} user{{ selectedCount > 1 ? 's' : '' }} selected</span>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"clearSelection()\"\n aria-label=\"Clear selection\"\n >\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear\n </button>\n </div>\n <div class=\"bulk-action-buttons\">\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"confirmBulkAction('enable')\"\n aria-label=\"Enable selected users\"\n >\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Enable</span>\n </button>\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"confirmBulkAction('disable')\"\n aria-label=\"Disable selected users\"\n >\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Disable</span>\n </button>\n <button\n mjButton variant=\"secondary\" size=\"sm\"\n (click)=\"openBulkRoleAssign()\"\n aria-label=\"Assign role to selected users\"\n >\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Assign Role</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmBulkAction('delete')\"\n aria-label=\"Delete selected users\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-text\">Delete</span>\n </button>\n </div>\n </div>\n }\n\n <!-- Stats Cards -->\n <div class=\"mj-grid-4\" role=\"region\" aria-label=\"User statistics\">\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-total\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-users\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Total users count\">{{ stats.totalUsers }}</div>\n <div class=\"stat-label\">Total Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-active\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-check\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Active users count\">{{ stats.activeUsers }}</div>\n <div class=\"stat-label\">Active Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-inactive\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-user-xmark\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Inactive users count\">{{ stats.inactiveUsers }}</div>\n <div class=\"stat-label\">Inactive Users</div>\n </div>\n </div>\n\n <div class=\"mj-card\">\n <div class=\"stat-icon stat-icon-admin\" aria-hidden=\"true\">\n <i class=\"fa-solid fa-shield-halved\"></i>\n </div>\n <div class=\"stat-content\">\n <div class=\"stat-value\" aria-label=\"Owner users count\">{{ stats.adminUsers }}</div>\n <div class=\"stat-label\">Owners</div>\n </div>\n </div>\n </div>\n\n <!-- Filters Section -->\n <div class=\"filters-section\" role=\"search\" aria-label=\"Filter users\">\n <div class=\"filters-row\">\n <!-- Search -->\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search users by name or email...\"\n (input)=\"onSearchChange($event)\"\n [value]=\"filters$.value.search\"\n aria-label=\"Search users by name or email\"\n />\n </div>\n\n <!-- Mobile: Filter Toggle Button -->\n <button\n class=\"mobile-filter-toggle\"\n (click)=\"showMobileFilters = !showMobileFilters\"\n [class.active]=\"showMobileFilters\"\n [attr.aria-expanded]=\"showMobileFilters\"\n aria-label=\"Toggle filters\"\n >\n <i class=\"fa-solid fa-filter\" aria-hidden=\"true\"></i>\n @if (hasActiveFilters) {\n <span class=\"filter-badge\">{{ activeFilterCount }}</span>\n }\n </button>\n\n <!-- Desktop: Status Filter - Button group -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label\">Status</label>\n <div class=\"mj-filter-buttons\" role=\"group\" aria-labelledby=\"status-filter-label\">\n <button mjButton\n [variant]=\"filters$.value.status === 'all' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('all')\"\n [attr.aria-pressed]=\"filters$.value.status === 'all'\"\n >\n All\n </button>\n <button mjButton\n [variant]=\"filters$.value.status === 'active' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('active')\"\n [attr.aria-pressed]=\"filters$.value.status === 'active'\"\n >\n Active\n </button>\n <button mjButton\n [variant]=\"filters$.value.status === 'inactive' ? 'primary' : 'flat'\"\n (click)=\"onStatusFilterChange('inactive')\"\n [attr.aria-pressed]=\"filters$.value.status === 'inactive'\"\n >\n Inactive\n </button>\n </div>\n </div>\n\n <!-- Desktop: Role Filter -->\n <div class=\"mj-filter-group desktop-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter\">Role</label>\n <select\n id=\"role-filter\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n\n <!-- Mobile: Filter Dropdown Panel -->\n @if (showMobileFilters) {\n <div class=\"mobile-filter-dropdown\">\n <div class=\"mobile-filter-content\">\n <!-- Status Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" id=\"status-filter-label-mobile\">Status</label>\n <select\n class=\"mj-filter-select\"\n [value]=\"filters$.value.status\"\n (change)=\"onStatusFilterChange($any($event.target).value)\"\n aria-labelledby=\"status-filter-label-mobile\"\n >\n <option value=\"all\">All Status</option>\n <option value=\"active\">Active</option>\n <option value=\"inactive\">Inactive</option>\n </select>\n </div>\n\n <!-- Role Filter -->\n <div class=\"mj-filter-group\">\n <label class=\"mj-filter-label\" for=\"role-filter-mobile\">Role</label>\n <select\n id=\"role-filter-mobile\"\n class=\"mj-filter-select\"\n (change)=\"onRoleFilterChange($any($event.target).value)\"\n aria-label=\"Filter by role\"\n >\n <option value=\"\">All Roles</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n\n <!-- Clear Filters Button -->\n @if (hasActiveFilters) {\n <button mjButton variant=\"flat\" size=\"sm\" class=\"clear-filters-btn\" (click)=\"clearFilters()\">\n <i class=\"fa-solid fa-times\" aria-hidden=\"true\"></i>\n Clear Filters\n </button>\n }\n </div>\n </div>\n }\n </div>\n </div><!-- End Sticky Header -->\n\n <!-- Scrollable Content Section -->\n <div class=\"scrollable-content\">\n <!-- Loading State -->\n @if (isLoading) {\n <div class=\"loading-container\" role=\"status\" aria-live=\"polite\" aria-busy=\"true\">\n <mj-loading text=\"Loading users...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- Error State -->\n @if (error && !isLoading) {\n <div class=\"error-container\" role=\"alert\" aria-live=\"assertive\">\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 class=\"retry-button\" (click)=\"loadInitialData()\" aria-label=\"Retry loading users\">\n <i class=\"fa-solid fa-refresh\" aria-hidden=\"true\"></i>\n Try Again\n </button>\n </div>\n </div>\n }\n\n <!-- Content Area -->\n @if (!isLoading && !error) {\n <div class=\"content-area\">\n <!-- Users List -->\n <div class=\"users-list\" role=\"list\" aria-label=\"Users list\">\n <!-- List Header with Select All -->\n <div class=\"list-header\">\n <label class=\"select-all-label\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isAllSelected\"\n [indeterminate]=\"isIndeterminate\"\n (change)=\"toggleSelectAll()\"\n aria-label=\"Select all users\"\n />\n <span class=\"select-all-text\">Select All ({{ filteredUsers.length }})</span>\n </label>\n @if (hasSelection) {\n <span class=\"selection-count\">{{ selectedCount }} selected</span>\n }\n </div>\n\n @for (user of filteredUsers; track user.ID) {\n <div\n class=\"user-card\"\n [class.expanded]=\"isUserExpanded(user.ID)\"\n [class.selected]=\"isUserSelected(user.ID)\"\n role=\"listitem\"\n >\n <!-- User Card Header - Always Visible -->\n <div\n class=\"user-header\"\n (click)=\"toggleUserExpansion(user.ID)\"\n role=\"button\"\n [attr.aria-expanded]=\"isUserExpanded(user.ID)\"\n tabindex=\"0\"\n (keydown.enter)=\"toggleUserExpansion(user.ID)\"\n >\n <!-- Selection Checkbox -->\n <div class=\"user-selection\" (click)=\"$event.stopPropagation()\">\n <input\n type=\"checkbox\"\n class=\"checkbox\"\n [checked]=\"isUserSelected(user.ID)\"\n (change)=\"toggleUserSelection(user.ID, $event)\"\n [attr.aria-label]=\"'Select ' + user.Name\"\n />\n </div>\n\n <!-- User Info -->\n <div class=\"user-info\">\n <div class=\"user-avatar\" aria-hidden=\"true\">\n {{ getUserInitials(user) }}\n </div>\n <div class=\"user-details\">\n <h3 class=\"user-name\">{{ user.Name }}</h3>\n <p class=\"user-email\">{{ user.Email }}</p>\n </div>\n </div>\n\n <!-- User Meta -->\n <div class=\"user-meta\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"user-actions desktop-only\" (click)=\"$event.stopPropagation()\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n title=\"Edit\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n [title]=\"user.IsActive ? 'Deactivate' : 'Activate'\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n title=\"Delete\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n </button>\n </div>\n <button class=\"expand-btn\" aria-label=\"Toggle user details\">\n <i class=\"fa-solid fa-chevron-down\" aria-hidden=\"true\"></i>\n </button>\n </div>\n </div>\n\n <!-- User Card Content - Expanded -->\n @if (isUserExpanded(user.ID)) {\n <div class=\"user-content\">\n <!-- Mobile Actions Bar -->\n <div class=\"mobile-actions-bar\" (click)=\"$event.stopPropagation()\">\n <span class=\"status-badge\" [class]=\"getStatusClass(user)\">\n <i [class]=\"'fa-solid ' + getStatusIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.IsActive ? 'Active' : 'Inactive' }}\n </span>\n <div class=\"mobile-action-buttons\">\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"editUser(user)\"\n [attr.aria-label]=\"'Edit ' + user.Name\"\n >\n <i class=\"fa-solid fa-edit\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Edit</span>\n </button>\n <button\n mjButton variant=\"flat\" size=\"sm\"\n (click)=\"toggleUserStatus(user)\"\n [attr.aria-label]=\"(user.IsActive ? 'Deactivate ' : 'Activate ') + user.Name\"\n >\n <i [class]=\"user.IsActive ? 'fa-solid fa-toggle-on' : 'fa-solid fa-toggle-off'\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">{{ user.IsActive ? 'Disable' : 'Enable' }}</span>\n </button>\n <button\n mjButton variant=\"danger\" size=\"sm\"\n (click)=\"confirmDeleteUser(user)\"\n [attr.aria-label]=\"'Delete ' + user.Name\"\n >\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n <span class=\"btn-label\">Delete</span>\n </button>\n </div>\n </div>\n\n <!-- User Stats -->\n <div class=\"user-stats\">\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Type:</span>\n <span class=\"stat-value\">\n <i [class]=\"'fa-solid ' + getUserTypeIcon(user)\" aria-hidden=\"true\"></i>\n {{ user.Type }}\n </span>\n </div>\n <div class=\"stat-item\">\n <i class=\"fa-solid fa-id-card\" aria-hidden=\"true\"></i>\n <span class=\"stat-label\">Full Name:</span>\n <span class=\"stat-value\">{{ user.FirstName }} {{ user.LastName }}</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\">{{ user.__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\">{{ user.__mj_UpdatedAt | date:'short' }}</span>\n </div>\n </div>\n\n <!-- User Roles Section -->\n <div class=\"roles-section\">\n <h4 class=\"section-title\">\n <i class=\"fa-solid fa-user-shield\" aria-hidden=\"true\"></i>\n Assigned Roles\n </h4>\n @if (getUserRoles(user.ID).length > 0) {\n <div class=\"roles-grid\">\n @for (role of getUserRoles(user.ID); track role.ID) {\n <div class=\"role-item\">\n <i class=\"fa-solid fa-shield\" aria-hidden=\"true\"></i>\n {{ role.Name }}\n </div>\n }\n </div>\n } @else {\n <p class=\"no-roles\">No roles assigned to this user</p>\n }\n </div>\n </div>\n }\n </div>\n }\n\n @if (filteredUsers.length === 0) {\n <div class=\"empty-state\" role=\"status\">\n <i class=\"fa-solid fa-users-slash empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No users found</p>\n <p class=\"empty-subtext\">Try adjusting your filters or add a new user</p>\n </div>\n }\n </div>\n </div>\n }\n </div><!-- End Scrollable Content -->\n\n <!-- User Create/Edit Dialog -->\n <mj-user-dialog\n [data]=\"userDialogData\"\n [visible]=\"showUserDialog\"\n (result)=\"onUserDialogResult($event)\">\n </mj-user-dialog>\n\n <!-- Delete Confirmation Dialog -->\n @if (showDeleteConfirm && selectedUser) {\n <div\n class=\"modal-backdrop\"\n (click)=\"showDeleteConfirm = false\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"delete-dialog-title\"\n aria-describedby=\"delete-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\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-desc\">\n <p>Are you sure you want to delete user <strong>{{ selectedUser.Name }}</strong>?</p>\n <p class=\"text-muted\">This action cannot be undone.</p>\n </div>\n <div class=\"modal-footer\">\n <button mjButton variant=\"danger\" (click)=\"deleteUser()\">\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n Delete User\n </button>\n <button mjButton (click)=\"showDeleteConfirm = false\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Action Confirmation Dialog -->\n @if (showBulkActionConfirm) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkAction()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-action-dialog-title\"\n aria-describedby=\"bulk-action-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-action-dialog-title\">\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-exclamation-triangle text-danger\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on text-success\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off text-warning\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionTitle() }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkAction()\"\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=\"bulk-action-dialog-desc\">\n <p>{{ getBulkActionMessage() }}</p>\n @if (bulkActionType === 'delete') {\n <p class=\"text-muted\">This action cannot be undone.</p>\n }\n </div>\n <div class=\"modal-footer\">\n <button mjButton\n [variant]=\"bulkActionType === 'delete' ? 'danger' : 'primary'\"\n (click)=\"executeBulkAction()\"\n [disabled]=\"isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Processing...\n } @else {\n @if (bulkActionType === 'delete') {\n <i class=\"fa-solid fa-trash\" aria-hidden=\"true\"></i>\n } @else if (bulkActionType === 'enable') {\n <i class=\"fa-solid fa-toggle-on\" aria-hidden=\"true\"></i>\n } @else {\n <i class=\"fa-solid fa-toggle-off\" aria-hidden=\"true\"></i>\n }\n {{ getBulkActionButtonText() }}\n }\n </button>\n <button mjButton (click)=\"cancelBulkAction()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n\n <!-- Bulk Role Assignment Dialog -->\n @if (showBulkRoleAssign) {\n <div\n class=\"modal-backdrop\"\n (click)=\"cancelBulkRoleAssign()\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"bulk-role-dialog-title\"\n aria-describedby=\"bulk-role-dialog-desc\"\n >\n <div class=\"modal-dialog\" (click)=\"$event.stopPropagation()\">\n <div class=\"modal-header\">\n <h3 class=\"modal-title\" id=\"bulk-role-dialog-title\">\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role to {{ selectedCount }} User{{ selectedCount > 1 ? 's' : '' }}\n </h3>\n <button\n class=\"modal-close\"\n (click)=\"cancelBulkRoleAssign()\"\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=\"bulk-role-dialog-desc\">\n <p>Select a role to assign to the selected users:</p>\n <div class=\"form-field\">\n <label class=\"field-label\" for=\"bulk-role-select\">Role</label>\n <select\n id=\"bulk-role-select\"\n class=\"field-select\"\n [(ngModel)]=\"bulkRoleId\"\n aria-label=\"Select role to assign\"\n >\n <option value=\"\">Select a role...</option>\n @for (role of roles; track role.ID) {\n <option [value]=\"role.ID\">{{ role.Name }}</option>\n }\n </select>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n mjButton variant=\"primary\"\n (click)=\"executeBulkRoleAssign()\"\n [disabled]=\"!bulkRoleId || isLoading\"\n >\n @if (isLoading) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n Assigning...\n } @else {\n <i class=\"fa-solid fa-user-tag\" aria-hidden=\"true\"></i>\n Assign Role\n }\n </button>\n <button mjButton (click)=\"cancelBulkRoleAssign()\" [disabled]=\"isLoading\">\n Cancel\n </button>\n </div>\n </div>\n </div>\n }\n</div>\n"]}
|
|
@@ -3,12 +3,13 @@ import { MJUserEntity } from '@memberjunction/core-entities';
|
|
|
3
3
|
import { UserAvatarService } from '@memberjunction/ng-user-avatar';
|
|
4
4
|
import { SharedService } from '@memberjunction/ng-shared';
|
|
5
5
|
import { BehaviorSubject } from 'rxjs';
|
|
6
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
6
7
|
import * as i0 from "@angular/core";
|
|
7
8
|
interface IconCategory {
|
|
8
9
|
name: string;
|
|
9
10
|
icons: string[];
|
|
10
11
|
}
|
|
11
|
-
export declare class UserProfileSettingsComponent implements OnInit, OnDestroy {
|
|
12
|
+
export declare class UserProfileSettingsComponent extends BaseAngularComponent implements OnInit, OnDestroy {
|
|
12
13
|
private userAvatarService;
|
|
13
14
|
private sharedService;
|
|
14
15
|
private cdr;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-profile-settings.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-profile-settings/user-profile-settings.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIxF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAc,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAW,MAAM,MAAM,CAAC
|
|
1
|
+
{"version":3,"file":"user-profile-settings.component.d.ts","sourceRoot":"","sources":["../../../src/lib/user-profile-settings/user-profile-settings.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAIxF,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,OAAO,EAAc,aAAa,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,eAAe,EAAW,MAAM,MAAM,CAAC;AAGhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;;AACrE,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,qBAMa,4BAA6B,SAAQ,oBAAqB,YAAW,MAAM,EAAE,SAAS;IA0G/F,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IA5GhB,WAAW,EAAG,YAAY,CAAC;IAC3B,WAAW,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAS;IAG5D,aAAa,SAAM;IACnB,iBAAiB,SAAM;IACvB,mBAAmB,SAAM;IACzB,gBAAgB,SAAM;IACtB,UAAU,SAAM;IAChB,gBAAgB,SAAM;IAGtB,QAAQ,UAAS;IACjB,kBAAkB,UAAS;IAC3B,YAAY,SAAM;IAGlB,cAAc,SAAM;IACpB,WAAW,0BAAmC;IAC9C,sBAAsB,EAAE,YAAY,EAAE,CAAM;IAC5C,kBAAkB,SAAK;IAGvB,OAAO,CAAC,QAAQ,CAAuB;IAGvC,cAAc,EAAE,YAAY,EAAE,CA4E5B;gBAGQ,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM;IAIlB,QAAQ;IAqBd,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAYnC;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAMtC;;;OAGG;IACH,OAAO,CAAC,WAAW;IAgCnB;;;OAGG;IACH,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAU1C;;OAEG;IACH,eAAe,IAAI,IAAI;IAKvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAuBzB;;OAEG;IACH,SAAS,CAAC,GAAG,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,IAAI;IAK5D;;OAEG;IACG,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCjD;;OAEG;IACH,WAAW,IAAI,IAAI;IAanB;;OAEG;IACH,WAAW,IAAI,IAAI;IAgBnB;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAOnC;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI1C;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAOvC;;;OAGG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAmDtC;;OAEG;IACH,OAAO,CAAC,aAAa;IAuBrB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAwE3B;;OAEG;IACH,MAAM,IAAI,IAAI;IAMd;;OAEG;IACH,OAAO,CAAC,WAAW;yCAhhBR,4BAA4B;2CAA5B,4BAA4B;CAyhBxC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Component } from '@angular/core';
|
|
2
|
-
import { Metadata } from '@memberjunction/core';
|
|
3
2
|
import { MJGlobal, MJEventType } from '@memberjunction/global';
|
|
4
3
|
import { EventCodes } from '@memberjunction/ng-shared';
|
|
5
4
|
import { BehaviorSubject, Subject } from 'rxjs';
|
|
6
5
|
import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
|
|
6
|
+
import { BaseAngularComponent } from '@memberjunction/ng-base-types';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
import * as i1 from "@memberjunction/ng-user-avatar";
|
|
9
9
|
import * as i2 from "@memberjunction/ng-shared";
|
|
@@ -261,7 +261,7 @@ function UserProfileSettingsComponent_Conditional_40_Template(rf, ctx) { if (rf
|
|
|
261
261
|
i0.ɵɵtext(2, "Save Changes");
|
|
262
262
|
i0.ɵɵelementEnd();
|
|
263
263
|
} }
|
|
264
|
-
export class UserProfileSettingsComponent {
|
|
264
|
+
export class UserProfileSettingsComponent extends BaseAngularComponent {
|
|
265
265
|
userAvatarService;
|
|
266
266
|
sharedService;
|
|
267
267
|
cdr;
|
|
@@ -365,13 +365,14 @@ export class UserProfileSettingsComponent {
|
|
|
365
365
|
}
|
|
366
366
|
];
|
|
367
367
|
constructor(userAvatarService, sharedService, cdr, ngZone) {
|
|
368
|
+
super();
|
|
368
369
|
this.userAvatarService = userAvatarService;
|
|
369
370
|
this.sharedService = sharedService;
|
|
370
371
|
this.cdr = cdr;
|
|
371
372
|
this.ngZone = ngZone;
|
|
372
373
|
}
|
|
373
374
|
async ngOnInit() {
|
|
374
|
-
const md =
|
|
375
|
+
const md = this.ProviderToUse;
|
|
375
376
|
const currentUserInfo = md.CurrentUser;
|
|
376
377
|
// Load the full MJUserEntity to access avatar fields
|
|
377
378
|
this.currentUser = await md.GetEntityObject('MJ: Users');
|
|
@@ -752,7 +753,7 @@ export class UserProfileSettingsComponent {
|
|
|
752
753
|
}, 3000);
|
|
753
754
|
}
|
|
754
755
|
static ɵfac = function UserProfileSettingsComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || UserProfileSettingsComponent)(i0.ɵɵdirectiveInject(i1.UserAvatarService), i0.ɵɵdirectiveInject(i2.SharedService), i0.ɵɵdirectiveInject(i0.ChangeDetectorRef), i0.ɵɵdirectiveInject(i0.NgZone)); };
|
|
755
|
-
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], standalone: false, decls: 43, vars: 22, consts: [["fileInput", ""], [1, "user-profile-settings"], [1, "profile-header"], [1, "description"], ["role", "alert", 1, "alert", "alert-error"], ["role", "status", "aria-live", "polite", 1, "alert", "alert-success"], [1, "avatar-preview-section"], [1, "preview-label"], [1, "preview-container"], ["alt", "Avatar preview", 1, "preview-image", 3, "src"], [1, "preview-icon-wrapper"], [1, "preview-placeholder"], ["role", "tablist", "aria-label", "Avatar customization options", 1, "tab-navigation"], ["role", "tab", "aria-controls", "panel-upload", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-upload"], ["role", "tab", "aria-controls", "panel-url", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["role", "tab", "aria-controls", "panel-icon", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-icons"], ["role", "tab", "aria-controls", "panel-provider", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-brands", "fa-microsoft"], [1, "tab-content"], ["id", "panel-upload", "role", "tabpanel", 1, "upload-section"], ["id", "panel-url", "role", "tabpanel", 1, "url-section"], ["id", "panel-icon", "role", "tabpanel", 1, "icon-section"], ["id", "panel-provider", "role", "tabpanel", 1, "provider-section"], [1, "action-buttons"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], ["aria-label", "Dismiss error", 1, "close-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], ["aria-hidden", "true"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["type", "file", "accept", "image/png,image/jpeg,image/jpg,image/gif,image/webp", 2, "display", "none", 3, "change"], [1, "upload-btn", 3, "click"], [1, "upload-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], [1, "selected-file"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-image"], ["aria-label", "Remove selected file", 1, "remove-btn", 3, "click"], ["for", "imageUrl"], ["type", "text", "id", "imageUrl", "placeholder", "https://example.com/avatar.jpg", 1, "url-input", 3, "ngModelChange", "input", "ngModel"], [1, "url-info"], [1, "icon-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search icons by name...", "aria-label", "Search icons", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Clear search", 1, "mj-search-clear"], [1, "icon-filter-info"], [1, "icon-categories-container"], [1, "empty-state"], ["aria-label", "Clear search", 1, "mj-search-clear", 3, "click"], [1, "icon-category"], [1, "category-title"], ["role", "radiogroup", 1, "icon-grid"], ["role", "radio", 1, "icon-option", 3, "selected", "title"], ["role", "radio", 1, "icon-option", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "provider-info"], [1, "sync-btn", 3, "click", "disabled"], [1, "provider-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-lightbulb"], [1, "provider-divider"], [1, "revert-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function UserProfileSettingsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
756
|
+
static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: UserProfileSettingsComponent, selectors: [["mj-user-profile-settings"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 43, vars: 22, consts: [["fileInput", ""], [1, "user-profile-settings"], [1, "profile-header"], [1, "description"], ["role", "alert", 1, "alert", "alert-error"], ["role", "status", "aria-live", "polite", 1, "alert", "alert-success"], [1, "avatar-preview-section"], [1, "preview-label"], [1, "preview-container"], ["alt", "Avatar preview", 1, "preview-image", 3, "src"], [1, "preview-icon-wrapper"], [1, "preview-placeholder"], ["role", "tablist", "aria-label", "Avatar customization options", 1, "tab-navigation"], ["role", "tab", "aria-controls", "panel-upload", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-upload"], ["role", "tab", "aria-controls", "panel-url", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-link"], ["role", "tab", "aria-controls", "panel-icon", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-icons"], ["role", "tab", "aria-controls", "panel-provider", 1, "tab-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-brands", "fa-microsoft"], [1, "tab-content"], ["id", "panel-upload", "role", "tabpanel", 1, "upload-section"], ["id", "panel-url", "role", "tabpanel", 1, "url-section"], ["id", "panel-icon", "role", "tabpanel", 1, "icon-section"], ["id", "panel-provider", "role", "tabpanel", 1, "provider-section"], [1, "action-buttons"], ["mjButton", "", "variant", "primary", 3, "click", "disabled"], ["mjButton", "", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-exclamation-triangle"], ["aria-label", "Dismiss error", 1, "close-btn", 3, "click"], ["aria-hidden", "true", 1, "fa-solid", "fa-xmark"], ["aria-hidden", "true", 1, "fa-solid", "fa-check-circle"], ["aria-hidden", "true"], ["aria-hidden", "true", 1, "fa-solid", "fa-user"], ["type", "file", "accept", "image/png,image/jpeg,image/jpg,image/gif,image/webp", 2, "display", "none", 3, "change"], [1, "upload-btn", 3, "click"], [1, "upload-info"], ["aria-hidden", "true", 1, "fa-solid", "fa-info-circle"], [1, "selected-file"], ["aria-hidden", "true", 1, "fa-solid", "fa-file-image"], ["aria-label", "Remove selected file", 1, "remove-btn", 3, "click"], ["for", "imageUrl"], ["type", "text", "id", "imageUrl", "placeholder", "https://example.com/avatar.jpg", 1, "url-input", 3, "ngModelChange", "input", "ngModel"], [1, "url-info"], [1, "icon-search-container"], [1, "mj-search"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "mj-search-icon"], ["type", "text", "placeholder", "Search icons by name...", "aria-label", "Search icons", 1, "mj-search-input", 3, "input", "value"], ["aria-label", "Clear search", 1, "mj-search-clear"], [1, "icon-filter-info"], [1, "icon-categories-container"], [1, "empty-state"], ["aria-label", "Clear search", 1, "mj-search-clear", 3, "click"], [1, "icon-category"], [1, "category-title"], ["role", "radiogroup", 1, "icon-grid"], ["role", "radio", 1, "icon-option", 3, "selected", "title"], ["role", "radio", 1, "icon-option", 3, "click", "title"], ["aria-hidden", "true", 1, "fa-solid", "fa-search", "empty-icon"], [1, "empty-text"], [1, "empty-subtext"], [1, "provider-info"], [1, "sync-btn", 3, "click", "disabled"], [1, "provider-note"], ["aria-hidden", "true", 1, "fa-solid", "fa-lightbulb"], [1, "provider-divider"], [1, "revert-btn", 3, "click", "disabled"], ["aria-hidden", "true", 1, "fa-solid", "fa-rotate-left"], ["aria-hidden", "true", 1, "fa-solid", "fa-spinner", "fa-spin"], ["aria-hidden", "true", 1, "fa-solid", "fa-save"]], template: function UserProfileSettingsComponent_Template(rf, ctx) { if (rf & 1) {
|
|
756
757
|
i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "h3");
|
|
757
758
|
i0.ɵɵtext(3, "Avatar Settings");
|
|
758
759
|
i0.ɵɵelementEnd();
|
|
@@ -844,5 +845,5 @@ export class UserProfileSettingsComponent {
|
|
|
844
845
|
type: Component,
|
|
845
846
|
args: [{ standalone: false, selector: 'mj-user-profile-settings', template: "<div class=\"user-profile-settings\">\n <!-- Header Section -->\n <div class=\"profile-header\">\n <h3>Avatar Settings</h3>\n <p class=\"description\">Customize your profile picture with an image, URL, or icon</p>\n </div>\n\n <!-- Error Message -->\n @if (errorMessage) {\n <div class=\"alert alert-error\" role=\"alert\">\n <i class=\"fa-solid fa-exclamation-triangle\" aria-hidden=\"true\"></i>\n <span>{{ errorMessage }}</span>\n <button class=\"close-btn\" (click)=\"errorMessage = ''\" aria-label=\"Dismiss error\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n\n <!-- Success Message -->\n @if (showSuccessMessage) {\n <div class=\"alert alert-success\" role=\"status\" aria-live=\"polite\">\n <i class=\"fa-solid fa-check-circle\" aria-hidden=\"true\"></i>\n <span>Avatar updated successfully!</span>\n </div>\n }\n\n <!-- Avatar Preview Section -->\n <div class=\"avatar-preview-section\">\n <div class=\"preview-label\">Preview</div>\n <div class=\"preview-container\">\n @if (previewUrl) {\n <img [src]=\"previewUrl\" alt=\"Avatar preview\" class=\"preview-image\" />\n } @else if (previewIconClass) {\n <div class=\"preview-icon-wrapper\">\n <i [class]=\"previewIconClass + ' preview-icon'\" aria-hidden=\"true\"></i>\n </div>\n } @else {\n <div class=\"preview-placeholder\">\n <i class=\"fa-solid fa-user\" aria-hidden=\"true\"></i>\n <span>No avatar selected</span>\n </div>\n }\n </div>\n </div>\n\n <!-- Tab Navigation -->\n <div class=\"tab-navigation\" role=\"tablist\" aria-label=\"Avatar customization options\">\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'upload'\"\n (click)=\"selectTab('upload')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'upload'\"\n aria-controls=\"panel-upload\"\n >\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n <span>Upload</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'url'\"\n (click)=\"selectTab('url')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'url'\"\n aria-controls=\"panel-url\"\n >\n <i class=\"fa-solid fa-link\" aria-hidden=\"true\"></i>\n <span>URL</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'icon'\"\n (click)=\"selectTab('icon')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'icon'\"\n aria-controls=\"panel-icon\"\n >\n <i class=\"fa-solid fa-icons\" aria-hidden=\"true\"></i>\n <span>Icon</span>\n </button>\n <button\n class=\"tab-btn\"\n [class.active]=\"selectedTab === 'provider'\"\n (click)=\"selectTab('provider')\"\n role=\"tab\"\n [attr.aria-selected]=\"selectedTab === 'provider'\"\n aria-controls=\"panel-provider\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n <span>Sync</span>\n </button>\n </div>\n\n <!-- Tab Content -->\n <div class=\"tab-content\">\n <!-- Upload Tab -->\n @if (selectedTab === 'upload') {\n <div class=\"upload-section\" id=\"panel-upload\" role=\"tabpanel\">\n <input\n type=\"file\"\n #fileInput\n accept=\"image/png,image/jpeg,image/jpg,image/gif,image/webp\"\n (change)=\"onFileSelected($event)\"\n style=\"display: none\"\n />\n\n <button class=\"upload-btn\" (click)=\"fileInput.click()\">\n <i class=\"fa-solid fa-upload\" aria-hidden=\"true\"></i>\n Choose Image\n </button>\n\n <div class=\"upload-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Max 200KB - PNG, JPG, GIF, WEBP\n </div>\n\n @if (uploadedFileName) {\n <div class=\"selected-file\">\n <i class=\"fa-solid fa-file-image\" aria-hidden=\"true\"></i>\n <span>{{ uploadedFileName }}</span>\n <button class=\"remove-btn\" (click)=\"clearUpload()\" aria-label=\"Remove selected file\">\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n </div>\n }\n </div>\n }\n\n <!-- URL Tab -->\n @if (selectedTab === 'url') {\n <div class=\"url-section\" id=\"panel-url\" role=\"tabpanel\">\n <label for=\"imageUrl\">Image URL</label>\n <input\n type=\"text\"\n id=\"imageUrl\"\n class=\"url-input\"\n placeholder=\"https://example.com/avatar.jpg\"\n [(ngModel)]=\"imageUrlInput\"\n (input)=\"onUrlChange()\"\n />\n <div class=\"url-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n Enter a URL to an image hosted online\n </div>\n </div>\n }\n\n <!-- Icon Tab -->\n @if (selectedTab === 'icon') {\n <div class=\"icon-section\" id=\"panel-icon\" role=\"tabpanel\">\n <!-- Icon Search -->\n <div class=\"icon-search-container\">\n <div class=\"mj-search\">\n <i class=\"fa-solid fa-search mj-search-icon\" aria-hidden=\"true\"></i>\n <input\n type=\"text\"\n class=\"mj-search-input\"\n placeholder=\"Search icons by name...\"\n [value]=\"iconSearchTerm\"\n (input)=\"onIconSearchChange($event)\"\n aria-label=\"Search icons\"\n />\n @if (iconSearchTerm) {\n <button\n class=\"mj-search-clear\"\n (click)=\"clearIconSearch()\"\n aria-label=\"Clear search\"\n >\n <i class=\"fa-solid fa-xmark\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n <div class=\"icon-filter-info\">\n {{ totalFilteredIcons }} icon{{ totalFilteredIcons !== 1 ? 's' : '' }} found\n </div>\n </div>\n\n <!-- Icon Categories -->\n <div class=\"icon-categories-container\">\n @if (filteredIconCategories.length > 0) {\n @for (category of filteredIconCategories; track category.name) {\n <div class=\"icon-category\">\n <h4 class=\"category-title\">{{ category.name }}</h4>\n <div class=\"icon-grid\" role=\"radiogroup\" [attr.aria-label]=\"category.name + ' icons'\">\n @for (icon of category.icons; track icon) {\n <button\n class=\"icon-option\"\n [class.selected]=\"isIconSelected(icon)\"\n (click)=\"selectIcon(icon)\"\n [title]=\"extractIconName(icon)\"\n role=\"radio\"\n [attr.aria-checked]=\"isIconSelected(icon)\"\n [attr.aria-label]=\"extractIconName(icon) + ' icon'\"\n >\n <i [class]=\"icon\" aria-hidden=\"true\"></i>\n </button>\n }\n </div>\n </div>\n }\n } @else {\n <div class=\"empty-state\">\n <i class=\"fa-solid fa-search empty-icon\" aria-hidden=\"true\"></i>\n <p class=\"empty-text\">No icons found</p>\n <p class=\"empty-subtext\">Try a different search term</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Provider Sync Tab -->\n @if (selectedTab === 'provider') {\n <div class=\"provider-section\" id=\"panel-provider\" role=\"tabpanel\">\n <div class=\"provider-info\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <p>Sync your avatar from your authentication provider account</p>\n </div>\n\n <button\n class=\"sync-btn\"\n (click)=\"syncFromProvider()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-brands fa-microsoft\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Syncing...</span>\n } @else {\n <span>Sync from Microsoft Account</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-lightbulb\" aria-hidden=\"true\"></i>\n <small>This will download your profile photo from Microsoft and save it to your profile</small>\n </div>\n\n <hr class=\"provider-divider\" />\n\n <button\n class=\"revert-btn\"\n (click)=\"revertToDefault()\"\n [disabled]=\"isSaving\"\n >\n <i class=\"fa-solid fa-rotate-left\" aria-hidden=\"true\"></i>\n @if (isSaving) {\n <span>Reverting...</span>\n } @else {\n <span>Revert to Default</span>\n }\n </button>\n\n <div class=\"provider-note\">\n <i class=\"fa-solid fa-info-circle\" aria-hidden=\"true\"></i>\n <small>Clears your avatar settings and restores the automatic sync from your auth provider</small>\n </div>\n </div>\n }\n </div>\n\n <!-- Action Buttons -->\n <div class=\"action-buttons\">\n <button\n mjButton variant=\"primary\"\n (click)=\"save()\"\n [disabled]=\"isSaving || selectedTab === 'provider'\"\n >\n @if (isSaving) {\n <i class=\"fa-solid fa-spinner fa-spin\" aria-hidden=\"true\"></i>\n <span>Saving...</span>\n } @else {\n <i class=\"fa-solid fa-save\" aria-hidden=\"true\"></i>\n <span>Save Changes</span>\n }\n </button>\n <button\n mjButton\n (click)=\"cancel()\"\n [disabled]=\"isSaving\"\n >\n Cancel\n </button>\n </div>\n</div>\n", styles: ["/* =============================================================================\n User Profile Settings Component\n Using MJ Design Tokens\n ============================================================================= */\n\n/* Host element must be scrollable */\n:host {\n display: block;\n height: 100%;\n width: 100%;\n overflow-y: auto;\n overflow-x: hidden;\n}\n\n/* -----------------------------------------------------------------------------\n Container & Layout\n ----------------------------------------------------------------------------- */\n.user-profile-settings {\n max-width: 800px;\n margin: 0 auto;\n padding: 1.5rem;\n background: var(--mj-bg-page);\n min-height: 100%;\n}\n\n/* -----------------------------------------------------------------------------\n Header Section\n ----------------------------------------------------------------------------- */\n.profile-header {\n margin-bottom: 1.5rem;\n}\n\n.profile-header h3 {\n margin: 0 0 0.5rem 0;\n font-size: 1.75rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.profile-header .description {\n margin: 0;\n font-size: 1rem;\n color: var(--mj-text-muted);\n}\n\n/* -----------------------------------------------------------------------------\n Alert Messages\n ----------------------------------------------------------------------------- */\n.alert {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n border-radius: 8px;\n margin-bottom: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n animation: fadeIn 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.alert i {\n flex-shrink: 0;\n font-size: 1rem;\n}\n\n.alert span {\n flex: 1;\n}\n\n.alert .close-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n color: inherit;\n opacity: 0.7;\n transition: opacity 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.alert .close-btn:hover {\n opacity: 1;\n}\n\n.alert.alert-error {\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n color: var(--mj-status-error);\n}\n\n.alert.alert-success {\n background: color-mix(in srgb, var(--mj-status-success) 15%, var(--mj-bg-surface));\n color: var(--mj-status-success);\n}\n\n/* -----------------------------------------------------------------------------\n Avatar Preview Section\n ----------------------------------------------------------------------------- */\n.avatar-preview-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n margin-bottom: 2rem;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n border: 1px solid var(--mj-border-strong);\n}\n\n.preview-label {\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--mj-text-muted);\n margin-bottom: 1rem;\n text-transform: uppercase;\n letter-spacing: 0.05em;\n}\n\n.preview-container {\n width: 120px;\n height: 120px;\n border-radius: 50%;\n overflow: hidden;\n background: var(--mj-bg-surface);\n border: 3px solid var(--mj-border-strong);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: border-color 0.2s;\n}\n\n.preview-container:has(.preview-image),\n.preview-container:has(.preview-icon) {\n border-color: var(--mj-brand-primary);\n}\n\n.preview-image {\n width: 100%;\n height: 100%;\n object-fit: cover;\n}\n\n.preview-icon-wrapper {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.preview-icon {\n font-size: 3.5rem;\n color: var(--mj-brand-primary);\n}\n\n.preview-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.5rem;\n color: var(--mj-text-muted);\n}\n\n.preview-placeholder i {\n font-size: 2.5rem;\n}\n\n.preview-placeholder span {\n font-size: 0.875rem;\n}\n\n/* -----------------------------------------------------------------------------\n Tab Navigation\n ----------------------------------------------------------------------------- */\n.tab-navigation {\n display: flex;\n gap: 0.25rem;\n margin-bottom: 1.5rem;\n border-bottom: 2px solid var(--mj-border-strong);\n background: var(--mj-bg-surface);\n}\n\n.tab-btn {\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n background: transparent;\n border: none;\n border-bottom: 3px solid transparent;\n cursor: pointer;\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-muted);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n margin-bottom: -2px;\n min-height: 48px;\n}\n\n.tab-btn i {\n font-size: 1rem;\n}\n\n.tab-btn:hover {\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface-sunken);\n}\n\n.tab-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: -2px;\n}\n\n.tab-btn.active {\n color: var(--mj-brand-primary);\n border-bottom-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n/* -----------------------------------------------------------------------------\n Tab Content\n ----------------------------------------------------------------------------- */\n.tab-content {\n min-height: 300px;\n padding: 1.5rem;\n background: var(--mj-bg-surface-sunken);\n border-radius: 12px;\n margin-bottom: 1.5rem;\n border: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Upload Section\n ----------------------------------------------------------------------------- */\n.upload-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1rem;\n}\n\n.upload-btn {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:hover {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.upload-btn:active {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.upload-btn i {\n font-size: 1rem;\n}\n\n.upload-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.upload-info i {\n color: var(--mj-brand-primary);\n}\n\n.selected-file {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 400px;\n}\n\n.selected-file i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n}\n\n.selected-file span {\n flex: 1;\n font-size: 0.875rem;\n color: var(--mj-text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.selected-file .remove-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s, background 0.2s;\n border-radius: 4px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n.selected-file .remove-btn:hover {\n color: var(--mj-status-error);\n background: color-mix(in srgb, var(--mj-status-error) 15%, var(--mj-bg-surface));\n}\n\n.selected-file .remove-btn i {\n font-size: 1rem;\n color: inherit;\n}\n\n/* -----------------------------------------------------------------------------\n URL Section\n ----------------------------------------------------------------------------- */\n.url-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n}\n\n.url-section label {\n font-size: 0.875rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n}\n\n.url-input {\n padding: 0.875rem 1rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n font-size: 1rem;\n color: var(--mj-text-primary);\n background: var(--mj-bg-surface);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.url-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.url-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.url-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.url-info {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.url-info i {\n color: var(--mj-brand-primary);\n}\n\n/* -----------------------------------------------------------------------------\n Icon Section (with Search)\n ----------------------------------------------------------------------------- */\n.icon-section {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n}\n\n.icon-search-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding-bottom: 1rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n/* Search Component */\n.mj-search {\n position: relative;\n width: 100%;\n}\n\n.mj-search-icon {\n position: absolute;\n left: 1rem;\n top: 50%;\n transform: translateY(-50%);\n color: var(--mj-text-muted);\n font-size: 1rem;\n pointer-events: none;\n transition: color 0.2s ease;\n}\n\n.mj-search-input {\n width: 100%;\n padding: 0.875rem 2.75rem 0.875rem 2.75rem;\n border: 2px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 1rem;\n background: var(--mj-bg-surface);\n color: var(--mj-text-primary);\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n.mj-search-input::placeholder {\n color: var(--mj-text-muted);\n}\n\n.mj-search-input:hover {\n border-color: var(--mj-brand-primary);\n background: var(--mj-bg-surface);\n}\n\n.mj-search-input:focus {\n outline: none;\n border-color: var(--mj-brand-primary);\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--mj-brand-primary) 20%, transparent);\n background: var(--mj-bg-surface);\n}\n\n.mj-search:focus-within .mj-search-icon {\n color: var(--mj-brand-primary);\n}\n\n.mj-search-clear {\n position: absolute;\n right: 0.5rem;\n top: 50%;\n transform: translateY(-50%);\n background: transparent;\n border: none;\n cursor: pointer;\n padding: 0.5rem;\n color: var(--mj-text-muted);\n border-radius: 9999px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s ease;\n}\n\n.mj-search-clear:hover {\n color: var(--mj-bg-surface);\n background: var(--mj-brand-primary);\n}\n\n.icon-filter-info {\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n padding-left: 0.25rem;\n}\n\n.icon-categories-container {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n max-height: 350px;\n overflow-y: auto;\n padding-right: 0.5rem;\n -webkit-overflow-scrolling: touch;\n}\n\n.icon-category .category-title {\n font-size: 1rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.75rem 0;\n padding-bottom: 0.5rem;\n border-bottom: 1px solid var(--mj-border-strong);\n}\n\n.icon-grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, minmax(50px, 1fr));\n gap: 0.5rem;\n}\n\n.icon-option {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.75rem;\n background: var(--mj-bg-surface);\n border: 2px solid var(--mj-border-strong);\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-width: 44px;\n min-height: 44px;\n}\n\n.icon-option i {\n font-size: 1.5rem;\n color: var(--mj-text-muted);\n transition: color 0.2s;\n}\n\n.icon-option:hover {\n border-color: var(--mj-brand-primary);\n background: color-mix(in srgb, var(--mj-brand-primary) 10%, var(--mj-bg-surface));\n}\n\n.icon-option:hover i {\n color: var(--mj-brand-primary);\n}\n\n.icon-option:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.icon-option.selected {\n border-color: var(--mj-brand-primary);\n background: var(--mj-brand-primary);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.icon-option.selected i {\n color: var(--mj-bg-surface);\n}\n\n/* Custom Scrollbar for Icon Section */\n.icon-categories-container::-webkit-scrollbar {\n width: 6px;\n}\n\n.icon-categories-container::-webkit-scrollbar-track {\n background: var(--mj-bg-surface-sunken);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb {\n background: var(--mj-border-strong);\n border-radius: 3px;\n}\n\n.icon-categories-container::-webkit-scrollbar-thumb:hover {\n background: var(--mj-text-muted);\n}\n\n/* Empty State */\n.empty-state {\n text-align: center;\n padding: 3rem 1.5rem;\n}\n\n.empty-state .empty-icon {\n font-size: 3rem;\n color: var(--mj-border-strong);\n margin-bottom: 1rem;\n}\n\n.empty-state .empty-text {\n font-size: 1.25rem;\n font-weight: 600;\n color: var(--mj-text-primary);\n margin: 0 0 0.5rem 0;\n}\n\n.empty-state .empty-subtext {\n font-size: 1rem;\n color: var(--mj-text-muted);\n margin: 0;\n}\n\n/* -----------------------------------------------------------------------------\n Provider Section\n ----------------------------------------------------------------------------- */\n.provider-section {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 1.5rem;\n padding: 1rem 0;\n}\n\n.provider-info {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem;\n background: var(--mj-bg-surface);\n border: 1px solid var(--mj-border-strong);\n border-radius: 8px;\n width: 100%;\n max-width: 500px;\n}\n\n.provider-info i {\n color: var(--mj-brand-primary);\n font-size: 1.2rem;\n flex-shrink: 0;\n}\n\n.provider-info p {\n margin: 0;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n}\n\n.sync-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 1rem 2rem;\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border: none;\n border-radius: 9999px;\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 48px;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.sync-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.sync-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.sync-btn i {\n font-size: 1.2rem;\n}\n\n.provider-note {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--mj-text-muted);\n max-width: 500px;\n text-align: center;\n}\n\n.provider-note i {\n color: var(--mj-status-warning);\n margin-top: 0.1rem;\n flex-shrink: 0;\n}\n\n.provider-divider {\n border: none;\n border-top: 1px solid var(--mj-border-strong);\n width: 100%;\n max-width: 500px;\n margin: 0.5rem 0;\n}\n\n.revert-btn {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.75rem 1.5rem;\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n border-radius: 9999px;\n font-size: 0.875rem;\n font-weight: 600;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n min-height: 44px;\n}\n\n.revert-btn:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.revert-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n/* -----------------------------------------------------------------------------\n Action Buttons\n ----------------------------------------------------------------------------- */\n.action-buttons {\n display: flex;\n gap: 0.75rem;\n justify-content: flex-start;\n padding-top: 1rem;\n border-top: 1px solid var(--mj-border-strong);\n}\n\n/* -----------------------------------------------------------------------------\n Button System\n ----------------------------------------------------------------------------- */\n.mj-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 0.5rem;\n padding: 0.75rem 1.5rem;\n font-size: 0.875rem;\n font-weight: 600;\n border: none;\n border-radius: 9999px;\n cursor: pointer;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n white-space: nowrap;\n min-height: 44px;\n}\n\n.mj-btn:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.mj-btn:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n.mj-btn-primary {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 4px 8px rgba(0, 0, 0, 0.08);\n}\n\n.mj-btn-primary:active:not(:disabled) {\n background: var(--mj-brand-primary);\n transform: scale(0.98);\n}\n\n.mj-btn-secondary {\n background: var(--mj-bg-surface);\n color: var(--mj-brand-primary);\n border: 1px solid var(--mj-border-strong);\n}\n\n.mj-btn-secondary:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-secondary:active:not(:disabled) {\n background: var(--mj-brand-primary);\n border-color: var(--mj-brand-primary);\n}\n\n.mj-btn-ghost {\n background: transparent;\n color: var(--mj-text-muted);\n padding: 0.5rem;\n}\n\n.mj-btn-ghost:hover:not(:disabled) {\n background: var(--mj-brand-primary);\n color: var(--mj-bg-surface);\n}\n\n.mj-btn-ghost:active:not(:disabled) {\n background: var(--mj-brand-primary);\n}\n\n.mj-btn-sm {\n padding: 0.5rem 0.875rem;\n font-size: 0.8125rem;\n min-height: 36px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Focus Indicators\n ----------------------------------------------------------------------------- */\nbutton:focus-visible,\ninput:focus-visible {\n outline: 2px solid var(--mj-brand-primary);\n outline-offset: 2px;\n}\n\n/* -----------------------------------------------------------------------------\n Accessibility: Reduced Motion\n ----------------------------------------------------------------------------- */\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n animation-duration: 0.01ms !important;\n animation-iteration-count: 1 !important;\n transition-duration: 0.01ms !important;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Animations\n ----------------------------------------------------------------------------- */\n@keyframes fadeIn {\n from {\n opacity: 0;\n }\n to {\n opacity: 1;\n }\n}\n\n/* -----------------------------------------------------------------------------\n Responsive Design - Mobile First\n ----------------------------------------------------------------------------- */\n@media (max-width: 639px) {\n .user-profile-settings {\n padding: 1rem;\n }\n\n .tab-navigation .tab-btn {\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem;\n font-size: 0.75rem;\n }\n\n .tab-navigation .tab-btn i {\n font-size: 1.2rem;\n }\n\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(45px, 1fr));\n }\n\n .icon-categories-container {\n max-height: 300px;\n }\n\n .action-buttons {\n flex-direction: column;\n }\n\n .action-buttons .mj-btn {\n width: 100%;\n justify-content: center;\n }\n\n .provider-section {\n padding: 0.5rem 0;\n }\n\n .sync-btn,\n .revert-btn {\n width: 100%;\n max-width: 300px;\n justify-content: center;\n }\n}\n\n@media (min-width: 640px) {\n .icon-search-container {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .mj-search {\n max-width: 300px;\n }\n}\n\n@media (min-width: 768px) {\n .user-profile-settings {\n padding: 2rem;\n }\n\n .icon-categories-container {\n max-height: 400px;\n }\n}\n\n@media (min-width: 1024px) {\n .icon-grid {\n grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));\n }\n}\n"] }]
|
|
846
847
|
}], () => [{ type: i1.UserAvatarService }, { type: i2.SharedService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }], null); })();
|
|
847
|
-
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber:
|
|
848
|
+
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(UserProfileSettingsComponent, { className: "UserProfileSettingsComponent", filePath: "src/lib/user-profile-settings/user-profile-settings.component.ts", lineNumber: 24 }); })();
|
|
848
849
|
//# sourceMappingURL=user-profile-settings.component.js.map
|