update schema and so on

This commit is contained in:
2026-01-20 02:24:23 +01:00
parent da290a8ff8
commit e01c643683
5 changed files with 305 additions and 8 deletions

View File

@@ -14,6 +14,8 @@ export function initEditor() {
const btnClose = document.getElementById('btn-close');
const btnClear = document.getElementById('btn-clear-main');
const editorSelect = document.getElementById('editorTypeSelect');
const versionSelect = document.getElementById('versionSelect');
const btnRestoreVersion = document.getElementById('btn-restore-version');
const craftEditor = initCraftEditor();
  const prevDlg      = document.getElementById('previewDialog');
@@ -35,6 +37,7 @@ export function initEditor() {
let senderOptions = [];
let senderLoadPromise = null;
let currentEditorType = 'grapesjs';
let versionItems = [];
  const ok  = (m) => toast(m, true);
  const err = (m) => toast(m, false);
@@ -66,6 +69,56 @@ export function initEditor() {
}
}
function formatVersionDate(value) {
if (!value) return '';
try {
const date = new Date(value);
if (Number.isNaN(date.getTime())) return value;
return date.toLocaleString('de-DE');
} catch {
return value;
}
}
function setVersionUiVisible(show) {
if (versionSelect) versionSelect.classList.toggle('hidden', !show);
if (btnRestoreVersion) btnRestoreVersion.classList.toggle('hidden', !show);
}
setVersionUiVisible(false);
function renderVersionOptions(items) {
versionItems = items || [];
if (!versionSelect) return;
const rows = Array.isArray(versionItems) ? versionItems : [];
versionSelect.innerHTML = '<option value="">Letzte Versionen</option>';
if (!rows.length) {
versionSelect.disabled = true;
return;
}
versionSelect.disabled = false;
rows.forEach((item) => {
const opt = document.createElement('option');
const label = `#${item.version_no} ${formatVersionDate(item.created_at)}`;
opt.value = String(item.id);
opt.textContent = label;
versionSelect.appendChild(opt);
});
}
async function loadVersionsForCurrent() {
if (!current?.id || !current?.section?.is_template) {
renderVersionOptions([]);
return;
}
try {
const res = await apiAction('content_versions.list', { method: 'GET', data: { content_id: current.id } });
renderVersionOptions(Array.isArray(res?.items) ? res.items : []);
} catch {
renderVersionOptions([]);
}
}
  function writeHtmlToFrame(html) {
    iframe.srcdoc = `<!doctype html><html>
      <head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
@@ -286,7 +339,7 @@ export function initEditor() {
  // ---------- Öffnen ----------
async function open(item, resource, sectionOverride) {
const section = item?.section || sectionOverride || window.__activeSection || null;
    current = {
current = {
      resource: 'content',
      id: Number(item?.id || 0),
      name: item?.name || '',
@@ -297,9 +350,10 @@ export function initEditor() {
    // globaler Kontext
    window.__currentItemId    = current.id;
    window.__currentEditorCtx = { id: current.id, mode: current.section.slug, section: current.section };
    setSendContext(current.section?.is_template ? current.id : 0, current.name);
    if (btnTest) btnTest.classList.toggle('hidden', !current.section?.is_template);
window.__currentEditorCtx = { id: current.id, mode: current.section.slug, section: current.section };
setSendContext(current.section?.is_template ? current.id : 0, current.name);
if (btnTest) btnTest.classList.toggle('hidden', !current.section?.is_template);
setVersionUiVisible(!!current.section?.is_template);
    // Neuen Token erzeugen & alten Listener entfernen
    reqToken++;
@@ -339,7 +393,8 @@ export function initEditor() {
} catch {}
})(),
      (async() => { snippets = await buildSnippetsForContext(current); })(),
      (async() => { refLib   = await buildRefLibForContext(current); })()
      (async() => { refLib   = await buildRefLibForContext(current); })(),
(async() => { await loadVersionsForCurrent(); })()
    ]);
editorType = editorType === 'craftjs' ? 'craftjs' : 'grapesjs';
@@ -446,10 +501,13 @@ export function initEditor() {
const res = await apiUpdate('content', current.id, payload);
if (res?.ok) ok('Gespeichert');
else err(res?.error || 'Speichern fehlgeschlagen');
if (res?.ok) setTimeout(loadVersionsForCurrent, 300);
return res?.ok;
}
return delegateCommand('save-data');
const okSave = await delegateCommand('save-data');
if (okSave) setTimeout(loadVersionsForCurrent, 800);
return okSave;
}
  // ... (Der Rest der Funktionen bleibt unverändert) ...
@@ -598,6 +656,23 @@ export function initEditor() {
btnCancelSend&& (btnCancelSend.onclick= closeSend);
sendForm && (sendForm.onsubmit = doSend);
editorSelect && (editorSelect.onchange = () => switchEditor(editorSelect.value));
btnRestoreVersion && (btnRestoreVersion.onclick = async () => {
if (!current?.id || !current?.section?.is_template) return;
const versionId = Number(versionSelect?.value || 0);
if (!versionId) {
err('Bitte eine Version auswählen');
return;
}
if (!confirm('Version wiederherstellen? Der aktuelle Stand wird überschrieben.')) return;
try {
const res = await apiAction('content_versions.restore', { method: 'POST', data: { id: versionId, content_id: current.id } });
if (!res?.ok) throw new Error(res?.error || 'Wiederherstellen fehlgeschlagen');
ok('Version wiederhergestellt');
await open({ id: current.id, name: current.name, section: current.section }, null, current.section);
} catch (e) {
err(e.message || 'Wiederherstellen fehlgeschlagen');
}
});
window.AdminTestSend = window.AdminTestSend || {};
window.AdminTestSend.open = (opts = {}) => {

View File

@@ -58,6 +58,11 @@ require __DIR__ . '/../partials/structure/layout_start.php';
<option value="grapesjs">GrapesJS</option>
<option value="craftjs">Craft.js</option>
</select>
<label class="text-xs text-slate-600">Version</label>
<select id="versionSelect" class="input h-8 py-0 text-sm min-w-[200px]">
<option value="">Letzte Versionen</option>
</select>
<button id="btn-restore-version" type="button" class="btn">Wiederherstellen</button>
<button id="btn-clear-main" type="button" class="btn" title="Leeren">🧹</button>
<button id="btn-preview" type="button" class="btn">Vorschau</button>
<button id="btn-test" type="button" class="btn">Testversand</button>