// noqa: js-006 - async init pattern is safe, loadData has try/catch // static/admin/js/admin-users.js // Create custom logger for admin users const adminUsersLog = window.LogConfig.createLogger('ADMIN-USERS'); function adminUsersPage() { return { // Inherit base layout functionality ...data(), // Set page identifier currentPage: 'admin-users', // State adminUsers: [], loading: false, error: null, currentUserId: null, filters: { search: '', is_super_admin: '', is_active: '' }, stats: { total_admins: 0, super_admins: 0, platform_admins: 0, active_admins: 0 }, pagination: { page: 1, per_page: 20, total: 0, pages: 0 }, // Initialization async init() { adminUsersLog.info('=== ADMIN USERS PAGE INITIALIZING ==='); // Prevent multiple initializations if (window._adminUsersInitialized) { adminUsersLog.warn('Admin users page already initialized, skipping...'); return; } window._adminUsersInitialized = true; // Get current user ID this.currentUserId = this.adminProfile?.id || null; // Load platform settings for rows per page if (window.PlatformSettings) { this.pagination.per_page = await window.PlatformSettings.getRowsPerPage(); } await this.loadAdminUsers(); await this.loadStats(); adminUsersLog.info('=== ADMIN USERS PAGE INITIALIZATION COMPLETE ==='); }, // Format date helper formatDate(dateString) { if (!dateString) return '-'; return Utils.formatDate(dateString); }, // Computed: Total number of pages get totalPages() { return this.pagination.pages; }, // Computed: Start index for pagination display get startIndex() { if (this.pagination.total === 0) return 0; return (this.pagination.page - 1) * this.pagination.per_page + 1; }, // Computed: End index for pagination display get endIndex() { const end = this.pagination.page * this.pagination.per_page; return end > this.pagination.total ? this.pagination.total : end; }, // Computed: Generate page numbers array with ellipsis get pageNumbers() { const pages = []; const totalPages = this.totalPages; const current = this.pagination.page; if (totalPages <= 7) { // Show all pages if 7 or fewer for (let i = 1; i <= totalPages; i++) { pages.push(i); } } else { // Always show first page pages.push(1); if (current > 3) { pages.push('...'); } // Show pages around current page const start = Math.max(2, current - 1); const end = Math.min(totalPages - 1, current + 1); for (let i = start; i <= end; i++) { pages.push(i); } if (current < totalPages - 2) { pages.push('...'); } // Always show last page pages.push(totalPages); } return pages; }, // Load admin users from API async loadAdminUsers() { adminUsersLog.info('Loading admin users...'); this.loading = true; this.error = null; try { const params = new URLSearchParams(); // Calculate skip for pagination const skip = (this.pagination.page - 1) * this.pagination.per_page; params.append('skip', skip); params.append('limit', this.pagination.per_page); if (this.filters.search) { params.append('search', this.filters.search); } if (this.filters.is_super_admin === 'false') { params.append('include_super_admins', 'false'); } if (this.filters.is_active !== '') { params.append('is_active', this.filters.is_active); } const url = `/admin/admin-users?${params}`; window.LogConfig.logApiCall('GET', url, null, 'request'); const startTime = performance.now(); const response = await apiClient.get(url); const duration = performance.now() - startTime; window.LogConfig.logApiCall('GET', url, response, 'response'); window.LogConfig.logPerformance('Load Admin Users', duration); // Transform API response to expected format let admins = response.admins || []; // Apply client-side filtering for search and super admin status if (this.filters.search) { const searchLower = this.filters.search.toLowerCase(); admins = admins.filter(admin => admin.username?.toLowerCase().includes(searchLower) || admin.email?.toLowerCase().includes(searchLower) || admin.first_name?.toLowerCase().includes(searchLower) || admin.last_name?.toLowerCase().includes(searchLower) ); } // Filter by super admin status if (this.filters.is_super_admin === 'true') { admins = admins.filter(admin => admin.is_super_admin); } // Filter by active status if (this.filters.is_active !== '') { const isActive = this.filters.is_active === 'true'; admins = admins.filter(admin => admin.is_active === isActive); } // Transform platform_assignments to platforms for template this.adminUsers = admins.map(admin => ({ ...admin, platforms: (admin.platform_assignments || []).map(pa => ({ id: pa.platform_id, code: pa.platform_code, name: pa.platform_name })), full_name: [admin.first_name, admin.last_name].filter(Boolean).join(' ') || null })); this.pagination.total = response.total || this.adminUsers.length; this.pagination.pages = Math.ceil(this.pagination.total / this.pagination.per_page) || 1; adminUsersLog.info(`Loaded ${this.adminUsers.length} admin users`); } catch (error) { window.LogConfig.logError(error, 'Load Admin Users'); this.error = error.message || 'Failed to load admin users'; Utils.showToast('Failed to load admin users', 'error'); } finally { this.loading = false; } }, // Load statistics (computed from admin users data) async loadStats() { adminUsersLog.info('Loading admin user statistics...'); try { // Fetch all admin users to compute stats (max 500 per API limit) const url = '/admin/admin-users?skip=0&limit=500'; window.LogConfig.logApiCall('GET', url, null, 'request'); const response = await apiClient.get(url); window.LogConfig.logApiCall('GET', url, response, 'response'); const admins = response.admins || []; // Compute stats from the data this.stats = { total_admins: admins.length, super_admins: admins.filter(a => a.is_super_admin).length, platform_admins: admins.filter(a => !a.is_super_admin).length, active_admins: admins.filter(a => a.is_active).length }; adminUsersLog.debug('Stats computed:', this.stats); } catch (error) { window.LogConfig.logError(error, 'Load Admin Stats'); // Stats are non-critical, don't show error toast } }, // Search with debounce debouncedSearch() { // Clear existing timeout if (this._searchTimeout) { clearTimeout(this._searchTimeout); } // Set new timeout this._searchTimeout = setTimeout(() => { adminUsersLog.info('Search triggered:', this.filters.search); this.pagination.page = 1; this.loadAdminUsers(); }, 300); }, // Pagination nextPage() { if (this.pagination.page < this.pagination.pages) { this.pagination.page++; adminUsersLog.info('Next page:', this.pagination.page); this.loadAdminUsers(); } }, previousPage() { if (this.pagination.page > 1) { this.pagination.page--; adminUsersLog.info('Previous page:', this.pagination.page); this.loadAdminUsers(); } }, goToPage(pageNum) { if (pageNum !== '...' && pageNum >= 1 && pageNum <= this.totalPages) { this.pagination.page = pageNum; adminUsersLog.info('Go to page:', this.pagination.page); this.loadAdminUsers(); } }, // Actions viewAdminUser(admin) { adminUsersLog.info('View admin user:', admin.username); window.location.href = `/admin/admin-users/${admin.id}`; }, editAdminUser(admin) { adminUsersLog.info('Edit admin user:', admin.username); window.location.href = `/admin/admin-users/${admin.id}/edit`; }, async deleteAdminUser(admin) { adminUsersLog.warn('Delete admin user requested:', admin.username); // Prevent self-deletion if (admin.id === this.currentUserId) { Utils.showToast('You cannot delete your own account', 'error'); return; } if (!confirm(`Are you sure you want to delete admin user "${admin.username}"?\n\nThis action cannot be undone.`)) { adminUsersLog.info('Delete cancelled by user'); return; } // Second confirmation for safety if (!confirm(`FINAL CONFIRMATION\n\nAre you absolutely sure you want to delete "${admin.username}"?`)) { adminUsersLog.info('Delete cancelled by user (second confirmation)'); return; } try { const url = `/admin/admin-users/${admin.id}`; window.LogConfig.logApiCall('DELETE', url, null, 'request'); await apiClient.delete(url); Utils.showToast('Admin user deleted successfully', 'success'); adminUsersLog.info('Admin user deleted successfully'); await this.loadAdminUsers(); await this.loadStats(); } catch (error) { window.LogConfig.logError(error, 'Delete Admin User'); Utils.showToast(error.message || 'Failed to delete admin user', 'error'); } }, openCreateModal() { adminUsersLog.info('Open create admin user page'); window.location.href = '/admin/admin-users/create'; } }; } adminUsersLog.info('Admin users module loaded');