"feat: Integrate printer functionality into blueprint system"
This commit is contained in:
@@ -104,13 +104,17 @@
|
||||
|
||||
// Error Handler für unbehandelte Fehler
|
||||
window.addEventListener('error', function(e) {
|
||||
console.error('🐛 JavaScript Error abgefangen:', {
|
||||
message: e.message,
|
||||
filename: e.filename,
|
||||
lineno: e.lineno,
|
||||
colno: e.colno,
|
||||
error: e.error
|
||||
});
|
||||
// Bessere Fehler-Serialisierung
|
||||
const errorInfo = {
|
||||
message: e.message || 'Unbekannter Fehler',
|
||||
filename: e.filename || 'Unbekannte Datei',
|
||||
lineno: e.lineno || 0,
|
||||
colno: e.colno || 0,
|
||||
stack: e.error ? e.error.stack : 'Stack nicht verfügbar',
|
||||
type: e.error ? e.error.constructor.name : 'Unbekannter Typ'
|
||||
};
|
||||
|
||||
console.error('🐛 JavaScript Error abgefangen:', errorInfo);
|
||||
|
||||
// Spezifische Fehlerbehebungen
|
||||
if (e.message.includes('MVP.UI.DarkModeManager is not a constructor')) {
|
||||
@@ -125,6 +129,19 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.message.includes('refreshStats is not defined')) {
|
||||
console.log('🔧 refreshStats Fehler erkannt - lade global-refresh-functions.js');
|
||||
// Versuche, global-refresh-functions.js zu laden
|
||||
const script = document.createElement('script');
|
||||
script.src = '/static/js/global-refresh-functions.js';
|
||||
script.onload = function() {
|
||||
console.log('✅ global-refresh-functions.js nachgeladen');
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e.message.includes('Cannot read properties of undefined')) {
|
||||
console.log('🔧 Undefined Properties Fehler erkannt - ignoriert für Stabilität');
|
||||
e.preventDefault();
|
||||
|
@@ -58,6 +58,62 @@ window.refreshDashboard = async function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -210,6 +266,57 @@ function updateDashboardStats(stats) {
|
||||
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
|
||||
*/
|
||||
|
Reference in New Issue
Block a user