From f4fa8acb97723a17863bbed322d8821713b4bec3 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Mon, 27 Apr 2026 02:23:44 +0200 Subject: [PATCH] sdsad --- modules/pihole/assets/pihole.css | 41 ++++++++++++++ modules/pihole/assets/pihole.js | 95 +++++++++++++++++++++++++++++++- 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/modules/pihole/assets/pihole.css b/modules/pihole/assets/pihole.css index 3775e1e..6e00a93 100644 --- a/modules/pihole/assets/pihole.css +++ b/modules/pihole/assets/pihole.css @@ -198,6 +198,47 @@ color: var(--muted); } +.pihole-console-modal { + width: min(720px, 96vw); +} + +.pihole-console-body { + margin-top: 16px; + display: grid; + gap: 10px; + max-height: 48vh; + overflow: auto; + padding: 4px; +} + +.pihole-console-line { + display: grid; + gap: 4px; + padding: 12px 14px; + border-radius: 14px; + border: 1px solid var(--line); + background: rgba(255, 255, 255, 0.6); +} + +.pihole-console-line span { + font-size: 0.8rem; + color: var(--muted); +} + +.pihole-console-line strong { + font-weight: 600; +} + +.pihole-console-line.is-success { + border-color: rgba(0, 179, 164, 0.22); + background: rgba(0, 179, 164, 0.08); +} + +.pihole-console-line.is-error { + border-color: rgba(255, 90, 61, 0.24); + background: rgba(255, 90, 61, 0.08); +} + .pihole-instance-card { padding: 16px; background: var(--panel-2); diff --git a/modules/pihole/assets/pihole.js b/modules/pihole/assets/pihole.js index 0ba9dc7..33551a9 100644 --- a/modules/pihole/assets/pihole.js +++ b/modules/pihole/assets/pihole.js @@ -19,6 +19,9 @@ let refreshTimer = null; let loadInFlight = false; let actionInFlight = false; + let actionConsoleApi = null; + let actionConsoleBody = null; + let actionConsoleClose = null; const apiCall = async (action, payload = {}) => { const res = await fetch(`/module/pihole/api?action=${encodeURIComponent(action)}`, @@ -47,9 +50,82 @@ el.textContent = value; }; + const ensureActionConsole = () => { + if (actionConsoleApi && actionConsoleBody && actionConsoleClose) { + return; + } + + const root = document.createElement('div'); + root.className = 'modal'; + root.dataset.piholeConsoleModal = '1'; + root.setAttribute('aria-hidden', 'true'); + root.innerHTML = ` + + `; + document.body.appendChild(root); + + actionConsoleBody = root.querySelector('[data-pihole-console-body]'); + actionConsoleClose = root.querySelector('[data-pihole-console-close]'); + const clearBtn = root.querySelector('[data-pihole-console-clear]'); + + actionConsoleApi = window.NexusModal && typeof window.NexusModal.create === 'function' + ? window.NexusModal.create(root, { initialFocus: '[data-pihole-console-close]' }) + : { + open() { + root.classList.add('is-open'); + root.setAttribute('aria-hidden', 'false'); + }, + close() { + root.classList.remove('is-open'); + root.setAttribute('aria-hidden', 'true'); + }, + }; + + if (actionConsoleClose) { + actionConsoleClose.addEventListener('click', () => { + if (!actionInFlight) { + actionConsoleApi.close(); + } + }); + } + + if (clearBtn) { + clearBtn.addEventListener('click', () => { + if (actionConsoleBody) { + actionConsoleBody.innerHTML = ''; + } + }); + } + }; + + const appendActionLog = (message, tone = 'info') => { + ensureActionConsole(); + if (!actionConsoleBody) { + return; + } + const row = document.createElement('div'); + row.className = `pihole-console-line is-${tone}`; + row.innerHTML = `${new Date().toLocaleTimeString('de-DE')}${message}`; + actionConsoleBody.appendChild(row); + actionConsoleBody.scrollTop = actionConsoleBody.scrollHeight; + }; + const setActionLock = (locked, message = 'Bitte warten ...') => { actionInFlight = locked; page.classList.toggle('is-busy', locked); + ensureActionConsole(); let overlay = page.querySelector('[data-pihole-busy-overlay]'); if (!overlay) { @@ -67,6 +143,9 @@ } overlay.hidden = !locked; + if (actionConsoleClose) { + actionConsoleClose.disabled = locked; + } page.querySelectorAll('button, input, select, textarea').forEach((el) => { const formControl = el; @@ -229,26 +308,38 @@ : action === 'gravity' ? 'Listen werden aktualisiert ...' : 'Aktion wird ausgefuehrt ...'; + ensureActionConsole(); + if (actionConsoleBody) { + actionConsoleBody.innerHTML = ''; + } + actionConsoleApi.open(); + appendActionLog(actionLabel, 'info'); setActionLock(true, actionLabel); if (action === 'enable') { + appendActionLog(`Aktiviere ${instance === 'all' ? 'alle Instanzen' : `Instanz ${instance}`}.`, 'info'); await apiCall('enable', payload); } else if (action === 'disable' || action === 'disable-custom') { if (!payload.minutes || payload.minutes <= 0) { - alert('Bitte Minuten angeben.'); + appendActionLog('Fehler: Bitte Minuten angeben.', 'error'); return; } + appendActionLog(`Deaktiviere ${instance === 'all' ? 'alle Instanzen' : `Instanz ${instance}`} fuer ${payload.minutes} Minuten.`, 'info'); await apiCall('disable', payload); } else if (action === 'gravity') { + appendActionLog(`Starte Listen-Update fuer ${instance === 'all' ? 'alle Instanzen' : `Instanz ${instance}`}.`, 'info'); await apiCall('gravity', payload); const status = document.querySelector('[data-list-update-status]'); if (status) status.textContent = 'Listen-Update gestartet.'; } else if (action === 'update') { + appendActionLog(`Starte Pi-hole-Update fuer ${instance === 'all' ? 'alle Instanzen' : `Instanz ${instance}`}.`, 'info'); await apiCall('update', payload); } + appendActionLog('Aktion abgeschlossen. Dashboard wird aktualisiert.', 'success'); await loadDashboard(); + appendActionLog('Anzeige erfolgreich aktualisiert.', 'success'); } catch (err) { - alert(`Aktion fehlgeschlagen: ${err.message}`); + appendActionLog(`Aktion fehlgeschlagen: ${err.message}`, 'error'); } finally { setActionLock(false); }