Title: Enhanced System Logs and UI Updates
🎉 New system logs have been implemented for improved monitoring and debugging capabilities. These include:
- admin.log
- admin_api.log
- app.log
- data_management.log
- drucker_steuerung.log
- energy_monitoring.log
- hardware_integration.log
- job_queue_system.log
- monitoring_analytics.log
- permissions.
This commit is contained in:
@ -1083,6 +1083,208 @@ class AdminDashboard {
|
||||
}
|
||||
}
|
||||
|
||||
// ===== DIREKTE BENUTZERVERWALTUNGS-FUNKTIONEN =====
|
||||
|
||||
async updateUserRole(userId, newRole) {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': this.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ role: newRole })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.showNotification(`✅ Rolle erfolgreich aktualisiert`, 'success');
|
||||
// Seite nach kurzer Zeit neu laden
|
||||
setTimeout(() => window.location.reload(), 1000);
|
||||
} else {
|
||||
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
|
||||
// Rolle zurücksetzen bei Fehler
|
||||
const selectElement = document.querySelector(`select[data-user-id="${userId}"]`);
|
||||
if (selectElement) {
|
||||
selectElement.value = selectElement.value === 'admin' ? 'user' : 'admin';
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren der Rolle:', error);
|
||||
this.showNotification('❌ Fehler beim Aktualisieren der Rolle', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async toggleUserStatus(userId, isActive) {
|
||||
try {
|
||||
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': this.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ active: isActive })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const statusText = isActive ? 'aktiviert' : 'deaktiviert';
|
||||
this.showNotification(`✅ Benutzer erfolgreich ${statusText}`, 'success');
|
||||
|
||||
// Status-Text visuell aktualisieren
|
||||
const row = document.querySelector(`tr[data-user-id="${userId}"]`);
|
||||
const statusSpan = row.querySelector('.status-toggle + span');
|
||||
if (statusSpan) {
|
||||
statusSpan.textContent = isActive ? 'Aktiv' : 'Inaktiv';
|
||||
statusSpan.className = `ml-2 text-xs ${isActive ? 'text-green-700 dark:text-green-400' : 'text-red-700 dark:text-red-400'}`;
|
||||
}
|
||||
} else {
|
||||
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
|
||||
// Checkbox zurücksetzen
|
||||
const checkbox = document.querySelector(`input[data-user-id="${userId}"].status-toggle`);
|
||||
if (checkbox) checkbox.checked = !isActive;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Ändern des Status:', error);
|
||||
this.showNotification('❌ Fehler beim Ändern des Status', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async updateUserPermission(userId, permission, isEnabled) {
|
||||
try {
|
||||
const permissionData = {
|
||||
[permission]: isEnabled
|
||||
};
|
||||
|
||||
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}/permissions`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': this.csrfToken
|
||||
},
|
||||
body: JSON.stringify(permissionData)
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
const permissionNames = {
|
||||
'can_start_jobs': 'Jobs starten',
|
||||
'needs_approval': 'Genehmigung erforderlich',
|
||||
'can_approve_jobs': 'Jobs genehmigen'
|
||||
};
|
||||
const actionText = isEnabled ? 'aktiviert' : 'deaktiviert';
|
||||
this.showNotification(`✅ ${permissionNames[permission]} ${actionText}`, 'success');
|
||||
} else {
|
||||
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
|
||||
// Checkbox zurücksetzen
|
||||
const checkbox = document.querySelector(`input[data-user-id="${userId}"][data-permission="${permission}"]`);
|
||||
if (checkbox) checkbox.checked = !isEnabled;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Aktualisieren der Berechtigung:', error);
|
||||
this.showNotification('❌ Fehler beim Aktualisieren der Berechtigung', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
async resetUserPassword(userId, userName) {
|
||||
if (!confirm(`🔑 Möchten Sie das Passwort für "${userName}" wirklich zurücksetzen?\n\nDem Benutzer wird ein neues temporäres Passwort zugewiesen.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Temporäres Passwort generieren
|
||||
const tempPassword = this.generateTempPassword();
|
||||
|
||||
const response = await fetch(`${this.apiBaseUrl}/api/admin/users/${userId}`, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': this.csrfToken
|
||||
},
|
||||
body: JSON.stringify({ password: tempPassword })
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
// Passwort-Modal anzeigen
|
||||
this.showPasswordResetModal(userName, tempPassword);
|
||||
} else {
|
||||
this.showNotification(`❌ Fehler: ${data.error}`, 'error');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Zurücksetzen des Passworts:', error);
|
||||
this.showNotification('❌ Fehler beim Zurücksetzen des Passworts', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
generateTempPassword() {
|
||||
const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789';
|
||||
let password = '';
|
||||
for (let i = 0; i < 12; i++) {
|
||||
password += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
return password;
|
||||
}
|
||||
|
||||
showPasswordResetModal(userName, tempPassword) {
|
||||
const modalHtml = `
|
||||
<div id="password-reset-modal" class="fixed inset-0 bg-black/60 backdrop-blur-sm z-50 flex items-center justify-center p-4">
|
||||
<div class="bg-white dark:bg-slate-800 rounded-2xl p-8 max-w-md w-full shadow-2xl">
|
||||
<div class="text-center mb-6">
|
||||
<div class="w-16 h-16 bg-green-100 dark:bg-green-900/30 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||
<svg class="w-8 h-8 text-green-600 dark:text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 7a2 2 0 012 2m4 0a6 6 0 01-7.743 5.743L11 17H9v2H7v2H4a1 1 0 01-1-1v-2.586a1 1 0 01.293-.707l5.964-5.964A6 6 0 1121 9z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="text-2xl font-bold text-slate-900 dark:text-white">Passwort zurückgesetzt</h3>
|
||||
<p class="text-slate-600 dark:text-slate-400 mt-2">Neues temporäres Passwort für <strong>${userName}</strong></p>
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 dark:bg-slate-700 rounded-xl p-4 mb-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="font-mono text-lg font-bold text-slate-900 dark:text-white">${tempPassword}</div>
|
||||
<button onclick="navigator.clipboard.writeText('${tempPassword}'); this.innerHTML='✓ Kopiert'"
|
||||
class="px-3 py-1 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition-colors text-sm">
|
||||
Kopieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-xl p-4 mb-6">
|
||||
<p class="text-sm text-yellow-800 dark:text-yellow-200">
|
||||
<strong>Wichtig:</strong> Teilen Sie dieses Passwort sicher mit dem Benutzer mit und bitten Sie ihn, es sofort zu ändern.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button onclick="document.getElementById('password-reset-modal').remove()"
|
||||
class="w-full px-6 py-3 bg-green-500 text-white rounded-xl hover:bg-green-600 transition-colors font-medium">
|
||||
Verstanden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
document.body.insertAdjacentHTML('beforeend', modalHtml);
|
||||
}
|
||||
|
||||
async impersonateUser(userId, userName) {
|
||||
if (!confirm(`👤 Möchten Sie sich als "${userName}" anmelden?\n\nSie können jederzeit zur Admin-Ansicht zurückkehren.`)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Impersonation-API implementieren falls gewünscht
|
||||
this.showNotification('🚧 Impersonation-Feature wird implementiert...', 'info');
|
||||
} catch (error) {
|
||||
console.error('Fehler bei der Benutzer-Impersonation:', error);
|
||||
this.showNotification('❌ Fehler bei der Benutzer-Impersonation', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
editUser(userId) {
|
||||
console.log(`✏️ Benutzer ${userId} wird bearbeitet`);
|
||||
this.showUserModal(userId);
|
||||
|
Reference in New Issue
Block a user