eadsd
This commit is contained in:
@@ -38,6 +38,7 @@ export function initEditor() {
|
|||||||
let senderLoadPromise = null;
|
let senderLoadPromise = null;
|
||||||
let currentEditorType = 'grapesjs';
|
let currentEditorType = 'grapesjs';
|
||||||
let versionItems = [];
|
let versionItems = [];
|
||||||
|
let savedSnapshot = '';
|
||||||
|
|
||||||
const ok = (m) => toast(m, true);
|
const ok = (m) => toast(m, true);
|
||||||
const err = (m) => toast(m, false);
|
const err = (m) => toast(m, false);
|
||||||
@@ -87,6 +88,83 @@ export function initEditor() {
|
|||||||
|
|
||||||
setVersionUiVisible(false);
|
setVersionUiVisible(false);
|
||||||
|
|
||||||
|
function normalizeSnapshotValue(value) {
|
||||||
|
return value === null || value === undefined ? '' : String(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildSnapshot({ editorType, html, json, craftJson }) {
|
||||||
|
return JSON.stringify({
|
||||||
|
editorType: normalizeSnapshotValue(editorType),
|
||||||
|
html: normalizeSnapshotValue(html),
|
||||||
|
json: normalizeSnapshotValue(json),
|
||||||
|
craftJson: normalizeSnapshotValue(craftJson),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractContentFields(payload = {}) {
|
||||||
|
const base = payload || {};
|
||||||
|
const item = base.item || {};
|
||||||
|
return {
|
||||||
|
html: base.html ?? base.html_content ?? item.html ?? item.html_content ?? '',
|
||||||
|
json: base.content ?? base.json_content ?? item.content ?? item.json_content ?? '',
|
||||||
|
craftJson: base.craft_json ?? item.craft_json ?? '',
|
||||||
|
editorType: String(base.editor_type ?? item.editor_type ?? currentEditorType ?? 'grapesjs').toLowerCase(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function buildCurrentSnapshot() {
|
||||||
|
if (currentEditorType === 'craftjs') {
|
||||||
|
return buildSnapshot({
|
||||||
|
editorType: 'craftjs',
|
||||||
|
html: craftEditor ? craftEditor.getContent() : '',
|
||||||
|
json: '',
|
||||||
|
craftJson: craftEditor && craftEditor.getCraftJson ? craftEditor.getCraftJson() : '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const editor = await waitForEditor(2000);
|
||||||
|
const win = iframe?.contentWindow;
|
||||||
|
const fontCss = win?.BridgeParts?.RTE_FONT_FACE_CSS || '';
|
||||||
|
const cssPayload = (fontCss ? fontCss + '\n' : '') + (editor.getCss() || '');
|
||||||
|
const htmlContent = (editor.getHtml() || '') + '<style>' + cssPayload + '</style>';
|
||||||
|
let jsonRaw = '';
|
||||||
|
try {
|
||||||
|
jsonRaw = JSON.stringify(editor.getProjectData());
|
||||||
|
} catch {}
|
||||||
|
return buildSnapshot({
|
||||||
|
editorType: 'grapesjs',
|
||||||
|
html: htmlContent,
|
||||||
|
json: jsonRaw,
|
||||||
|
craftJson: '',
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
return buildSnapshot({ editorType: currentEditorType, html: '', json: '', craftJson: '' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSavedSnapshotFromData(payload) {
|
||||||
|
const fields = extractContentFields(payload);
|
||||||
|
savedSnapshot = buildSnapshot(fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function hasUnsavedChanges() {
|
||||||
|
if (!savedSnapshot) return false;
|
||||||
|
const currentSnapshot = await buildCurrentSnapshot();
|
||||||
|
return currentSnapshot !== savedSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function confirmUnsavedChanges() {
|
||||||
|
const dirty = await hasUnsavedChanges();
|
||||||
|
if (!dirty) return true;
|
||||||
|
const shouldSave = window.confirm('Ungespeicherte Änderungen gefunden. Jetzt speichern?');
|
||||||
|
if (shouldSave) {
|
||||||
|
const okSave = await save();
|
||||||
|
if (!okSave) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function renderVersionOptions(items) {
|
function renderVersionOptions(items) {
|
||||||
versionItems = items || [];
|
versionItems = items || [];
|
||||||
if (!versionSelect) return;
|
if (!versionSelect) return;
|
||||||
@@ -125,6 +203,33 @@ export function initEditor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function applyVersionPayload(payload) {
|
||||||
|
const data = extractContentFields(payload);
|
||||||
|
const targetType = data.editorType === 'craftjs' ? 'craftjs' : 'grapesjs';
|
||||||
|
setEditorType(targetType);
|
||||||
|
if (targetType === 'craftjs') {
|
||||||
|
craftEditor?.setContent(data.html || '', data.craftJson || '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const editor = await waitForEditor(3000);
|
||||||
|
const jsonRaw = normalizeSnapshotValue(data.json).trim();
|
||||||
|
if (jsonRaw) {
|
||||||
|
try {
|
||||||
|
const project = JSON.parse(jsonRaw);
|
||||||
|
editor.loadProjectData(project);
|
||||||
|
return;
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
const html = normalizeSnapshotValue(data.html);
|
||||||
|
editor.setComponents(html);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadLatestContentFromServer() {
|
||||||
|
const res = await apiAction('content.get', { method: 'GET', data: { id: current.id, section_id: current.section.id } });
|
||||||
|
await applyVersionPayload(res || {});
|
||||||
|
setSavedSnapshotFromData(res || {});
|
||||||
|
}
|
||||||
|
|
||||||
function writeHtmlToFrame(html) {
|
function writeHtmlToFrame(html) {
|
||||||
iframe.srcdoc = `<!doctype html><html>
|
iframe.srcdoc = `<!doctype html><html>
|
||||||
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
|
<head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"></head>
|
||||||
@@ -404,6 +509,7 @@ export function initEditor() {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
editorType = editorType === 'craftjs' ? 'craftjs' : 'grapesjs';
|
editorType = editorType === 'craftjs' ? 'craftjs' : 'grapesjs';
|
||||||
|
setSavedSnapshotFromData({ html: fresh, content: jsonState, editor_type: editorType, craft_json: craftJson });
|
||||||
setEditorType(editorType);
|
setEditorType(editorType);
|
||||||
if (editorType === 'craftjs') {
|
if (editorType === 'craftjs') {
|
||||||
const craftHtml = extractCraftHtml(craftJson, fresh);
|
const craftHtml = extractCraftHtml(craftJson, fresh);
|
||||||
@@ -512,7 +618,15 @@ export function initEditor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const okSave = await delegateCommand('save-data');
|
const okSave = await delegateCommand('save-data');
|
||||||
if (okSave) setTimeout(loadVersionsForCurrent, 800);
|
if (okSave) {
|
||||||
|
setTimeout(async () => {
|
||||||
|
await loadVersionsForCurrent();
|
||||||
|
try {
|
||||||
|
const res = await apiAction('content.get', { method: 'GET', data: { id: current.id, section_id: current.section.id } });
|
||||||
|
setSavedSnapshotFromData(res || {});
|
||||||
|
} catch {}
|
||||||
|
}, 800);
|
||||||
|
}
|
||||||
return okSave;
|
return okSave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,9 +698,11 @@ export function initEditor() {
|
|||||||
}
|
}
|
||||||
function closePreview(){ prevDlg?.close?.(); }
|
function closePreview(){ prevDlg?.close?.(); }
|
||||||
|
|
||||||
function close() {
|
async function close() {
|
||||||
// nächstes Öffnen invalidiert laufende asyncs
|
const proceed = await confirmUnsavedChanges();
|
||||||
reqToken++;
|
if (!proceed) return;
|
||||||
|
// nächstes Öffnen invalidiert laufende asyncs
|
||||||
|
reqToken++;
|
||||||
|
|
||||||
try { iframe.contentWindow?.postMessage({source:'admin',type:'reset'}, '*'); } catch {}
|
try { iframe.contentWindow?.postMessage({source:'admin',type:'reset'}, '*'); } catch {}
|
||||||
if (bridgeListener) window.removeEventListener('message', bridgeListener);
|
if (bridgeListener) window.removeEventListener('message', bridgeListener);
|
||||||
@@ -662,6 +778,26 @@ export function initEditor() {
|
|||||||
btnCancelSend&& (btnCancelSend.onclick= closeSend);
|
btnCancelSend&& (btnCancelSend.onclick= closeSend);
|
||||||
sendForm && (sendForm.onsubmit = doSend);
|
sendForm && (sendForm.onsubmit = doSend);
|
||||||
editorSelect && (editorSelect.onchange = () => switchEditor(editorSelect.value));
|
editorSelect && (editorSelect.onchange = () => switchEditor(editorSelect.value));
|
||||||
|
versionSelect && (versionSelect.onchange = async () => {
|
||||||
|
if (!current?.id) return;
|
||||||
|
const proceed = await confirmUnsavedChanges();
|
||||||
|
if (!proceed) {
|
||||||
|
versionSelect.value = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const versionId = Number(versionSelect.value || 0);
|
||||||
|
if (!versionId) {
|
||||||
|
await loadLatestContentFromServer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const res = await apiAction('content_versions.get', { method: 'GET', data: { id: versionId, content_id: current.id } });
|
||||||
|
if (!res?.ok) throw new Error(res?.error || 'Version konnte nicht geladen werden');
|
||||||
|
await applyVersionPayload(res?.item || res);
|
||||||
|
} catch (e) {
|
||||||
|
err(e.message || 'Version konnte nicht geladen werden');
|
||||||
|
}
|
||||||
|
});
|
||||||
btnRestoreVersion && (btnRestoreVersion.onclick = async () => {
|
btnRestoreVersion && (btnRestoreVersion.onclick = async () => {
|
||||||
if (!current?.id) return;
|
if (!current?.id) return;
|
||||||
const versionId = Number(versionSelect?.value || 0);
|
const versionId = Number(versionSelect?.value || 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user