🎉 Improved backend structure & logs organization 🎉
This commit is contained in:
Binary file not shown.
+6
-45
@@ -6321,53 +6321,14 @@ def api_admin_stats_live():
|
||||
cpu_percent = psutil.cpu_percent(interval=1)
|
||||
memory_percent = psutil.virtual_memory().percent
|
||||
|
||||
# Windows-sichere Disk-Usage-Bestimmung
|
||||
disk_percent = 0.0
|
||||
try:
|
||||
if os.name == 'nt': # Windows
|
||||
# Windows: Verwende sicheren Pfad-Ansatz
|
||||
import string
|
||||
|
||||
# Versuche verschiedene Windows-Laufwerke
|
||||
drives_to_check = ['C:', 'D:', 'E:']
|
||||
|
||||
for drive in drives_to_check:
|
||||
try:
|
||||
# Prüfe ob Laufwerk existiert
|
||||
if os.path.exists(drive + '\\'):
|
||||
disk_usage = psutil.disk_usage(drive + '\\')
|
||||
disk_percent = disk_usage.percent
|
||||
break
|
||||
except (OSError, SystemError) as drive_error:
|
||||
app_logger.debug(f"Laufwerk {drive} nicht verfügbar: {str(drive_error)}")
|
||||
continue
|
||||
|
||||
# Fallback: Verwende os.statvfs alternative
|
||||
if disk_percent == 0.0:
|
||||
try:
|
||||
import shutil
|
||||
total, used, free = shutil.disk_usage('C:\\')
|
||||
disk_percent = (used / total) * 100.0
|
||||
except Exception as shutil_error:
|
||||
app_logger.debug(f"Shutil disk_usage fehlgeschlagen: {str(shutil_error)}")
|
||||
disk_percent = 0.0
|
||||
|
||||
else: # Unix/Linux
|
||||
# Unix: Standard-Pfad verwenden
|
||||
disk_percent = psutil.disk_usage('/').percent
|
||||
|
||||
except Exception as disk_error:
|
||||
app_logger.warning(f"Disk-Usage-Bestimmung fehlgeschlagen: {str(disk_error)}")
|
||||
disk_percent = 0.0
|
||||
# Disk-Pfad sicher bestimmen
|
||||
disk_path = '/' if os.name != 'nt' else 'C:\\'
|
||||
disk_percent = psutil.disk_usage(disk_path).percent
|
||||
|
||||
# Uptime sicher berechnen
|
||||
try:
|
||||
boot_time = psutil.boot_time()
|
||||
current_time = time.time()
|
||||
uptime_seconds = int(current_time - boot_time)
|
||||
except Exception as uptime_error:
|
||||
app_logger.debug(f"Uptime-Berechnung fehlgeschlagen: {str(uptime_error)}")
|
||||
uptime_seconds = 0
|
||||
boot_time = psutil.boot_time()
|
||||
current_time = time.time()
|
||||
uptime_seconds = int(current_time - boot_time)
|
||||
|
||||
stats['system'] = {
|
||||
'cpu_percent': float(cpu_percent),
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,156 +0,0 @@
|
||||
# UI-Verbesserungen - User Dropdown und DND Counter
|
||||
|
||||
## Übersicht
|
||||
|
||||
Es wurden zwei kritische UI-Probleme behoben, die die Benutzererfahrung beeinträchtigt haben.
|
||||
|
||||
## Behobene Probleme
|
||||
|
||||
### 1. ✅ User-Dropdown funktioniert nicht richtig
|
||||
|
||||
**Problem**: Das User-Dropdown in der Navigationsleiste reagierte nicht auf Klicks und konnte nicht geöffnet/geschlossen werden.
|
||||
|
||||
**Ursache**: Fehlende JavaScript-Funktionalität für Dropdown-Interaktionen.
|
||||
|
||||
**Lösung**: Vollständige JavaScript-Implementierung hinzugefügt:
|
||||
|
||||
#### Neue Funktionen:
|
||||
- **`initializeUserDropdown()`**: Hauptfunktion für Dropdown-Management
|
||||
- **Click-Toggle**: Öffnet/schließt das Dropdown beim Klick auf den User-Button
|
||||
- **Outside-Click**: Schließt das Dropdown beim Klicken außerhalb
|
||||
- **Escape-Taste**: Schließt das Dropdown und setzt Fokus zurück
|
||||
- **Keyboard-Navigation**: Arrow Keys für Navigation zwischen Menüpunkten
|
||||
- **Smooth Animationen**: CSS-Transitions für bessere UX
|
||||
- **ARIA-Support**: Vollständige Accessibility-Unterstützung
|
||||
|
||||
#### Technische Details:
|
||||
```javascript
|
||||
// Beispiel der Animation-Logik
|
||||
function openDropdown() {
|
||||
userDropdown.classList.remove('hidden');
|
||||
userMenuButton.setAttribute('aria-expanded', 'true');
|
||||
|
||||
// Animation
|
||||
userDropdown.style.opacity = '0';
|
||||
userDropdown.style.transform = 'scale(0.95) translateY(-5px)';
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
userDropdown.style.transition = 'all 0.15s ease-out';
|
||||
userDropdown.style.opacity = '1';
|
||||
userDropdown.style.transform = 'scale(1) translateY(0)';
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 2. ✅ DND Counter Element entfernt
|
||||
|
||||
**Problem**: Das dndCounter-Element war unerwünscht und sollte komplett entfernt werden:
|
||||
```html
|
||||
<span id="dndCounter" class="dnd-counter hidden px-2 py-1 bg-orange-500 text-white rounded-full text-xs font-medium">0 unterdrückt</span>
|
||||
```
|
||||
|
||||
**Lösung**: Vollständige Entfernung:
|
||||
|
||||
#### HTML-Bereinigung:
|
||||
- ✅ `dndCounter`-Element aus `base.html` entfernt
|
||||
- ✅ Umstrukturierung der DND-Status-Anzeige zu einfachem Text-Format
|
||||
|
||||
#### JavaScript-Bereinigung:
|
||||
- ✅ Alle dndCounter-Referenzen aus `DoNotDisturbManager` entfernt
|
||||
- ✅ Counter-Update-Logik entfernt
|
||||
- ✅ DOM-Queries auf dndCounter entfernt
|
||||
|
||||
#### Vorher:
|
||||
```javascript
|
||||
const dndCounter = document.getElementById('dndCounter');
|
||||
// Counter aktualisieren
|
||||
if (dndCounter) {
|
||||
if (this.suppressedCount > 0 && this.isEnabled) {
|
||||
dndCounter.textContent = `${this.suppressedCount} unterdrückt`;
|
||||
dndCounter.classList.remove('hidden');
|
||||
} else {
|
||||
dndCounter.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Nachher:
|
||||
```javascript
|
||||
// Counter-Logik vollständig entfernt
|
||||
// Nur noch einfache Textanzeige im DND-Status
|
||||
```
|
||||
|
||||
### 3. ✅ Bonus: Mobile Menu Funktionalität
|
||||
|
||||
**Zusätzliche Verbesserung**: Mobile Menu Toggle-Funktionalität implementiert
|
||||
|
||||
#### Features:
|
||||
- **Responsive Design**: Automatisches Verstecken bei Desktop-Größe
|
||||
- **Icon-Wechsel**: Hamburger ↔ X Animation
|
||||
- **ARIA-Labels**: Accessibility-konforme Beschriftung
|
||||
- **Touch-optimiert**: Bessere Bedienung auf mobilen Geräten
|
||||
|
||||
## Kaskaden-Analyse
|
||||
|
||||
### Betroffene Dateien:
|
||||
1. **`templates/base.html`**:
|
||||
- dndCounter HTML-Element entfernt
|
||||
- User-Dropdown JavaScript hinzugefügt
|
||||
- Mobile Menu JavaScript hinzugefügt
|
||||
- DoNotDisturbManager bereinigt
|
||||
|
||||
### Abhängigkeiten geprüft:
|
||||
- ✅ **Keine anderen Referenzen** auf dndCounter gefunden
|
||||
- ✅ **User-Dropdown HTML** war bereits korrekt strukturiert
|
||||
- ✅ **Mobile Menu HTML** war bereits vorhanden
|
||||
- ✅ **CSS-Klassen** bleiben unverändert funktionsfähig
|
||||
|
||||
### Rückwärts-Kompatibilität:
|
||||
- ✅ Alle bestehenden Features funktionieren weiterhin
|
||||
- ✅ DND-Funktionalität arbeitet ohne Counter
|
||||
- ✅ Navigation auf allen Geräten funktional
|
||||
- ✅ Keine Breaking Changes
|
||||
|
||||
## Qualitätssicherung
|
||||
|
||||
### Funktionale Tests:
|
||||
- ✅ User-Dropdown öffnet/schließt korrekt
|
||||
- ✅ Keyboard-Navigation funktioniert
|
||||
- ✅ Mobile Menu responsiv
|
||||
- ✅ DND-Manager funktioniert ohne Counter
|
||||
- ✅ Keine JavaScript-Fehler in Console
|
||||
|
||||
### Browser-Kompatibilität:
|
||||
- ✅ Chrome/Edge (Webkit)
|
||||
- ✅ Firefox
|
||||
- ✅ Safari
|
||||
- ✅ Mobile Browser
|
||||
|
||||
### Accessibility:
|
||||
- ✅ ARIA-Attribute korrekt gesetzt
|
||||
- ✅ Keyboard-Navigation funktional
|
||||
- ✅ Screen-Reader kompatibel
|
||||
- ✅ Focus-Management implementiert
|
||||
|
||||
## Deployment-Status
|
||||
|
||||
**Status**: ✅ **PRODUKTIONSBEREIT**
|
||||
|
||||
**Rollback-Plan**: Falls Probleme auftreten:
|
||||
1. Git-Revert zu vorherigem Commit
|
||||
2. Alternativ: User-Dropdown JavaScript deaktivieren
|
||||
3. dndCounter temporär wieder hinzufügen (falls nötig)
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
1. **Live-Tests** auf Staging-Environment
|
||||
2. **User-Feedback** sammeln zur neuen Dropdown-UX
|
||||
3. **Performance-Monitoring** der neuen JavaScript-Funktionen
|
||||
4. **Weitere UI-Optimierungen** basierend auf Nutzungsstatistiken
|
||||
|
||||
---
|
||||
|
||||
**Datum**: Januar 2025
|
||||
**Entwickler**: AI Assistant
|
||||
**Review**: Code-Review erfolgreich abgeschlossen
|
||||
**Status**: Implementiert und getestet
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:13 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
|
||||
2025-06-01 03:04:47 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
|
||||
2025-06-01 03:06:06 - [analytics] analytics - [INFO] INFO - 📈 Analytics Engine initialisiert
|
||||
@@ -4,3 +4,189 @@
|
||||
2025-06-01 02:47:47 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
|
||||
2025-06-01 02:48:30 - [app] app - [WARNING] WARNING - DatabaseCleanupManager nicht verfügbar - Fallback auf Legacy-Cleanup
|
||||
2025-06-01 02:48:30 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
|
||||
2025-06-01 03:01:13 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
|
||||
2025-06-01 03:01:14 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen)
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - Job-Scheduler gestartet
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
|
||||
2025-06-01 03:01:15 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
|
||||
2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:01:49 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': None, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': None, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:01:54 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:25 - [app] app - [ERROR] ERROR - Fehler beim Abrufen der Dashboard-Statistiken: tuple index out of range
|
||||
2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 0, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:25 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:56 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh angefordert von User 1
|
||||
2025-06-01 03:02:58 - [app] app - [ERROR] ERROR - Fehler beim Abrufen der Dashboard-Statistiken: tuple index out of range
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 0, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': None, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:02:58 - [app] app - [INFO] INFO - Dashboard-Refresh erfolgreich: {'active_jobs': 0, 'available_printers': 0, 'total_jobs': 0, 'pending_jobs': 0, 'success_rate': 0, 'completed_jobs': 0, 'failed_jobs': 0, 'cancelled_jobs': 0, 'total_users': 1, 'online_printers': 0, 'offline_printers': 0}
|
||||
2025-06-01 03:04:46 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen)
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - ✅ Printer Queue Manager erfolgreich gestartet
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - Job-Scheduler gestartet
|
||||
2025-06-01 03:04:48 - [app] app - [INFO] INFO - Starte HTTP-Server auf 0.0.0.0:80
|
||||
2025-06-01 03:06:06 - [app] app - [INFO] INFO - Optimierte SQLite-Engine erstellt: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend\database\myp.db
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - SQLite für Produktionsumgebung konfiguriert (WAL-Modus, Cache, Optimierungen)
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ Zentraler Shutdown-Manager initialisiert
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🔄 Starte Datenbank-Setup und Migrationen...
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - Datenbank mit Optimierungen initialisiert
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ JobOrder-Tabelle bereits vorhanden
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - Admin-Benutzer admin (admin@mercedes-benz.com) existiert bereits. Passwort wurde zurückgesetzt.
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - ✅ Datenbank-Setup und Migrationen erfolgreich abgeschlossen
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🖨️ Starte automatische Steckdosen-Initialisierung...
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - ℹ️ Keine Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - 🔄 Debug-Modus: Queue Manager deaktiviert für Entwicklung
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - Job-Scheduler gestartet
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - Starte Debug-Server auf 0.0.0.0:5000 (HTTP)
|
||||
2025-06-01 03:06:07 - [app] app - [INFO] INFO - Windows-Debug-Modus: Auto-Reload deaktiviert
|
||||
2025-06-01 03:06:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:18 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:18 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:19 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:42 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:42 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:43 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:43 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:44 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:48 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:49 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:49 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:49 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:50 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:50 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:50 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:50 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:51 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:51 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:52 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:52 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:53 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:53 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:54 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:54 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:55 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:58 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:06:59 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:59 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:06:59 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:00 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:04 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:05 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:05 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:05 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:06 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:14 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:14 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:14 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:15 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:17 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:18 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:18 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:18 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:19 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:23 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:24 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:24 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:24 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:25 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_database_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:27 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:28 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:29 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:29 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:30 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:37 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:37 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_status: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:07:38 - [app] app - [WARNING] WARNING - Disk-Informationen nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:07:38 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:08:12 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:08:12 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_system_health: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:08:13 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
2025-06-01 03:08:13 - [app] app - [INFO] INFO - Admin-Check für Funktion api_admin_stats_live: User authenticated: True, User ID: 1, Is Admin: True
|
||||
2025-06-01 03:08:14 - [app] app - [WARNING] WARNING - System-Performance-Metriken nicht verfügbar: argument 1 (impossible<bad format char>)
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:13 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
|
||||
2025-06-01 03:04:47 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
|
||||
2025-06-01 03:06:06 - [backup] backup - [INFO] INFO - BackupManager initialisiert (minimal implementation)
|
||||
@@ -0,0 +1,2 @@
|
||||
2025-06-01 03:06:34 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
||||
2025-06-01 03:08:04 - [calendar] calendar - [INFO] INFO - 📅 Kalender-Events abgerufen: 0 Einträge für Zeitraum 2025-06-01 00:00:00 bis 2025-06-08 00:00:00
|
||||
@@ -0,0 +1,12 @@
|
||||
2025-06-01 03:01:14 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
|
||||
2025-06-01 03:01:15 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
|
||||
2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
|
||||
2025-06-01 03:04:48 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
|
||||
2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard-Background-Worker gestartet
|
||||
2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server wird mit threading initialisiert (eventlet-Fallback)
|
||||
2025-06-01 03:06:07 - [dashboard] dashboard - [INFO] INFO - Dashboard WebSocket-Server initialisiert (async_mode: threading)
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:13 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:04:47 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:06:06 - [database] database - [INFO] INFO - Datenbank-Wartungs-Scheduler gestartet
|
||||
@@ -0,0 +1,6 @@
|
||||
2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 🧹 Starte umfassendes Datenbank-Cleanup...
|
||||
2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 📝 Schritt 1: Schließe alle Datenbankverbindungen...
|
||||
2025-06-01 03:03:00 - [database_cleanup] database_cleanup - [INFO] INFO - 🔄 Schließe alle aktiven Datenbankverbindungen...
|
||||
2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 🧹 Starte umfassendes Datenbank-Cleanup...
|
||||
2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 📝 Schritt 1: Schließe alle Datenbankverbindungen...
|
||||
2025-06-01 03:04:49 - [database_cleanup] database_cleanup - [INFO] INFO - 🔄 Schließe alle aktiven Datenbankverbindungen...
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:14 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
|
||||
2025-06-01 03:04:48 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
|
||||
2025-06-01 03:06:07 - [email_notification] email_notification - [INFO] INFO - 📧 Offline-E-Mail-Benachrichtigung initialisiert (kein echter E-Mail-Versand)
|
||||
@@ -31,3 +31,6 @@
|
||||
2025-06-01 01:51:40 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-01 02:42:45 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-01 02:43:03 - myp.jobs - INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-01 03:06:28 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-01 03:07:42 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
2025-06-01 03:07:55 - [jobs] jobs - [INFO] INFO - Jobs abgerufen: 0 von 0 (Seite 1)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
2025-06-01 03:01:14 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:01:15 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:04:48 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:04:48 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:06:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
2025-06-01 03:06:07 - [maintenance] maintenance - [INFO] INFO - Wartungs-Scheduler gestartet
|
||||
@@ -0,0 +1,6 @@
|
||||
2025-06-01 03:01:15 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
2025-06-01 03:01:15 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
2025-06-01 03:04:48 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
2025-06-01 03:04:48 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
2025-06-01 03:06:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
2025-06-01 03:06:07 - [multi_location] multi_location - [INFO] INFO - Standard-Standort erstellt
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:15 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||
2025-06-01 03:04:48 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||
2025-06-01 03:06:07 - [permissions] permissions - [INFO] INFO - 🔐 Permission Template Helpers registriert
|
||||
@@ -0,0 +1,167 @@
|
||||
2025-06-01 03:01:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||
2025-06-01 03:01:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||
2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
|
||||
2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
|
||||
2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
|
||||
2025-06-01 03:01:15 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
|
||||
2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:19 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:21 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
|
||||
2025-06-01 03:01:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
|
||||
2025-06-01 03:01:33 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
|
||||
2025-06-01 03:01:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
|
||||
2025-06-01 03:01:45 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
|
||||
2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:51 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s
|
||||
2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:01:55 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:26 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:56 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:57 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:02:59 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:04:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||
2025-06-01 03:04:47 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||
2025-06-01 03:04:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
|
||||
2025-06-01 03:04:48 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
|
||||
2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
|
||||
2025-06-01 03:04:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
|
||||
2025-06-01 03:04:55 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
|
||||
2025-06-01 03:05:01 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
|
||||
2025-06-01 03:06:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🖨️ Drucker-Monitor initialisiert
|
||||
2025-06-01 03:06:06 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Automatische Tapo-Erkennung in separatem Thread gestartet
|
||||
2025-06-01 03:06:07 - [printer_monitor] printer_monitor - [INFO] INFO - 🚀 Starte Steckdosen-Initialisierung beim Programmstart...
|
||||
2025-06-01 03:06:07 - [printer_monitor] printer_monitor - [WARNING] WARNING - ⚠️ Keine aktiven Drucker zur Initialisierung gefunden
|
||||
2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Starte automatische Tapo-Steckdosenerkennung...
|
||||
2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Teste 6 Standard-IPs aus der Konfiguration
|
||||
2025-06-01 03:06:08 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 1/6: 192.168.0.103
|
||||
2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:10 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:14 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 2/6: 192.168.0.104
|
||||
2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:20 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 3/6: 192.168.0.100
|
||||
2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:24 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:25 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:26 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 4/6: 192.168.0.101
|
||||
2025-06-01 03:06:32 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 5/6: 192.168.0.102
|
||||
2025-06-01 03:06:38 - [printer_monitor] printer_monitor - [INFO] INFO - 🔍 Teste IP 6/6: 192.168.0.105
|
||||
2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:42 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:44 - [printer_monitor] printer_monitor - [INFO] INFO - ✅ Steckdosen-Erkennung abgeschlossen: 0/6 Steckdosen gefunden in 36.0s
|
||||
2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:48 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:50 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:51 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:53 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:06:58 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:04 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:13 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:17 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:23 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:27 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:39 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:41 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:49 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:07:52 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - 🔄 Aktualisiere Live-Druckerstatus...
|
||||
2025-06-01 03:08:12 - [printer_monitor] printer_monitor - [INFO] INFO - ℹ️ Keine aktiven Drucker gefunden
|
||||
@@ -2886,3 +2886,111 @@
|
||||
2025-06-01 02:43:37 - myp.printers - INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 02:44:06 - myp.printers - INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 02:44:07 - myp.printers - INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:01:19 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 15.66ms
|
||||
2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:01:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.17ms
|
||||
2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:01:50 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.94ms
|
||||
2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:01:55 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.06ms
|
||||
2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:02:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.46ms
|
||||
2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:02:26 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.16ms
|
||||
2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:02:56 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.40ms
|
||||
2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:02:57 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.84ms
|
||||
2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:02:59 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.32ms
|
||||
2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:10 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.71ms
|
||||
2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:17 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.44ms
|
||||
2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:24 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.16ms
|
||||
2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.36ms
|
||||
2025-06-01 03:06:25 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:06:28 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:42 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 11.01ms
|
||||
2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:48 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.57ms
|
||||
2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 14.08ms
|
||||
2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:50 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 17.65ms
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.08ms
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:51 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.72ms
|
||||
2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:52 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.45ms
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 12.55ms
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:53 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 5.40ms
|
||||
2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:06:58 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 16.40ms
|
||||
2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:04 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.09ms
|
||||
2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:13 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 9.67ms
|
||||
2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:17 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 8.53ms
|
||||
2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:23 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.79ms
|
||||
2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:27 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.96ms
|
||||
2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:39 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.91ms
|
||||
2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 4.61ms
|
||||
2025-06-01 03:07:41 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:07:42 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:49 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 10.00ms
|
||||
2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 7.43ms
|
||||
2025-06-01 03:07:52 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:07:55 - [printers] printers - [INFO] INFO - Schnelles Laden abgeschlossen: 6 Drucker geladen (ohne Status-Check)
|
||||
2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - 🔄 Live-Status-Abfrage von Benutzer Administrator (ID: 1)
|
||||
2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - ✅ Live-Status-Abfrage erfolgreich: 0 Drucker
|
||||
2025-06-01 03:08:12 - [printers] printers - [INFO] INFO - ✅ API-Live-Drucker-Status-Abfrage 'get_live_printer_status' erfolgreich in 13.12ms
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Initialisiere neuen Queue-Manager...
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Zentrale Shutdown-Verwaltung erkannt - deaktiviere lokale Signal-Handler
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🚀 Starte Printer Queue Manager...
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Queue-Überwachung gestartet (Intervall: 120 Sekunden)
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Printer Queue Manager gestartet
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestartet
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔄 Stoppe Queue-Manager...
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ⏳ Warte auf Monitor-Thread...
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🛑 Shutdown-Signal empfangen - beende Monitor-Loop
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - 🔚 Monitor-Loop beendet
|
||||
2025-06-01 03:04:48 - [queue_manager] queue_manager - [INFO] INFO - ✅ Queue-Manager erfolgreich gestoppt
|
||||
@@ -2812,3 +2812,16 @@
|
||||
2025-06-01 02:42:28 - myp.scheduler - INFO - Scheduler gestartet
|
||||
2025-06-01 02:44:24 - myp.scheduler - INFO - Scheduler-Thread beendet
|
||||
2025-06-01 02:44:24 - myp.scheduler - INFO - Scheduler gestoppt
|
||||
2025-06-01 03:01:13 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-01 03:01:15 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-01 03:01:15 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-01 03:03:00 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread beendet
|
||||
2025-06-01 03:03:00 - [scheduler] scheduler - [INFO] INFO - Scheduler gestoppt
|
||||
2025-06-01 03:04:47 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-01 03:04:48 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-01 03:04:48 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
2025-06-01 03:04:49 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread beendet
|
||||
2025-06-01 03:04:49 - [scheduler] scheduler - [INFO] INFO - Scheduler gestoppt
|
||||
2025-06-01 03:06:06 - [scheduler] scheduler - [INFO] INFO - Task check_jobs registriert: Intervall 30s, Enabled: True
|
||||
2025-06-01 03:06:07 - [scheduler] scheduler - [INFO] INFO - Scheduler-Thread gestartet
|
||||
2025-06-01 03:06:07 - [scheduler] scheduler - [INFO] INFO - Scheduler gestartet
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
2025-06-01 03:01:15 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||
2025-06-01 03:04:48 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||
2025-06-01 03:06:07 - [security] security - [INFO] INFO - 🔒 Security System initialisiert
|
||||
@@ -0,0 +1,14 @@
|
||||
2025-06-01 03:01:15 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [WARNING] WARNING - 🛑 Signal 2 empfangen - starte koordiniertes Shutdown
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown...
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 4 Cleanup-Funktionen aus...
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Beende Scheduler mit stop()...
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Scheduler erfolgreich gestoppt
|
||||
2025-06-01 03:03:00 - [shutdown_manager] shutdown_manager - [INFO] INFO - 💾 Führe sicheres Datenbank-Cleanup durch...
|
||||
2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
|
||||
2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Starte koordiniertes System-Shutdown...
|
||||
2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🧹 Führe 4 Cleanup-Funktionen aus...
|
||||
2025-06-01 03:04:48 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔄 Beende Scheduler mit stop()...
|
||||
2025-06-01 03:04:49 - [shutdown_manager] shutdown_manager - [INFO] INFO - ✅ Scheduler erfolgreich gestoppt
|
||||
2025-06-01 03:04:49 - [shutdown_manager] shutdown_manager - [INFO] INFO - 💾 Führe sicheres Datenbank-Cleanup durch...
|
||||
2025-06-01 03:06:07 - [shutdown_manager] shutdown_manager - [INFO] INFO - 🔧 Shutdown-Manager initialisiert
|
||||
@@ -0,0 +1,27 @@
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:01:15.112489
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-01 03:01:15 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:04:48.521790
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-01 03:04:48 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ==================================================
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🚀 MYP Platform Backend wird gestartet...
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🐍 Python Version: 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 💻 Betriebssystem: nt (win32)
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 📁 Arbeitsverzeichnis: C:\Users\TTOMCZA.EMEA\Dev\Projektarbeit-MYP\backend
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ⏰ Startzeit: 2025-06-01T03:06:07.426354
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🪟 Windows-Modus: Aktiviert
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - 🔒 Windows-sichere Log-Rotation: Aktiviert
|
||||
2025-06-01 03:06:07 - [startup] startup - [INFO] INFO - ==================================================
|
||||
@@ -0,0 +1,16 @@
|
||||
2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
|
||||
2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
|
||||
2025-06-01 03:01:13 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-01 03:03:00 - [windows_fixes] windows_fixes - [INFO] INFO - 🔄 Starte Windows Thread-Shutdown...
|
||||
2025-06-01 03:03:00 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Windows Thread-Shutdown abgeschlossen
|
||||
2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
|
||||
2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
|
||||
2025-06-01 03:04:46 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
2025-06-01 03:04:49 - [windows_fixes] windows_fixes - [INFO] INFO - 🔄 Starte Windows Thread-Shutdown...
|
||||
2025-06-01 03:04:49 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Windows Thread-Shutdown abgeschlossen
|
||||
2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - 🔧 Wende Windows-spezifische Fixes an...
|
||||
2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Subprocess automatisch gepatcht für UTF-8 Encoding (run + Popen)
|
||||
2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Globaler subprocess-Patch angewendet
|
||||
2025-06-01 03:06:06 - [windows_fixes] windows_fixes - [INFO] INFO - ✅ Alle Windows-Fixes erfolgreich angewendet
|
||||
@@ -2,163 +2,344 @@
|
||||
|
||||
/* Base Glass Effects */
|
||||
.glass-base {
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.25);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.12),
|
||||
0 8px 16px rgba(0, 0, 0, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.glass-strong {
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
box-shadow: 0 35px 60px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
-webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
box-shadow:
|
||||
0 35px 70px rgba(0, 0, 0, 0.15),
|
||||
0 12px 24px rgba(0, 0, 0, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.glass-subtle {
|
||||
backdrop-filter: blur(16px) saturate(150%) brightness(105%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(150%) brightness(105%);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
box-shadow:
|
||||
0 15px 35px rgba(0, 0, 0, 0.08),
|
||||
0 4px 8px rgba(0, 0, 0, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
/* Light Mode Glass */
|
||||
.glass-light {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.1),
|
||||
0 8px 16px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
.glass-light-strong {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
background: rgba(255, 255, 255, 0.75);
|
||||
border: 1px solid rgba(255, 255, 255, 0.5);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.12),
|
||||
0 10px 20px rgba(0, 115, 206, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
/* Light Mode Glass Premium */
|
||||
.glass-light-premium {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.9) 0%,
|
||||
rgba(248, 250, 252, 0.8) 50%,
|
||||
rgba(255, 255, 255, 0.85) 100%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.08),
|
||||
0 10px 20px rgba(0, 115, 206, 0.06),
|
||||
inset 0 2px 0 rgba(255, 255, 255, 0.8),
|
||||
inset 0 0 20px rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.glass-light-card {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.95) 0%,
|
||||
rgba(250, 251, 252, 0.9) 100%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.4);
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.06),
|
||||
0 8px 16px rgba(0, 115, 206, 0.04),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
/* Dark Mode Glass */
|
||||
.glass-dark {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
background: rgba(15, 23, 42, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.4),
|
||||
0 8px 16px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.glass-dark-strong {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
background: rgba(30, 41, 59, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 35px 60px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
||||
box-shadow:
|
||||
0 35px 70px rgba(0, 0, 0, 0.5),
|
||||
0 12px 24px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
/* Interactive Glass Elements */
|
||||
.glass-interactive {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.glass-interactive::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.2),
|
||||
transparent);
|
||||
transition: left 0.6s ease;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.glass-interactive:hover {
|
||||
transform: translateY(-2px);
|
||||
backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
-webkit-backdrop-filter: blur(28px) saturate(220%) brightness(125%);
|
||||
box-shadow: 0 40px 80px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.15);
|
||||
transform: translateY(-3px) scale(1.01);
|
||||
backdrop-filter: blur(32px) saturate(240%) brightness(130%);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(240%) brightness(130%);
|
||||
box-shadow:
|
||||
0 40px 80px rgba(0, 0, 0, 0.15),
|
||||
0 16px 32px rgba(0, 115, 206, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.4);
|
||||
}
|
||||
|
||||
.glass-interactive:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.glass-interactive:active {
|
||||
transform: translateY(-1px) scale(0.99);
|
||||
transition: transform 0.1s ease;
|
||||
}
|
||||
|
||||
/* Glass Navigation */
|
||||
.glass-nav {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(120%);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.9) 0%,
|
||||
rgba(248, 250, 252, 0.85) 50%,
|
||||
rgba(255, 255, 255, 0.9) 100%);
|
||||
backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
-webkit-backdrop-filter: blur(24px) saturate(200%) brightness(115%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.5);
|
||||
border-bottom: 1px solid rgba(203, 213, 225, 0.6);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(0, 0, 0, 0.08),
|
||||
0 4px 12px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.dark .glass-nav {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
background: rgba(15, 23, 42, 0.85);
|
||||
border-color: rgba(51, 65, 85, 0.6);
|
||||
border-bottom-color: rgba(71, 85, 105, 0.7);
|
||||
box-shadow:
|
||||
0 8px 32px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Glass Cards */
|
||||
.glass-card-enhanced {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
.glass-card {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.95) 0%,
|
||||
rgba(250, 251, 252, 0.9) 100%);
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border: 1px solid rgba(229, 231, 235, 0.6);
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.08),
|
||||
0 8px 16px rgba(0, 115, 206, 0.04),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
padding: 1.5rem;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .glass-card-enhanced {
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
.glass-card::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg,
|
||||
transparent 0%,
|
||||
rgba(226, 232, 240, 0.8) 50%,
|
||||
transparent 100%);
|
||||
}
|
||||
|
||||
.glass-card-enhanced:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 35px 70px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.15);
|
||||
.glass-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.12),
|
||||
0 12px 24px rgba(0, 115, 206, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.95);
|
||||
}
|
||||
|
||||
.dark .glass-card-enhanced:hover {
|
||||
box-shadow: 0 35px 70px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
.dark .glass-card {
|
||||
background: rgba(30, 41, 59, 0.85);
|
||||
border-color: rgba(100, 116, 139, 0.4);
|
||||
box-shadow:
|
||||
0 20px 40px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.dark .glass-card:hover {
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.15);
|
||||
}
|
||||
|
||||
/* Glass Buttons */
|
||||
.glass-btn {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(16px) saturate(150%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(150%) brightness(110%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.9) 0%,
|
||||
rgba(248, 250, 252, 0.8) 100%);
|
||||
backdrop-filter: blur(16px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(180%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
padding: 0.75rem 1.5rem;
|
||||
color: #0f172a;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 1px 2px rgba(255, 255, 255, 0.8);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0, 0, 0, 0.08),
|
||||
0 2px 4px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.dark .glass-btn {
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
.glass-btn:hover {
|
||||
transform: translateY(-1px);
|
||||
backdrop-filter: blur(20px) saturate(170%) brightness(115%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(170%) brightness(115%);
|
||||
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.15);
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.95) 0%,
|
||||
rgba(248, 250, 252, 0.85) 100%);
|
||||
box-shadow:
|
||||
0 8px 20px rgba(0, 0, 0, 0.12),
|
||||
0 4px 8px rgba(0, 115, 206, 0.08),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.glass-btn:active {
|
||||
transform: translateY(0);
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
.glass-btn-primary {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(0, 115, 206, 0.9) 0%,
|
||||
rgba(0, 90, 159, 0.85) 100%);
|
||||
color: white;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0, 115, 206, 0.3),
|
||||
0 2px 4px rgba(0, 115, 206, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.glass-btn-primary:hover {
|
||||
background: linear-gradient(135deg,
|
||||
rgba(0, 115, 206, 0.95) 0%,
|
||||
rgba(0, 90, 159, 0.9) 100%);
|
||||
box-shadow:
|
||||
0 8px 20px rgba(0, 115, 206, 0.4),
|
||||
0 4px 8px rgba(0, 115, 206, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.dark .glass-btn {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
color: #e2e8f0;
|
||||
border-color: rgba(100, 116, 139, 0.6);
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Glass Modals */
|
||||
.glass-modal {
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
backdrop-filter: blur(32px) saturate(200%) brightness(115%);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(200%) brightness(115%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: linear-gradient(135deg,
|
||||
rgba(255, 255, 255, 0.98) 0%,
|
||||
rgba(248, 250, 252, 0.95) 50%,
|
||||
rgba(255, 255, 255, 0.98) 100%);
|
||||
backdrop-filter: blur(32px) saturate(220%) brightness(120%);
|
||||
-webkit-backdrop-filter: blur(32px) saturate(220%) brightness(120%);
|
||||
border: 1px solid rgba(226, 232, 240, 0.7);
|
||||
border-radius: 20px;
|
||||
box-shadow: 0 50px 100px rgba(0, 0, 0, 0.25), 0 0 0 1px rgba(255, 255, 255, 0.2);
|
||||
box-shadow:
|
||||
0 50px 100px rgba(0, 0, 0, 0.15),
|
||||
0 20px 40px rgba(0, 115, 206, 0.08),
|
||||
inset 0 2px 0 rgba(255, 255, 255, 0.9),
|
||||
inset 0 0 40px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.dark .glass-modal {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
box-shadow: 0 50px 100px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
background: rgba(15, 23, 42, 0.95);
|
||||
border-color: rgba(51, 65, 85, 0.7);
|
||||
box-shadow:
|
||||
0 50px 100px rgba(0, 0, 0, 0.5),
|
||||
inset 0 2px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Glass Form Elements */
|
||||
.glass-input {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(16px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(150%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(16px);
|
||||
-webkit-backdrop-filter: blur(16px);
|
||||
border: 1px solid rgba(226, 232, 240, 0.6);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
padding: 0.75rem 1rem;
|
||||
color: #0f172a;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.06),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.dark .glass-input {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
||||
.glass-input:focus {
|
||||
outline: none;
|
||||
border-color: rgba(0, 115, 206, 0.6);
|
||||
box-shadow:
|
||||
0 4px 12px rgba(0, 115, 206, 0.15),
|
||||
0 0 0 3px rgba(0, 115, 206, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.glass-input:focus {
|
||||
backdrop-filter: blur(20px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.15), 0 0 0 2px rgba(59, 130, 246, 0.5);
|
||||
.dark .glass-input {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
border-color: rgba(100, 116, 139, 0.6);
|
||||
color: #e2e8f0;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 0, 0, 0.2),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Glass Dropdown */
|
||||
@@ -204,11 +385,13 @@
|
||||
|
||||
/* Responsive glass effects */
|
||||
@media (max-width: 768px) {
|
||||
.glass-base,
|
||||
.glass-strong,
|
||||
.glass-card-enhanced {
|
||||
backdrop-filter: blur(16px) saturate(150%);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(150%);
|
||||
.glass-card {
|
||||
padding: 1rem;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.glass-modal {
|
||||
border-radius: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,7 +399,7 @@
|
||||
@media (prefers-contrast: high) {
|
||||
.glass-base,
|
||||
.glass-strong,
|
||||
.glass-card-enhanced {
|
||||
.glass-card {
|
||||
border-width: 2px;
|
||||
backdrop-filter: blur(12px);
|
||||
-webkit-backdrop-filter: blur(12px);
|
||||
@@ -226,12 +409,77 @@
|
||||
/* Reduced motion support */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.glass-interactive,
|
||||
.glass-card-enhanced,
|
||||
.glass-btn {
|
||||
transition: none;
|
||||
.glass-btn,
|
||||
.glass-card {
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.glass-float {
|
||||
animation: none;
|
||||
.glass-interactive::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Glass Loading States */
|
||||
.glass-loading {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.glass-loading::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.3),
|
||||
transparent);
|
||||
animation: glass-shimmer 2s infinite;
|
||||
}
|
||||
|
||||
.dark .glass-loading::after {
|
||||
background: linear-gradient(90deg,
|
||||
transparent,
|
||||
rgba(255, 255, 255, 0.1),
|
||||
transparent);
|
||||
}
|
||||
|
||||
@keyframes glass-shimmer {
|
||||
0% { left: -100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
/* Premium Glow Effects for Light Mode */
|
||||
.glass-glow {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.glass-glow::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
background: linear-gradient(45deg,
|
||||
rgba(0, 115, 206, 0.1),
|
||||
rgba(0, 90, 159, 0.05),
|
||||
rgba(0, 115, 206, 0.1));
|
||||
border-radius: inherit;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.glass-glow:hover::after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dark .glass-glow::after {
|
||||
background: linear-gradient(45deg,
|
||||
rgba(59, 130, 246, 0.2),
|
||||
rgba(29, 78, 216, 0.1),
|
||||
rgba(59, 130, 246, 0.2));
|
||||
}
|
||||
@@ -1,31 +1,44 @@
|
||||
/**
|
||||
* Mercedes-Benz MYP Platform - Professional Theme
|
||||
* Professionelle Light/Dark Mode Implementierung
|
||||
* Mercedes-Benz MYP Platform - Erweiterte Professional Theme
|
||||
* Verbesserte Light/Dark Mode Implementierung mit optimierten Kontrasten
|
||||
*/
|
||||
|
||||
/* Globale CSS-Variablen für konsistente Theming */
|
||||
:root {
|
||||
/* Mercedes-Benz Markenfarben */
|
||||
--mb-primary: #3b82f6;
|
||||
--mb-primary-dark: #1d4ed8;
|
||||
/* Mercedes-Benz Markenfarben - Erweitert */
|
||||
--mb-primary: #0073ce;
|
||||
--mb-primary-dark: #005a9f;
|
||||
--mb-secondary: #64748b;
|
||||
--mb-accent: #0ea5e9;
|
||||
--mb-black: #000000;
|
||||
--mb-silver: #c0c0c0;
|
||||
|
||||
/* Light Mode Farbpalette */
|
||||
/* Light Mode Farbpalette - Verbessert */
|
||||
--light-bg-primary: #ffffff;
|
||||
--light-bg-secondary: #f8fafc;
|
||||
--light-bg-tertiary: #f1f5f9;
|
||||
--light-bg-accent: #fafbfc;
|
||||
--light-surface: #ffffff;
|
||||
--light-surface-hover: #f8fafc;
|
||||
--light-surface-active: #f1f5f9;
|
||||
--light-text-primary: #0f172a;
|
||||
--light-text-secondary: #475569;
|
||||
--light-text-muted: #64748b;
|
||||
--light-text-accent: #0073ce;
|
||||
--light-border: #e2e8f0;
|
||||
--light-border-strong: #cbd5e1;
|
||||
--light-shadow: rgba(0, 0, 0, 0.1);
|
||||
--light-shadow-strong: rgba(0, 0, 0, 0.15);
|
||||
--light-border-accent: #0073ce20;
|
||||
--light-shadow: rgba(0, 0, 0, 0.08);
|
||||
--light-shadow-strong: rgba(0, 0, 0, 0.12);
|
||||
--light-shadow-accent: rgba(0, 115, 206, 0.15);
|
||||
|
||||
/* Dark Mode Farbpalette */
|
||||
/* Neue Light Mode Gradients */
|
||||
--light-gradient-primary: linear-gradient(135deg, #ffffff 0%, #f8fafc 50%, #f1f5f9 100%);
|
||||
--light-gradient-card: linear-gradient(135deg, #ffffff 0%, #fafbfc 100%);
|
||||
--light-gradient-hero: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 50%, #f1f5f9 100%);
|
||||
--light-gradient-accent: linear-gradient(135deg, #0073ce 0%, #005a9f 100%);
|
||||
|
||||
/* Dark Mode Farbpalette - Unverändert */
|
||||
--dark-bg-primary: #0f172a;
|
||||
--dark-bg-secondary: #1e293b;
|
||||
--dark-bg-tertiary: #334155;
|
||||
@@ -40,16 +53,28 @@
|
||||
--dark-shadow-strong: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
/* Professionelle Hero-Header Stile */
|
||||
/* Professionelle Hero-Header Stile - Verbessert */
|
||||
.professional-hero {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 2rem;
|
||||
margin: 1.5rem;
|
||||
margin-bottom: 2rem;
|
||||
background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%);
|
||||
background: var(--light-gradient-hero);
|
||||
border: 1px solid var(--light-border);
|
||||
box-shadow: 0 20px 40px var(--light-shadow);
|
||||
box-shadow:
|
||||
0 20px 40px var(--light-shadow),
|
||||
0 8px 16px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.professional-hero:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 25px 50px var(--light-shadow-strong),
|
||||
0 12px 24px var(--light-shadow-accent),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
|
||||
.dark .professional-hero {
|
||||
@@ -139,19 +164,21 @@
|
||||
|
||||
/* Professional Buttons */
|
||||
.btn-professional {
|
||||
background: linear-gradient(135deg, var(--mb-primary) 0%, var(--mb-primary-dark) 100%);
|
||||
background: var(--light-gradient-accent);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 1rem;
|
||||
padding: 0.75rem 2rem;
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.75rem 1.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
letter-spacing: 0.025em;
|
||||
text-transform: uppercase;
|
||||
transition: all 0.3s ease;
|
||||
letter-spacing: 0.025em;
|
||||
transition: all 0.2s ease;
|
||||
box-shadow:
|
||||
0 2px 8px rgba(0, 115, 206, 0.25),
|
||||
0 1px 3px rgba(0, 115, 206, 0.1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.btn-professional::before {
|
||||
@@ -162,19 +189,20 @@
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
transition: left 0.5s ease;
|
||||
}
|
||||
|
||||
.btn-professional:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 4px 15px rgba(0, 115, 206, 0.35),
|
||||
0 2px 8px rgba(0, 115, 206, 0.2);
|
||||
}
|
||||
|
||||
.btn-professional:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.btn-professional:hover {
|
||||
background: linear-gradient(135deg, var(--mb-primary-dark) 0%, #1e40af 100%);
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 25px rgba(59, 130, 246, 0.4);
|
||||
}
|
||||
|
||||
.btn-professional:active {
|
||||
transform: translateY(0);
|
||||
}
|
||||
@@ -246,45 +274,47 @@
|
||||
|
||||
/* Professional Cards */
|
||||
.card-professional {
|
||||
background: var(--light-surface);
|
||||
background: var(--light-gradient-card);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 1.25rem;
|
||||
border-radius: 1rem;
|
||||
padding: 1.5rem;
|
||||
box-shadow: 0 4px 20px var(--light-shadow);
|
||||
box-shadow:
|
||||
0 4px 15px var(--light-shadow),
|
||||
0 2px 8px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.dark .card-professional {
|
||||
background: var(--dark-surface);
|
||||
border-color: var(--dark-border);
|
||||
box-shadow: 0 4px 20px var(--dark-shadow);
|
||||
}
|
||||
|
||||
.card-professional::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: linear-gradient(90deg, var(--mb-primary), var(--mb-accent));
|
||||
transform: scaleX(0);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.card-professional:hover::before {
|
||||
transform: scaleX(1);
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--light-gradient-accent);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.card-professional:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 12px 40px var(--light-shadow-strong);
|
||||
box-shadow:
|
||||
0 8px 25px var(--light-shadow-strong),
|
||||
0 4px 12px var(--light-shadow-accent),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
.dark .card-professional:hover {
|
||||
box-shadow: 0 12px 40px var(--dark-shadow-strong);
|
||||
.card-professional:hover::before {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.dark .card-professional {
|
||||
background: var(--dark-surface);
|
||||
border-color: var(--dark-border);
|
||||
box-shadow: 0 4px 15px var(--dark-shadow);
|
||||
}
|
||||
|
||||
/* Professional Statistics Cards */
|
||||
@@ -358,49 +388,106 @@
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* Status-spezifische Farben */
|
||||
.status-pending {
|
||||
background: rgba(251, 191, 36, 0.1);
|
||||
color: #92400e;
|
||||
border-color: rgba(251, 191, 36, 0.3);
|
||||
}
|
||||
|
||||
.dark .status-pending {
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.status-approved {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
/* Verbesserte Status Indicators */
|
||||
.status-online {
|
||||
background: linear-gradient(135deg, #ecfdf5 0%, #d1fae5 100%);
|
||||
color: #065f46;
|
||||
border: 1px solid rgba(16, 185, 129, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.1);
|
||||
}
|
||||
|
||||
.dark .status-online {
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.15) 0%, rgba(16, 185, 129, 0.05) 100%);
|
||||
color: #10b981;
|
||||
border-color: rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.status-offline {
|
||||
background: linear-gradient(135deg, #fef2f2 0%, #fecaca 100%);
|
||||
color: #991b1b;
|
||||
border: 1px solid rgba(239, 68, 68, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.1);
|
||||
}
|
||||
|
||||
.dark .status-offline {
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, rgba(239, 68, 68, 0.05) 100%);
|
||||
color: #ef4444;
|
||||
border-color: rgba(239, 68, 68, 0.3);
|
||||
}
|
||||
|
||||
.status-printing {
|
||||
background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
|
||||
color: #1d4ed8;
|
||||
border: 1px solid rgba(59, 130, 246, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(59, 130, 246, 0.1);
|
||||
}
|
||||
|
||||
.dark .status-printing {
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.15) 0%, rgba(59, 130, 246, 0.05) 100%);
|
||||
color: #3b82f6;
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
}
|
||||
|
||||
.status-maintenance {
|
||||
background: linear-gradient(135deg, #faf5ff 0%, #ede9fe 100%);
|
||||
color: #6b21a8;
|
||||
border: 1px solid rgba(139, 92, 246, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(139, 92, 246, 0.1);
|
||||
}
|
||||
|
||||
.dark .status-maintenance {
|
||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.15) 0%, rgba(139, 92, 246, 0.05) 100%);
|
||||
color: #8b5cf6;
|
||||
border-color: rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
background: linear-gradient(135deg, #fffbeb 0%, #fef3c7 100%);
|
||||
color: #92400e;
|
||||
border: 1px solid rgba(251, 191, 36, 0.2);
|
||||
box-shadow: 0 2px 8px rgba(251, 191, 36, 0.1);
|
||||
}
|
||||
|
||||
.dark .status-pending {
|
||||
background: linear-gradient(135deg, rgba(251, 191, 36, 0.15) 0%, rgba(251, 191, 36, 0.05) 100%);
|
||||
color: #fbbf24;
|
||||
border-color: rgba(251, 191, 36, 0.3);
|
||||
}
|
||||
|
||||
.status-approved {
|
||||
background: linear-gradient(135deg, #ecfdf5 0%, #a7f3d0 100%);
|
||||
color: #065f46;
|
||||
border: 1px solid rgba(16, 185, 129, 0.3);
|
||||
box-shadow: 0 2px 8px rgba(16, 185, 129, 0.15);
|
||||
}
|
||||
|
||||
.dark .status-approved {
|
||||
background: rgba(16, 185, 129, 0.2);
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.2) 0%, rgba(16, 185, 129, 0.1) 100%);
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.status-denied {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
background: linear-gradient(135deg, #fef2f2 0%, #fca5a5 100%);
|
||||
color: #991b1b;
|
||||
border-color: rgba(239, 68, 68, 0.3);
|
||||
border: 1px solid rgba(239, 68, 68, 0.3);
|
||||
box-shadow: 0 2px 8px rgba(239, 68, 68, 0.15);
|
||||
}
|
||||
|
||||
.dark .status-denied {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.2) 0%, rgba(239, 68, 68, 0.1) 100%);
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
/* Professional Typography */
|
||||
.title-professional {
|
||||
background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-secondary) 100%);
|
||||
background: linear-gradient(135deg, var(--light-text-primary) 0%, var(--light-text-accent) 50%, var(--light-text-secondary) 100%);
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-weight: 700;
|
||||
letter-spacing: -0.025em;
|
||||
line-height: 1.1;
|
||||
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.dark .title-professional {
|
||||
@@ -415,6 +502,7 @@
|
||||
font-size: 1.125rem;
|
||||
line-height: 1.6;
|
||||
font-weight: 400;
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
.dark .subtitle-professional {
|
||||
@@ -423,11 +511,14 @@
|
||||
|
||||
/* Professional Navigation */
|
||||
.nav-professional {
|
||||
background: var(--light-surface);
|
||||
background: var(--light-gradient-card);
|
||||
border: 1px solid var(--light-border);
|
||||
border-radius: 1rem;
|
||||
padding: 0.5rem;
|
||||
box-shadow: 0 4px 15px var(--light-shadow);
|
||||
box-shadow:
|
||||
0 4px 15px var(--light-shadow),
|
||||
0 2px 8px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
backdrop-filter: blur(20px);
|
||||
}
|
||||
|
||||
@@ -448,6 +539,7 @@
|
||||
font-weight: 500;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dark .nav-item-professional {
|
||||
@@ -458,6 +550,7 @@
|
||||
background: var(--light-surface-hover);
|
||||
color: var(--light-text-primary);
|
||||
transform: translateX(4px);
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .nav-item-professional:hover {
|
||||
@@ -466,9 +559,11 @@
|
||||
}
|
||||
|
||||
.nav-item-professional.active {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
background: linear-gradient(135deg, rgba(0, 115, 206, 0.1) 0%, rgba(0, 115, 206, 0.05) 100%);
|
||||
color: var(--mb-primary);
|
||||
font-weight: 600;
|
||||
border: 1px solid var(--light-border-accent);
|
||||
box-shadow: 0 2px 8px var(--light-shadow-accent);
|
||||
}
|
||||
|
||||
.dark .nav-item-professional.active {
|
||||
@@ -479,10 +574,14 @@
|
||||
.table-professional {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
background: var(--light-surface);
|
||||
background: var(--light-gradient-card);
|
||||
border-radius: 1rem;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4px 20px var(--light-shadow);
|
||||
box-shadow:
|
||||
0 4px 20px var(--light-shadow),
|
||||
0 2px 8px rgba(0, 115, 206, 0.05),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
border: 1px solid var(--light-border);
|
||||
}
|
||||
|
||||
.dark .table-professional {
|
||||
@@ -491,12 +590,23 @@
|
||||
}
|
||||
|
||||
.table-professional th {
|
||||
background: var(--light-bg-secondary);
|
||||
background: linear-gradient(135deg, var(--light-bg-secondary) 0%, var(--light-bg-tertiary) 100%);
|
||||
color: var(--light-text-primary);
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
padding: 1rem 1.5rem;
|
||||
border-bottom: 1px solid var(--light-border);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.table-professional th::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, transparent 0%, var(--light-border-strong) 50%, transparent 100%);
|
||||
}
|
||||
|
||||
.dark .table-professional th {
|
||||
@@ -509,6 +619,7 @@
|
||||
padding: 1rem 1.5rem;
|
||||
border-bottom: 1px solid var(--light-border);
|
||||
color: var(--light-text-secondary);
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.dark .table-professional td {
|
||||
@@ -518,6 +629,8 @@
|
||||
|
||||
.table-professional tbody tr:hover {
|
||||
background: var(--light-surface-hover);
|
||||
transform: scale(1.005);
|
||||
box-shadow: 0 2px 8px var(--light-shadow);
|
||||
}
|
||||
|
||||
.dark .table-professional tbody tr:hover {
|
||||
@@ -534,47 +647,74 @@
|
||||
gap: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
box-shadow: 0 4px 15px var(--light-shadow);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.alert-professional::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 4px;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(59, 130, 246, 0.1);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
background: linear-gradient(135deg, rgba(59, 130, 246, 0.08) 0%, rgba(59, 130, 246, 0.03) 100%);
|
||||
border-color: rgba(59, 130, 246, 0.2);
|
||||
color: #1e40af;
|
||||
}
|
||||
|
||||
.alert-info::before {
|
||||
background: linear-gradient(180deg, #3b82f6 0%, #1d4ed8 100%);
|
||||
}
|
||||
|
||||
.dark .alert-info {
|
||||
background: rgba(59, 130, 246, 0.2);
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
.alert-success {
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
border-color: rgba(16, 185, 129, 0.3);
|
||||
background: linear-gradient(135deg, rgba(16, 185, 129, 0.08) 0%, rgba(16, 185, 129, 0.03) 100%);
|
||||
border-color: rgba(16, 185, 129, 0.2);
|
||||
color: #065f46;
|
||||
}
|
||||
|
||||
.alert-success::before {
|
||||
background: linear-gradient(180deg, #10b981 0%, #059669 100%);
|
||||
}
|
||||
|
||||
.dark .alert-success {
|
||||
background: rgba(16, 185, 129, 0.2);
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(251, 191, 36, 0.1);
|
||||
border-color: rgba(251, 191, 36, 0.3);
|
||||
background: linear-gradient(135deg, rgba(251, 191, 36, 0.08) 0%, rgba(251, 191, 36, 0.03) 100%);
|
||||
border-color: rgba(251, 191, 36, 0.2);
|
||||
color: #92400e;
|
||||
}
|
||||
|
||||
.alert-warning::before {
|
||||
background: linear-gradient(180deg, #fbbf24 0%, #f59e0b 100%);
|
||||
}
|
||||
|
||||
.dark .alert-warning {
|
||||
background: rgba(251, 191, 36, 0.2);
|
||||
color: #fbbf24;
|
||||
}
|
||||
|
||||
.alert-error {
|
||||
background: rgba(239, 68, 68, 0.1);
|
||||
border-color: rgba(239, 68, 68, 0.3);
|
||||
background: linear-gradient(135deg, rgba(239, 68, 68, 0.08) 0%, rgba(239, 68, 68, 0.03) 100%);
|
||||
border-color: rgba(239, 68, 68, 0.2);
|
||||
color: #991b1b;
|
||||
}
|
||||
|
||||
.alert-error::before {
|
||||
background: linear-gradient(180deg, #ef4444 0%, #dc2626 100%);
|
||||
}
|
||||
|
||||
.dark .alert-error {
|
||||
background: rgba(239, 68, 68, 0.2);
|
||||
color: #ef4444;
|
||||
@@ -582,8 +722,24 @@
|
||||
|
||||
/* Background Gradients für verschiedene Seiten */
|
||||
.bg-professional {
|
||||
background: linear-gradient(135deg, var(--light-bg-primary) 0%, var(--light-bg-secondary) 50%, var(--light-bg-tertiary) 100%);
|
||||
background: var(--light-gradient-primary);
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.bg-professional::before {
|
||||
content: '';
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background:
|
||||
radial-gradient(circle at 20% 50%, rgba(0, 115, 206, 0.03) 0%, transparent 50%),
|
||||
radial-gradient(circle at 80% 20%, rgba(0, 115, 206, 0.02) 0%, transparent 50%),
|
||||
radial-gradient(circle at 40% 80%, rgba(0, 115, 206, 0.01) 0%, transparent 50%);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.dark .bg-professional {
|
||||
@@ -593,6 +749,7 @@
|
||||
/* Utilities */
|
||||
.text-professional-primary {
|
||||
color: var(--light-text-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dark .text-professional-primary {
|
||||
@@ -601,6 +758,7 @@
|
||||
|
||||
.text-professional-secondary {
|
||||
color: var(--light-text-secondary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.dark .text-professional-secondary {
|
||||
@@ -609,12 +767,22 @@
|
||||
|
||||
.text-professional-muted {
|
||||
color: var(--light-text-muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.dark .text-professional-muted {
|
||||
color: var(--dark-text-muted);
|
||||
}
|
||||
|
||||
.text-professional-accent {
|
||||
color: var(--light-text-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dark .text-professional-accent {
|
||||
color: #60a5fa;
|
||||
}
|
||||
|
||||
/* Censored Text for Privacy Protection */
|
||||
.censored-text {
|
||||
font-family: monospace;
|
||||
@@ -623,13 +791,18 @@
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
font-weight: 500;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dark .censored-text {
|
||||
background: linear-gradient(45deg, var(--dark-text-secondary), var(--dark-text-muted));
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
.censored-text::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
background: currentColor;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
/* Smooth transitions für alle professionellen Komponenten */
|
||||
@@ -660,6 +833,14 @@
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.nav-professional {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.nav-item-professional {
|
||||
padding: 0.5rem 0.75rem;
|
||||
}
|
||||
|
||||
.stat-number {
|
||||
font-size: 2rem;
|
||||
}
|
||||
@@ -949,10 +1130,6 @@
|
||||
}
|
||||
|
||||
/* Professional Accent Colors */
|
||||
.text-professional-accent {
|
||||
color: var(--mb-accent);
|
||||
}
|
||||
|
||||
.bg-professional-accent {
|
||||
background-color: var(--mb-accent);
|
||||
}
|
||||
@@ -981,3 +1158,60 @@
|
||||
transform: translate(-50%, -50%) scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Neue Premium-Komponenten */
|
||||
.glass-professional {
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(180%) brightness(110%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.15),
|
||||
0 8px 16px rgba(0, 115, 206, 0.1),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.6);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.dark .glass-professional {
|
||||
background: rgba(30, 41, 59, 0.8);
|
||||
border-color: rgba(255, 255, 255, 0.1);
|
||||
box-shadow:
|
||||
0 25px 50px rgba(0, 0, 0, 0.3),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* Enhanced Hover States für Light Mode */
|
||||
.hover-lift {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.hover-lift:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow:
|
||||
0 10px 25px var(--light-shadow-strong),
|
||||
0 4px 12px var(--light-shadow-accent);
|
||||
}
|
||||
|
||||
.dark .hover-lift:hover {
|
||||
box-shadow: 0 10px 25px var(--dark-shadow-strong);
|
||||
}
|
||||
|
||||
/* Accessibility Enhancements */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
* {
|
||||
transition: none !important;
|
||||
animation: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus States */
|
||||
.focus-professional:focus {
|
||||
outline: 2px solid var(--light-text-accent);
|
||||
outline-offset: 2px;
|
||||
box-shadow: 0 0 0 4px rgba(0, 115, 206, 0.15);
|
||||
}
|
||||
|
||||
.dark .focus-professional:focus {
|
||||
outline-color: #60a5fa;
|
||||
box-shadow: 0 0 0 4px rgba(96, 165, 250, 0.15);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
+87
-108
@@ -92,17 +92,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
// User-Dropdown-Funktionalität initialisieren
|
||||
initializeUserDropdown();
|
||||
|
||||
// Mobile Menu Toggle initialisieren
|
||||
initializeMobileMenu();
|
||||
|
||||
// MYP App für Offline-Funktionalität initialisieren
|
||||
if (typeof MYPApp !== 'undefined') {
|
||||
window.mypApp = new MYPApp();
|
||||
}
|
||||
|
||||
// User-Dropdown-Funktionalität initialisieren
|
||||
initUserDropdown();
|
||||
|
||||
// Flask Flash Messages über das Glassmorphism-System anzeigen
|
||||
const flashContainer = document.getElementById('flask-flash-messages');
|
||||
if (flashContainer) {
|
||||
@@ -733,7 +730,7 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- DND Status und Counter -->
|
||||
<!-- DND Status -->
|
||||
<div id="dndStatus" class="text-xs text-slate-500 dark:text-slate-400">
|
||||
<span class="dnd-status-text">Alle Benachrichtigungen aktiv</span>
|
||||
</div>
|
||||
@@ -812,17 +809,14 @@
|
||||
* Initialisierung aller UI-Komponenten nach DOM-Load
|
||||
*/
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// User-Dropdown-Funktionalität initialisieren
|
||||
initializeUserDropdown();
|
||||
|
||||
// Mobile Menu Toggle initialisieren
|
||||
initializeMobileMenu();
|
||||
|
||||
// MYP App für Offline-Funktionalität initialisieren
|
||||
if (typeof MYPApp !== 'undefined') {
|
||||
window.mypApp = new MYPApp();
|
||||
}
|
||||
|
||||
// User-Dropdown-Funktionalität initialisieren
|
||||
initUserDropdown();
|
||||
|
||||
// Flask Flash Messages über das Glassmorphism-System anzeigen
|
||||
const flashContainer = document.getElementById('flask-flash-messages');
|
||||
if (flashContainer) {
|
||||
@@ -857,154 +851,139 @@
|
||||
/**
|
||||
* User-Dropdown-Funktionalität
|
||||
*/
|
||||
function initializeUserDropdown() {
|
||||
function initUserDropdown() {
|
||||
const userMenuButton = document.getElementById('user-menu-button');
|
||||
const userDropdown = document.getElementById('user-dropdown');
|
||||
const userMenuContainer = document.getElementById('user-menu-container');
|
||||
|
||||
if (!userMenuButton || !userDropdown) return;
|
||||
console.log('🔍 User-Dropdown Init:', { userMenuButton, userDropdown });
|
||||
|
||||
if (!userMenuButton || !userDropdown) {
|
||||
console.warn('⚠️ User-Dropdown-Elemente nicht gefunden:', {
|
||||
button: !!userMenuButton,
|
||||
dropdown: !!userDropdown
|
||||
});
|
||||
return; // Nicht angemeldet oder Elemente nicht gefunden
|
||||
}
|
||||
|
||||
let isDropdownOpen = false;
|
||||
|
||||
// Toggle-Funktion
|
||||
function toggleDropdown(e) {
|
||||
e.stopPropagation();
|
||||
const isExpanded = userMenuButton.getAttribute('aria-expanded') === 'true';
|
||||
function toggleDropdown(event) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
if (isExpanded) {
|
||||
closeDropdown();
|
||||
} else {
|
||||
isDropdownOpen = !isDropdownOpen;
|
||||
console.log('🔄 Toggle Dropdown:', isDropdownOpen);
|
||||
|
||||
if (isDropdownOpen) {
|
||||
openDropdown();
|
||||
} else {
|
||||
closeDropdown();
|
||||
}
|
||||
}
|
||||
|
||||
// Dropdown öffnen
|
||||
function openDropdown() {
|
||||
userDropdown.classList.remove('hidden');
|
||||
userMenuButton.setAttribute('aria-expanded', 'true');
|
||||
|
||||
// Animation für bessere UX
|
||||
// Reset any existing styles
|
||||
userDropdown.style.transition = '';
|
||||
userDropdown.style.opacity = '0';
|
||||
userDropdown.style.transform = 'scale(0.95) translateY(-5px)';
|
||||
userDropdown.style.transform = 'translateY(-10px) scale(0.95)';
|
||||
|
||||
// Kleine Verzögerung für Animation
|
||||
// Force reflow
|
||||
userDropdown.offsetHeight;
|
||||
|
||||
// Apply opening animation
|
||||
requestAnimationFrame(() => {
|
||||
userDropdown.style.transition = 'all 0.15s ease-out';
|
||||
userDropdown.style.transition = 'all 0.2s ease-out';
|
||||
userDropdown.style.opacity = '1';
|
||||
userDropdown.style.transform = 'scale(1) translateY(0)';
|
||||
userDropdown.style.transform = 'translateY(0) scale(1)';
|
||||
});
|
||||
|
||||
console.log('✅ Dropdown geöffnet');
|
||||
}
|
||||
|
||||
// Dropdown schließen
|
||||
function closeDropdown() {
|
||||
userDropdown.style.transition = 'all 0.15s ease-in';
|
||||
userDropdown.style.opacity = '0';
|
||||
userDropdown.style.transform = 'scale(0.95) translateY(-5px)';
|
||||
userDropdown.style.transform = 'translateY(-10px) scale(0.95)';
|
||||
|
||||
setTimeout(() => {
|
||||
userDropdown.classList.add('hidden');
|
||||
userMenuButton.setAttribute('aria-expanded', 'false');
|
||||
// Reset inline styles
|
||||
userDropdown.style.transition = '';
|
||||
userDropdown.style.opacity = '';
|
||||
userDropdown.style.transform = '';
|
||||
}, 150);
|
||||
|
||||
isDropdownOpen = false;
|
||||
console.log('❌ Dropdown geschlossen');
|
||||
}
|
||||
|
||||
// Event-Listener
|
||||
// Event-Listener für Button-Click
|
||||
userMenuButton.addEventListener('click', toggleDropdown);
|
||||
|
||||
// Außerhalb des Dropdowns klicken schließt es
|
||||
// Alternative: Auch auf touchstart für mobile Geräte
|
||||
userMenuButton.addEventListener('touchstart', function(e) {
|
||||
e.preventDefault();
|
||||
toggleDropdown(e);
|
||||
}, { passive: false });
|
||||
|
||||
// Event-Listener für Klicks außerhalb des Dropdowns
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!userMenuContainer.contains(e.target)) {
|
||||
closeDropdown();
|
||||
if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) {
|
||||
if (isDropdownOpen) {
|
||||
closeDropdown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Escape-Taste schließt das Dropdown
|
||||
// Touch-Events für mobile Geräte
|
||||
document.addEventListener('touchstart', function(e) {
|
||||
if (!userMenuButton.contains(e.target) && !userDropdown.contains(e.target)) {
|
||||
if (isDropdownOpen) {
|
||||
closeDropdown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Escape-Taste zum Schließen
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape' && userMenuButton.getAttribute('aria-expanded') === 'true') {
|
||||
if (e.key === 'Escape' && isDropdownOpen) {
|
||||
closeDropdown();
|
||||
userMenuButton.focus();
|
||||
}
|
||||
});
|
||||
|
||||
// Keyboard-Navigation im Dropdown
|
||||
// Fokus-Management für bessere Accessibility
|
||||
userDropdown.addEventListener('keydown', function(e) {
|
||||
const focusableElements = userDropdown.querySelectorAll('a, button');
|
||||
const currentIndex = Array.from(focusableElements).indexOf(document.activeElement);
|
||||
if (e.key === 'Tab') {
|
||||
const focusableElements = userDropdown.querySelectorAll('a, button');
|
||||
const firstElement = focusableElements[0];
|
||||
const lastElement = focusableElements[focusableElements.length - 1];
|
||||
|
||||
switch(e.key) {
|
||||
case 'ArrowDown':
|
||||
if (e.shiftKey && document.activeElement === firstElement) {
|
||||
e.preventDefault();
|
||||
const nextIndex = (currentIndex + 1) % focusableElements.length;
|
||||
focusableElements[nextIndex].focus();
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
lastElement.focus();
|
||||
} else if (!e.shiftKey && document.activeElement === lastElement) {
|
||||
e.preventDefault();
|
||||
const prevIndex = currentIndex === 0 ? focusableElements.length - 1 : currentIndex - 1;
|
||||
focusableElements[prevIndex].focus();
|
||||
break;
|
||||
case 'Tab':
|
||||
// Tab schließt das Dropdown
|
||||
if (!e.shiftKey && currentIndex === focusableElements.length - 1) {
|
||||
closeDropdown();
|
||||
} else if (e.shiftKey && currentIndex === 0) {
|
||||
closeDropdown();
|
||||
}
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Mobile Menu Toggle Funktionalität
|
||||
*/
|
||||
function initializeMobileMenu() {
|
||||
const mobileMenuToggle = document.getElementById('mobileMenuToggle');
|
||||
const mobileMenu = document.getElementById('mobileMenu');
|
||||
|
||||
if (!mobileMenuToggle || !mobileMenu) return;
|
||||
|
||||
mobileMenuToggle.addEventListener('click', function() {
|
||||
const isExpanded = mobileMenuToggle.getAttribute('aria-expanded') === 'true';
|
||||
|
||||
if (isExpanded) {
|
||||
// Menü schließen
|
||||
mobileMenu.classList.add('hidden');
|
||||
mobileMenuToggle.setAttribute('aria-expanded', 'false');
|
||||
mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen');
|
||||
|
||||
// Icon zu Hamburger ändern
|
||||
mobileMenuToggle.innerHTML = `
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
`;
|
||||
} else {
|
||||
// Menü öffnen
|
||||
mobileMenu.classList.remove('hidden');
|
||||
mobileMenuToggle.setAttribute('aria-expanded', 'true');
|
||||
mobileMenuToggle.setAttribute('aria-label', 'Menü schließen');
|
||||
|
||||
// Icon zu X ändern
|
||||
mobileMenuToggle.innerHTML = `
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
|
||||
</svg>
|
||||
`;
|
||||
firstElement.focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Mobile Menu bei Resize auf Desktop schließen
|
||||
// Window resize handler
|
||||
window.addEventListener('resize', function() {
|
||||
if (window.innerWidth >= 1024) { // lg breakpoint
|
||||
mobileMenu.classList.add('hidden');
|
||||
mobileMenuToggle.setAttribute('aria-expanded', 'false');
|
||||
mobileMenuToggle.setAttribute('aria-label', 'Menü öffnen');
|
||||
|
||||
// Icon zurück zu Hamburger
|
||||
mobileMenuToggle.innerHTML = `
|
||||
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
|
||||
</svg>
|
||||
`;
|
||||
if (isDropdownOpen) {
|
||||
closeDropdown();
|
||||
}
|
||||
});
|
||||
|
||||
console.log('✅ User-Dropdown erfolgreich initialisiert');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -357,6 +357,155 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timer Management Section -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<!-- Session Timer -->
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="section-title mb-0">Session-Timer</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="mb-status-indicator mb-status-idle" id="session-timer-status"></div>
|
||||
<span class="text-sm text-slate-500 dark:text-slate-400">Gestoppt</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timer Container -->
|
||||
<div id="session-countdown-timer" class="mb-6"></div>
|
||||
|
||||
<!-- Timer Configuration -->
|
||||
<div class="bg-gray-50 dark:bg-slate-700/30 rounded-lg p-4 mb-4">
|
||||
<h4 class="text-sm font-medium text-slate-900 dark:text-white mb-3">Timer-Einstellungen</h4>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs text-slate-500 dark:text-slate-400 mb-1">Dauer (Minuten)</label>
|
||||
<select id="session-duration" class="w-full px-3 py-2 text-sm border border-gray-300 dark:border-slate-600 rounded-md bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
|
||||
<option value="30">30 Minuten</option>
|
||||
<option value="60">1 Stunde</option>
|
||||
<option value="120" selected>2 Stunden</option>
|
||||
<option value="240">4 Stunden</option>
|
||||
<option value="480">8 Stunden</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-slate-500 dark:text-slate-400 mb-1">Force-Quit Aktion</label>
|
||||
<select id="session-force-quit" class="w-full px-3 py-2 text-sm border border-gray-300 dark:border-slate-600 rounded-md bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
|
||||
<option value="logout" selected>Automatisch abmelden</option>
|
||||
<option value="warning">Nur warnen</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3">
|
||||
<label class="block text-xs text-slate-500 dark:text-slate-400 mb-1">Warnung (Sekunden vor Ablauf)</label>
|
||||
<input type="number" id="session-warning" value="60" min="10" max="300" class="w-full px-3 py-2 text-sm border border-gray-300 dark:border-slate-600 rounded-md bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Quick Actions -->
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button id="create-session-timer" class="btn-primary text-sm px-4 py-2">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
|
||||
</svg>
|
||||
Timer erstellen
|
||||
</button>
|
||||
<button id="extend-session-5min" class="btn-secondary text-sm px-4 py-2">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
+5 Min
|
||||
</button>
|
||||
<button id="extend-session-15min" class="btn-secondary text-sm px-4 py-2">
|
||||
+15 Min
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kiosk Timer (Admin Only) -->
|
||||
{% if current_user.is_admin %}
|
||||
<div class="dashboard-card p-6">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h2 class="section-title mb-0">Kiosk-Timer</h2>
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="mb-status-indicator mb-status-idle" id="kiosk-timer-status"></div>
|
||||
<span class="text-sm text-slate-500 dark:text-slate-400">Inaktiv</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Timer Container -->
|
||||
<div id="kiosk-countdown-timer" class="mb-6"></div>
|
||||
|
||||
<!-- Admin Configuration -->
|
||||
<div class="bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg p-4 mb-4">
|
||||
<div class="flex items-center mb-3">
|
||||
<svg class="w-5 h-5 text-amber-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
|
||||
</svg>
|
||||
<h4 class="text-sm font-medium text-amber-800 dark:text-amber-200">Administrator-Funktion</h4>
|
||||
</div>
|
||||
<p class="text-xs text-amber-700 dark:text-amber-300 mb-3">Kiosk-Timer gelten systemweit für alle Benutzer und führen bei Ablauf automatische Aktionen aus.</p>
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs text-amber-700 dark:text-amber-300 mb-1">Dauer (Minuten)</label>
|
||||
<select id="kiosk-duration" class="w-full px-3 py-2 text-sm border border-amber-300 dark:border-amber-700 rounded-md bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
|
||||
<option value="15">15 Minuten</option>
|
||||
<option value="30" selected>30 Minuten</option>
|
||||
<option value="60">1 Stunde</option>
|
||||
<option value="120">2 Stunden</option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-amber-700 dark:text-amber-300 mb-1">System-Aktion</label>
|
||||
<select id="kiosk-action" class="w-full px-3 py-2 text-sm border border-amber-300 dark:border-amber-700 rounded-md bg-white dark:bg-slate-800 text-slate-900 dark:text-white">
|
||||
<option value="logout" selected>Alle Benutzer abmelden</option>
|
||||
<option value="restart">System neustarten</option>
|
||||
<option value="shutdown">System herunterfahren</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Admin Actions -->
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<button id="create-kiosk-timer" class="btn-warning text-sm px-4 py-2">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2zm10-10V7a4 4 0 00-8 0v4h8z" />
|
||||
</svg>
|
||||
Kiosk-Timer starten
|
||||
</button>
|
||||
<button id="stop-kiosk-timer" class="btn-danger text-sm px-4 py-2">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 10a1 1 0 011-1h4a1 1 0 011 1v4a1 1 0 01-1 1h-4a1 1 0 01-1-1v-4z" />
|
||||
</svg>
|
||||
Stoppen
|
||||
</button>
|
||||
<button id="force-quit-now" class="btn-danger text-sm px-4 py-2">
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
|
||||
</svg>
|
||||
Force-Quit jetzt
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<!-- Timer Overview for Non-Admin -->
|
||||
<div class="dashboard-card p-6">
|
||||
<h2 class="section-title">Timer-Übersicht</h2>
|
||||
<div id="timer-overview" class="space-y-4">
|
||||
<!-- Dynamic timer list will be populated here -->
|
||||
<div class="text-center py-8">
|
||||
<svg class="w-12 h-12 mx-auto mb-3 text-slate-400 dark:text-slate-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<p class="text-slate-700 dark:text-slate-300 font-medium mb-1">Keine aktiven Timer</p>
|
||||
<p class="text-slate-500 dark:text-slate-400 text-sm">Erstellen Sie einen Session-Timer für automatische Verwaltung.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Active Jobs Section -->
|
||||
<div class="dashboard-card p-6">
|
||||
<h2 class="section-title">Aktuelle Druckaufträge</h2>
|
||||
@@ -498,6 +647,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_js %}
|
||||
<script src="{{ url_for('static', filename='js/countdown-timer.js') }}"></script>
|
||||
<script>
|
||||
class DashboardManager {
|
||||
constructor() {
|
||||
@@ -941,12 +1091,512 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
window.dashboardManager = new DashboardManager();
|
||||
|
||||
// Timer-Funktionalität initialisieren
|
||||
initializeTimerControls();
|
||||
|
||||
// Cleanup beim Verlassen
|
||||
window.addEventListener('beforeunload', () => {
|
||||
if (window.dashboardManager) {
|
||||
window.dashboardManager.cleanup();
|
||||
}
|
||||
// Timer cleanup
|
||||
if (window.TimerManager) {
|
||||
window.TimerManager.destroyAll();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Initialisiert die Timer-Steuerung im Dashboard
|
||||
*/
|
||||
function initializeTimerControls() {
|
||||
console.log('🕒 Timer-Steuerung wird initialisiert...');
|
||||
|
||||
// Session-Timer Ereignisse
|
||||
setupSessionTimerEvents();
|
||||
|
||||
// Kiosk-Timer Ereignisse (nur für Admins)
|
||||
if (document.getElementById('create-kiosk-timer')) {
|
||||
setupKioskTimerEvents();
|
||||
}
|
||||
|
||||
// Bestehende Timer laden
|
||||
loadExistingTimers();
|
||||
|
||||
// Timer-Status regelmäßig aktualisieren
|
||||
setInterval(updateTimerStatus, 5000);
|
||||
|
||||
console.log('✅ Timer-Steuerung erfolgreich initialisiert');
|
||||
}
|
||||
|
||||
/**
|
||||
* Konfiguriert Session-Timer Ereignisse
|
||||
*/
|
||||
function setupSessionTimerEvents() {
|
||||
// Timer erstellen
|
||||
const createBtn = document.getElementById('create-session-timer');
|
||||
if (createBtn) {
|
||||
createBtn.addEventListener('click', async function() {
|
||||
const duration = parseInt(document.getElementById('session-duration').value);
|
||||
const forceQuitAction = document.getElementById('session-force-quit').value;
|
||||
const warningThreshold = parseInt(document.getElementById('session-warning').value);
|
||||
|
||||
await createSessionTimer(duration, forceQuitAction, warningThreshold);
|
||||
});
|
||||
}
|
||||
|
||||
// Timer verlängern - 5 Minuten
|
||||
const extend5Btn = document.getElementById('extend-session-5min');
|
||||
if (extend5Btn) {
|
||||
extend5Btn.addEventListener('click', async function() {
|
||||
await extendSessionTimer(300); // 5 Minuten = 300 Sekunden
|
||||
});
|
||||
}
|
||||
|
||||
// Timer verlängern - 15 Minuten
|
||||
const extend15Btn = document.getElementById('extend-session-15min');
|
||||
if (extend15Btn) {
|
||||
extend15Btn.addEventListener('click', async function() {
|
||||
await extendSessionTimer(900); // 15 Minuten = 900 Sekunden
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Konfiguriert Kiosk-Timer Ereignisse (Admin)
|
||||
*/
|
||||
function setupKioskTimerEvents() {
|
||||
// Kiosk-Timer erstellen
|
||||
const createKioskBtn = document.getElementById('create-kiosk-timer');
|
||||
if (createKioskBtn) {
|
||||
createKioskBtn.addEventListener('click', async function() {
|
||||
const duration = parseInt(document.getElementById('kiosk-duration').value);
|
||||
const action = document.getElementById('kiosk-action').value;
|
||||
|
||||
await createKioskTimer(duration, action);
|
||||
});
|
||||
}
|
||||
|
||||
// Kiosk-Timer stoppen
|
||||
const stopKioskBtn = document.getElementById('stop-kiosk-timer');
|
||||
if (stopKioskBtn) {
|
||||
stopKioskBtn.addEventListener('click', async function() {
|
||||
await stopKioskTimer();
|
||||
});
|
||||
}
|
||||
|
||||
// Force-Quit sofort ausführen
|
||||
const forceQuitBtn = document.getElementById('force-quit-now');
|
||||
if (forceQuitBtn) {
|
||||
forceQuitBtn.addEventListener('click', async function() {
|
||||
if (confirm('⚠️ Force-Quit wird sofort ausgeführt. Alle Benutzer werden abgemeldet. Fortfahren?')) {
|
||||
await executeForceQuitNow();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen Session-Timer
|
||||
*/
|
||||
async function createSessionTimer(durationMinutes, forceQuitAction, warningThreshold) {
|
||||
try {
|
||||
showTimerLoading('session');
|
||||
|
||||
// API-Aufruf zur Timer-Erstellung
|
||||
const response = await fetch('/api/timers/session/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({
|
||||
duration_minutes: durationMinutes
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
// Timer-UI erstellen
|
||||
const timer = window.TimerManager.create('session_timer', {
|
||||
container: 'session-countdown-timer',
|
||||
duration: durationMinutes * 60,
|
||||
forceQuitAction: forceQuitAction,
|
||||
warningThreshold: warningThreshold,
|
||||
syncWithServer: true,
|
||||
apiBase: '/api/timers/session_timer_' + getCurrentUserId(),
|
||||
size: 'medium',
|
||||
theme: 'primary',
|
||||
warningMessage: 'Ihre Session läuft ab! Speichern Sie Ihre Arbeit.',
|
||||
autoStart: true,
|
||||
|
||||
// Callbacks
|
||||
onTick: (remaining, total) => {
|
||||
updateTimerStatusIndicator('session', 'running');
|
||||
},
|
||||
onWarning: (remaining) => {
|
||||
showTimerWarning('Session läuft in ' + Math.floor(remaining / 60) + ' Minuten ab!');
|
||||
updateTimerStatusIndicator('session', 'warning');
|
||||
},
|
||||
onExpired: () => {
|
||||
updateTimerStatusIndicator('session', 'expired');
|
||||
if (forceQuitAction === 'logout') {
|
||||
showLogoutWarning();
|
||||
}
|
||||
},
|
||||
onForceQuit: () => {
|
||||
handleSessionForceQuit(forceQuitAction);
|
||||
}
|
||||
});
|
||||
|
||||
showTimerSuccess('Session-Timer erfolgreich erstellt und gestartet');
|
||||
updateSessionTimerControls(true);
|
||||
|
||||
} else {
|
||||
throw new Error(result.error || 'Timer konnte nicht erstellt werden');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Erstellen des Session-Timers:', error);
|
||||
showTimerError('Session-Timer konnte nicht erstellt werden: ' + error.message);
|
||||
} finally {
|
||||
hideTimerLoading('session');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen Kiosk-Timer (Admin)
|
||||
*/
|
||||
async function createKioskTimer(durationMinutes, action) {
|
||||
try {
|
||||
showTimerLoading('kiosk');
|
||||
|
||||
const response = await fetch('/api/timers/kiosk/create', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({
|
||||
duration_minutes: durationMinutes,
|
||||
auto_start: true
|
||||
})
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
// Kiosk-Timer UI erstellen
|
||||
const timer = window.TimerManager.create('kiosk_timer', {
|
||||
container: 'kiosk-countdown-timer',
|
||||
duration: durationMinutes * 60,
|
||||
forceQuitAction: action,
|
||||
warningThreshold: 30,
|
||||
syncWithServer: true,
|
||||
apiBase: '/api/timers/kiosk_session',
|
||||
size: 'medium',
|
||||
theme: 'warning',
|
||||
warningMessage: '⚠️ Kiosk-Session läuft ab! System wird automatisch ' + getActionText(action) + '.',
|
||||
autoStart: true,
|
||||
showControls: true,
|
||||
|
||||
onTick: (remaining, total) => {
|
||||
updateTimerStatusIndicator('kiosk', 'running');
|
||||
broadcastKioskTimerUpdate(remaining, total);
|
||||
},
|
||||
onWarning: (remaining) => {
|
||||
showKioskWarning('Kiosk-Timer läuft in ' + Math.floor(remaining / 60) + ' Minuten ab!');
|
||||
updateTimerStatusIndicator('kiosk', 'warning');
|
||||
},
|
||||
onExpired: () => {
|
||||
updateTimerStatusIndicator('kiosk', 'expired');
|
||||
executeKioskAction(action);
|
||||
}
|
||||
});
|
||||
|
||||
showTimerSuccess('Kiosk-Timer erfolgreich gestartet');
|
||||
updateKioskTimerControls(true);
|
||||
|
||||
} else {
|
||||
throw new Error(result.error || 'Kiosk-Timer konnte nicht erstellt werden');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Erstellen des Kiosk-Timers:', error);
|
||||
showTimerError('Kiosk-Timer konnte nicht erstellt werden: ' + error.message);
|
||||
} finally {
|
||||
hideTimerLoading('kiosk');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verlängert Session-Timer
|
||||
*/
|
||||
async function extendSessionTimer(additionalSeconds) {
|
||||
try {
|
||||
const timer = window.TimerManager.get('session_timer');
|
||||
if (!timer) {
|
||||
showTimerError('Kein aktiver Session-Timer gefunden');
|
||||
return;
|
||||
}
|
||||
|
||||
const success = await timer.extend(additionalSeconds);
|
||||
if (success) {
|
||||
const minutes = Math.floor(additionalSeconds / 60);
|
||||
showTimerSuccess(`Session-Timer um ${minutes} Minuten verlängert`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Verlängern des Session-Timers:', error);
|
||||
showTimerError('Timer konnte nicht verlängert werden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stoppt Kiosk-Timer
|
||||
*/
|
||||
async function stopKioskTimer() {
|
||||
try {
|
||||
const timer = window.TimerManager.get('kiosk_timer');
|
||||
if (!timer) {
|
||||
showTimerError('Kein aktiver Kiosk-Timer gefunden');
|
||||
return;
|
||||
}
|
||||
|
||||
const success = await timer.stop();
|
||||
if (success) {
|
||||
showTimerSuccess('Kiosk-Timer gestoppt');
|
||||
updateKioskTimerControls(false);
|
||||
updateTimerStatusIndicator('kiosk', 'stopped');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Stoppen des Kiosk-Timers:', error);
|
||||
showTimerError('Kiosk-Timer konnte nicht gestoppt werden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Führt Force-Quit sofort aus
|
||||
*/
|
||||
async function executeForceQuitNow() {
|
||||
try {
|
||||
const response = await fetch('/api/timers/kiosk_session/force-quit', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCSRFToken()
|
||||
}
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success) {
|
||||
showTimerSuccess('Force-Quit wird ausgeführt...');
|
||||
|
||||
// Je nach Aktion unterschiedlich behandeln
|
||||
if (result.action === 'logout') {
|
||||
setTimeout(() => {
|
||||
window.location.href = result.redirect_url || '/login';
|
||||
}, 2000);
|
||||
} else {
|
||||
showTimerSuccess('Force-Quit-Aktion ausgeführt: ' + result.action);
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.error || 'Force-Quit fehlgeschlagen');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Force-Quit:', error);
|
||||
showTimerError('Force-Quit konnte nicht ausgeführt werden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt bestehende Timer beim Seitenaufruf
|
||||
*/
|
||||
async function loadExistingTimers() {
|
||||
try {
|
||||
const response = await fetch('/api/timers');
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success && result.data) {
|
||||
result.data.forEach(timerData => {
|
||||
if (timerData.status === 'running') {
|
||||
recreateTimerFromData(timerData);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Laden bestehender Timer:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recreiert Timer aus Server-Daten
|
||||
*/
|
||||
function recreateTimerFromData(timerData) {
|
||||
const isSessionTimer = timerData.timer_type === 'session';
|
||||
const isKioskTimer = timerData.timer_type === 'kiosk';
|
||||
|
||||
if (isSessionTimer && timerData.context_id === getCurrentUserId()) {
|
||||
// Session-Timer für aktuellen Benutzer recreieren
|
||||
const timer = window.TimerManager.create('session_timer', {
|
||||
container: 'session-countdown-timer',
|
||||
duration: timerData.duration_seconds,
|
||||
remaining: timerData.remaining_seconds,
|
||||
forceQuitAction: timerData.force_quit_action,
|
||||
warningThreshold: timerData.force_quit_warning_seconds,
|
||||
syncWithServer: true,
|
||||
autoStart: false, // Läuft bereits
|
||||
size: 'medium',
|
||||
theme: 'primary'
|
||||
});
|
||||
|
||||
updateTimerStatusIndicator('session', 'running');
|
||||
updateSessionTimerControls(true);
|
||||
|
||||
} else if (isKioskTimer && isCurrentUserAdmin()) {
|
||||
// Kiosk-Timer für Admin recreieren
|
||||
const timer = window.TimerManager.create('kiosk_timer', {
|
||||
container: 'kiosk-countdown-timer',
|
||||
duration: timerData.duration_seconds,
|
||||
remaining: timerData.remaining_seconds,
|
||||
forceQuitAction: timerData.force_quit_action,
|
||||
warningThreshold: timerData.force_quit_warning_seconds,
|
||||
syncWithServer: true,
|
||||
autoStart: false, // Läuft bereits
|
||||
size: 'medium',
|
||||
theme: 'warning'
|
||||
});
|
||||
|
||||
updateTimerStatusIndicator('kiosk', 'running');
|
||||
updateKioskTimerControls(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert Timer-Status regelmäßig
|
||||
*/
|
||||
async function updateTimerStatus() {
|
||||
// Implementierung für regelmäßige Status-Updates
|
||||
const sessionTimer = window.TimerManager.get('session_timer');
|
||||
const kioskTimer = window.TimerManager.get('kiosk_timer');
|
||||
|
||||
if (sessionTimer && sessionTimer.config.syncWithServer) {
|
||||
sessionTimer.syncWithServer();
|
||||
}
|
||||
|
||||
if (kioskTimer && kioskTimer.config.syncWithServer) {
|
||||
kioskTimer.syncWithServer();
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktionen
|
||||
function updateTimerStatusIndicator(timerType, status) {
|
||||
const indicator = document.getElementById(`${timerType}-timer-status`);
|
||||
const statusText = indicator?.nextElementSibling;
|
||||
|
||||
if (indicator) {
|
||||
indicator.className = `mb-status-indicator ${getTimerStatusClass(status)}`;
|
||||
}
|
||||
|
||||
if (statusText) {
|
||||
statusText.textContent = getTimerStatusText(status);
|
||||
}
|
||||
}
|
||||
|
||||
function getTimerStatusClass(status) {
|
||||
const classes = {
|
||||
'running': 'mb-status-busy',
|
||||
'stopped': 'mb-status-idle',
|
||||
'warning': 'mb-status-busy',
|
||||
'expired': 'mb-status-offline'
|
||||
};
|
||||
return classes[status] || 'mb-status-idle';
|
||||
}
|
||||
|
||||
function getTimerStatusText(status) {
|
||||
const texts = {
|
||||
'running': 'Läuft',
|
||||
'stopped': 'Gestoppt',
|
||||
'warning': 'Warnung',
|
||||
'expired': 'Abgelaufen'
|
||||
};
|
||||
return texts[status] || 'Unbekannt';
|
||||
}
|
||||
|
||||
function updateSessionTimerControls(active) {
|
||||
const createBtn = document.getElementById('create-session-timer');
|
||||
const extendBtns = [
|
||||
document.getElementById('extend-session-5min'),
|
||||
document.getElementById('extend-session-15min')
|
||||
];
|
||||
|
||||
if (createBtn) createBtn.disabled = active;
|
||||
extendBtns.forEach(btn => {
|
||||
if (btn) btn.disabled = !active;
|
||||
});
|
||||
}
|
||||
|
||||
function updateKioskTimerControls(active) {
|
||||
const createBtn = document.getElementById('create-kiosk-timer');
|
||||
const stopBtn = document.getElementById('stop-kiosk-timer');
|
||||
const forceQuitBtn = document.getElementById('force-quit-now');
|
||||
|
||||
if (createBtn) createBtn.disabled = active;
|
||||
if (stopBtn) stopBtn.disabled = !active;
|
||||
if (forceQuitBtn) forceQuitBtn.disabled = !active;
|
||||
}
|
||||
|
||||
function showTimerLoading(timerType) {
|
||||
// Implementierung für Loading-Anzeige
|
||||
}
|
||||
|
||||
function hideTimerLoading(timerType) {
|
||||
// Implementierung für Loading-Anzeige ausblenden
|
||||
}
|
||||
|
||||
function showTimerSuccess(message) {
|
||||
if (window.dashboardManager) {
|
||||
window.dashboardManager.showToast(message, 'success');
|
||||
}
|
||||
}
|
||||
|
||||
function showTimerError(message) {
|
||||
if (window.dashboardManager) {
|
||||
window.dashboardManager.showToast(message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function showTimerWarning(message) {
|
||||
if (window.dashboardManager) {
|
||||
window.dashboardManager.showToast(message, 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
function getActionText(action) {
|
||||
const actions = {
|
||||
'logout': 'abgemeldet',
|
||||
'restart': 'neugestartet',
|
||||
'shutdown': 'heruntergefahren'
|
||||
};
|
||||
return actions[action] || action;
|
||||
}
|
||||
|
||||
function getCurrentUserId() {
|
||||
return {{ current_user.id }};
|
||||
}
|
||||
|
||||
function isCurrentUserAdmin() {
|
||||
return {{ 'true' if current_user.is_admin else 'false' }};
|
||||
}
|
||||
|
||||
function getCSRFToken() {
|
||||
const token = document.querySelector('meta[name="csrf-token"]');
|
||||
return token ? token.getAttribute('content') : '';
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
"""
|
||||
SSL-Konfiguration für HTTPS-Server
|
||||
Importiert SSL-Funktionalität aus der Hauptkonfiguration
|
||||
"""
|
||||
|
||||
try:
|
||||
from config.settings_copy import get_ssl_context
|
||||
except ImportError:
|
||||
def get_ssl_context():
|
||||
"""Fallback wenn settings_copy nicht verfügbar"""
|
||||
return None
|
||||
Reference in New Issue
Block a user