Files
emailtemplate.it/public/assets/js/bridge/library.js
2025-12-04 22:33:05 +01:00

167 lines
10 KiB
JavaScript
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.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* /assets/js/bridge/library.js — Kategorien, Defaults, Snippets (FINAL UND KORRIGIERT) */
(function(w){
  var B = w.BridgeParts = w.BridgeParts || {};
if (!B.CATEGORY_CONFIG) B.CATEGORY_CONFIG = {}; // Muss vorhanden sein
  /* Panels/Views sicherstellen (Unverändert) */
  B.ensureViews = function(ed){
    var pn = ed.Panels;
    if (!pn.getPanel('views')) pn.addPanel({ id:'views' });
    if (!pn.getButton('views','open-blocks'))
      pn.addButton('views',[{ id:'open-blocks', command:'open-blocks', togglable:1, className:'gjs-pn-btn' }]);
    if (!pn.getButton('views','open-layers'))
      pn.addButton('views',[{ id:'open-layers', command:'open-layers', togglable:1, className:'gjs-pn-btn' }]);
    if (!pn.getButton('views','open-sm'))
      pn.addButton('views',[{ id:'open-sm', command:'open-sm', togglable:1, className:'gjs-pn-btn' }]);
    try{ var b=pn.getButton('views','open-blocks'); b && b.set('active',true); }catch{}
  };
  /* Helpers --------------------------------------------------------------- */
  function addOnce(bm, id, def){
    if (!id || typeof id !== 'string') return;
    try{ if (bm.get && bm.get(id)) return; bm.add(id, def); }catch{}
  }
  // Kategorien erzeugen (Funktion unverändert)
  function forceCategory(bm, id, label, open){
    try{
      if (typeof bm.addCategory === 'function') {
        var cts = bm.getCategories && bm.getCategories();
        var find = function(){
          if (!cts) return null;
          if (typeof cts.findWhere === 'function') {
            return cts.findWhere({ id }) || cts.findWhere({ label });
          }
          var arr = cts.models || cts || [];
          for (var i=0;i<arr.length;i++){
            var m = arr[i], lid = (m.get?m.get('id'):m.id), lbl=(m.get?m.get('label'):m.label);
            if (lid===id || lbl===label) return m;
          }
          return null;
        };
        var c = find();
        if (!c) c = bm.addCategory({ id:id, label:label, open:!!open });
        try { c.set && c.set('open', !!open); } catch {}
        return c;
      }
    }catch{}
    return { id:id, label:label, open:!!open, __labelOnly:true };
  }
  function ensureCategories(bm){
    // Stellt sicher, dass die vier Hauptkategorien erstellt werden.
    var C_CUSTOM = forceCategory(bm,'custom', B.CATEGORY_CONFIG.custom.label, true);
    var C_STD  = forceCategory(bm,'bausteine', B.CATEGORY_CONFIG.bausteine.label, true);
    var C_LIB  = forceCategory(bm,'mysnips', B.CATEGORY_CONFIG.mysnips.label, true);
    var C_TPLS = forceCategory(bm,'lib-templates', B.CATEGORY_CONFIG['lib-templates'].label, true);
   
    return { C_CUSTOM, C_STD, C_LIB, C_TPLS };
  }
  B._ensureCategories = ensureCategories;
  /* Harte Zuordnung von Custom-IDs → Kategorien (ENTFERNT) */
  B.forceFixFlexCategories = function(ed){
    // Logik liegt jetzt im Plugin
  };
  // **Harte** Sortierung der Kategorien Sammlung + DOM (DOM-Fallback)
  B.enforceCategoryOrder = function(ed){
    try{
      var bm  = ed.BlockManager;
      setTimeout(function(){
        try{
          var cont = bm.getContainer && bm.getContainer();
          if (!cont) return;
          // Notfall-DOM-Sortierung (falls das Plugin versagt)
          var nodes = Array.prototype.slice.call(cont.querySelectorAll('.gjs-block-category'));
          if (!nodes.length) return;
          function nodeRank(n){
            var t = (n.querySelector('.gjs-title') || n).textContent || '';
            var s = t.trim().toLowerCase();
            if (s==='bibliothek: templates (ref)') return 1; // Prio 1
            if (s==='custom')                       return 2; // Prio 2
            if (s==='bausteine')                    return 3; // Prio 3
            if (s.startsWith('bibliothek'))         return 4; // Prio 4+
            return 99;
          }
          nodes.sort(function(a,b){ return nodeRank(a)-nodeRank(b); })
               .forEach(function(n){ cont.appendChild(n); });
        }catch{}
      },0);
    }catch{}
  };
  /* Kategorien normalisieren + sortieren (ENTFERNT) */
  B.normalizeCategories = function(ed){
    // Logik liegt jetzt im Plugin
  };
  /* Bausteine (Explizite Zuweisung zur ID 'bausteine') */
  B.addDefaultBlocks = function(ed){
    var bm = ed.BlockManager;
    B._ensureCategories(bm); // Stellen Sie sicher, dass alle Hauptkategorien existieren
    // Explizite Kategorie-Definition basierend auf der ID 'bausteine'
    var cat_bausteine = { id:'bausteine', label:B.CATEGORY_CONFIG.bausteine.label, open:true };
  addOnce(bm,'blk-img', { label:'Bild', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="5" width="18" height="14" fill="none" stroke="currentColor" stroke-width="2"/><path d="M8 13l3-3 5 6" fill="none" stroke="currentColor" stroke-width="2"/><circle cx="9" cy="9" r="1.5" fill="currentColor"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td align="center"><img src="https://via.placeholder.com/600x200" alt="" width="600" style="max-width:100%;display:block;border:0;" /></td></tr></table>' });
  addOnce(bm,'blk-btn', { label:'Button', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="4" y="7" width="16" height="10" rx="5" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" cellpadding="0" cellspacing="0" align="center" style="font-family:Arial,sans-serif;margin:16px auto;"><tr><td><a href="#" style="background:#0ea5e9;color:#fff;text-decoration:none;padding:12px 20px;border-radius:6px;display:inline-block;">Call to Action</a></td></tr></table>' });
  addOnce(bm,'blk-text', { label:'Text', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 7h16M4 12h10M4 17h8" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td style="font-size:16px;line-height:1.5;color:#0f172a;"><p style="margin:0 0 12px 0;">Überschrift</p><p style="margin:0;">Fließtext …</p></td></tr></table>' });
  addOnce(bm,'blk-2cols', { label:'2 Spalten', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="4" y="6" width="7" height="12" fill="none" stroke="currentColor" stroke-width="2"/><rect x="13" y="6" width="7" height="12" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td width="50%" valign="top" style="padding:8px;"><p style="margin:0;">Linke Spalte</p></td><td width="50%" valign="top" style="padding:8px;"><p style="margin:0;">Rechte Spalte</p></td></tr></table>' });
  addOnce(bm,'blk-600', { label:'Container 600px', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><rect x="3" y="7" width="18" height="10" rx="2" fill="none" stroke="currentColor" stroke-width="2"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="font-family:Arial,sans-serif"><tr><td align="center"><table role="presentation" width="600" cellpadding="0" cellspacing="0" style="width:600px;max-width:100%;background:#ffffff;border:1px solid #e5e7eb;border-radius:6px;"><tr><td style="padding:16px;"><p style="margin:0;">Inhalt hier hinein …</p></td></tr></table></td></tr></table>' });
  addOnce(bm,'blk-hr', { label:'Trenner', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M4 12h16" stroke="currentColor" stroke-width="2" stroke-linecap="round"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td style="padding:8px 0;"><hr style="border:none;border-top:1px solid #e5e7eb;margin:0;" /></td></tr></table>' });
  addOnce(bm,'blk-spacer', { label:'Abstand', category:cat_bausteine, media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M12 6v12" stroke="currentColor" stroke-width="2" stroke-linecap="round"/><circle cx="12" cy="6" r="1.5" fill="currentColor"/><circle cx="12" cy="18" r="1.5" fill="currentColor"/></svg>', content:'<table role="presentation" width="100%" cellpadding="0" cellspacing="0"><tr><td style="height:16px;line-height:16px;font-size:0;">&nbsp;</td></tr></table>' });
  };
  /* Snippets → Custom (Initiale Zuweisung zur ID 'custom') */
  B.replaceSnippetBlocks = function(ed, list){
    try{
      var bm = ed.BlockManager;
      B._ensureCategories(bm);
      var all = (bm.getAll && bm.getAll()) || [];
      (all.models || all).forEach(function(b){
        if (!b) return;
        var id=b.get&&b.get('id');
        // Entferne alte Snippets
        if(id && String(id).startsWith('snip-')) try{ bm.remove(id); }catch{}
      });
      // Explizite Kategorie-Definition basierend auf der ID 'custom'
      var cat_custom = { id:'custom', label:B.CATEGORY_CONFIG.custom.label, open:true };
      (list||[]).forEach(function(raw){
        if(!raw) return;
        var html = raw.html || raw.content || '';
        if(!html) return;
        var id = 'snip-'+(raw.id ?? ('x'+Math.random().toString(36).slice(2)));
        addOnce(bm, id, {
          label: raw.name || ('Snippet '+(raw.id ?? '')),
          // Zuweisung zur 'Custom' Kategorie
          category: cat_custom,
          media:'<svg viewBox="0 0 24 24" width="22" height="22"><path d="M5 7h14M5 12h10M5 17h8" stroke="currentColor" stroke-width="2" fill="none" stroke-linecap="round"/></svg>',
          content: html
        });
      });
    }catch{}
    B.renderBlocks && B.renderBlocks(ed);
  };
  /* Snippets nachladen (für Buttons) */
  B.fetchSnippets = async function(){
    try{
      var res = await fetch('../api.php?resource=snippets&action=list&t='+Date.now(), {
        credentials:'same-origin', cache:'no-store', headers:{'Cache-Control':'no-cache'}
      });
      var rows = await res.json();
      rows = rows && rows.items ? rows.items : (Array.isArray(rows) ? rows : []);
      return rows.map(function(r){ return { id:r.id, name:r.name, html:r.content||r.html||'' }; });
    }catch(e){ B.log && B.log('reload-snippets-error:'+e); return []; }
  };
})(window);