From a0ca704ac1e1c98a649ea17f83018d638ef046a7 Mon Sep 17 00:00:00 2001 From: SW Date: Thu, 1 Oct 2026 14:48:16 +0200 Subject: [PATCH] fix: move inline JavaScript to external file to comply with CSP --- static/app.js | 79 ++++++++++++++++++++++ templates/allocation_detail.html | 10 +-- templates/fragments/allocations_table.html | 8 +-- templates/index.html | 64 +++--------------- 4 files changed, 97 insertions(+), 64 deletions(-) create mode 100644 static/app.js diff --git a/static/app.js b/static/app.js new file mode 100644 index 0000000..bbb7e6d --- /dev/null +++ b/static/app.js @@ -0,0 +1,79 @@ +document.addEventListener('DOMContentLoaded', function () { + // Open allocation modal + document.querySelectorAll('.allocate-btn').forEach(function (btn) { + btn.addEventListener('click', function () { + 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(); + }); + }); +}); + +async function openAllocateModal(btn) { + const slug = btn.dataset.slug; + const name = btn.dataset.name; + const select = document.getElementById('prefix-' + slug); + const prefixLength = select ? select.value : ''; + + 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) { + document.getElementById('modal-warning').textContent = 'Could not load preview.'; + } + + document.getElementById('allocate-modal').style.display = 'flex'; +} diff --git a/templates/allocation_detail.html b/templates/allocation_detail.html index f1585f6..40739bc 100644 --- a/templates/allocation_detail.html +++ b/templates/allocation_detail.html @@ -76,7 +76,7 @@ {% if allocation.status == "active" || allocation.status == "reserved" %} - + {% endif %} Back @@ -108,8 +108,8 @@ {% endif %} -