import { apiList, apiGet, apiDelete, apiUpdate, toast } from './api.js';
function formatUsage(usage){
if (!usage || !usage.total) return '';
const parts=[];
if (usage.templates) parts.push(`${usage.templates} Template${usage.templates!==1?'s':''}`);
if (usage.sections) parts.push(`${usage.sections} Section${usage.sections!==1?'s':''}`);
if (usage.blocks) parts.push(`${usage.blocks} Block${usage.blocks!==1?'s':''}`);
if (usage.snippets) parts.push(`${usage.snippets} Snippet${usage.snippets!==1?'s':''}`);
if (!parts.length) return '';
return `
Dieses Element wird aktuell verwendet in: ${parts.join(', ')}.
Das Löschen entfernt diese Referenzen.
`;
}
function esc(s=''){
return String(s)
.replace(/&/g,'&')
.replace(//g,'>')
.replace(/"/g,'"')
.replace(/'/g,''');
}
async function openSnippetEditor(id){
const dlg = document.getElementById('editSnippetDialog');
const form = document.getElementById('editSnippetForm');
const inpName = document.getElementById('edit_snip_name');
const taContent = document.getElementById('edit_snip_content');
const btnCancel = document.getElementById('editSnippetCancel');
// Daten laden
let resp = {};
try { resp = await apiGet('snippets', id) || {}; } catch(e){}
const row = resp?.item || resp?.data || resp || {};
const contentValue = resp?.content ?? row.content ?? '';
if (inpName) inpName.value = row.name || '';
if (taContent) taContent.value = contentValue;
function cleanup(){
form && form.removeEventListener('submit', onSubmit);
btnCancel && (btnCancel.onclick = null);
}
async function onSubmit(ev){
ev.preventDefault();
try{
const res = await apiUpdate('snippets', id, {
name: inpName ? inpName.value : '',
content: taContent ? taContent.value : ''
});
toast(res && res.ok ? 'Snippet gespeichert' : 'Speichern fehlgeschlagen', !!(res && res.ok));
dlg && dlg.close();
cleanup();
// Liste neu laden
loadList('snippets');
}catch(e){
toast('Speichern fehlgeschlagen', false);
}
}
if (form) form.addEventListener('submit', onSubmit, { once:false });
if (btnCancel) btnCancel.onclick = () => { dlg && dlg.close(); cleanup(); };
dlg && dlg.showModal();
}
export async function loadList(resource){
const el=document.getElementById(`view-${resource}`); if(!el) return;
el.innerHTML=`
${resource.charAt(0).toUpperCase()+resource.slice(1)}
Lade …
`;
const data=await apiList(resource);
const list=el.querySelector(`#list-${resource}`);
if(!Array.isArray(data)||data.length===0){
list.innerHTML=`Keine Einträge
`;
return;
}
function parentBadge(r,it){
if(r==='sections'&&it.template_id) return ` Template #${it.template_id}${it.template_name ? ' · '+esc(it.template_name) : ''}`;
if(r==='blocks'&&it.section_id) return ` Section #${it.section_id}${it.section_name ? ' · '+esc(it.section_name) : ''}`;
if(r==='snippets'&&it.block_id) return ` Block #${it.block_id}${it.block_name ? ' · '+esc(it.block_name) : ''}`;
return ' frei';
}
list.innerHTML=data.map(item=>{
const name = esc(item.name||'');
const openBtn = (['templates','sections','blocks'].includes(resource))
? `` : '';
const editBtn = (resource==='snippets')
? `` : '';
const testBtn = resource==='templates'
? `` : '';
const prevBtn = ``;
const delBtn = ``;
return `
${name || '(ohne Name)'}
#${item.id}
${parentBadge(resource,item)}
${[openBtn, editBtn, testBtn, prevBtn, delBtn].filter(Boolean).join('')}
`;
}).join('');
// --- Editor öffnen (ANPASSUNG) -----------------------------------------
list.querySelectorAll('[data-open]').forEach(b=>b.addEventListener('click', async ()=>{
const [res,id]=b.dataset.open.split(':');
// Detail laden, um Name + aktuellen HTML/Content zu haben
const obj = await apiGet(res,id);
const name = obj?.name || '';
const html = obj ? (obj.html ?? obj.content ?? '') : '';
// Globale Kontexte (werden von Editor/anderen Modulen genutzt)
window.__currentItemId = Number(id);
window.__currentEditorCtx = { id:Number(id), mode:res };
// Bevorzugt EditorUI.open nutzen; Fallback: __openEditor (Bestand)
if (window.EditorUI && typeof window.EditorUI.open === 'function') {
window.EditorUI.open({ id:Number(id), name, html }, res);
} else if (window.__openEditor) {
window.__openEditor({ resource:res, id:Number(id), name, html });
} else {
console.warn('Kein Editor-Entry-Point gefunden (EditorUI.open / __openEditor).');
toast('Editor ist nicht initialisiert.', false);
}
}));
// -----------------------------------------------------------------------
// edit snippet
list.querySelectorAll('[data-edit]').forEach(b=>b.addEventListener('click', async ()=>{
const [, id] = b.dataset.edit.split(':');
await openSnippetEditor(id);
}));
// preview
const prevDlg=document.getElementById('previewDialog'), prevFrame=document.getElementById('previewFrame');
list.querySelectorAll('[data-preview]').forEach(b=>b.addEventListener('click', async ()=>{
const [res,id]=b.dataset.preview.split(':');
const obj=await apiGet(res,id);
const html=(obj?.html||obj?.content||'(leer)'+html+'';
prevDlg.showModal();
}));
// test send (templates only)
list.querySelectorAll('[data-test]').forEach(b=>b.addEventListener('click', ()=>{
const id = Number(b.dataset.test || '0');
const nm = b.dataset.name || '';
if (!id) {
toast('Testversand: Ungültige ID', false);
return;
}
if (window.AdminTestSend && typeof window.AdminTestSend.open === 'function') {
window.AdminTestSend.open({ id, name: nm });
} else {
toast('Testversand ist aktuell nicht verfügbar.', false);
}
}));
// delete
const delDlg=document.getElementById('deleteDialog'),
delText=document.getElementById('deleteText'),
delForm=document.getElementById('deleteForm'),
delCancel=document.getElementById('deleteCancel');
let pending=null;
delCancel && (delCancel.onclick=()=>{pending=null;delDlg.close();});
list.querySelectorAll('[data-del]').forEach(b=>b.addEventListener('click', async ()=>{
const [res,id]=b.dataset.del.split(':'); const nm=b.dataset.name||'';
let usage = null;
try {
const detail = await apiGet(res, id);
usage = detail?.usage || null;
} catch {}
pending={res,id,nm,usage};
const usageWarn = formatUsage(usage);
delText && (delText.innerHTML=`Soll ${nm || '(ohne Name)'} #${id} aus ${res} wirklich gelöscht werden?
Achtung: Kinder-Elemente werden nicht automatisch mit gelöscht.${usageWarn}`);
delDlg.showModal();
}));
delForm && (delForm.onsubmit=async(e)=>{
e.preventDefault();
if(!pending) return delDlg.close();
const r=await apiDelete(pending.res,pending.id);
delDlg.close();
toast(r&&r.ok?'Gelöscht':'Löschen fehlgeschlagen', !!(r&&r.ok), {duration:3000});
loadList(resource);
});
}
export function initLists(){
loadList('templates');
// Public reload helper (wird vom Snippet-Editor genutzt)
window.__reloadList = loadList;
// Backwards compat (falls woanders genutzt)
window.loadList = loadList;
}