/** * MYP Platform - Globale Refresh-Funktionen * Sammelt alle Refresh-Funktionen für verschiedene Seiten und Komponenten */ /** * Dashboard-Refresh-Funktion */ window.refreshDashboard = async function() { const refreshButton = document.getElementById('refreshDashboard'); if (refreshButton) { // Button-State ändern refreshButton.disabled = true; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.add('animate-spin'); } } try { // Dashboard-Statistiken aktualisieren const response = await fetch('/api/dashboard/refresh', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCSRFToken() } }); const data = await response.json(); if (data.success) { // Statistiken im DOM aktualisieren updateDashboardStats(data.stats); // Benachrichtigung anzeigen showToast('✅ Dashboard erfolgreich aktualisiert', 'success'); // Seite neu laden für vollständige Aktualisierung setTimeout(() => { window.location.reload(); }, 1000); } else { showToast('❌ Fehler beim Aktualisieren des Dashboards', 'error'); } } catch (error) { console.error('Dashboard-Refresh Fehler:', error); showToast('❌ Netzwerkfehler beim Dashboard-Refresh', 'error'); } finally { // Button-State zurücksetzen if (refreshButton) { refreshButton.disabled = false; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.remove('animate-spin'); } } } }; /** * Statistiken-Refresh-Funktion */ window.refreshStats = async function() { const refreshButton = document.querySelector('button[onclick="refreshStats()"]'); if (refreshButton) { refreshButton.disabled = true; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.add('animate-spin'); } } try { // Basis-Statistiken laden if (typeof loadBasicStats === 'function') { await loadBasicStats(); } else { // Fallback: API-Aufruf für Statistiken const response = await fetch('/api/stats'); const data = await response.json(); if (response.ok) { // Statistiken im DOM aktualisieren updateStatsCounter('total-jobs-count', data.total_jobs); updateStatsCounter('completed-jobs-count', data.completed_jobs); updateStatsCounter('online-printers-count', data.online_printers); updateStatsCounter('success-rate-percent', data.success_rate + '%'); updateStatsCounter('active-jobs-count', data.active_jobs); updateStatsCounter('failed-jobs-count', data.failed_jobs); updateStatsCounter('total-users-count', data.total_users); } else { throw new Error(data.error || 'Fehler beim Laden der Statistiken'); } } // Charts aktualisieren if (window.refreshAllCharts) { window.refreshAllCharts(); } showToast('✅ Statistiken erfolgreich aktualisiert', 'success'); } catch (error) { console.error('Stats-Refresh Fehler:', error); showToast('❌ Fehler beim Aktualisieren der Statistiken', 'error'); } finally { if (refreshButton) { refreshButton.disabled = false; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.remove('animate-spin'); } } } }; /** * Jobs-Refresh-Funktion */ window.refreshJobs = async function() { const refreshButton = document.getElementById('refresh-button'); if (refreshButton) { refreshButton.disabled = true; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.add('animate-spin'); } } try { // Jobs-Daten neu laden mit verbesserter Fehlerbehandlung if (typeof window.jobManager !== 'undefined' && window.jobManager && window.jobManager.loadJobs) { await window.jobManager.loadJobs(); } else if (typeof jobManager !== 'undefined' && jobManager && jobManager.loadJobs) { await jobManager.loadJobs(); } else { // Fallback: API-Aufruf direkt console.log('📝 JobManager nicht verfügbar - verwende direkten API-Aufruf'); const response = await fetch('/api/jobs', { headers: { 'Content-Type': 'application/json', 'X-CSRFToken': getCSRFToken() } }); if (!response.ok) { throw new Error(`API-Fehler: ${response.status} ${response.statusText}`); } const data = await response.json(); console.log('📝 Jobs erfolgreich über API geladen:', data); // Wenn JobsContainer vorhanden ist, versuche die Jobs zu rendern const jobsContainer = document.querySelector('.jobs-container, #jobs-container, .job-grid'); if (jobsContainer && data.jobs) { // Einfache Jobs-Darstellung als Fallback jobsContainer.innerHTML = data.jobs.map(job => `

${job.filename || 'Unbekannter Job'}

Status: ${job.status || 'Unbekannt'}

`).join(''); } } showToast('✅ Druckaufträge erfolgreich aktualisiert', 'success'); } catch (error) { console.error('Jobs-Refresh Fehler:', error); const errorMessage = error.message === 'undefined' ? 'Jobs-Manager nicht verfügbar' : error.message || 'Unbekannter Fehler'; showToast(`❌ Fehler beim Laden der Jobs: ${errorMessage}`, 'error'); } finally { if (refreshButton) { refreshButton.disabled = false; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.remove('animate-spin'); } } } }; /** * Calendar-Refresh-Funktion */ window.refreshCalendar = async function() { const refreshButton = document.getElementById('refresh-button'); if (refreshButton) { refreshButton.disabled = true; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.add('animate-spin'); } } try { // FullCalendar neu laden falls verfügbar if (typeof calendar !== 'undefined' && calendar.refetchEvents) { calendar.refetchEvents(); showToast('✅ Kalender erfolgreich aktualisiert', 'success'); } else { // Fallback: Seite neu laden window.location.reload(); } } catch (error) { console.error('Calendar-Refresh Fehler:', error); showToast('❌ Fehler beim Aktualisieren des Kalenders', 'error'); } finally { if (refreshButton) { refreshButton.disabled = false; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.remove('animate-spin'); } } } }; /** * Drucker-Refresh-Funktion */ window.refreshPrinters = async function() { const refreshButton = document.getElementById('refresh-button'); if (refreshButton) { refreshButton.disabled = true; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.add('animate-spin'); } } try { // Drucker-Manager verwenden falls verfügbar if (typeof printerManager !== 'undefined' && printerManager.loadPrinters) { await printerManager.loadPrinters(); } else { // Fallback: API-Aufruf für Drucker-Update const response = await fetch('/api/printers/status/live', { headers: { 'X-CSRFToken': getCSRFToken() } }); if (response.ok) { // Seite neu laden für vollständige Aktualisierung window.location.reload(); } else { throw new Error('Drucker-Status konnte nicht abgerufen werden'); } } showToast('✅ Drucker erfolgreich aktualisiert', 'success'); } catch (error) { console.error('Printer-Refresh Fehler:', error); showToast('❌ Fehler beim Aktualisieren der Drucker', 'error'); } finally { if (refreshButton) { refreshButton.disabled = false; const icon = refreshButton.querySelector('svg'); if (icon) { icon.classList.remove('animate-spin'); } } } }; /** * Dashboard-Statistiken im DOM aktualisieren */ function updateDashboardStats(stats) { // Aktive Jobs const activeJobsEl = document.querySelector('[data-stat="active-jobs"]'); if (activeJobsEl) { activeJobsEl.textContent = stats.active_jobs || 0; } // Verfügbare Drucker const availablePrintersEl = document.querySelector('[data-stat="available-printers"]'); if (availablePrintersEl) { availablePrintersEl.textContent = stats.available_printers || 0; } // Gesamte Jobs const totalJobsEl = document.querySelector('[data-stat="total-jobs"]'); if (totalJobsEl) { totalJobsEl.textContent = stats.total_jobs || 0; } // Erfolgsrate const successRateEl = document.querySelector('[data-stat="success-rate"]'); if (successRateEl) { successRateEl.textContent = (stats.success_rate || 0) + '%'; } console.log('📊 Dashboard-Statistiken aktualisiert:', stats); } /** * Statistiken-Counter im DOM aktualisieren */ function updateStatsCounter(elementId, value, animate = true) { const element = document.getElementById(elementId); if (!element) return; if (animate) { // Animierte Zählung const currentValue = parseInt(element.textContent.replace(/[^\d]/g, '')) || 0; const targetValue = parseInt(value.toString().replace(/[^\d]/g, '')) || 0; if (currentValue !== targetValue) { animateCounter(element, currentValue, targetValue, value.toString()); } } else { element.textContent = value; } } /** * Animierte Counter-Funktion */ function animateCounter(element, start, end, finalText) { const duration = 1000; // 1 Sekunde const startTime = performance.now(); function updateCounter(currentTime) { const elapsed = currentTime - startTime; const progress = Math.min(elapsed / duration, 1); // Easing-Funktion (ease-out) const easeOut = 1 - Math.pow(1 - progress, 3); const currentValue = Math.round(start + (end - start) * easeOut); if (finalText.includes('%')) { element.textContent = currentValue + '%'; } else { element.textContent = currentValue; } if (progress < 1) { requestAnimationFrame(updateCounter); } else { element.textContent = finalText; } } requestAnimationFrame(updateCounter); } /** * CSRF-Token abrufen */ function getCSRFToken() { const token = document.querySelector('meta[name="csrf-token"]'); return token ? token.getAttribute('content') : ''; } /** * Toast-Benachrichtigung anzeigen */ function showToast(message, type = 'info') { // Prüfen ob der OptimizationManager verfügbar ist und dessen Toast-Funktion verwenden if (typeof optimizationManager !== 'undefined' && optimizationManager.showToast) { optimizationManager.showToast(message, type); return; } // Fallback: Einfache Console-Ausgabe const emoji = { success: '✅', error: '❌', warning: '⚠️', info: 'ℹ️' }; console.log(`${emoji[type] || 'ℹ️'} ${message}`); // Versuche eine Alert-Benachrichtigung zu erstellen try { const toast = document.createElement('div'); toast.className = `fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg transition-all duration-300 transform translate-x-full`; const colors = { success: 'bg-green-500 text-white', error: 'bg-red-500 text-white', warning: 'bg-yellow-500 text-black', info: 'bg-blue-500 text-white' }; toast.className += ` ${colors[type]}`; toast.textContent = message; document.body.appendChild(toast); // Animation einblenden setTimeout(() => { toast.classList.remove('translate-x-full'); }, 100); // Nach 3 Sekunden automatisch entfernen setTimeout(() => { toast.classList.add('translate-x-full'); setTimeout(() => { toast.remove(); }, 300); }, 3000); } catch (error) { console.warn('Toast-Erstellung fehlgeschlagen:', error); } } /** * Universelle Refresh-Funktion basierend auf aktueller Seite */ window.universalRefresh = function() { const currentPath = window.location.pathname; if (currentPath.includes('/dashboard')) { refreshDashboard(); } else if (currentPath.includes('/jobs')) { refreshJobs(); } else if (currentPath.includes('/calendar') || currentPath.includes('/schichtplan')) { refreshCalendar(); } else if (currentPath.includes('/printers') || currentPath.includes('/drucker')) { refreshPrinters(); } else { // Fallback: Seite neu laden window.location.reload(); } }; /** * Auto-Refresh-Funktionalität */ class AutoRefreshManager { constructor() { this.isEnabled = false; this.interval = null; this.intervalTime = 30000; // 30 Sekunden } start() { if (this.isEnabled) return; this.isEnabled = true; this.interval = setInterval(() => { // Nur refresh wenn Seite sichtbar ist if (!document.hidden) { universalRefresh(); } }, this.intervalTime); console.log('🔄 Auto-Refresh aktiviert (alle 30 Sekunden)'); } stop() { if (!this.isEnabled) return; this.isEnabled = false; if (this.interval) { clearInterval(this.interval); this.interval = null; } console.log('⏸️ Auto-Refresh deaktiviert'); } toggle() { if (this.isEnabled) { this.stop(); } else { this.start(); } } } // Globaler Auto-Refresh-Manager window.autoRefreshManager = new AutoRefreshManager(); /** * Keyboard-Shortcuts */ document.addEventListener('keydown', function(e) { // F5 oder Ctrl+R abfangen und eigene Refresh-Funktion verwenden if (e.key === 'F5' || (e.ctrlKey && e.key === 'r')) { e.preventDefault(); universalRefresh(); } // Ctrl+Shift+R für Auto-Refresh-Toggle if (e.ctrlKey && e.shiftKey && e.key === 'R') { e.preventDefault(); autoRefreshManager.toggle(); showToast( autoRefreshManager.isEnabled ? '🔄 Auto-Refresh aktiviert' : '⏸️ Auto-Refresh deaktiviert', 'info' ); } }); /** * Visibility API für Auto-Refresh bei Tab-Wechsel */ document.addEventListener('visibilitychange', function() { if (!document.hidden && autoRefreshManager.isEnabled) { // Verzögertes Refresh wenn Tab wieder sichtbar wird setTimeout(universalRefresh, 1000); } }); console.log('🔄 Globale Refresh-Funktionen geladen');