482 lines
15 KiB
JavaScript
482 lines
15 KiB
JavaScript
/**
|
|
* Mercedes-Benz MYP Platform - Zentrale Event Handler
|
|
* CSP-konforme Event-Handler ohne Inline-JavaScript
|
|
*/
|
|
|
|
class GlobalEventManager {
|
|
constructor() {
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
// Event-Delegation für bessere Performance und CSP-Konformität
|
|
document.addEventListener('click', this.handleClick.bind(this));
|
|
document.addEventListener('DOMContentLoaded', this.setupEventListeners.bind(this));
|
|
|
|
// Falls DOM bereits geladen
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', this.setupEventListeners.bind(this));
|
|
} else {
|
|
this.setupEventListeners();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Zentrale Click-Handler mit Event-Delegation
|
|
*/
|
|
handleClick(event) {
|
|
const target = event.target.closest('[data-action]');
|
|
if (!target) return;
|
|
|
|
const action = target.getAttribute('data-action');
|
|
const params = this.parseActionParams(target);
|
|
|
|
event.preventDefault();
|
|
this.executeAction(action, params, target);
|
|
}
|
|
|
|
/**
|
|
* Action-Parameter aus data-Attributen parsen
|
|
*/
|
|
parseActionParams(element) {
|
|
const params = {};
|
|
|
|
// Alle data-action-* Attribute sammeln
|
|
for (const attr of element.attributes) {
|
|
if (attr.name.startsWith('data-action-')) {
|
|
const key = attr.name.replace('data-action-', '');
|
|
params[key] = attr.value;
|
|
}
|
|
}
|
|
|
|
return params;
|
|
}
|
|
|
|
/**
|
|
* Action ausführen basierend auf dem Action-Namen
|
|
*/
|
|
executeAction(action, params, element) {
|
|
console.log(`🎯 Führe Action aus: ${action}`, params);
|
|
|
|
switch (action) {
|
|
// Dashboard Actions
|
|
case 'refresh-dashboard':
|
|
if (typeof refreshDashboard === 'function') refreshDashboard();
|
|
break;
|
|
|
|
// Navigation Actions
|
|
case 'logout':
|
|
if (typeof handleLogout === 'function') handleLogout();
|
|
break;
|
|
|
|
case 'go-back':
|
|
window.history.back();
|
|
break;
|
|
|
|
case 'reload-page':
|
|
window.location.reload();
|
|
break;
|
|
|
|
case 'print-page':
|
|
window.print();
|
|
break;
|
|
|
|
// Job Management Actions
|
|
case 'refresh-jobs':
|
|
if (typeof refreshJobs === 'function') refreshJobs();
|
|
break;
|
|
|
|
case 'toggle-batch-mode':
|
|
if (typeof toggleBatchMode === 'function') toggleBatchMode();
|
|
break;
|
|
|
|
case 'start-job':
|
|
if (typeof jobManager !== 'undefined' && params.id) {
|
|
jobManager.startJob(params.id);
|
|
}
|
|
break;
|
|
|
|
case 'pause-job':
|
|
if (typeof jobManager !== 'undefined' && params.id) {
|
|
jobManager.pauseJob(params.id);
|
|
}
|
|
break;
|
|
|
|
case 'resume-job':
|
|
if (typeof jobManager !== 'undefined' && params.id) {
|
|
jobManager.resumeJob(params.id);
|
|
}
|
|
break;
|
|
|
|
case 'delete-job':
|
|
if (typeof jobManager !== 'undefined' && params.id) {
|
|
jobManager.deleteJob(params.id);
|
|
}
|
|
break;
|
|
|
|
case 'open-job-details':
|
|
if (typeof jobManager !== 'undefined' && params.id) {
|
|
jobManager.openJobDetails(params.id);
|
|
}
|
|
break;
|
|
|
|
// Printer Management Actions
|
|
case 'refresh-printers':
|
|
if (typeof refreshPrinters === 'function') refreshPrinters();
|
|
break;
|
|
|
|
case 'toggle-maintenance-mode':
|
|
if (typeof toggleMaintenanceMode === 'function') toggleMaintenanceMode();
|
|
break;
|
|
|
|
case 'open-add-printer-modal':
|
|
if (typeof openAddPrinterModal === 'function') openAddPrinterModal();
|
|
break;
|
|
|
|
case 'toggle-auto-refresh':
|
|
if (typeof toggleAutoRefresh === 'function') toggleAutoRefresh();
|
|
break;
|
|
|
|
case 'clear-all-filters':
|
|
if (typeof clearAllFilters === 'function') clearAllFilters();
|
|
break;
|
|
|
|
case 'test-printer-connection':
|
|
if (typeof testPrinterConnection === 'function') testPrinterConnection();
|
|
break;
|
|
|
|
case 'delete-printer':
|
|
if (typeof deletePrinter === 'function') deletePrinter();
|
|
break;
|
|
|
|
case 'edit-printer':
|
|
if (typeof printerManager !== 'undefined' && params.id) {
|
|
printerManager.editPrinter(params.id);
|
|
}
|
|
break;
|
|
|
|
case 'connect-printer':
|
|
if (typeof printerManager !== 'undefined' && params.id) {
|
|
printerManager.connectPrinter(params.id);
|
|
}
|
|
break;
|
|
|
|
// Calendar Actions
|
|
case 'refresh-calendar':
|
|
if (typeof refreshCalendar === 'function') refreshCalendar();
|
|
break;
|
|
|
|
case 'toggle-auto-optimization':
|
|
if (typeof toggleAutoOptimization === 'function') toggleAutoOptimization();
|
|
break;
|
|
|
|
case 'export-calendar':
|
|
if (typeof exportCalendar === 'function') exportCalendar();
|
|
break;
|
|
|
|
case 'open-create-event-modal':
|
|
if (typeof openCreateEventModal === 'function') openCreateEventModal();
|
|
break;
|
|
|
|
// Modal Actions
|
|
case 'close-modal':
|
|
this.closeModal(params.target || element.closest('.fixed'));
|
|
break;
|
|
|
|
case 'close-printer-modal':
|
|
if (typeof closePrinterModal === 'function') closePrinterModal();
|
|
break;
|
|
|
|
case 'close-job-modal':
|
|
if (typeof closeJobModal === 'function') closeJobModal();
|
|
break;
|
|
|
|
case 'close-event-modal':
|
|
if (typeof closeEventModal === 'function') closeEventModal();
|
|
break;
|
|
|
|
// Form Actions
|
|
case 'reset-form':
|
|
if (typeof resetForm === 'function') resetForm();
|
|
else this.resetNearestForm(element);
|
|
break;
|
|
|
|
case 'clear-file':
|
|
if (typeof clearFile === 'function') clearFile();
|
|
break;
|
|
|
|
// Guest Request Actions
|
|
case 'check-status':
|
|
if (typeof checkStatus === 'function') checkStatus();
|
|
break;
|
|
|
|
case 'copy-code':
|
|
if (typeof copyCode === 'function') copyCode();
|
|
break;
|
|
|
|
case 'refresh-status':
|
|
if (typeof refreshStatus === 'function') refreshStatus();
|
|
break;
|
|
|
|
case 'show-status-check':
|
|
if (typeof showStatusCheck === 'function') showStatusCheck();
|
|
break;
|
|
|
|
// Admin Actions
|
|
case 'perform-bulk-action':
|
|
if (typeof performBulkAction === 'function' && params.type) {
|
|
performBulkAction(params.type);
|
|
}
|
|
break;
|
|
|
|
case 'close-bulk-modal':
|
|
if (typeof closeBulkModal === 'function') closeBulkModal();
|
|
break;
|
|
|
|
case 'clear-cache':
|
|
if (typeof clearCache === 'function') clearCache();
|
|
break;
|
|
|
|
case 'optimize-database':
|
|
if (typeof optimizeDatabase === 'function') optimizeDatabase();
|
|
break;
|
|
|
|
case 'create-backup':
|
|
if (typeof createBackup === 'function') createBackup();
|
|
break;
|
|
|
|
case 'download-logs':
|
|
if (typeof downloadLogs === 'function') downloadLogs();
|
|
break;
|
|
|
|
case 'run-maintenance':
|
|
if (typeof runMaintenance === 'function') runMaintenance();
|
|
break;
|
|
|
|
case 'save-settings':
|
|
if (typeof saveSettings === 'function') saveSettings();
|
|
break;
|
|
|
|
// Profile Actions
|
|
case 'toggle-edit-mode':
|
|
if (typeof toggleEditMode === 'function') toggleEditMode();
|
|
break;
|
|
|
|
case 'trigger-avatar-upload':
|
|
if (typeof triggerAvatarUpload === 'function') triggerAvatarUpload();
|
|
break;
|
|
|
|
case 'cancel-edit':
|
|
if (typeof cancelEdit === 'function') cancelEdit();
|
|
break;
|
|
|
|
case 'download-user-data':
|
|
if (typeof downloadUserData === 'function') downloadUserData();
|
|
break;
|
|
|
|
// Stats Actions
|
|
case 'refresh-stats':
|
|
if (typeof refreshStats === 'function') refreshStats();
|
|
break;
|
|
|
|
case 'export-stats':
|
|
if (typeof exportStats === 'function') exportStats();
|
|
break;
|
|
|
|
// Generic Actions
|
|
case 'remove-element':
|
|
const targetElement = params.target ?
|
|
document.querySelector(params.target) :
|
|
element.closest(params.selector || '.removable');
|
|
if (targetElement) {
|
|
targetElement.remove();
|
|
}
|
|
break;
|
|
|
|
case 'toggle-element':
|
|
const toggleTarget = params.target ?
|
|
document.querySelector(params.target) :
|
|
element.nextElementSibling;
|
|
if (toggleTarget) {
|
|
toggleTarget.classList.toggle('hidden');
|
|
}
|
|
break;
|
|
|
|
case 'show-element':
|
|
const showTarget = document.querySelector(params.target);
|
|
if (showTarget) {
|
|
showTarget.classList.remove('hidden');
|
|
}
|
|
break;
|
|
|
|
case 'hide-element':
|
|
const hideTarget = document.querySelector(params.target);
|
|
if (hideTarget) {
|
|
hideTarget.classList.add('hidden');
|
|
}
|
|
break;
|
|
|
|
default:
|
|
console.warn(`⚠️ Unbekannte Action: ${action}`);
|
|
// Versuche globale Funktion zu finden
|
|
if (typeof window[action] === 'function') {
|
|
window[action](params);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generische Modal-Schließfunktion
|
|
*/
|
|
closeModal(modalElement) {
|
|
if (modalElement) {
|
|
modalElement.classList.add('hidden');
|
|
modalElement.remove();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Nächstes Formular zurücksetzen
|
|
*/
|
|
resetNearestForm(element) {
|
|
const form = element.closest('form');
|
|
if (form) {
|
|
form.reset();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Spezifische Event-Listener einrichten
|
|
*/
|
|
setupEventListeners() {
|
|
// Auto-Refresh für bestimmte Seiten
|
|
this.setupAutoRefresh();
|
|
|
|
// Keyboard Shortcuts
|
|
this.setupKeyboardShortcuts();
|
|
|
|
// Form Validierung
|
|
this.setupFormValidation();
|
|
|
|
console.log('🔧 Globale Event-Handler initialisiert');
|
|
}
|
|
|
|
/**
|
|
* Auto-Refresh für Dashboard/Jobs einrichten
|
|
*/
|
|
setupAutoRefresh() {
|
|
const currentPath = window.location.pathname;
|
|
|
|
// Auto-refresh für Dashboard alle 30 Sekunden
|
|
if (currentPath.includes('/dashboard')) {
|
|
setInterval(() => {
|
|
if (typeof refreshDashboard === 'function') {
|
|
refreshDashboard();
|
|
}
|
|
}, 30000);
|
|
}
|
|
|
|
// Auto-refresh für Jobs alle 15 Sekunden
|
|
if (currentPath.includes('/jobs')) {
|
|
setInterval(() => {
|
|
if (typeof refreshJobs === 'function') {
|
|
refreshJobs();
|
|
}
|
|
}, 15000);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Keyboard Shortcuts einrichten
|
|
*/
|
|
setupKeyboardShortcuts() {
|
|
document.addEventListener('keydown', (event) => {
|
|
// ESC zum Schließen von Modals
|
|
if (event.key === 'Escape') {
|
|
const openModal = document.querySelector('.fixed:not(.hidden)');
|
|
if (openModal) {
|
|
this.closeModal(openModal);
|
|
}
|
|
}
|
|
|
|
// Ctrl+R für Refresh (überschreiben für spezifische Funktionen)
|
|
if (event.ctrlKey && event.key === 'r') {
|
|
event.preventDefault();
|
|
const currentPath = window.location.pathname;
|
|
|
|
if (currentPath.includes('/dashboard') && typeof refreshDashboard === 'function') {
|
|
refreshDashboard();
|
|
} else if (currentPath.includes('/jobs') && typeof refreshJobs === 'function') {
|
|
refreshJobs();
|
|
} else if (currentPath.includes('/printers') && typeof refreshPrinters === 'function') {
|
|
refreshPrinters();
|
|
} else {
|
|
window.location.reload();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Form-Validierung einrichten
|
|
*/
|
|
setupFormValidation() {
|
|
// Alle Formulare finden und Validierung hinzufügen
|
|
const forms = document.querySelectorAll('form[data-validate]');
|
|
forms.forEach(form => {
|
|
form.addEventListener('submit', this.validateForm.bind(this));
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Formular validieren
|
|
*/
|
|
validateForm(event) {
|
|
const form = event.target;
|
|
const requiredFields = form.querySelectorAll('[required]');
|
|
let isValid = true;
|
|
|
|
requiredFields.forEach(field => {
|
|
if (!field.value.trim()) {
|
|
isValid = false;
|
|
field.classList.add('border-red-500');
|
|
|
|
// Fehlermeldung anzeigen
|
|
const errorId = `${field.id}-error`;
|
|
let errorElement = document.getElementById(errorId);
|
|
|
|
if (!errorElement) {
|
|
errorElement = document.createElement('div');
|
|
errorElement.id = errorId;
|
|
errorElement.className = 'text-red-500 text-sm mt-1';
|
|
field.parentNode.appendChild(errorElement);
|
|
}
|
|
|
|
errorElement.textContent = `${field.getAttribute('data-label') || 'Dieses Feld'} ist erforderlich.`;
|
|
} else {
|
|
field.classList.remove('border-red-500');
|
|
const errorElement = document.getElementById(`${field.id}-error`);
|
|
if (errorElement) {
|
|
errorElement.remove();
|
|
}
|
|
}
|
|
});
|
|
|
|
if (!isValid) {
|
|
event.preventDefault();
|
|
}
|
|
|
|
return isValid;
|
|
}
|
|
}
|
|
|
|
// Globale Instanz erstellen
|
|
const globalEventManager = new GlobalEventManager();
|
|
|
|
// Export für Module
|
|
if (typeof module !== 'undefined' && module.exports) {
|
|
module.exports = GlobalEventManager;
|
|
}
|
|
|
|
console.log('🌍 Globaler Event Manager geladen');
|