function initApp() { console.log('sub-aligator app.js initialized'); // Ensure every modal starts closed, even if the browser restored a cached state. document.querySelectorAll('.modal-overlay').forEach(function (modal) { modal.style.display = 'none'; }); // Open allocation modal document.querySelectorAll('.allocate-btn').forEach(function (btn) { btn.addEventListener('click', function () { console.log('allocate-btn clicked', btn.dataset); openAllocateModal(btn); }); }); // Open release modal from history table document.querySelectorAll('.release-btn').forEach(function (btn) { btn.addEventListener('click', function () { const id = btn.dataset.id; const modal = document.getElementById('release-modal-' + id); if (modal) { modal.style.display = 'flex'; } }); }); // Close modal via Cancel button document.querySelectorAll('.cancel-btn').forEach(function (btn) { btn.addEventListener('click', function () { const modalId = btn.dataset.modal; const modal = document.getElementById(modalId); if (modal) { modal.style.display = 'none'; } }); }); // Close modal by clicking on the overlay background document.querySelectorAll('.modal-overlay').forEach(function (overlay) { overlay.addEventListener('click', function (event) { if (event.target === overlay) { overlay.style.display = 'none'; } }); }); // Prevent clicks inside the modal from closing it document.querySelectorAll('.modal').forEach(function (modal) { modal.addEventListener('click', function (event) { event.stopPropagation(); }); }); // Hide the modal right before its form is submitted. document.querySelectorAll('.modal form').forEach(function (form) { form.addEventListener('submit', function () { const overlay = form.closest('.modal-overlay'); if (overlay) { overlay.style.display = 'none'; } }); }); } async function openAllocateModal(btn) { const slug = btn.dataset.slug; const name = btn.dataset.name; const select = document.getElementById('prefix-' + slug); let prefixLength = ''; if (select && select.value) { prefixLength = select.value; } else if (select && select.options.length > 0) { prefixLength = select.options[0].value; } else { prefixLength = '24'; } console.log('openAllocateModal', { slug: slug, name: name, prefixLength: prefixLength }); document.getElementById('modal-pool-slug').value = slug; document.getElementById('modal-prefix-length').value = prefixLength; document.getElementById('modal-pool-name').textContent = name; document.getElementById('modal-prefix-display').textContent = '/' + prefixLength; try { const resp = await fetch('/partials/pools/' + slug + '/preview?prefix_length=' + prefixLength); const html = await resp.text(); const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); const cidr = doc.getElementById('preview-cidr')?.textContent || '–'; const addressCount = doc.getElementById('preview-address-count')?.textContent || '–'; const usableHosts = doc.getElementById('preview-usable-hosts')?.textContent || '–'; const warning = doc.getElementById('preview-warning')?.textContent || ''; document.getElementById('modal-cidr').textContent = cidr; document.getElementById('modal-address-count').textContent = addressCount; document.getElementById('modal-usable-hosts').textContent = usableHosts; document.getElementById('modal-warning').textContent = warning; } catch (e) { console.error('preview fetch failed', e); document.getElementById('modal-warning').textContent = 'Could not load preview.'; } document.getElementById('allocate-modal').style.display = 'flex'; } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initApp); } else { initApp(); }