🎉 Fix for JOBS_UNDEFINED and LOG_EXPORT issues, updated documentation 📚 in backend/docs.

This commit is contained in:
2025-06-01 04:04:34 +02:00
parent 45d8d46556
commit 5ee854cbc6
43 changed files with 3053 additions and 118 deletions

View File

@ -181,7 +181,7 @@ window.refreshStats = async function() {
};
/**
* Jobs-Refresh-Funktion
* Jobs-Refresh-Funktion - VERBESSERT mit umfassenden Null-Checks
*/
window.refreshJobs = async function() {
const refreshButton = document.getElementById('refresh-button');
@ -194,14 +194,27 @@ window.refreshJobs = async function() {
}
try {
// Jobs-Daten neu laden mit verbesserter Fehlerbehandlung
if (typeof window.jobManager !== 'undefined' && window.jobManager && window.jobManager.loadJobs) {
console.log('🔄 Starte Jobs-Refresh...');
// Mehrstufige Manager-Prüfung mit erweiterten Sicherheitschecks
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();
} else if (typeof jobManager !== 'undefined' && jobManager && 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 {
// Fallback: API-Aufruf direkt
// Fallback: Direkter API-Aufruf mit verbesserter Fehlerbehandlung
console.log('📝 JobManager nicht verfügbar - verwende direkten API-Aufruf');
const response = await fetch('/api/jobs', {
headers: {
'Content-Type': 'application/json',
@ -214,28 +227,128 @@ window.refreshJobs = async function() {
}
const data = await response.json();
console.log('📝 Jobs erfolgreich über API geladen:', data);
console.log('📝 API-Response erhalten:', 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 => `
<div class="job-card p-4 border rounded-lg">
<h3 class="font-semibold">${job.filename || 'Unbekannter Job'}</h3>
<p class="text-sm text-gray-600">Status: ${job.status || 'Unbekannt'}</p>
</div>
`).join('');
// VERBESSERTE Datenvalidierung
if (!data || typeof data !== 'object') {
throw new Error('Ungültige API-Response: Keine Daten erhalten');
}
// Sichere Jobs-Extraktion
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);
// Container-Updates mit Fallback-Rendering
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 {
// Sichere Job-Darstellung mit Null-Checks
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');
}
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');
console.error('Jobs-Refresh Fehler:', error);
// Intelligente Fehlermeldung basierend auf dem Fehlertyp
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');
// Fallback-Container mit Fehleranzeige
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;