window.Cockpit = (function () { const API = '/api/admin'; function toast(message, type) { type = type || 'info'; let root = document.getElementById('cockpit-toasts'); if (!root) { root = document.createElement('div'); root.id = 'cockpit-toasts'; root.className = 'toast-container'; document.body.appendChild(root); } const el = document.createElement('div'); el.className = 'toast toast-' + type; el.textContent = message; root.appendChild(el); setTimeout(function () { el.classList.add('toast-out'); setTimeout(function () { el.remove(); }, 300); }, 3500); } function clearEmbeddedIframes() { document.querySelectorAll('iframe.browser-novnc, iframe[data-clear-on-nav]').forEach(function (f) { try { f.src = 'about:blank'; } catch (e) {} }); } async function request(path, options) { options = options || {}; const url = path.startsWith('http') || path.startsWith('/api/') ? path : API + path; const headers = Object.assign({ 'Content-Type': 'application/json' }, options.headers || {}); const fetchOpts = Object.assign({}, options, { headers: headers }); if (options.signal) fetchOpts.signal = options.signal; const res = await fetch(url, fetchOpts); let data = null; try { data = await res.json(); } catch (e) { data = null; } if (!res.ok) { const msg = (data && (data.detail || data.message)) || res.statusText; throw new Error(typeof msg === 'string' ? msg : JSON.stringify(msg)); } return data; } function confirmDelete(message) { return window.confirm(message || 'Delete this item?'); } function openDrawer(id) { document.body.classList.add('drawer-open'); var el = document.getElementById(id); if (el) el.classList.add('open'); } function closeDrawer(id) { document.body.classList.remove('drawer-open'); if (id) { var el = document.getElementById(id); if (el) el.classList.remove('open'); } document.querySelectorAll('.drawer.open').forEach(function (d) { d.classList.remove('open'); }); } document.addEventListener('keydown', function (e) { if (e.key === 'Escape') closeDrawer(); }); document.addEventListener('click', function (e) { var link = e.target.closest('a[href]'); if (!link || link.target === '_blank' || link.hasAttribute('download')) return; var href = link.getAttribute('href') || ''; if (!href || href.charAt(0) === '#') return; if (href.indexOf('6080') !== -1 || href.indexOf('7788') !== -1) return; if (href.charAt(0) === '/' || href.indexOf('http') === 0) clearEmbeddedIframes(); }, true); return { toast: toast, api: request, confirmDelete: confirmDelete, openDrawer: openDrawer, closeDrawer: closeDrawer, clearIframes: clearEmbeddedIframes }; })();