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

159 lines
5.2 KiB
JavaScript

// assets/js/ui-tools.js
// Öffnet API-Health (JSON), DB-Doctor (Iframe) & beliebige JSON-GETs im Popup,
// ohne die Seite zu verlassen. Links bleiben als Fallback nutzbar.
(function () {
const dlg = document.getElementById('toolsDialog');
if (!dlg) return;
const title = document.getElementById('toolsTitle');
const btnX = document.getElementById('toolsClose');
const btnCopy = document.getElementById('toolsCopy');
const btnDl = document.getElementById('toolsDownload');
const jsonWrap = document.getElementById('toolsJsonWrap');
const jsonPre = document.getElementById('toolsJsonPre');
const frame = document.getElementById('toolsFrame');
function showJson(obj, ttl) {
title.textContent = ttl || 'Antwort (JSON)';
const txt = (typeof obj === 'string') ? obj : JSON.stringify(obj, null, 2);
jsonPre.textContent = txt;
jsonWrap.classList.remove('hidden');
frame.classList.add('hidden');
btnCopy.classList.remove('hidden');
btnDl.classList.remove('hidden');
try { dlg.showModal(); } catch {}
}
function showFrame(url, ttl) {
title.textContent = ttl || 'Werkzeug';
frame.src = url + (url.includes('?') ? '&' : '?') + 't=' + Date.now();
frame.classList.remove('hidden');
jsonWrap.classList.add('hidden');
btnCopy.classList.add('hidden');
btnDl.classList.add('hidden');
try { dlg.showModal(); } catch {}
}
btnX?.addEventListener('click', () => {
try { dlg.close(); } catch {}
frame.src = 'about:blank';
});
btnCopy?.addEventListener('click', async () => {
const txt = jsonPre.textContent || '';
try {
await navigator.clipboard.writeText(txt);
// optional: kleines Feedback
(window.Toast?.show || window.toast || (()=>{}))('In Zwischenablage kopiert');
} catch {}
});
btnDl?.addEventListener('click', () => {
const blob = new Blob([jsonPre.textContent || ''], { type:'application/json;charset=utf-8' });
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
const stamp = new Date().toISOString().replace(/[:.]/g,'-');
a.download = `response-${stamp}.json`;
document.body.appendChild(a);
a.click();
setTimeout(()=>{ URL.revokeObjectURL(a.href); a.remove(); }, 0);
});
// ------------------------------------------------------------
// 1) Offizieller Weg: Links mit data-popup="json" | "frame"
// ------------------------------------------------------------
document.addEventListener('click', async (ev) => {
const a = ev.target.closest('a[data-popup]');
if (!a) return;
const mode = (a.getAttribute('data-popup') || '').toLowerCase();
const href = a.getAttribute('href') || '#';
const ttl = a.getAttribute('data-title') || a.textContent.trim() || 'Werkzeug';
if (!/^json|frame$/.test(mode)) return;
// Cmd/Strg-Klick & Mittelklick respektieren (neuer Tab)
if (ev.metaKey || ev.ctrlKey || ev.button === 1) return;
ev.preventDefault();
if (mode === 'frame') {
showFrame(href, ttl);
return;
}
// mode === 'json'
try {
const r = await fetch(href, { credentials: 'include' });
const txt = await r.text();
let data = null;
try { data = JSON.parse(txt); } catch { data = txt; }
showJson(data, ttl);
} catch (e) {
showJson({ ok:false, error: String(e) }, ttl);
}
});
// ------------------------------------------------------------
// 2) Fallback: *alle* API-GET-Links (action=get) ohne data-popup
// -> automatisch im JSON-Popup öffnen
// ------------------------------------------------------------
document.addEventListener('click', async (ev) => {
const a = ev.target.closest('a');
if (!a) return;
// bereits oben behandelt
if (a.hasAttribute('data-popup')) return;
const href = a.getAttribute('href') || '';
// nur api.php-GET-Routen mit action=get abfangen
if (!/api\.php/i.test(href) || !/[?&]action=get(&|$)/i.test(href)) return;
// Cmd/Strg/Mittelklick respektieren
if (ev.metaKey || ev.ctrlKey || ev.button === 1) return;
ev.preventDefault();
const makeTitle = () => {
try {
const u = new URL(href, location.href);
const res = u.searchParams.get('resource') || 'resource';
const id = u.searchParams.get('id') || '';
// Optional: Name aus data-title wenn vorhanden
const custom = a.getAttribute('data-title');
return custom || `GET ${res}${id ? ` #${id}` : ''}`;
} catch { return 'GET'; }
};
const title = makeTitle();
// Popup öffnen (wie oben)
try {
const r = await fetch(href, { credentials: 'include' });
const txt = await r.text();
let data = null;
try { data = JSON.parse(txt); } catch { data = txt; }
showJson(data, title);
} catch (e) {
showJson({ ok:false, error: String(e) }, title);
}
}, true);
// Utility: Öffnen aus Code
window.AdminTools = {
openJson(url, title) {
fetch(url, { credentials: 'include' })
.then(r => r.text())
.then(txt => {
try { showJson(JSON.parse(txt), title); }
catch { showJson(txt, title); }
})
.catch(err => showJson({ ok:false, error:String(err) }, title));
},
openFrame(url, title) {
showFrame(url, title);
}
};
})();