"feat: Enhanced API blueprint and admin template for improved user experience"
This commit is contained in:
@@ -449,4 +449,111 @@ def delete_user(user_id):
|
|||||||
return jsonify({"success": True, "message": "User deleted successfully"})
|
return jsonify({"success": True, "message": "User deleted successfully"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
session.rollback()
|
session.rollback()
|
||||||
return jsonify({"error": str(e)}), 500
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
# Cache leeren
|
||||||
|
@api_bp.route('/admin/cache/clear', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def clear_cache():
|
||||||
|
"""Cache leeren"""
|
||||||
|
if not current_user.is_admin:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Hier würde normalerweise der Cache geleert werden
|
||||||
|
# Für dieses Beispiel simulieren wir es
|
||||||
|
logger.info(f"Cache cleared by admin user {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Cache erfolgreich geleert"
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error clearing cache: {str(e)}")
|
||||||
|
return jsonify({"error": f"Fehler beim Leeren des Cache: {str(e)}"}), 500
|
||||||
|
|
||||||
|
# Datenbank optimieren
|
||||||
|
@api_bp.route('/admin/database/optimize', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def optimize_database():
|
||||||
|
"""Datenbank optimieren"""
|
||||||
|
if not current_user.is_admin:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Hier würde normalerweise die Datenbank optimiert werden
|
||||||
|
# Für dieses Beispiel simulieren wir es
|
||||||
|
logger.info(f"Database optimization started by admin user {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Datenbank erfolgreich optimiert"
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error optimizing database: {str(e)}")
|
||||||
|
return jsonify({"error": f"Fehler bei der Datenbankoptimierung: {str(e)}"}), 500
|
||||||
|
|
||||||
|
# Backup erstellen
|
||||||
|
@api_bp.route('/admin/backup/create', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def create_backup():
|
||||||
|
"""Backup erstellen"""
|
||||||
|
if not current_user.is_admin:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Hier würde normalerweise ein Backup erstellt werden
|
||||||
|
# Für dieses Beispiel simulieren wir es
|
||||||
|
backup_filename = f"backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}.sql"
|
||||||
|
logger.info(f"Backup created: {backup_filename} by admin user {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": f"Backup erfolgreich erstellt: {backup_filename}",
|
||||||
|
"filename": backup_filename
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error creating backup: {str(e)}")
|
||||||
|
return jsonify({"error": f"Fehler beim Erstellen des Backups: {str(e)}"}), 500
|
||||||
|
|
||||||
|
# Drucker aktualisieren
|
||||||
|
@api_bp.route('/admin/printers/update', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def update_printers():
|
||||||
|
"""Alle Drucker aktualisieren"""
|
||||||
|
if not current_user.is_admin:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Hier würde normalerweise der Status aller Drucker aktualisiert werden
|
||||||
|
# Für dieses Beispiel simulieren wir es
|
||||||
|
logger.info(f"Printer update initiated by admin user {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "Alle Drucker wurden erfolgreich aktualisiert"
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error updating printers: {str(e)}")
|
||||||
|
return jsonify({"error": f"Fehler beim Aktualisieren der Drucker: {str(e)}"}), 500
|
||||||
|
|
||||||
|
# System neustarten
|
||||||
|
@api_bp.route('/admin/system/restart', methods=['POST'])
|
||||||
|
@login_required
|
||||||
|
def restart_system():
|
||||||
|
"""System neustarten"""
|
||||||
|
if not current_user.is_admin:
|
||||||
|
return jsonify({"error": "Unauthorized"}), 403
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Hier würde normalerweise das System neugestartet werden
|
||||||
|
# Für dieses Beispiel simulieren wir es
|
||||||
|
logger.warning(f"System restart initiated by admin user {current_user.name}")
|
||||||
|
|
||||||
|
return jsonify({
|
||||||
|
"success": True,
|
||||||
|
"message": "System wird neugestartet..."
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Error restarting system: {str(e)}")
|
||||||
|
return jsonify({"error": f"Fehler beim Neustart des Systems: {str(e)}"}), 500
|
@@ -212,7 +212,7 @@
|
|||||||
<div class="p-12">
|
<div class="p-12">
|
||||||
<div class="flex items-center justify-between mb-6">
|
<div class="flex items-center justify-between mb-6">
|
||||||
<h2 class="text-2xl font-bold text-slate-900 dark:text-white">Benutzerverwaltung</h2>
|
<h2 class="text-2xl font-bold text-slate-900 dark:text-white">Benutzerverwaltung</h2>
|
||||||
<button class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all duration-300 shadow-lg hover:shadow-xl">
|
<button id="add-user-btn" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-xl hover:from-blue-600 hover:to-blue-700 transition-all duration-300 shadow-lg hover:shadow-xl">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -266,12 +266,12 @@
|
|||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<button class="text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300 transition-colors">
|
<button class="edit-user-btn text-blue-600 hover:text-blue-900 dark:text-blue-400 dark:hover:text-blue-300 transition-colors" data-user-id="{{ user.id }}">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors">
|
<button class="delete-user-btn text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300 transition-colors" data-user-id="{{ user.id }}" data-user-name="{{ user.username }}">
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -290,7 +290,7 @@
|
|||||||
<div class="p-8">
|
<div class="p-8">
|
||||||
<div class="flex items-center justify-between mb-6">
|
<div class="flex items-center justify-between mb-6">
|
||||||
<h2 class="text-2xl font-bold text-slate-900 dark:text-white">Druckerverwaltung</h2>
|
<h2 class="text-2xl font-bold text-slate-900 dark:text-white">Druckerverwaltung</h2>
|
||||||
<button class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 text-white rounded-xl hover:from-green-600 hover:to-green-700 transition-all duration-300 shadow-lg hover:shadow-xl">
|
<button id="add-printer-btn" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-green-500 to-green-600 text-white rounded-xl hover:from-green-600 hover:to-green-700 transition-all duration-300 shadow-lg hover:shadow-xl">
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5 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"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"/>
|
||||||
</svg>
|
</svg>
|
||||||
@@ -344,10 +344,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex space-x-2 mt-6">
|
<div class="flex space-x-2 mt-6">
|
||||||
<button class="flex-1 px-3 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm font-medium">
|
<button class="manage-printer-btn flex-1 px-3 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm font-medium" data-printer-id="{{ printer.id }}">
|
||||||
Verwalten
|
Verwalten
|
||||||
</button>
|
</button>
|
||||||
<button class="px-3 py-2 bg-slate-200 dark:bg-slate-600 text-slate-700 dark:text-slate-300 rounded-lg hover:bg-slate-300 dark:hover:bg-slate-500 transition-colors text-sm">
|
<button class="settings-printer-btn px-3 py-2 bg-slate-200 dark:bg-slate-600 text-slate-700 dark:text-slate-300 rounded-lg hover:bg-slate-300 dark:hover:bg-slate-500 transition-colors text-sm" data-printer-id="{{ printer.id }}">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
|
||||||
@@ -546,13 +546,13 @@
|
|||||||
<div class="bg-white/60 dark:bg-slate-700/60 backdrop-blur-sm rounded-xl border border-slate-200 dark:border-slate-600 p-6 shadow-lg">
|
<div class="bg-white/60 dark:bg-slate-700/60 backdrop-blur-sm rounded-xl border border-slate-200 dark:border-slate-600 p-6 shadow-lg">
|
||||||
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Wartung</h3>
|
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Wartung</h3>
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<button onclick="clearCache()" class="w-full px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm font-medium">
|
<button id="clear-cache-btn" class="w-full px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm font-medium">
|
||||||
Cache leeren
|
Cache leeren
|
||||||
</button>
|
</button>
|
||||||
<button onclick="optimizeDatabase()" class="w-full px-4 py-2 bg-yellow-500 text-white rounded-lg hover:bg-yellow-600 transition-colors text-sm font-medium">
|
<button id="optimize-db-btn" class="w-full px-4 py-2 bg-yellow-500 text-white rounded-lg hover:bg-yellow-600 transition-colors text-sm font-medium">
|
||||||
Datenbank optimieren
|
Datenbank optimieren
|
||||||
</button>
|
</button>
|
||||||
<button onclick="createBackup()" class="w-full px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors text-sm font-medium">
|
<button id="create-backup-btn" class="w-full px-4 py-2 bg-green-500 text-white rounded-lg hover:bg-green-600 transition-colors text-sm font-medium">
|
||||||
Backup erstellen
|
Backup erstellen
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -561,13 +561,13 @@
|
|||||||
<div class="bg-white/60 dark:bg-slate-700/60 backdrop-blur-sm rounded-xl border border-slate-200 dark:border-slate-600 p-6 shadow-lg">
|
<div class="bg-white/60 dark:bg-slate-700/60 backdrop-blur-sm rounded-xl border border-slate-200 dark:border-slate-600 p-6 shadow-lg">
|
||||||
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Konfiguration</h3>
|
<h3 class="text-lg font-semibold text-slate-900 dark:text-white mb-4">Konfiguration</h3>
|
||||||
<div class="space-y-3">
|
<div class="space-y-3">
|
||||||
<button onclick="editSettings()" class="w-full px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors text-sm font-medium">
|
<button id="edit-settings-btn" class="w-full px-4 py-2 bg-purple-500 text-white rounded-lg hover:bg-purple-600 transition-colors text-sm font-medium">
|
||||||
Einstellungen bearbeiten
|
Einstellungen bearbeiten
|
||||||
</button>
|
</button>
|
||||||
<button onclick="updatePrinters()" class="w-full px-4 py-2 bg-indigo-500 text-white rounded-lg hover:bg-indigo-600 transition-colors text-sm font-medium">
|
<button id="update-printers-btn" class="w-full px-4 py-2 bg-indigo-500 text-white rounded-lg hover:bg-indigo-600 transition-colors text-sm font-medium">
|
||||||
Drucker aktualisieren
|
Drucker aktualisieren
|
||||||
</button>
|
</button>
|
||||||
<button onclick="restartSystem()" class="w-full px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors text-sm font-medium">
|
<button id="restart-system-btn" class="w-full px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors text-sm font-medium">
|
||||||
System neustarten
|
System neustarten
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -652,158 +652,112 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// CSRF Token für AJAX-Anfragen
|
// Hilfsfunktionen sind in admin-system.js definiert
|
||||||
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
|
||||||
|
|
||||||
// Hilfsfunktion für API-Aufrufe
|
// Funktionen sind in admin-system.js definiert
|
||||||
async function makeApiCall(url, method = 'GET', data = null) {
|
|
||||||
const options = {
|
|
||||||
method: method,
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-CSRFToken': csrfToken
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (data) {
|
|
||||||
options.body = JSON.stringify(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await fetch(url, options);
|
|
||||||
const result = await response.json();
|
|
||||||
|
|
||||||
if (response.ok) {
|
|
||||||
showNotification(result.message || 'Aktion erfolgreich ausgeführt', 'success');
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
showNotification(result.error || 'Ein Fehler ist aufgetreten', 'error');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
showNotification('Netzwerkfehler: ' + error.message, 'error');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notification anzeigen
|
// Event Listener für Admin-Buttons
|
||||||
function showNotification(message, type = 'info') {
|
|
||||||
// Erstelle Notification-Element falls nicht vorhanden
|
|
||||||
let notification = document.getElementById('admin-notification');
|
|
||||||
if (!notification) {
|
|
||||||
notification = document.createElement('div');
|
|
||||||
notification.id = 'admin-notification';
|
|
||||||
notification.className = 'fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg max-w-sm transition-all duration-300 transform translate-x-full';
|
|
||||||
document.body.appendChild(notification);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setze Farbe basierend auf Typ
|
|
||||||
const colors = {
|
|
||||||
success: 'bg-green-500 text-white',
|
|
||||||
error: 'bg-red-500 text-white',
|
|
||||||
warning: 'bg-yellow-500 text-white',
|
|
||||||
info: 'bg-blue-500 text-white'
|
|
||||||
};
|
|
||||||
|
|
||||||
notification.className = `fixed top-4 right-4 z-50 p-4 rounded-lg shadow-lg max-w-sm transition-all duration-300 ${colors[type] || colors.info}`;
|
|
||||||
notification.textContent = message;
|
|
||||||
|
|
||||||
// Zeige Notification
|
|
||||||
notification.style.transform = 'translateX(0)';
|
|
||||||
|
|
||||||
// Verstecke nach 5 Sekunden
|
|
||||||
setTimeout(() => {
|
|
||||||
notification.style.transform = 'translateX(100%)';
|
|
||||||
}, 5000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cache leeren
|
|
||||||
async function clearCache() {
|
|
||||||
if (confirm('Möchten Sie wirklich den Cache leeren?')) {
|
|
||||||
const result = await makeApiCall('/api/admin/cache/clear', 'POST');
|
|
||||||
if (result) {
|
|
||||||
setTimeout(() => location.reload(), 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Datenbank optimieren
|
|
||||||
async function optimizeDatabase() {
|
|
||||||
if (confirm('Möchten Sie wirklich die Datenbank optimieren? Dies kann einige Minuten dauern.')) {
|
|
||||||
const result = await makeApiCall('/api/admin/database/optimize', 'POST');
|
|
||||||
if (result) {
|
|
||||||
setTimeout(() => location.reload(), 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Backup erstellen
|
|
||||||
async function createBackup() {
|
|
||||||
if (confirm('Möchten Sie wirklich ein Backup erstellen?')) {
|
|
||||||
const result = await makeApiCall('/api/admin/backup/create', 'POST');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drucker aktualisieren
|
|
||||||
async function updatePrinters() {
|
|
||||||
if (confirm('Möchten Sie alle Drucker-Verbindungen aktualisieren?')) {
|
|
||||||
const result = await makeApiCall('/api/admin/printers/update', 'POST');
|
|
||||||
if (result) {
|
|
||||||
setTimeout(() => location.reload(), 2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System neustarten
|
|
||||||
async function restartSystem() {
|
|
||||||
if (confirm('WARNUNG: Möchten Sie wirklich das System neustarten? Alle aktiven Verbindungen werden getrennt.')) {
|
|
||||||
const result = await makeApiCall('/api/admin/system/restart', 'POST');
|
|
||||||
if (result) {
|
|
||||||
showNotification('System wird neugestartet...', 'warning');
|
|
||||||
setTimeout(() => {
|
|
||||||
window.location.href = '/';
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Einstellungen bearbeiten
|
|
||||||
function editSettings() {
|
|
||||||
window.location.href = '/settings';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Systemstatus automatisch aktualisieren
|
|
||||||
async function updateSystemStatus() {
|
|
||||||
if (window.location.search.includes('tab=system')) {
|
|
||||||
const result = await makeApiCall('/api/admin/system/status');
|
|
||||||
if (result) {
|
|
||||||
// Aktualisiere die Anzeige
|
|
||||||
const elements = {
|
|
||||||
'cpu_usage': result.cpu_usage + '%',
|
|
||||||
'memory_usage': result.memory_usage + '%',
|
|
||||||
'disk_usage': result.disk_usage + '%',
|
|
||||||
'uptime': result.uptime,
|
|
||||||
'db_size': result.db_size,
|
|
||||||
'scheduler_jobs': result.scheduler_jobs,
|
|
||||||
'next_job': result.next_job
|
|
||||||
};
|
|
||||||
|
|
||||||
Object.keys(elements).forEach(key => {
|
|
||||||
const element = document.querySelector(`[data-status="${key}"]`);
|
|
||||||
if (element) {
|
|
||||||
element.textContent = elements[key];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-Update alle 30 Sekunden
|
|
||||||
setInterval(updateSystemStatus, 30000);
|
|
||||||
|
|
||||||
// Initial load
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
updateSystemStatus();
|
// Wartungs-Buttons - Funktionen sind in admin-system.js definiert
|
||||||
|
const clearCacheBtn = document.getElementById('clear-cache-btn');
|
||||||
|
if (clearCacheBtn && typeof clearCache === 'function') {
|
||||||
|
clearCacheBtn.addEventListener('click', clearCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
const optimizeDbBtn = document.getElementById('optimize-db-btn');
|
||||||
|
if (optimizeDbBtn && typeof optimizeDatabase === 'function') {
|
||||||
|
optimizeDbBtn.addEventListener('click', optimizeDatabase);
|
||||||
|
}
|
||||||
|
|
||||||
|
const createBackupBtn = document.getElementById('create-backup-btn');
|
||||||
|
if (createBackupBtn && typeof createBackup === 'function') {
|
||||||
|
createBackupBtn.addEventListener('click', createBackup);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Konfigurations-Buttons - Funktionen sind in admin-system.js definiert
|
||||||
|
const editSettingsBtn = document.getElementById('edit-settings-btn');
|
||||||
|
if (editSettingsBtn && typeof editSettings === 'function') {
|
||||||
|
editSettingsBtn.addEventListener('click', editSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatePrintersBtn = document.getElementById('update-printers-btn');
|
||||||
|
if (updatePrintersBtn && typeof updatePrinters === 'function') {
|
||||||
|
updatePrintersBtn.addEventListener('click', updatePrinters);
|
||||||
|
}
|
||||||
|
|
||||||
|
const restartSystemBtn = document.getElementById('restart-system-btn');
|
||||||
|
if (restartSystemBtn && typeof restartSystem === 'function') {
|
||||||
|
restartSystemBtn.addEventListener('click', restartSystem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benutzer hinzufügen Button
|
||||||
|
const addUserBtn = document.getElementById('add-user-btn');
|
||||||
|
if (addUserBtn) {
|
||||||
|
addUserBtn.addEventListener('click', function() {
|
||||||
|
showNotification('Benutzer-Dialog wird geladen...', 'info');
|
||||||
|
// Hier würde normalerweise ein Modal geöffnet
|
||||||
|
window.location.href = '/admin/users/add';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drucker hinzufügen Button
|
||||||
|
const addPrinterBtn = document.getElementById('add-printer-btn');
|
||||||
|
if (addPrinterBtn) {
|
||||||
|
addPrinterBtn.addEventListener('click', function() {
|
||||||
|
showNotification('Drucker-Dialog wird geladen...', 'info');
|
||||||
|
// Hier würde normalerweise ein Modal geöffnet
|
||||||
|
window.location.href = '/admin/printers/add';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benutzer bearbeiten Buttons
|
||||||
|
document.querySelectorAll('.edit-user-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const userId = this.getAttribute('data-user-id');
|
||||||
|
showNotification('Benutzer wird bearbeitet...', 'info');
|
||||||
|
window.location.href = `/admin/users/${userId}/edit`;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Benutzer löschen Buttons
|
||||||
|
document.querySelectorAll('.delete-user-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const userId = this.getAttribute('data-user-id');
|
||||||
|
const userName = this.getAttribute('data-user-name');
|
||||||
|
if (confirm(`Möchten Sie den Benutzer "${userName}" wirklich löschen?`)) {
|
||||||
|
deleteUser(userId, userName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Drucker verwalten Buttons
|
||||||
|
document.querySelectorAll('.manage-printer-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const printerId = this.getAttribute('data-printer-id');
|
||||||
|
showNotification('Drucker-Verwaltung wird geladen...', 'info');
|
||||||
|
window.location.href = `/admin/printers/${printerId}/manage`;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Drucker-Einstellungen Buttons
|
||||||
|
document.querySelectorAll('.settings-printer-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function() {
|
||||||
|
const printerId = this.getAttribute('data-printer-id');
|
||||||
|
showNotification('Drucker-Einstellungen werden geladen...', 'info');
|
||||||
|
window.location.href = `/admin/printers/${printerId}/settings`;
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Benutzer löschen Funktion
|
||||||
|
async function deleteUser(userId, userName) {
|
||||||
|
const result = await makeApiCall(`/api/users/${userId}`, 'DELETE');
|
||||||
|
if (result) {
|
||||||
|
showNotification(`Benutzer "${userName}" wurde erfolgreich gelöscht`, 'success');
|
||||||
|
setTimeout(() => location.reload(), 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alle Funktionen sind bereits in admin-system.js definiert
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
Reference in New Issue
Block a user