class ConfigForm { constructor() { this.form = null; this._submitHandlerAttached = false; } resetForm() { this.form = document.getElementById('config-form'); if (this.form) { this.form.reset(); } } snapshotOriginal() { const original = {}; const data = window.configData && window.configData.config; if (!data) return original; Object.entries(data).forEach(([key, entry]) => { original[key] = entry && entry.value !== undefined ? String(entry.value) : ''; }); return original; } collectChanges(original) { const changes = []; if (!this.form) return changes; const current = {}; const inputs = this.form.querySelectorAll('input, select, textarea'); inputs.forEach((input) => { const name = input.name; if (!name || !name.startsWith('CFG_')) return; if (name.endsWith('_PORT_MANAGER')) return; // UI-only aggregate let value; if (input.type === 'checkbox') { value = input.checked ? 'true' : 'false'; } else { value = (input.value || '').trim(); } current[name] = value; }); Object.keys(current).forEach((name) => { const oldValue = original[name] !== undefined ? original[name] : ''; const newValue = current[name]; if (oldValue === newValue) return; const encoded = newValue.replace(/\|/g, '%7C'); changes.push(`${name}=${encoded}`); }); return changes; } async saveConfig() { this.form = document.getElementById('config-form'); if (!this.form) { console.error('ConfigForm: Form not found'); return; } const original = this.snapshotOriginal(); const changes = this.collectChanges(original); if (changes.length === 0) { this.showNotification('No configuration changes to save.', 'info'); return; } const encoded = changes.join('|'); try { if (!window.tasksManager || !window.tasksManager.router) { throw new Error('Task system not available'); } const task = await window.tasksManager.router.routeAction('config_update', { changes: `'${encoded.replace(/'/g, "'\\''")}'` }); this.showNotification( `Saving ${changes.length} configuration change${changes.length === 1 ? '' : 's'}...`, 'success' ); if (task && window.librePortalSPA && typeof window.librePortalSPA.navigate === 'function') { setTimeout(() => window.librePortalSPA.navigate(`/tasks/all?task=${task.id}`), 400); } else if (task && window.navigateToRoute) { setTimeout(() => window.navigateToRoute(`tasks/all?task=${task.id}`), 400); } } catch (error) { console.error('ConfigForm: Error saving configuration:', error); this.showNotification('Failed to save configuration: ' + error.message, 'error'); } } // preventDefault stops the form from falling back to GET (which dumps every // CFG into the URL). attachSubmitHandler() { const form = document.getElementById('config-form'); if (!form) return; if (form.dataset.submitWired === '1') return; form.dataset.submitWired = '1'; form.addEventListener('submit', (event) => { event.preventDefault(); this.saveConfig(); }); } showNotification(message, type) { type = type || 'info'; if (window.notificationSystem) { window.notificationSystem.show(message, type); return; } const notification = document.createElement('div'); notification.className = 'notification notification-' + type; notification.textContent = message; document.body.appendChild(notification); setTimeout(() => { if (notification.parentNode) notification.parentNode.removeChild(notification); }, 5000); } } window.ConfigForm = ConfigForm;