feat: Hinzufügen neuer API-Endpunkte zur erweiterten Drucker-Status-Verwaltung und Verbesserung der Benutzeroberfläche durch optimierte Lade- und Filtermechanismen. Implementierung von Caching für Online-Drucker und Live-Status sowie Auto-Update-Funktionalität zur Echtzeit-Überwachung. Anpassungen in den Templates zur Anzeige von Status-Übersichten und Filteroptionen für eine verbesserte Benutzererfahrung.

This commit is contained in:
2025-05-27 11:38:50 +02:00
parent c39595382c
commit cbe1864678
4 changed files with 985 additions and 142 deletions

View File

@@ -170,6 +170,10 @@
{% block extra_js %}
<script>
// Globale Variable für Admin-Status
window.isAdmin = {% if current_user.is_admin %}true{% else %}false{% endif %};
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// File upload preview
const fileInput = document.getElementById('stl_file');
@@ -251,95 +255,209 @@ function refreshJobs() {
});
}
// Laden der Drucker für das Dropdown
// Laden der Drucker für das Dropdown mit verbesserter Online-Erkennung
function loadPrinters() {
// Lade Drucker mit Status-Check für bessere Verfügbarkeitsprüfung
fetch('/api/printers/status')
const printerSelect = document.getElementById('printer_id');
// Loading-State anzeigen
printerSelect.innerHTML = '<option value="">Lade Drucker...</option>';
printerSelect.disabled = true;
// Zuerst versuchen, Online-Drucker zu laden (schnell)
fetch('/api/printers/online')
.then(response => response.json())
.then(data => {
const printerSelect = document.getElementById('printer_id');
printerSelect.innerHTML = '<option value="">Drucker auswählen...</option>';
const onlinePrinters = data.printers || [];
console.log('Online-Drucker geladen:', onlinePrinters);
// Prüfe ob data ein Array ist (direkte Antwort) oder ein Objekt mit printers-Property
const printers = Array.isArray(data) ? data : (data.printers || []);
console.log('Geladene Drucker:', printers);
// Filtere verfügbare Drucker (status: 'available' oder active: true)
const availablePrinters = printers.filter(printer => {
return printer.status === 'available' || printer.active === true;
});
console.log('Verfügbare Drucker:', availablePrinters);
if (availablePrinters.length === 0) {
// Fallback: Lade alle Drucker ohne Status-Check
return fetch('/api/printers')
.then(response => response.json())
.then(fallbackData => {
const fallbackPrinters = fallbackData.printers || [];
console.log('Fallback Drucker:', fallbackPrinters);
if (fallbackPrinters.length === 0) {
printerSelect.innerHTML = '<option value="">Keine Drucker verfügbar</option>';
showNotification('Keine Drucker in der Datenbank gefunden', 'warning');
return;
}
// Zeige alle Drucker an, auch wenn Status unbekannt
fallbackPrinters.forEach(printer => {
const option = document.createElement('option');
option.value = printer.id;
option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - Status unbekannt`;
printerSelect.appendChild(option);
});
showNotification(`${fallbackPrinters.length} Drucker geladen (Status unbekannt)`, 'info');
});
}
// Füge verfügbare Drucker hinzu
availablePrinters.forEach(printer => {
const option = document.createElement('option');
option.value = printer.id;
if (onlinePrinters.length > 0) {
// Online-Drucker verfügbar - diese bevorzugt anzeigen
populatePrinterSelect(onlinePrinters, true);
showNotification(`${onlinePrinters.length} online Drucker verfügbar`, 'success');
// Status-Indikator hinzufügen
const statusText = printer.status === 'available' ? '✅ Verfügbar' : '⚠️ Status unbekannt';
option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - ${statusText}`;
printerSelect.appendChild(option);
});
showNotification(`${availablePrinters.length} verfügbare Drucker geladen`, 'success');
// Zusätzlich alle Drucker laden für Vollständigkeit
loadAllPrintersAsSecondary(onlinePrinters);
} else {
// Keine Online-Drucker - lade alle mit Live-Status-Check
loadPrintersWithLiveStatus();
}
})
.catch(error => {
console.error('Fehler beim Laden der Drucker:', error);
console.error('Fehler beim Laden der Online-Drucker:', error);
// Fallback: Lade alle Drucker mit Live-Status
loadPrintersWithLiveStatus();
});
}
// Hilfsfunktion: Drucker-Select befüllen
function populatePrinterSelect(printers, onlineOnly = false) {
const printerSelect = document.getElementById('printer_id');
printerSelect.innerHTML = '<option value="">Drucker auswählen...</option>';
printerSelect.disabled = false;
if (printers.length === 0) {
printerSelect.innerHTML = '<option value="">Keine Drucker verfügbar</option>';
return;
}
// Sortiere Drucker: Online zuerst, dann nach Name
const sortedPrinters = printers.sort((a, b) => {
// Online-Status prüfen
const aOnline = a.status === 'available' || a.is_online || a.active;
const bOnline = b.status === 'available' || b.is_online || b.active;
if (aOnline && !bOnline) return -1;
if (!aOnline && bOnline) return 1;
// Bei gleichem Online-Status nach Name sortieren
return a.name.localeCompare(b.name);
});
sortedPrinters.forEach(printer => {
const option = document.createElement('option');
option.value = printer.id;
// Status-Indikator bestimmen
const isOnline = printer.status === 'available' || printer.is_online || printer.active;
let statusIcon, statusText;
if (isOnline) {
statusIcon = '🟢';
statusText = 'Online';
option.style.color = '#059669'; // Grün für online
} else {
statusIcon = '🔴';
statusText = 'Offline';
option.style.color = '#dc2626'; // Rot für offline
option.disabled = true; // Offline-Drucker deaktivieren
}
// Letzter Check-Zeitstempel
let lastChecked = '';
if (printer.last_checked) {
const checkTime = new Date(printer.last_checked);
const now = new Date();
const diffMinutes = Math.floor((now - checkTime) / 60000);
// Fallback: Versuche normale Drucker-API
fetch('/api/printers')
.then(response => response.json())
.then(data => {
const printerSelect = document.getElementById('printer_id');
const printers = data.printers || [];
if (printers.length === 0) {
printerSelect.innerHTML = '<option value="">Keine Drucker verfügbar</option>';
showNotification('Keine Drucker gefunden', 'error');
return;
}
printers.forEach(printer => {
const option = document.createElement('option');
option.value = printer.id;
option.textContent = `${printer.name} (${printer.model || 'Unbekanntes Modell'}) - Status unbekannt`;
printerSelect.appendChild(option);
});
showNotification(`${printers.length} Drucker geladen (ohne Status-Check)`, 'warning');
})
.catch(fallbackError => {
console.error('Auch Fallback-API fehlgeschlagen:', fallbackError);
showNotification('Fehler beim Laden der Drucker', 'error');
});
if (diffMinutes < 1) {
lastChecked = ' (gerade geprüft)';
} else if (diffMinutes < 60) {
lastChecked = ` (vor ${diffMinutes} Min)`;
} else {
lastChecked = ` (vor ${Math.floor(diffMinutes / 60)} Std)`;
}
}
option.textContent = `${statusIcon} ${printer.name} (${printer.model || 'Unbekanntes Modell'}) - ${statusText}${lastChecked}`;
// Tooltip für zusätzliche Informationen
option.title = `Standort: ${printer.location || 'Unbekannt'}\nIP: ${printer.plug_ip || printer.ip_address || 'Unbekannt'}\nStatus: ${statusText}${lastChecked}`;
printerSelect.appendChild(option);
});
// Hinweis für Offline-Drucker
const offlineCount = printers.filter(p => !(p.status === 'available' || p.is_online || p.active)).length;
if (offlineCount > 0) {
const infoOption = document.createElement('option');
infoOption.disabled = true;
infoOption.textContent = `--- ${offlineCount} Drucker offline (nicht verfügbar) ---`;
infoOption.style.fontStyle = 'italic';
infoOption.style.color = '#6b7280';
printerSelect.appendChild(infoOption);
}
}
// Alle Drucker als sekundäre Option laden
function loadAllPrintersAsSecondary(onlinePrinters) {
fetch('/api/printers/status/live')
.then(response => response.json())
.then(data => {
const allPrinters = data.printers || [];
// Prüfe, ob es zusätzliche Drucker gibt, die nicht in der Online-Liste sind
const onlineIds = new Set(onlinePrinters.map(p => p.id));
const additionalPrinters = allPrinters.filter(p => !onlineIds.has(p.id));
if (additionalPrinters.length > 0) {
// Kombiniere Online- und zusätzliche Drucker
const combinedPrinters = [...onlinePrinters, ...additionalPrinters];
populatePrinterSelect(combinedPrinters, false);
const totalOnline = combinedPrinters.filter(p => p.status === 'available' || p.is_online || p.active).length;
showNotification(`${totalOnline} von ${combinedPrinters.length} Drucker online`, totalOnline > 0 ? 'success' : 'warning');
}
})
.catch(error => {
console.error('Fehler beim Laden aller Drucker:', error);
// Nicht kritisch, Online-Drucker sind bereits geladen
});
}
// Drucker mit Live-Status-Check laden (Fallback)
function loadPrintersWithLiveStatus() {
showNotification('Überprüfe Drucker-Status...', 'info');
fetch('/api/printers/status/live')
.then(response => response.json())
.then(data => {
const printers = data.printers || [];
console.log('Live-Status-Drucker geladen:', printers);
if (printers.length === 0) {
// Letzter Fallback: Normale Drucker-API
return loadPrintersBasic();
}
populatePrinterSelect(printers, false);
const onlineCount = printers.filter(p => p.status === 'available' || p.is_online || p.active).length;
if (onlineCount > 0) {
showNotification(`${onlineCount} von ${printers.length} Drucker online (Live-Check)`, 'success');
} else {
showNotification(`${printers.length} Drucker gefunden, aber alle offline`, 'warning');
}
})
.catch(error => {
console.error('Fehler beim Live-Status-Check:', error);
showNotification('Live-Status-Check fehlgeschlagen, lade Basis-Daten...', 'warning');
loadPrintersBasic();
});
}
// Basis-Drucker-Laden (letzter Fallback)
function loadPrintersBasic() {
fetch('/api/printers')
.then(response => response.json())
.then(data => {
const printers = data.printers || [];
console.log('Basis-Drucker geladen:', printers);
if (printers.length === 0) {
const printerSelect = document.getElementById('printer_id');
printerSelect.innerHTML = '<option value="">Keine Drucker in der Datenbank</option>';
printerSelect.disabled = true;
showNotification('Keine Drucker in der Datenbank gefunden', 'error');
return;
}
// Alle Drucker als "Status unbekannt" anzeigen
const printersWithUnknownStatus = printers.map(printer => ({
...printer,
status: 'unknown',
is_online: false,
active: true // Erlaube Auswahl trotz unbekanntem Status
}));
populatePrinterSelect(printersWithUnknownStatus, false);
showNotification(`${printers.length} Drucker geladen (Status unbekannt)`, 'warning');
})
.catch(error => {
console.error('Auch Basis-API fehlgeschlagen:', error);
const printerSelect = document.getElementById('printer_id');
printerSelect.innerHTML = '<option value="">Fehler beim Laden der Drucker</option>';
printerSelect.disabled = true;
showNotification('Fehler beim Laden der Drucker', 'error');
});
}
@@ -723,7 +841,7 @@ function renderJobCard(job) {
}
// Admin: Beenden-Button für laufende Jobs
if (job.status === 'running' && isAdmin) {
if (job.status === 'running' && window.isAdmin) {
actionButtons += `
<button type="button" onclick="finishJob(${job.id})"
class="text-red-600 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 text-sm font-medium transition-colors duration-200">
@@ -978,7 +1096,6 @@ function formatDateTime(isoString) {
});
}
// Globale Variable für Admin-Status
const isAdmin = {% if current_user.is_admin %}true{% else %}false{% endif %};
// Globale Variable für Admin-Status wird über window.isAdmin gesetzt
</script>
{% endblock %}