Files
emailtemplate.it/public/assets/js/bridge/refs.js
2026-02-09 01:38:39 +01:00

167 lines
7.2 KiB
JavaScript
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* /assets/js/bridge/refs.js — Referenzen & Custom Fix/Flex (FINAL KORRIGIERT: Snippet Cleanup) */
(function (w) {
  var B = w.BridgeParts = w.BridgeParts || {};
  if (!B.CATEGORY_CONFIG) B.CATEGORY_CONFIG = {}; 
  /* ---------- Basis-Konfig (unverändert) ---------- */
  var SHOW_SNIPPETS_IN_FIX_DEFAULT = false;
  var MODE = (window.__editorMode || 'templates').toLowerCase();
  /* ---------- Hilfs-UI (unverändert) ---------- */
  B.editorRefPlaceholder = function (type, id, name) {
    var safe = (name || '').replace(/[<>&"]/g, '');
    return {
      html:
        '<div data-ref-type="' + type + '" data-ref-id="' + id + '" data-ref-name="' + safe + '" ' +
        'style="border:1px dashed #94a3b8;padding:8px;border-radius:6px;background:#f8fafc;margin:8px 0;">' +
        '<strong style="font:600 12px system-ui,Arial">Ref: ' + type + ' #' + id + '</strong>' +
        '<div style="font:12px system-ui,Arial;opacity:.8">' + safe + '</div>' +
        '</div>'
    };
  };
  /* ---------- Loader (REST) (unverändert) ---------- */
  async function jsonList(url){
    try{
      var res = await fetch(url, { credentials:'same-origin', cache:'no-store' });
      var data = await res.json();
      return data && data.items ? data.items : (Array.isArray(data) ? data : []);
    }catch(e){ return []; }
  }
  B.fetchTemplates = async function(){ 
    var rows = await jsonList('../api.php?action=templates.list&t='+Date.now());
    return rows.map(r => ({ id:r.id, name:r.name }));
  };
  B.fetchTemplateFull = async function (id) {
    try {
      var url = '../api.php?action=templates.get&id=' + encodeURIComponent(id) + '&t=' + Date.now();
      var res = await fetch(url, { credentials: 'same-origin', cache: 'no-store' });
      var data = await res.json();
      var it = data && (data.item || data);
      return (it && (it.html || it.content)) ? (it.html || it.content) : '';
    } catch (e) { return ''; }
  };
  B.fetchSections = async function(){
    var rows = await jsonList('../api.php?action=sections.list&t='+Date.now());
    return rows.map(r => ({ id:r.id, name:r.name, html:r.html || '' }));
  };
  B.fetchBlocks = async function(){
    var rows = await jsonList('../api.php?action=blocks.list&t='+Date.now());
    return rows.map(r => ({ id:r.id, name:r.name, html:r.html || '' }));
  };
  B.fetchSnippets = async function(){
    var rows = await jsonList('../api.php?action=snippets.list&t='+Date.now());
    return rows.map(r => ({ id:r.id, name:r.name, html:r.html || r.content || '' }));
  };
  /* ---------- lokale Helfer (unverändert) ---------- */
  function addOnce(bm, id, def){
    if (!id || typeof id !== 'string') return;
    try{ if (bm.get && bm.get(id)) return; bm.add(id, def); }catch{}
  }
  function removeByPrefix(bm, prefix){
    try{
      var all = (bm.getAll && bm.getAll()) || [];
      (all.models || all).forEach(function(b){
        if (!b) return;
        var id = (b.get && b.get('id')) || b.id || '';
        if (id && String(id).startsWith(prefix)) {
          try{ bm.remove(id); }catch{}
        }
      });
    }catch{}
  }
  /* ---------- Referenzbibliothek (lib-*) (angepasst: Zuweisung zu 'custom') ---------- */
  B.addReferenceLibrary = function (ed, payload) {
    payload = payload || {};
    var templates = payload.templates || [];
    var sections  = payload.sections  || [];
    var blocks    = payload.blocks    || [];
// Aggressive Bereinigung aller lib-tpl-ref-* Blöcke
removeByPrefix(ed.BlockManager, 'lib-tpl-ref-');
    var bm = ed.BlockManager;
    if (B._ensureCategories) B._ensureCategories(bm); // Stellt sicher, dass die Hauptkategorien existieren
    // Explizite Kategorie-Definitionen
    var cat_templates = { id:'lib-templates', label:B.CATEGORY_CONFIG['lib-templates'].label, open:true };
    var cat_custom = { id:'custom', label:B.CATEGORY_CONFIG.custom.label, open:true };
    
    // Template-Referenzen (Prio 1) - NUR IM TEMPLATE-MODUS HINZUFÜGEN
if (MODE === 'templates') {
      templates.forEach(function (t) {
        addOnce(bm, 'lib-tpl-ref-' + t.id, {
          label: (t.name || ('Vorlage #' + t.id)),
          category: cat_templates, // Zuweisung zur Prio 1
          media: '<svg viewBox="0 0 24 24" width="22" height="22"><rect x="4" y="5" width="16" height="14" rx="2" stroke="currentColor" fill="none" stroke-width="2"/></svg>',
          content: B.editorRefPlaceholder('template', t.id, t.name).html
        });
      });
}
    // Sections-Referenzen (werden zu Custom umgeleitet, Prio 2)
    sections.forEach(function (s) {
      addOnce(bm, 'lib-sec-' + s.id, {
        label: s.name || ('Section #' + s.id),
        category: cat_custom, // Explizit Custom
        media: '<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="4" width="18" height="16" rx="2" stroke="currentColor" fill="none" stroke-width="2"/></svg>',
        content: B.editorRefPlaceholder('section', s.id, s.name).html
      });
    });
    // Blocks-Referenzen (werden zu Custom umgeleitet, Prio 2)
    blocks.forEach(function (b) {
      addOnce(bm, 'lib-blk-' + b.id, {
        label: b.name || ('Block #' + b.id),
        category: cat_custom, // Explizit Custom
        media: '<svg viewBox="0 0 24 24" width="22" height="22"><rect x="6" y="7" width="12" height="10" rx="2" stroke="currentColor" fill="none" stroke-width="2"/></svg>',
        content: B.editorRefPlaceholder('block', b.id, b.name).html
      });
    });
  };
  /* ---------- Custom Fix/Flex (ENTFERNT / GELEERT) ---------- */
  B.addCustomLibrary = function (ed, payload, mode) {
    /* (Keine Aktion nötig.) */
  };
// WICHTIGE NEUE FUNKTION: Entfernt alle alten Snippet-Blöcke
B.addEditableTemplatesLibrary = function(ed) {
// Aggressive Bereinigung aller alten flexiblen Snippet-Blöcke,
// um Konflikte mit den neuen custom-snippet-* Blöcken zu vermeiden.
removeByPrefix(ed.BlockManager, 'snip-');
return Promise.resolve();
};
  /* ---------- Ref-Sammlung für Speichern/Render (unverändert) ---------- */
  B.collectRefs = function (ed) {
    var root = ed.getWrapper && ed.getWrapper();
    var els = root && root.find ? root.find('[data-ref-type]') : [];
    var out = [];
    if (Array.isArray(els) && els.length) {
      els.forEach(function (el) {
        try {
          var m = el.getAttributes ? el.getAttributes() : {};
          var t = (m['data-ref-type'] || '').toString().toLowerCase();
          var i = parseInt(m['data-ref-id'] || '0', 10);
          if (!t || !i) return;
          if (!/^(template|section|block|snippet)$/.test(t)) return;
          if (t === 'snippet') return; // Snippets immer flex/by value
          out.push({
            sort: out.length,
            ref_type: t === 'template' ? 'section' : t,
            ref_id: i,
            overrides_json: null,
            lock_to_version: null
          });
        } catch {}
      });
    }
    return out;
  };
})(window);