diff --git a/js/nc_connector_edit_v2.js b/js/nc_connector_edit_v2.js index 8fbfd24..2d866bc 100644 --- a/js/nc_connector_edit_v2.js +++ b/js/nc_connector_edit_v2.js @@ -2,20 +2,16 @@ 'use strict'; function ready(callback) { - if (document.readyState === 'loading') { - document.addEventListener('DOMContentLoaded', function () { window.setTimeout(callback, 0); }); - } else { - window.setTimeout(callback, 0); - } + if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', callback); + else callback(); } ready(function () { var section = document.getElementById('nc-connector'); if (!section) return; - var pwgTokenInput = section.querySelector('input[name="pwg_token"]'); - var pwgToken = pwgTokenInput ? pwgTokenInput.value : ''; - var modeKey = 'bratonienNcWizardMode'; + var tokenInput = section.querySelector('input[name="pwg_token"]'); + var pwgToken = tokenInput ? tokenInput.value : ''; function escapeHtml(value) { return String(value == null ? '' : value).replace(/[&<>"']/g, function (c) { @@ -23,27 +19,9 @@ }); } - function setMode(value) { - try { sessionStorage.setItem(modeKey, value); } catch (e) {} - } - - function postForm(label, tool, id, mode) { - var form = document.createElement('form'); - form.method = 'post'; - form.style.display = 'inline'; - form.dataset.ncV2Action = tool; - form.innerHTML = '' - + '' - + ''; - if (mode) form.addEventListener('submit', function () { setMode(mode); }, true); - return form; - } - function loadConnection(id) { return fetch('plugins/bratonien_tools/nc-connector-edit-data.php?connection_id='+encodeURIComponent(id)+'&_='+Date.now(), { - credentials:'same-origin', - cache:'no-store', - headers:{'Accept':'application/json'} + credentials:'same-origin', cache:'no-store', headers:{'Accept':'application/json'} }).then(function (response) { return response.json().then(function (data) { if (!response.ok) throw new Error(data.error || ('HTTP '+response.status)); @@ -52,6 +30,16 @@ }); } + function createPostForm(label, tool, id) { + var form = document.createElement('form'); + form.method = 'post'; + form.style.display = 'inline'; + form.innerHTML = '' + + '' + + ''; + return form; + } + function dialog() { var node = document.getElementById('bratonien-nc-connection-edit-v2'); if (node) return node; @@ -60,11 +48,11 @@ node.className = 'bratonien-edit-dialog'; node.innerHTML = '
' + '
' - + '

Verbindung bearbeiten

Alle für diese Verbindung nötigen Zugänge werden hier gemeinsam gepflegt.

' - + '
' - + '
'; + + '

Verbindung bearbeiten

Die Einstellungen gelten nur für diese Verbindung.

' + + '' + + '
'; document.body.appendChild(node); - node.querySelector('[data-edit-v2-close]').addEventListener('click', function () { node.close(); }); + node.querySelector('[data-edit-close]').addEventListener('click', function () { node.close(); }); node.addEventListener('click', function (event) { if (event.target === node) node.close(); }); return node; } @@ -78,129 +66,68 @@ + ''; } - function clearValidation(form) { - [].slice.call(form.querySelectorAll('[aria-invalid="true"]')).forEach(function (field) { - field.removeAttribute('aria-invalid'); - field.style.borderColor = ''; - field.style.boxShadow = ''; - }); - [].slice.call(form.querySelectorAll('[data-edit-v2-field-error]')).forEach(function (node) { node.remove(); }); - var box = form.querySelector('[data-edit-v2-error-summary]'); - if (box) box.remove(); + function showError(form, data) { + var old = form.querySelector('[data-edit-error]'); + if (old) old.remove(); + var box = document.createElement('div'); + box.dataset.editError = '1'; + box.className = 'bratonien-main-cache__warning'; + box.style.margin = '0 0 1rem'; + box.textContent = (data && data.message) ? data.message : 'Die Verbindung konnte nicht gespeichert werden.'; + form.insertBefore(box, form.firstChild); } - function fieldNodes(form, fieldName) { - return [].slice.call(form.querySelectorAll('[name="'+fieldName.replace(/"/g, '\\"')+'"]')); - } - - function showValidation(form, data) { - clearValidation(form); - var message = (data && data.message) ? data.message : 'Die Verbindung konnte nicht gespeichert werden.'; - var summary = document.createElement('div'); - summary.dataset.editV2ErrorSummary = '1'; - summary.className = 'bratonien-main-cache__warning'; - summary.style.margin = '0 0 1rem'; - summary.style.padding = '.75rem'; - summary.style.border = '1px solid currentColor'; - summary.innerHTML = 'Speichern fehlgeschlagen: '+escapeHtml(message); - form.insertBefore(summary, form.firstChild); - - var first = null; - var fields = data && Array.isArray(data.fields) ? data.fields : []; - fields.forEach(function (fieldName) { - fieldNodes(form, fieldName).forEach(function (field) { - field.setAttribute('aria-invalid', 'true'); - field.style.borderColor = '#d65a5a'; - field.style.boxShadow = '0 0 0 1px #d65a5a'; - if (!first) first = field; - var note = document.createElement('span'); - note.dataset.editV2FieldError = '1'; - note.className = 'bratonien-main-cache__warning'; - note.style.display = 'block'; - note.style.marginTop = '.25rem'; - note.textContent = message; - field.insertAdjacentElement('afterend', note); - }); - }); - - if (first) { - first.scrollIntoView({block:'center', behavior:'smooth'}); - window.setTimeout(function () { first.focus(); }, 150); - } else { - summary.scrollIntoView({block:'center', behavior:'smooth'}); - } - } - - function submitEditor(form, editDialog) { - clearValidation(form); + function submitLocal(form, editDialog) { if (!form.reportValidity()) return; - - var submit = form.querySelector('button[type="submit"]'); - if (submit) submit.disabled = true; - - var body = new FormData(form); + var button = form.querySelector('button[type="submit"]'); + if (button) button.disabled = true; fetch('plugins/bratonien_tools/nc-connector-edit-save.php', { - method:'POST', - credentials:'same-origin', - cache:'no-store', - headers:{'Accept':'application/json'}, - body:body + method:'POST', credentials:'same-origin', cache:'no-store', headers:{'Accept':'application/json'}, body:new FormData(form) }).then(function (response) { return response.json().then(function (data) { - if (!response.ok || !data.ok) { - showValidation(form, data); - return; - } + if (!response.ok || !data.ok) { showError(form, data); return; } editDialog.close(); window.location.reload(); }); }).catch(function (error) { - showValidation(form, {message:error.message || String(error), fields:[]}); + showError(form, {message:error.message || String(error)}); }).finally(function () { - if (submit) submit.disabled = false; + if (button) button.disabled = false; }); } - function openEditor(id) { + function openLocalEditor(id) { var editDialog = dialog(); - var content = editDialog.querySelector('[data-edit-v2-content]'); + var content = editDialog.querySelector('[data-edit-content]'); content.innerHTML = '

Verbindung wird geladen …

'; if (typeof editDialog.showModal === 'function') editDialog.showModal(); else editDialog.setAttribute('open', 'open'); loadConnection(id).then(function (data) { - if (data.adapter !== 'local') throw new Error('Diese Ansicht ist für eine noch nicht migrierte Verbindung vorgesehen.'); + if (data.adapter !== 'local') throw new Error('Diese Verbindung wird über den WebDAV-Assistenten bearbeitet.'); var legacy = data.legacy || {}; var webdav = data.webdav || {}; var storages = Array.isArray(legacy.storages) ? legacy.storages : []; var rows = storages.map(storageRow).join('') || storageRow({}); - var migrationText = webdav.migration_ready - ? 'Bereit. Nextcloud-Zugang und ein gültiger Piwigo-Zugang sind vollständig gespeichert.' - : 'Noch nicht bereit. Es fehlen: '+escapeHtml((webdav.migration_missing || []).join(', ') || 'WebDAV-Zugangsdaten')+'.'; - content.innerHTML = '
' + content.innerHTML = '' + '' + '' + '
Verbindung
' + '' + '
' - + '
Nextcloud / WebDAV
' - + '

Diese Angaben bestimmen, auf welche Ordner diese Verbindung zugreifen darf.

' - + '
' - + '' + + '
Nextcloud
' + + '' + '' + '' + '
' - + '
Piwigo-Zugang
' - + '

Bevorzugt wird die API. Benutzername und Passwort können als Fallback verwendet werden.

' - + '
' + + '
Piwigo-Zugang
' + '' + '' + '' + '' + '
' - + '

WebDAV-Migration: '+migrationText+'

' - + '
Bestehender Legacy-Weg
' + + '
Lokaler Connector
' + '' + '' + '' @@ -209,7 +136,7 @@ + '
' + '
Speicherorte
'+rows+'
' + '' - + '
Erweiterte Legacy-Einstellungen
' + + '
Erweiterte Einstellungen
' + '' + '' + '' @@ -217,105 +144,61 @@ + '' + '' + '
' - + '
' + + '
' + ''; - var form = content.querySelector('[data-edit-v2-form]'); - form.querySelector('[data-edit-v2-cancel]').addEventListener('click', function () { editDialog.close(); }); + var form = content.querySelector('[data-edit-form]'); + form.querySelector('[data-cancel]').addEventListener('click', function () { editDialog.close(); }); form.querySelector('[data-add-storage]').addEventListener('click', function () { form.querySelector('[data-storage-list]').insertAdjacentHTML('beforeend', storageRow({})); }); form.addEventListener('click', function (event) { var remove = event.target.closest('[data-remove-storage]'); - if (!remove) return; - var row = remove.closest('[data-storage-row]'); - if (row) row.remove(); + if (remove) { + var row = remove.closest('[data-storage-row]'); + if (row) row.remove(); + } }); form.addEventListener('submit', function (event) { event.preventDefault(); - event.stopPropagation(); - submitEditor(form, editDialog); + submitLocal(form, editDialog); }); }).catch(function (error) { content.innerHTML = '

Bearbeiten nicht möglich: '+escapeHtml(error.message || String(error))+'

'; }); } - function rebuildLocalActions(deleteForm, id, connectionData) { - var actions = deleteForm.parentElement; - if (!actions) return; - - [].slice.call(actions.querySelectorAll('form')).forEach(function (form) { - var migrate = form.querySelector('button[value="nc_connector_migrate_start"]'); - var editStart = form.querySelector('button[value="nc_connector_edit_start"]'); - if (migrate || editStart) form.remove(); - }); - [].slice.call(actions.children).forEach(function (child) { - if (child.tagName === 'BUTTON' && (child.textContent || '').trim() === 'Bearbeiten') child.remove(); - if (child.dataset && child.dataset.ncMigrationInfo) child.remove(); - }); - - var edit = document.createElement('button'); - edit.type = 'button'; - edit.className = 'buttonLike'; - edit.textContent = 'Bearbeiten'; - edit.addEventListener('click', function () { openEditor(id); }); - actions.insertBefore(edit, deleteForm); - - var info = document.createElement('span'); - info.dataset.ncMigrationInfo = '1'; - info.className = 'bratonien-base-note'; - info.textContent = 'WebDAV-Migration wird geprüft …'; - actions.insertBefore(info, deleteForm); - - var dataPromise = connectionData ? Promise.resolve(connectionData) : loadConnection(id); - dataPromise.then(function (data) { - var webdav = data.webdav || {}; - if (webdav.migration_ready) { - info.remove(); - actions.insertBefore(postForm('Auf WebDAV migrieren', 'nc_connector_migrate_start', id, 'migrate'), deleteForm); - } else { - var missing = (webdav.migration_missing || []).join(', '); - info.textContent = 'Migration noch nicht bereit: '+(missing || 'Zugangsdaten fehlen')+'. Zuerst „Bearbeiten“.'; - } - }).catch(function (error) { - info.textContent = 'Migration kann nicht geprüft werden: '+(error.message || String(error)); - }); - } - - function rebuildRemoteActions(deleteForm, id) { - var actions = deleteForm.parentElement; - if (!actions) return; - [].slice.call(actions.querySelectorAll('form')).forEach(function (form) { - var oldEdit = form.querySelector('button[value="nc_connector_edit_start"]'); - var oldMigrate = form.querySelector('button[value="nc_connector_migrate_start"]'); - if (oldEdit || oldMigrate) form.remove(); - }); - [].slice.call(actions.children).forEach(function (child) { - if (child.tagName === 'BUTTON' && (child.textContent || '').trim() === 'Bearbeiten') child.remove(); - if (child.dataset && child.dataset.ncMigrationInfo) child.remove(); - }); - actions.insertBefore(postForm('Bearbeiten', 'nc_connector_edit_start', id, 'edit'), deleteForm); - } - [].slice.call(section.querySelectorAll('button[value="nc_connector_edit_start"]')).forEach(function (button) { var form = button.closest('form'); if (form) form.remove(); }); + [].slice.call(section.querySelectorAll('button[value="nc_connector_migrate_start"]')).forEach(function (button) { + var form = button.closest('form'); + if (form) form.remove(); + }); + [].slice.call(section.querySelectorAll('button[value="nc_connector_delete"]')).forEach(function (deleteButton) { var deleteForm = deleteButton.closest('form'); - if (!deleteForm) return; + if (!deleteForm || !deleteForm.parentElement) return; var idInput = deleteForm.querySelector('input[name="connection_id"]'); if (!idInput) return; var id = idInput.value; + var actions = deleteForm.parentElement; loadConnection(id).then(function (data) { - if (data.adapter === 'local') rebuildLocalActions(deleteForm, id, data); - else rebuildRemoteActions(deleteForm, id); + var edit; + if (data.adapter === 'local') { + edit = document.createElement('button'); + edit.type = 'button'; + edit.className = 'buttonLike'; + edit.textContent = 'Bearbeiten'; + edit.addEventListener('click', function () { openLocalEditor(id); }); + } else { + edit = createPostForm('Bearbeiten', 'nc_connector_edit_start', id); + } + actions.insertBefore(edit, deleteForm); }).catch(function (error) { - var actions = deleteForm.parentElement; - if (!actions) return; var info = document.createElement('span'); info.className = 'bratonien-main-cache__warning'; info.textContent = 'Verbindung konnte nicht geladen werden: '+(error.message || String(error));