asdasd
This commit is contained in:
@@ -26,10 +26,14 @@ export function initEditor() {
|
|||||||
const sendInfo = document.getElementById('send_template_info');
|
const sendInfo = document.getElementById('send_template_info');
|
||||||
const btnCancelSend= document.getElementById('btn-cancel-send');
|
const btnCancelSend= document.getElementById('btn-cancel-send');
|
||||||
const btnSendNow = document.getElementById('btn-send-now');
|
const btnSendNow = document.getElementById('btn-send-now');
|
||||||
const sendSender = document.getElementById('send_sender');
|
const sendSender = document.getElementById('send_sender');
|
||||||
const sendSenderHint = document.getElementById('send_sender_hint');
|
const sendSenderHint = document.getElementById('send_sender_hint');
|
||||||
const prevFrame = document.getElementById('previewFrame');
|
const prevFrame = document.getElementById('previewFrame');
|
||||||
const btnPrevClose = document.getElementById('btn-close-preview');
|
const btnPrevClose = document.getElementById('btn-close-preview');
|
||||||
|
const unsavedDialog = document.getElementById('unsavedDialog');
|
||||||
|
const btnUnsavedCancel = document.getElementById('btn-unsaved-cancel');
|
||||||
|
const btnUnsavedDiscard = document.getElementById('btn-unsaved-discard');
|
||||||
|
const btnUnsavedSave = document.getElementById('btn-unsaved-save');
|
||||||
|
|
||||||
let current = null; // { resource, id, name, section }
|
let current = null; // { resource, id, name, section }
|
||||||
let bridgeListener = null;
|
let bridgeListener = null;
|
||||||
@@ -39,6 +43,7 @@ export function initEditor() {
|
|||||||
let currentEditorType = 'grapesjs';
|
let currentEditorType = 'grapesjs';
|
||||||
let versionItems = [];
|
let versionItems = [];
|
||||||
let savedSnapshot = '';
|
let savedSnapshot = '';
|
||||||
|
let lastVersionSelection = '';
|
||||||
|
|
||||||
const ok = (m) => toast(m, true);
|
const ok = (m) => toast(m, true);
|
||||||
const err = (m) => toast(m, false);
|
const err = (m) => toast(m, false);
|
||||||
@@ -153,16 +158,41 @@ export function initEditor() {
|
|||||||
return currentSnapshot !== savedSnapshot;
|
return currentSnapshot !== savedSnapshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showUnsavedDialog() {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
if (!unsavedDialog || typeof unsavedDialog.showModal !== 'function') {
|
||||||
|
resolve('discard');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const cleanup = () => {
|
||||||
|
btnUnsavedCancel && btnUnsavedCancel.removeEventListener('click', onCancel);
|
||||||
|
btnUnsavedDiscard && btnUnsavedDiscard.removeEventListener('click', onDiscard);
|
||||||
|
btnUnsavedSave && btnUnsavedSave.removeEventListener('click', onSave);
|
||||||
|
};
|
||||||
|
const closeWith = (choice) => {
|
||||||
|
cleanup();
|
||||||
|
unsavedDialog.close();
|
||||||
|
resolve(choice);
|
||||||
|
};
|
||||||
|
const onCancel = () => closeWith('cancel');
|
||||||
|
const onDiscard = () => closeWith('discard');
|
||||||
|
const onSave = () => closeWith('save');
|
||||||
|
btnUnsavedCancel && btnUnsavedCancel.addEventListener('click', onCancel);
|
||||||
|
btnUnsavedDiscard && btnUnsavedDiscard.addEventListener('click', onDiscard);
|
||||||
|
btnUnsavedSave && btnUnsavedSave.addEventListener('click', onSave);
|
||||||
|
unsavedDialog.showModal();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function confirmUnsavedChanges() {
|
async function confirmUnsavedChanges() {
|
||||||
const dirty = await hasUnsavedChanges();
|
const dirty = await hasUnsavedChanges();
|
||||||
if (!dirty) return true;
|
if (!dirty) return 'ok';
|
||||||
const shouldSave = window.confirm('Ungespeicherte Änderungen gefunden. Jetzt speichern?');
|
const choice = await showUnsavedDialog();
|
||||||
if (shouldSave) {
|
if (choice === 'save') {
|
||||||
const okSave = await save();
|
const okSave = await save();
|
||||||
if (!okSave) return false;
|
if (!okSave) return 'cancel';
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return true;
|
return choice;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderVersionOptions(items) {
|
function renderVersionOptions(items) {
|
||||||
@@ -187,6 +217,11 @@ export function initEditor() {
|
|||||||
opt.textContent = label;
|
opt.textContent = label;
|
||||||
versionSelect.appendChild(opt);
|
versionSelect.appendChild(opt);
|
||||||
});
|
});
|
||||||
|
if (lastVersionSelection) {
|
||||||
|
versionSelect.value = lastVersionSelection;
|
||||||
|
} else {
|
||||||
|
versionSelect.value = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadVersionsForCurrent() {
|
async function loadVersionsForCurrent() {
|
||||||
@@ -209,6 +244,7 @@ export function initEditor() {
|
|||||||
setEditorType(targetType);
|
setEditorType(targetType);
|
||||||
if (targetType === 'craftjs') {
|
if (targetType === 'craftjs') {
|
||||||
craftEditor?.setContent(data.html || '', data.craftJson || '');
|
craftEditor?.setContent(data.html || '', data.craftJson || '');
|
||||||
|
setSavedSnapshotFromData(payload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const editor = await waitForEditor(3000);
|
const editor = await waitForEditor(3000);
|
||||||
@@ -217,17 +253,18 @@ export function initEditor() {
|
|||||||
try {
|
try {
|
||||||
const project = JSON.parse(jsonRaw);
|
const project = JSON.parse(jsonRaw);
|
||||||
editor.loadProjectData(project);
|
editor.loadProjectData(project);
|
||||||
|
setSavedSnapshotFromData(payload);
|
||||||
return;
|
return;
|
||||||
} catch {}
|
} catch {}
|
||||||
}
|
}
|
||||||
const html = normalizeSnapshotValue(data.html);
|
const html = normalizeSnapshotValue(data.html);
|
||||||
editor.setComponents(html);
|
editor.setComponents(html);
|
||||||
|
setSavedSnapshotFromData(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function loadLatestContentFromServer() {
|
async function loadLatestContentFromServer() {
|
||||||
const res = await apiAction('content.get', { method: 'GET', data: { id: current.id, section_id: current.section.id } });
|
const res = await apiAction('content.get', { method: 'GET', data: { id: current.id, section_id: current.section.id } });
|
||||||
await applyVersionPayload(res || {});
|
await applyVersionPayload(res || {});
|
||||||
setSavedSnapshotFromData(res || {});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeHtmlToFrame(html) {
|
function writeHtmlToFrame(html) {
|
||||||
@@ -451,11 +488,11 @@ export function initEditor() {
|
|||||||
async function open(item, resource, sectionOverride) {
|
async function open(item, resource, sectionOverride) {
|
||||||
const section = item?.section || sectionOverride || window.__activeSection || null;
|
const section = item?.section || sectionOverride || window.__activeSection || null;
|
||||||
current = {
|
current = {
|
||||||
resource: 'content',
|
resource: 'content',
|
||||||
id: Number(item?.id || 0),
|
id: Number(item?.id || 0),
|
||||||
name: item?.name || '',
|
name: item?.name || '',
|
||||||
section: section,
|
section: section,
|
||||||
};
|
};
|
||||||
if (!current.id) return err('Ungültige ID');
|
if (!current.id) return err('Ungültige ID');
|
||||||
if (!current.section) return err('Section nicht gefunden');
|
if (!current.section) return err('Section nicht gefunden');
|
||||||
|
|
||||||
@@ -465,6 +502,8 @@ export function initEditor() {
|
|||||||
setSendContext(current.section?.is_template ? current.id : 0, current.name);
|
setSendContext(current.section?.is_template ? current.id : 0, current.name);
|
||||||
if (btnTest) btnTest.classList.toggle('hidden', !current.section?.is_template);
|
if (btnTest) btnTest.classList.toggle('hidden', !current.section?.is_template);
|
||||||
setVersionUiVisible(true);
|
setVersionUiVisible(true);
|
||||||
|
if (versionSelect) versionSelect.value = '';
|
||||||
|
lastVersionSelection = '';
|
||||||
|
|
||||||
// Neuen Token erzeugen & alten Listener entfernen
|
// Neuen Token erzeugen & alten Listener entfernen
|
||||||
reqToken++;
|
reqToken++;
|
||||||
@@ -699,8 +738,8 @@ export function initEditor() {
|
|||||||
function closePreview(){ prevDlg?.close?.(); }
|
function closePreview(){ prevDlg?.close?.(); }
|
||||||
|
|
||||||
async function close() {
|
async function close() {
|
||||||
const proceed = await confirmUnsavedChanges();
|
const decision = await confirmUnsavedChanges();
|
||||||
if (!proceed) return;
|
if (decision === 'cancel') return;
|
||||||
// nächstes Öffnen invalidiert laufende asyncs
|
// nächstes Öffnen invalidiert laufende asyncs
|
||||||
reqToken++;
|
reqToken++;
|
||||||
|
|
||||||
@@ -780,22 +819,26 @@ export function initEditor() {
|
|||||||
editorSelect && (editorSelect.onchange = () => switchEditor(editorSelect.value));
|
editorSelect && (editorSelect.onchange = () => switchEditor(editorSelect.value));
|
||||||
versionSelect && (versionSelect.onchange = async () => {
|
versionSelect && (versionSelect.onchange = async () => {
|
||||||
if (!current?.id) return;
|
if (!current?.id) return;
|
||||||
const proceed = await confirmUnsavedChanges();
|
const previousSelection = lastVersionSelection;
|
||||||
if (!proceed) {
|
const decision = await confirmUnsavedChanges();
|
||||||
versionSelect.value = '';
|
if (decision === 'cancel') {
|
||||||
|
versionSelect.value = previousSelection;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const versionId = Number(versionSelect.value || 0);
|
const versionId = Number(versionSelect.value || 0);
|
||||||
if (!versionId) {
|
if (!versionId) {
|
||||||
await loadLatestContentFromServer();
|
await loadLatestContentFromServer();
|
||||||
|
lastVersionSelection = '';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const res = await apiAction('content_versions.get', { method: 'GET', data: { id: versionId, content_id: current.id } });
|
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');
|
if (!res?.ok) throw new Error(res?.error || 'Version konnte nicht geladen werden');
|
||||||
await applyVersionPayload(res?.item || res);
|
await applyVersionPayload(res?.item || res);
|
||||||
|
lastVersionSelection = String(versionId);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err(e.message || 'Version konnte nicht geladen werden');
|
err(e.message || 'Version konnte nicht geladen werden');
|
||||||
|
versionSelect.value = previousSelection;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
btnRestoreVersion && (btnRestoreVersion.onclick = async () => {
|
btnRestoreVersion && (btnRestoreVersion.onclick = async () => {
|
||||||
|
|||||||
@@ -114,6 +114,18 @@ require __DIR__ . '/../partials/structure/layout_start.php';
|
|||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
|
||||||
|
<dialog id="unsavedDialog" class="rounded-2xl p-0 w-[440px]">
|
||||||
|
<div class="p-4 bg-white rounded-2xl space-y-4">
|
||||||
|
<h3 class="text-lg font-semibold">Ungespeicherte Änderungen</h3>
|
||||||
|
<p class="text-sm text-slate-600">Es gibt ungespeicherte Änderungen. Möchtest du diese speichern?</p>
|
||||||
|
<div class="flex justify-end gap-2">
|
||||||
|
<button type="button" id="btn-unsaved-cancel" class="btn">Abbrechen</button>
|
||||||
|
<button type="button" id="btn-unsaved-discard" class="btn">Nicht speichern</button>
|
||||||
|
<button type="button" id="btn-unsaved-save" class="btn">Speichern</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
<!-- Edit Snippet Dialog -->
|
<!-- Edit Snippet Dialog -->
|
||||||
<dialog id="editSnippetDialog" class="rounded-2xl p-0 w-[700px]">
|
<dialog id="editSnippetDialog" class="rounded-2xl p-0 w-[700px]">
|
||||||
<form id="editSnippetForm" method="dialog" class="p-4 bg-white rounded-2xl">
|
<form id="editSnippetForm" method="dialog" class="p-4 bg-white rounded-2xl">
|
||||||
|
|||||||
Reference in New Issue
Block a user