manage-your-printer/static/js/global-refresh-functions.min.js
2025-06-04 10:03:22 +02:00

47 lines
14 KiB
JavaScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function safeUpdateElement(elementId,value,options={}){const{fallbackValue='-',logWarning=true,attribute='textContent',transform=null}=options;const element=document.getElementById(elementId);if(!element){if(logWarning){console.warn(`🔍 Element mit ID'${elementId}'nicht gefunden`);}
return false;}
try{const finalValue=value!==undefined&&value!==null?value:fallbackValue;const displayValue=transform?transform(finalValue):finalValue;element[attribute]=displayValue;return true;}catch(error){console.error(`❌ Fehler beim Aktualisieren von Element'${elementId}':`,error);return false;}}
function safeBatchUpdate(updates,options={}){const results={};Object.entries(updates).forEach(([elementId,value])=>{results[elementId]=safeUpdateElement(elementId,value,options);});const successful=Object.values(results).filter(Boolean).length;const total=Object.keys(updates).length;console.log(`📊 Batch-Update:${successful}/${total}Elemente erfolgreich aktualisiert`);return results;}
function elementExists(elementId){return document.getElementById(elementId)!==null;}
window.refreshDashboard=async function(){const refreshButton=document.getElementById('refreshDashboard');if(refreshButton){refreshButton.disabled=true;const icon=refreshButton.querySelector('svg');if(icon){icon.classList.add('animate-spin');}}
try{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){updateDashboardStats(data.stats);showToast('✅ Dashboard erfolgreich aktualisiert','success');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{if(refreshButton){refreshButton.disabled=false;const icon=refreshButton.querySelector('svg');if(icon){icon.classList.remove('animate-spin');}}}};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{if(typeof loadBasicStats==='function'){await loadBasicStats();}else{const response=await fetch('/api/stats');const data=await response.json();if(response.ok){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');}}
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');}}}};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{console.log('🔄 Starte Jobs-Refresh...');let refreshSuccess=false;if(typeof window.jobManager!=='undefined'&&window.jobManager&&typeof window.jobManager.loadJobs==='function'){console.log('📝 Verwende window.jobManager.loadJobs()');await window.jobManager.loadJobs();refreshSuccess=true;}else if(typeof jobManager!=='undefined'&&jobManager&&typeof jobManager.loadJobs==='function'){console.log('📝 Verwende lokalen jobManager.loadJobs()');await jobManager.loadJobs();refreshSuccess=true;}else{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('📝 API-Response erhalten:',data);if(!data||typeof data!=='object'){throw new Error('Ungültige API-Response: Keine Daten erhalten');}
let jobs=[];if(Array.isArray(data.jobs)){jobs=data.jobs;}else if(Array.isArray(data)){jobs=data;}else if(data.success&&Array.isArray(data.data)){jobs=data.data;}else{console.warn('⚠️ Keine Jobs-Array in API-Response gefunden:',data);jobs=[];}
console.log(`📝 ${jobs.length}Jobs aus API extrahiert:`,jobs);const jobsContainers=['.jobs-container','#jobs-container','.job-grid','#jobs-list','#jobs-grid'];let containerFound=false;for(const selector of jobsContainers){const container=document.querySelector(selector);if(container){containerFound=true;console.log(`📝 Container gefunden:${selector}`);if(jobs.length===0){container.innerHTML=`<div class="text-center py-12"><div class="text-gray-400 dark:text-gray-600 text-6xl mb-4">📭</div><h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">Keine Jobs vorhanden</h3><p class="text-gray-500 dark:text-gray-400">Es wurden noch keine Druckaufträge erstellt.</p></div>`;}else{const jobCards=jobs.map(job=>{if(!job||typeof job!=='object'){console.warn('⚠️ Ungültiges Job-Objekt übersprungen:',job);return'';}
return`<div class="job-card p-4 border rounded-lg bg-white dark:bg-slate-800 shadow-sm hover:shadow-md transition-shadow"><h3 class="font-semibold text-gray-900 dark:text-white mb-2">${job.filename||job.title||job.name||'Unbekannter Job'}</h3><div class="text-sm text-gray-600 dark:text-gray-400 space-y-1"><p><span class="font-medium">ID:</span>${job.id||'N/A'}</p><p><span class="font-medium">Status:</span>${job.status||'Unbekannt'}</p>${job.printer_name?`<p><span class="font-medium">Drucker:</span>${job.printer_name}</p>`:''}
${job.created_at?`<p><span class="font-medium">Erstellt:</span>${new Date(job.created_at).toLocaleDateString('de-DE')}</p>`:''}</div></div>`;}).filter(card=>card!=='').join('');container.innerHTML=jobCards||`<div class="text-center py-8"><p class="text-gray-500 dark:text-gray-400">Keine gültigen Jobs zum Anzeigen</p></div>`;}
break;}}
if(!containerFound){console.warn('⚠️ Kein Jobs-Container gefunden. Verfügbare Container:',jobsContainers);}
refreshSuccess=true;}
if(refreshSuccess){showToast('✅ Druckaufträge erfolgreich aktualisiert','success');}}catch(error){console.error('❌ Jobs-Refresh Fehler:',error);let errorMessage;if(error.message.includes('undefined')){errorMessage='Jobs-Daten nicht verfügbar';}else if(error.message.includes('fetch')){errorMessage='Netzwerkfehler beim Laden der Jobs';}else if(error.message.includes('API')){errorMessage='Server-Fehler beim Laden der Jobs';}else{errorMessage=error.message||'Unbekannter Fehler beim Laden der Jobs';}
showToast(`❌ Fehler:${errorMessage}`,'error');const container=document.querySelector('.jobs-container, #jobs-container, .job-grid, #jobs-list');if(container){container.innerHTML=`<div class="text-center py-12"><div class="text-red-400 dark:text-red-600 text-6xl mb-4">⚠️</div><h3 class="text-lg font-medium text-gray-900 dark:text-white mb-2">Fehler beim Laden</h3><p class="text-gray-500 dark:text-gray-400 mb-4">${errorMessage}</p><button onclick="refreshJobs()"class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors">Erneut versuchen</button></div>`;}}finally{if(refreshButton){refreshButton.disabled=false;const icon=refreshButton.querySelector('svg');if(icon){icon.classList.remove('animate-spin');}}}};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{if(typeof calendar!=='undefined'&&calendar.refetchEvents){calendar.refetchEvents();showToast('✅ Kalender erfolgreich aktualisiert','success');}else{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');}}}};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{if(typeof printerManager!=='undefined'&&printerManager.loadPrinters){await printerManager.loadPrinters();}else{const response=await fetch('/api/printers/status/live',{headers:{'X-CSRFToken':getCSRFToken()}});if(response.ok){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');}}}};function updateDashboardStats(stats){const activeJobsEl=document.querySelector('[data-stat="active-jobs"]');if(activeJobsEl){activeJobsEl.textContent=stats.active_jobs||0;}
const availablePrintersEl=document.querySelector('[data-stat="available-printers"]');if(availablePrintersEl){availablePrintersEl.textContent=stats.available_printers||0;}
const totalJobsEl=document.querySelector('[data-stat="total-jobs"]');if(totalJobsEl){totalJobsEl.textContent=stats.total_jobs||0;}
const successRateEl=document.querySelector('[data-stat="success-rate"]');if(successRateEl){successRateEl.textContent=(stats.success_rate||0)+'%';}
console.log('📊 Dashboard-Statistiken aktualisiert:',stats);}
function updateStatsCounter(elementId,value,animate=true){const element=document.getElementById(elementId);if(!element){console.warn(`Element mit ID'${elementId}'nicht gefunden`);return;}
if(value===null||value===undefined){console.warn(`Ungültiger Wert für Element'${elementId}':`,value);value=0;}
if(animate){const currentValue=parseInt(element.textContent.replace(/[^\d]/g,''))||0;const targetValue=parseInt(value.toString().replace(/[^\d]/g,''))||0;if(currentValue!==targetValue){const finalTextValue=value!==null&&value!==undefined?value.toString():'0';animateCounter(element,currentValue,targetValue,finalTextValue);}}else{element.textContent=value!==null&&value!==undefined?value.toString():'0';}}
function animateCounter(element,start,end,finalText){if(!element){console.warn('animateCounter: Kein gültiges Element übergeben');return;}
if(typeof finalText!=='string'){if(finalText===null||finalText===undefined||(typeof finalText==='object'&&finalText!==null)){console.warn('animateCounter: Problematischer finalText-Wert:',finalText);}
finalText=finalText!==null&&finalText!==undefined?String(finalText):'0';}
start=parseInt(start)||0;end=parseInt(end)||0;const duration=1000;const startTime=performance.now();function updateCounter(currentTime){const elapsed=currentTime-startTime;const progress=Math.min(elapsed/duration,1);const easeOut=1-Math.pow(1-progress,3);const currentValue=Math.round(start+(end-start)*easeOut);try{if(typeof finalText==='string'&&finalText.includes('%')){element.textContent=currentValue+'%';}else{element.textContent=currentValue;}}catch(error){console.warn('animateCounter: Fehler bei finalText.includes:',error,'finalText:',finalText);element.textContent=currentValue;}
if(progress<1){requestAnimationFrame(updateCounter);}else{try{element.textContent=finalText;}catch(error){console.warn('animateCounter: Fehler bei finaler Zuweisung:',error);element.textContent=String(end);}}}
requestAnimationFrame(updateCounter);}
function getCSRFToken(){const token=document.querySelector('meta[name="csrf-token"]');return token?token.getAttribute('content'):'';}
function showToast(message,type='info'){if(typeof optimizationManager!=='undefined'&&optimizationManager.showToast){optimizationManager.showToast(message,type);return;}
const emoji={success:'✅',error:'❌',warning:'⚠️',info:''};console.log(`${emoji[type]||''}${message}`);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);setTimeout(()=>{toast.classList.remove('translate-x-full');},100);setTimeout(()=>{toast.classList.add('translate-x-full');setTimeout(()=>{toast.remove();},300);},3000);}catch(error){console.warn('Toast-Erstellung fehlgeschlagen:',error);}}
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{window.location.reload();}};class AutoRefreshManager{constructor(){this.isEnabled=false;this.interval=null;this.intervalTime=30000;}
start(){if(this.isEnabled)return;this.isEnabled=true;this.interval=setInterval(()=>{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();}}}
window.autoRefreshManager=new AutoRefreshManager();document.addEventListener('keydown',function(e){if(e.key==='F5'||(e.ctrlKey&&e.key==='r')){e.preventDefault();universalRefresh();}
if(e.ctrlKey&&e.shiftKey&&e.key==='R'){e.preventDefault();autoRefreshManager.toggle();showToast(autoRefreshManager.isEnabled?'🔄 Auto-Refresh aktiviert':'⏸️ Auto-Refresh deaktiviert','info');}});document.addEventListener('visibilitychange',function(){if(!document.hidden&&autoRefreshManager.isEnabled){setTimeout(universalRefresh,1000);}});console.log('🔄 Globale Refresh-Funktionen geladen');