Loading editor/html/index.html +5 −0 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ <button id="btn-settings-open-connmgr" class="set-save-btn" data-i18n="I18N_OPEN_CONN_MANAGER">Verbindungsmanager öffnen</button> </div> </div> <!-- Plugin settings section (loaded dynamically) --> <div id="settings-plugin" class="set-section" style="display:none"> <div id="settings-plugin-content"></div> </div> </div> </div> <div class="dialog-actions"> Loading editor/html/js/api.js +33 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,26 @@ var EditorApi = (function() { }); } function requestAjax(method, url, body, contentType) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url.replace(/^\//, ''), true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); if (contentType) xhr.setRequestHeader('Content-Type', contentType); xhr.onreadystatechange = function() { if (xhr.readyState !== 4) return; if (xhr.status === 401) { window.location.href = 'login.html'; return; } if (xhr.status >= 200 && xhr.status < 300) { try { resolve(JSON.parse(xhr.responseText)); } catch(e) { resolve(xhr.responseText); } } else { try { reject(JSON.parse(xhr.responseText)); } catch(e) { reject({error: xhr.statusText || 'Request failed'}); } } }; xhr.onerror = function() { reject({error: 'Network error'}); }; xhr.send(body || null); }); } function requestCancellable(method, url, data) { var xhr = new XMLHttpRequest(); var promise = new Promise(function(resolve, reject) { Loading Loading @@ -420,6 +440,19 @@ var EditorApi = (function() { publishSurvey: function(surveyId, connId) { return request('POST', '/api/survey/publish', { survey_id: surveyId, conn_id: connId }); }, // Plugin settings (served by the backend settings router via AJAX) getPluginSettingsNav: function() { return requestAjax('GET', 'settings/api/nav'); }, getPluginSettingsForm: function(pluginId) { return requestAjax('GET', 'settings/' + encodeURIComponent(pluginId)); }, postPluginSettingsForm: function(actionUrl, formDataStr) { return requestAjax('POST', actionUrl, formDataStr, 'application/x-www-form-urlencoded'); } }; })(); editor/html/js/editor.js +64 −0 Original line number Diff line number Diff line Loading @@ -1068,9 +1068,73 @@ document.getElementById('settings-ai-apikey').value = resp.api_key || ''; document.getElementById('settings-ai-status').textContent = ''; }); // Load plugin settings nav items var nav = document.querySelector('#settings-dialog .set-nav'); // Remove previously added plugin nav items var oldPluginItems = nav.querySelectorAll('.set-nav-item[data-plugin]'); for (var i = 0; i < oldPluginItems.length; i++) oldPluginItems[i].remove(); EditorApi.getPluginSettingsNav().then(function(resp) { var items = resp.nav || []; items.forEach(function(item) { var li = document.createElement('li'); li.className = 'set-nav-item'; li.setAttribute('data-section', 'plugin'); li.setAttribute('data-plugin', item.id); li.textContent = item.name; li.addEventListener('click', function() { var allItems = document.querySelectorAll('#settings-dialog .set-nav-item'); for (var j = 0; j < allItems.length; j++) allItems[j].classList.remove('active'); li.classList.add('active'); var sections = document.querySelectorAll('#settings-dialog .set-section'); for (var k = 0; k < sections.length; k++) sections[k].style.display = 'none'; document.getElementById('settings-plugin').style.display = 'block'; loadPluginSettingsSection(item.id); }); nav.appendChild(li); }); }).catch(function() {}); document.getElementById('settings-dialog').showModal(); } function loadPluginSettingsSection(pluginId) { var contentEl = document.getElementById('settings-plugin-content'); contentEl.innerHTML = '<p class="hint">Lade...</p>'; EditorApi.getPluginSettingsForm(pluginId).then(function(resp) { contentEl.innerHTML = resp.html || ''; var form = contentEl.querySelector('form'); if (form) setupPluginFormSubmit(form, pluginId); }).catch(function(err) { contentEl.innerHTML = '<p class="set-status error">Fehler beim Laden: ' + (err.error || '') + '</p>'; }); } function setupPluginFormSubmit(form, pluginId) { form.addEventListener('submit', function(e) { e.preventDefault(); var actionUrl = form.getAttribute('action') || ('settings/' + pluginId); var params = []; var elements = form.elements; for (var i = 0; i < elements.length; i++) { var el = elements[i]; if (!el.name || el.disabled) continue; if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) continue; params.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value)); } var contentEl = document.getElementById('settings-plugin-content'); EditorApi.postPluginSettingsForm(actionUrl, params.join('&')).then(function(resp) { contentEl.innerHTML = resp.html || ''; var newForm = contentEl.querySelector('form'); if (newForm) setupPluginFormSubmit(newForm, pluginId); }).catch(function(err) { contentEl.innerHTML = '<p class="set-status error">Fehler: ' + (err.error || '') + '</p>'; }); }); } function bindSettingsDialog() { document.getElementById('btn-settings-close').addEventListener('click', function() { document.getElementById('settings-dialog').close(); Loading Loading
editor/html/index.html +5 −0 Original line number Diff line number Diff line Loading @@ -380,6 +380,11 @@ <button id="btn-settings-open-connmgr" class="set-save-btn" data-i18n="I18N_OPEN_CONN_MANAGER">Verbindungsmanager öffnen</button> </div> </div> <!-- Plugin settings section (loaded dynamically) --> <div id="settings-plugin" class="set-section" style="display:none"> <div id="settings-plugin-content"></div> </div> </div> </div> <div class="dialog-actions"> Loading
editor/html/js/api.js +33 −0 Original line number Diff line number Diff line Loading @@ -46,6 +46,26 @@ var EditorApi = (function() { }); } function requestAjax(method, url, body, contentType) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url.replace(/^\//, ''), true); xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); if (contentType) xhr.setRequestHeader('Content-Type', contentType); xhr.onreadystatechange = function() { if (xhr.readyState !== 4) return; if (xhr.status === 401) { window.location.href = 'login.html'; return; } if (xhr.status >= 200 && xhr.status < 300) { try { resolve(JSON.parse(xhr.responseText)); } catch(e) { resolve(xhr.responseText); } } else { try { reject(JSON.parse(xhr.responseText)); } catch(e) { reject({error: xhr.statusText || 'Request failed'}); } } }; xhr.onerror = function() { reject({error: 'Network error'}); }; xhr.send(body || null); }); } function requestCancellable(method, url, data) { var xhr = new XMLHttpRequest(); var promise = new Promise(function(resolve, reject) { Loading Loading @@ -420,6 +440,19 @@ var EditorApi = (function() { publishSurvey: function(surveyId, connId) { return request('POST', '/api/survey/publish', { survey_id: surveyId, conn_id: connId }); }, // Plugin settings (served by the backend settings router via AJAX) getPluginSettingsNav: function() { return requestAjax('GET', 'settings/api/nav'); }, getPluginSettingsForm: function(pluginId) { return requestAjax('GET', 'settings/' + encodeURIComponent(pluginId)); }, postPluginSettingsForm: function(actionUrl, formDataStr) { return requestAjax('POST', actionUrl, formDataStr, 'application/x-www-form-urlencoded'); } }; })();
editor/html/js/editor.js +64 −0 Original line number Diff line number Diff line Loading @@ -1068,9 +1068,73 @@ document.getElementById('settings-ai-apikey').value = resp.api_key || ''; document.getElementById('settings-ai-status').textContent = ''; }); // Load plugin settings nav items var nav = document.querySelector('#settings-dialog .set-nav'); // Remove previously added plugin nav items var oldPluginItems = nav.querySelectorAll('.set-nav-item[data-plugin]'); for (var i = 0; i < oldPluginItems.length; i++) oldPluginItems[i].remove(); EditorApi.getPluginSettingsNav().then(function(resp) { var items = resp.nav || []; items.forEach(function(item) { var li = document.createElement('li'); li.className = 'set-nav-item'; li.setAttribute('data-section', 'plugin'); li.setAttribute('data-plugin', item.id); li.textContent = item.name; li.addEventListener('click', function() { var allItems = document.querySelectorAll('#settings-dialog .set-nav-item'); for (var j = 0; j < allItems.length; j++) allItems[j].classList.remove('active'); li.classList.add('active'); var sections = document.querySelectorAll('#settings-dialog .set-section'); for (var k = 0; k < sections.length; k++) sections[k].style.display = 'none'; document.getElementById('settings-plugin').style.display = 'block'; loadPluginSettingsSection(item.id); }); nav.appendChild(li); }); }).catch(function() {}); document.getElementById('settings-dialog').showModal(); } function loadPluginSettingsSection(pluginId) { var contentEl = document.getElementById('settings-plugin-content'); contentEl.innerHTML = '<p class="hint">Lade...</p>'; EditorApi.getPluginSettingsForm(pluginId).then(function(resp) { contentEl.innerHTML = resp.html || ''; var form = contentEl.querySelector('form'); if (form) setupPluginFormSubmit(form, pluginId); }).catch(function(err) { contentEl.innerHTML = '<p class="set-status error">Fehler beim Laden: ' + (err.error || '') + '</p>'; }); } function setupPluginFormSubmit(form, pluginId) { form.addEventListener('submit', function(e) { e.preventDefault(); var actionUrl = form.getAttribute('action') || ('settings/' + pluginId); var params = []; var elements = form.elements; for (var i = 0; i < elements.length; i++) { var el = elements[i]; if (!el.name || el.disabled) continue; if ((el.type === 'checkbox' || el.type === 'radio') && !el.checked) continue; params.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value)); } var contentEl = document.getElementById('settings-plugin-content'); EditorApi.postPluginSettingsForm(actionUrl, params.join('&')).then(function(resp) { contentEl.innerHTML = resp.html || ''; var newForm = contentEl.querySelector('form'); if (newForm) setupPluginFormSubmit(newForm, pluginId); }).catch(function(err) { contentEl.innerHTML = '<p class="set-status error">Fehler: ' + (err.error || '') + '</p>'; }); }); } function bindSettingsDialog() { document.getElementById('btn-settings-close').addEventListener('click', function() { document.getElementById('settings-dialog').close(); Loading