diff --git a/openwisp_ipam/static/openwisp-ipam/css/admin.css b/openwisp_ipam/static/openwisp-ipam/css/admin.css index 221d42d..aecf3da 100644 --- a/openwisp_ipam/static/openwisp-ipam/css/admin.css +++ b/openwisp_ipam/static/openwisp-ipam/css/admin.css @@ -5,6 +5,9 @@ .subnet-visual{ margin: 10px 20px 0; padding: 0; +} + +section.subnet-visual{ overflow-anchor: none; overflow-y: scroll; height: 700px; @@ -15,7 +18,7 @@ width: 120px; text-align: center; padding: 5px 0; - margin: 0 5px 10px 5px; + margin: 0 10px 10px 0px; border-radius: 0; color: #fff; background: rgba(20, 102, 26, 0.9); @@ -47,3 +50,6 @@ } .subnet-visual .page{ display: inline } + +#goto-input{ padding: 5px 10px } +#goto-button{ padding: 7px 10px } diff --git a/openwisp_ipam/static/openwisp-ipam/js/subnet.js b/openwisp_ipam/static/openwisp-ipam/js/subnet.js index d700309..d508adc 100644 --- a/openwisp_ipam/static/openwisp-ipam/js/subnet.js +++ b/openwisp_ipam/static/openwisp-ipam/js/subnet.js @@ -26,6 +26,14 @@ django.jQuery(function ($) { // Open the specific subnet page that used clicked on. document.location.href = data.node.a_attr.href; }); + + // go to keyup + $('#goto-input').on('keyup', function (event) { + event.preventDefault(); + if (event.key === 'Enter') { + django.jQuery('#goto-button').trigger('click'); + } + }); }); @@ -35,6 +43,7 @@ function initHostsInfiniteScroll($, current_subnet, address_add_url, address_cha fetchedPages = [], busy = false, nextPageUrl = '/api/v1/subnet/' + current_subnet + '/hosts/', + searchQuery = '', lastRenderedPage = 0; //1 based indexing (0 -> no page rendered) function addressListItem(addr) { var id = normalizeIP(addr.address); @@ -58,11 +67,47 @@ function initHostsInfiniteScroll($, current_subnet, address_add_url, address_cha }); return div; } + function validateIp(ip_address, callback) { + if (ip_address === '') { + callback(true); + return; + } + $.ajax({ + type: 'GET', + url: '/api/v1/subnet/' + current_subnet + '/hosts/?start=' + ip_address, + success: function (res) { + callback(res.results[0].address === ip_address); + }, + error: function (error) { + callback(false); + throw error; + }, + }); + } + function goTo() { + var input = $("#goto-input").val().toLowerCase().trim(); + validateIp(input, function (isValid) { + if (isValid) { + $("#invalid-address").hide(); + if (input !== searchQuery) { + searchQuery = input; + nextPageUrl = '/api/v1/subnet/' + current_subnet + '/hosts/?start=' + searchQuery; + $('#subnet-visual').empty(); + fetchedPages = []; + lastRenderedPage = 0; + busy = false; + onUpdate(); + } + } else { + $("#invalid-address").show(); + } + }); + } function appendPage() { - $('.subnet-visual').append(pageContainer(fetchedPages[lastRenderedPage])); + $('#subnet-visual').append(pageContainer(fetchedPages[lastRenderedPage])); if (lastRenderedPage >= renderedPages) { - var removedDiv = $('.subnet-visual div:first'); - $('.subnet-visual').scrollTop($('.subnet-visual').scrollTop() - removedDiv.height()); + var removedDiv = $('#subnet-visual div:first'); + $('#subnet-visual').scrollTop($('#subnet-visual').scrollTop() - removedDiv.height()); removedDiv.remove(); } lastRenderedPage += 1; @@ -97,19 +142,19 @@ function initHostsInfiniteScroll($, current_subnet, address_add_url, address_cha function pageUp() { busy = true; if (lastRenderedPage > renderedPages) { - $('.subnet-visual div:last').remove(); + $('#subnet-visual div:last').remove(); var addedDiv = pageContainer(fetchedPages[lastRenderedPage - renderedPages - 1]); - $('.subnet-visual').prepend(addedDiv); - $('.subnet-visual').scrollTop($('.subnet-visual').scrollTop() + addedDiv.height()); + $('#subnet-visual').prepend(addedDiv); + $('#subnet-visual').scrollTop($('#subnet-visual').scrollTop() + addedDiv.height()); lastRenderedPage -= 1; } busy = false; } function onUpdate() { if (!busy) { - var scrollTop = $('.subnet-visual').scrollTop(), - scrollBottom = scrollTop + $('.subnet-visual').innerHeight(), - height = $('.subnet-visual')[0].scrollHeight; + var scrollTop = $('#subnet-visual').scrollTop(), + scrollBottom = scrollTop + $('#subnet-visual').innerHeight(), + height = $('#subnet-visual')[0].scrollHeight; if (height * 0.75 <= scrollBottom) { pageDown(); } else if (height * 0.25 >= scrollTop) { @@ -117,6 +162,9 @@ function initHostsInfiniteScroll($, current_subnet, address_add_url, address_cha } } } - $('.subnet-visual').scroll(onUpdate); + $("#goto-button").on("click", function () { + goTo(); + }); + $('#subnet-visual').scroll(onUpdate); onUpdate(); } diff --git a/openwisp_ipam/templates/admin/openwisp-ipam/subnet/change_form.html b/openwisp_ipam/templates/admin/openwisp-ipam/subnet/change_form.html index 2a3757c..6e09ed5 100644 --- a/openwisp_ipam/templates/admin/openwisp-ipam/subnet/change_form.html +++ b/openwisp_ipam/templates/admin/openwisp-ipam/subnet/change_form.html @@ -27,8 +27,17 @@