/** * Admin Panel JavaScript * Handles the functionality of the admin panel interface */ document.addEventListener('DOMContentLoaded', function() { // Initialize admin panel initializeAdminPanel(); // Load initial data loadAdminStats(); // Initialisiere den aktiven Tab basierend auf der URL oder default initializeActiveTab(); // Initialize modals and button event handlers initializeEventHandlers(); // Set up auto-refresh timer (every 30 seconds) setInterval(function() { if (document.visibilityState === 'visible') { refreshActiveTabData(); } }, 30000); }); // Initialisiere den aktiven Tab function initializeActiveTab() { // Prüfe URL Hash const hash = window.location.hash.substring(1); if (hash) { activateTab(hash); } else { // Default Tab laden const defaultTab = document.querySelector('.nav-tab'); if (defaultTab) { const tabName = defaultTab.getAttribute('data-tab'); activateTab(tabName); } } } // Aktiviere einen Tab und lade seine Daten function activateTab(tabName) { // UI aktualisieren const tabs = document.querySelectorAll('.nav-tab'); tabs.forEach(tab => { if (tab.getAttribute('data-tab') === tabName) { tab.classList.add('active'); } else { tab.classList.remove('active'); } }); // Inhalte anzeigen/verstecken const tabPanes = document.querySelectorAll('.tab-pane'); tabPanes.forEach(pane => { if (pane.id === `${tabName}-tab`) { pane.classList.add('active'); pane.classList.remove('hidden'); } else { pane.classList.remove('active'); pane.classList.add('hidden'); } }); // Daten für den Tab laden switch(tabName) { case 'users': loadUsers(); break; case 'printers': loadPrinters(); break; case 'scheduler': loadSchedulerStatus(); break; case 'system': loadSystemStats(); break; case 'logs': loadLogs(); break; } // URL Hash aktualisieren window.location.hash = tabName; } // Refresh only the data for the active tab function refreshActiveTabData() { const activeTab = document.querySelector('.nav-tab.active'); if (!activeTab) return; const tabName = activeTab.getAttribute('data-tab'); switch(tabName) { case 'users': loadUsers(); break; case 'printers': loadPrinters(); break; case 'scheduler': loadSchedulerStatus(); break; case 'system': loadSystemStats(); break; case 'logs': loadLogs(); break; } // Always refresh the stats loadAdminStats(); } // Initialize event handlers for buttons that previously used onclick function initializeEventHandlers() { // Add user button const addUserBtn = document.getElementById('add-user-btn'); if (addUserBtn) { addUserBtn.addEventListener('click', showAddUserModal); } // Add printer button const addPrinterBtn = document.getElementById('add-printer-btn'); if (addPrinterBtn) { addPrinterBtn.addEventListener('click', showAddPrinterModal); } // Refresh logs button const refreshLogsBtn = document.getElementById('refresh-logs-btn'); if (refreshLogsBtn) { refreshLogsBtn.addEventListener('click', refreshLogs); } // Delete modal close buttons const closeDeleteModalBtn = document.getElementById('close-delete-modal'); if (closeDeleteModalBtn) { closeDeleteModalBtn.addEventListener('click', closeDeleteModal); } const cancelDeleteBtn = document.getElementById('cancel-delete'); if (cancelDeleteBtn) { cancelDeleteBtn.addEventListener('click', closeDeleteModal); } // Add user modal handlers const closeAddUserBtn = document.getElementById('close-add-user-modal'); if (closeAddUserBtn) { closeAddUserBtn.addEventListener('click', closeAddUserModal); } const cancelAddUserBtn = document.getElementById('cancel-add-user'); if (cancelAddUserBtn) { cancelAddUserBtn.addEventListener('click', closeAddUserModal); } const confirmAddUserBtn = document.getElementById('confirm-add-user'); if (confirmAddUserBtn) { confirmAddUserBtn.addEventListener('click', addUser); } // Add printer modal handlers const closeAddPrinterBtn = document.getElementById('close-add-printer-modal'); if (closeAddPrinterBtn) { closeAddPrinterBtn.addEventListener('click', closeAddPrinterModal); } const cancelAddPrinterBtn = document.getElementById('cancel-add-printer'); if (cancelAddPrinterBtn) { cancelAddPrinterBtn.addEventListener('click', closeAddPrinterModal); } const confirmAddPrinterBtn = document.getElementById('confirm-add-printer'); if (confirmAddPrinterBtn) { confirmAddPrinterBtn.addEventListener('click', addPrinter); } // Scheduler buttons const startSchedulerBtn = document.getElementById('start-scheduler'); if (startSchedulerBtn) { startSchedulerBtn.addEventListener('click', startScheduler); } const stopSchedulerBtn = document.getElementById('stop-scheduler'); if (stopSchedulerBtn) { stopSchedulerBtn.addEventListener('click', stopScheduler); } // Global refresh button const refreshButton = document.createElement('button'); refreshButton.id = 'refresh-admin-btn'; refreshButton.className = 'fixed bottom-8 right-8 p-3 bg-primary text-white rounded-full shadow-lg z-40'; refreshButton.innerHTML = ` `; refreshButton.title = 'Alle Daten aktualisieren'; refreshButton.addEventListener('click', refreshAllData); // Füge den Button zum Body hinzu, falls er noch nicht existiert if (!document.getElementById('refresh-admin-btn')) { document.body.appendChild(refreshButton); } } // Modal functions function showAddUserModal() { const modal = document.getElementById('add-user-modal'); if (modal) { // Reset form const form = document.getElementById('add-user-form'); if (form) { form.reset(); } // Show modal modal.classList.remove('hidden'); modal.classList.add('show'); modal.style.display = 'flex'; } } function closeAddUserModal() { const modal = document.getElementById('add-user-modal'); if (modal) { modal.classList.remove('show'); modal.classList.add('hidden'); modal.style.display = 'none'; } } async function addUser() { const form = document.getElementById('add-user-form'); if (!form) return; const userData = { email: document.getElementById('user-email').value, name: document.getElementById('user-name').value, password: document.getElementById('user-password').value, role: document.getElementById('user-role').value, status: document.getElementById('user-status').value }; try { const response = await fetch('/api/users', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCSRFToken() }, body: JSON.stringify(userData) }); if (!response.ok) { throw new Error('Fehler beim Hinzufügen des Benutzers'); } // Erfolgsmeldung anzeigen showNotification('Benutzer erfolgreich hinzugefügt', 'success'); // Modal schließen closeAddUserModal(); // Benutzerliste aktualisieren loadUsers(); } catch (error) { console.error('Error adding user:', error); showNotification(error.message, 'error'); } } function showAddPrinterModal() { const modal = document.getElementById('add-printer-modal'); if (modal) { // Reset form const form = document.getElementById('add-printer-form'); if (form) { form.reset(); } // Show modal modal.classList.remove('hidden'); modal.classList.add('show'); modal.style.display = 'flex'; } } function closeAddPrinterModal() { const modal = document.getElementById('add-printer-modal'); if (modal) { modal.classList.remove('show'); modal.classList.add('hidden'); modal.style.display = 'none'; } } async function addPrinter() { const form = document.getElementById('add-printer-form'); if (!form) return; const printerData = { name: document.getElementById('printer-name').value, model: document.getElementById('printer-model').value, ip_address: document.getElementById('printer-ip').value, location: document.getElementById('printer-location').value, status: document.getElementById('printer-status').value }; try { const response = await fetch('/api/printers', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCSRFToken() }, body: JSON.stringify(printerData) }); if (!response.ok) { throw new Error('Fehler beim Hinzufügen des Druckers'); } // Erfolgsmeldung anzeigen showNotification('Drucker erfolgreich hinzugefügt', 'success'); // Modal schließen closeAddPrinterModal(); // Druckerliste aktualisieren loadPrinters(); } catch (error) { console.error('Error adding printer:', error); showNotification(error.message, 'error'); } } function refreshLogs() { loadLogs(); showNotification('Logs aktualisiert', 'info'); } function closeDeleteModal() { const modal = document.getElementById('delete-confirm-modal'); if (modal) { modal.classList.remove('show'); modal.style.display = 'none'; } } function showDeleteConfirmation(id, type, name, callback) { const modal = document.getElementById('delete-confirm-modal'); const messageEl = document.getElementById('delete-message'); const idField = document.getElementById('delete-id'); const typeField = document.getElementById('delete-type'); const confirmBtn = document.getElementById('confirm-delete'); if (modal && messageEl && idField && typeField && confirmBtn) { messageEl.textContent = `Möchten Sie ${type === 'user' ? 'den Benutzer' : 'den Drucker'} "${name}" wirklich löschen?`; idField.value = id; typeField.value = type; confirmBtn.onclick = function() { if (typeof callback === 'function') { callback(id, name); } closeDeleteModal(); }; modal.classList.add('show'); modal.style.display = 'flex'; } } function initializeAdminPanel() { // Tab Navigation const tabs = document.querySelectorAll('.nav-tab'); tabs.forEach(tab => { tab.addEventListener('click', function() { const tabName = this.getAttribute('data-tab'); if (!tabName) return; activateTab(tabName); }); }); // Log Level Filter const logLevelFilter = document.getElementById('log-level-filter'); if (logLevelFilter) { logLevelFilter.addEventListener('change', function() { if (window.logsData) { const level = this.value; if (level === 'all') { window.filteredLogs = [...window.logsData]; } else { window.filteredLogs = window.logsData.filter(log => log.level.toLowerCase() === level); } renderLogs(); } }); } // Confirm Delete const confirmDeleteBtn = document.getElementById('confirm-delete'); if (confirmDeleteBtn) { confirmDeleteBtn.addEventListener('click', function() { const id = document.getElementById('delete-id').value; const type = document.getElementById('delete-type').value; if (type === 'user') { deleteUser(id); } else if (type === 'printer') { deletePrinter(id); } closeDeleteModal(); }); } } async function loadAdminStats() { try { const response = await fetch('/api/admin/stats'); if (!response.ok) { throw new Error('Fehler beim Laden der Admin-Statistiken'); } const data = await response.json(); // Aktualisiere die Statistik-Karten const statsContainer = document.getElementById('admin-stats'); if (!statsContainer) { console.warn('Stats-Container nicht gefunden'); return; } statsContainer.innerHTML = `
${data.last_run ? new Date(data.last_run).toLocaleString('de-DE') : 'Nie'}
${data.next_run ? new Date(data.next_run).toLocaleString('de-DE') : 'Nicht geplant'}
${data.interval || '60'} Sekunden
${data.processed_jobs || 0} Jobs seit dem letzten Neustart
Job ID | Name | Geplant für | Status |
---|---|---|---|
${job.id} | ${job.name} | ${new Date(job.start_time).toLocaleString('de-DE')} | Warten |
Keine ausstehenden Jobs in der Warteschlange
${data.os_name || 'Unbekannt'} ${data.os_version || ''}
${data.uptime || 'Unbekannt'}
${data.python_version || 'Unbekannt'}
${data.server_time ? new Date(data.server_time).toLocaleString('de-DE') : 'Unbekannt'}
${event.message}
${new Date(event.timestamp).toLocaleString('de-DE')}
Keine Ereignisse vorhanden
'; } systemEventsElement.innerHTML = eventsHtml; } } catch (error) { console.error('Error loading system stats:', error); showNotification('Fehler beim Laden der Systemstatistiken', 'error'); } } // Lade Logs async function loadLogs() { try { const response = await fetch('/api/logs'); if (!response.ok) { throw new Error('Fehler beim Laden der Logs'); } const data = await response.json(); // Logs im globalen Objekt speichern window.logsData = data.logs || []; window.filteredLogs = [...window.logsData]; // Logs rendern renderLogs(); } catch (error) { console.error('Error loading logs:', error); showNotification('Fehler beim Laden der Logs', 'error'); } } // Hilfsfunktion zum Rendern der Logs function renderLogs() { const logsContainer = document.getElementById('logs-container'); if (!logsContainer) return; if (!window.filteredLogs || window.filteredLogs.length === 0) { logsContainer.innerHTML = '${log.details}