diff --git a/netbox_topology_views/api/views.py b/netbox_topology_views/api/views.py index 07ca7b5..94469c9 100644 --- a/netbox_topology_views/api/views.py +++ b/netbox_topology_views/api/views.py @@ -78,7 +78,7 @@ class SearchViewSet(ReadOnlyModelViewSet): queryset = Device.objects.all() serializer_class = TopologyDummySerializer - def _filter(self, site, role, name, tags, region): + def _filter(self, site, role, name, tags, region, location): filter_devices = Device.objects.all() if name is not None: filter_devices = filter_devices.filter(name__contains=name) @@ -90,6 +90,8 @@ class SearchViewSet(ReadOnlyModelViewSet): filter_devices = filter_devices.filter(tags__id__in=tags) if region is not None: filter_devices = filter_devices.filter(site__region__id__in=region) + if location is not None: + filter_devices = filter_devices.filter(location__id__in=location) return filter_devices @@ -115,14 +117,15 @@ class SearchViewSet(ReadOnlyModelViewSet): if regions == []: regions = None + locations = request.query_params.getlist('locations[]', None) + if locations == []: + locations = None + hide_unconnected = request.query_params.get('hide_unconnected', None) if hide_unconnected == "": hide_unconnected = None - print(hide_unconnected) - if hide_unconnected == 'false': - print("ok") - devices = self._filter(sites, devicerole, name, tags, regions) + devices = self._filter(sites, devicerole, name, tags, regions, locations) nodes = [] edges = [] diff --git a/netbox_topology_views/static/netbox_topology_views/js/app.js b/netbox_topology_views/static/netbox_topology_views/js/app.js index c81ebea..12693ef 100644 --- a/netbox_topology_views/static/netbox_topology_views/js/app.js +++ b/netbox_topology_views/static/netbox_topology_views/js/app.js @@ -1 +1 @@ -var graph=null,container=null;function iniPlotboxFull(){document.addEventListener("DOMContentLoaded",function(){container=document.getElementById("fullvisgraph"),startRender()},!1)}function startRender(){var e=location.search;$.ajax({type:"GET",url:"../../api/plugins/topology-views/search/search/"+e,contentType:"application/json; charset=utf-8",success:function(e,t,n){graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),$.each(e.nodes,function(e,t){nodes.add(t)}),$.each(e.edges,function(e,t){edges.add(t)}),graph.fit(),canvas=document.getElementById("fullvisgraph").getElementsByTagName("canvas")[0]}})}graph=null,container=null;var downloadButton=null,MIME_TYPE="image/png",canvas=null,csrftoken=null,nodes=new vis.DataSet,edges=new vis.DataSet,options={interaction:{hover:!0,hoverConnectedEdges:!0,multiselect:!1},nodes:{shape:"image",brokenImage:"../../static/netbox_topology_views/img/role-unknown.png",size:35,font:{multi:"md",face:"helvetica"}},edges:{length:100,width:2,font:{face:"helvetica"}},physics:{solver:"forceAtlas2Based"}},selected_regions=[];function iniPlotboxIndex(){document.addEventListener("DOMContentLoaded",function(){container=document.getElementById("visgraph"),csrftoken=jQuery("[name=csrfmiddlewaretoken]").val(),startLoadSearchBar(),handleButtonPress(),downloadButton=document.getElementById("btnDownloadImage"),btnFullView=document.getElementById("btnFullView")},!1)}function startLoadSearchBar(){$("#device-roles").select2({allowClear:!0,placeholder:"---------",theme:"bootstrap",multiple:!0,ajax:{url:"../../api/dcim/device-roles/?brief=true",dataType:"json",type:"GET",data:function(e){return{q:e.term}},processResults:function(e){return{results:$.map(e.results,function(e){return{text:e.name,id:e.id}})}}}}),$("#sites").select2({allowClear:!0,placeholder:"---------",theme:"bootstrap",multiple:!0,ajax:{url:function(e){var t="../../api/dcim/sites/?brief=true";if(0==selected_regions.length)return t;for(var n=0;nLoading data'),e.preventDefault();var t=$("#name").val(),n=$("#device-roles").val(),a=$("#sites").val(),s=$("#tags").val(),o=$("#regions").val(),r=$("#checkHideUnconnected").is(":checked");$.ajax({type:"GET",url:"../../api/plugins/topology-views/search/search/",data:{name:t,"devicerole[]":n,"sites[]":a,"tags[]":s,"regions[]":o,hide_unconnected:r},headers:{"X-CSRFToken":csrftoken},contentType:"application/json; charset=utf-8",dataType:"json",beforeSend:function(){new_url=this.url.split("../../api/plugins/topology-views/search/search/?"),new_url=new_url[1],new_url="../../plugins/topology-views/full?"+new_url,btnFullView.classList.remove("disabled"),btnFullView.href=new_url},success:function(e,t,n){$("#status").html('Drawing network'),graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),$.each(e.nodes,function(e,t){nodes.add(t)}),$.each(e.edges,function(e,t){edges.add(t)}),graph.fit(),canvas=document.getElementById("visgraph").getElementsByTagName("canvas")[0],graph.on("afterDrawing",function(){$("#status").html('Ready');var e=canvas.toDataURL(MIME_TYPE);downloadButton.href=e,downloadButton.download="topology"}),graph.on("dragEnd",function(e){dragged=this.getPositions(e.nodes),$.each(dragged,function(e,t){$("#coordstatus").html(""),$("#checkSaveCoordinates").is(":checked")&&$.ajax({url:"../../api/plugins/topology-views/save-coords/save_coords/",type:"PATCH",dataType:"json",headers:{"X-CSRFToken":csrftoken},contentType:"application/json; charset=utf-8",processData:!1,data:JSON.stringify({node_id:e,x:t.x,y:t.y}),error:function(e){$("#coordstatus").html('Failed to update coordinates')},success:function(e){$("#coordstatus").html('Updated coordinates')}})})})},error:function(e){$("#status").html('Something went wrong')}})})} \ No newline at end of file +var graph=null,container=null;function iniPlotboxFull(){document.addEventListener("DOMContentLoaded",function(){container=document.getElementById("fullvisgraph"),startRender()},!1)}function startRender(){var e=location.search;$.ajax({type:"GET",url:"../../api/plugins/topology-views/search/search/"+e,contentType:"application/json; charset=utf-8",success:function(e,t,n){graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),$.each(e.nodes,function(e,t){nodes.add(t)}),$.each(e.edges,function(e,t){edges.add(t)}),graph.fit(),canvas=document.getElementById("fullvisgraph").getElementsByTagName("canvas")[0]}})}graph=null,container=null;var downloadButton=null,MIME_TYPE="image/png",canvas=null,csrftoken=null,nodes=new vis.DataSet,edges=new vis.DataSet,options={interaction:{hover:!0,hoverConnectedEdges:!0,multiselect:!1},nodes:{shape:"image",brokenImage:"../../static/netbox_topology_views/img/role-unknown.png",size:35,font:{multi:"md",face:"helvetica"}},edges:{length:100,width:2,font:{face:"helvetica"}},physics:{solver:"forceAtlas2Based"}},selected_regions=[],selected_sites=[];function iniPlotboxIndex(){document.addEventListener("DOMContentLoaded",function(){container=document.getElementById("visgraph"),csrftoken=jQuery("[name=csrfmiddlewaretoken]").val(),startLoadSearchBar(),handleButtonPress(),downloadButton=document.getElementById("btnDownloadImage"),btnFullView=document.getElementById("btnFullView")},!1)}function startLoadSearchBar(){$("#device-roles").select2({allowClear:!0,placeholder:"---------",theme:"bootstrap",multiple:!0,ajax:{url:"../../api/dcim/device-roles/?brief=true",dataType:"json",type:"GET",data:function(e){return{q:e.term}},processResults:function(e){return{results:$.map(e.results,function(e){return{text:e.name,id:e.id}})}}}}),$("#sites").select2({allowClear:!0,placeholder:"---------",theme:"bootstrap",multiple:!0,ajax:{url:function(e){var t="../../api/dcim/sites/?brief=true";if(0==selected_regions.length)return t;for(var n=0;nLoading data'),e.preventDefault();var t=$("#name").val(),n=$("#device-roles").val(),s=$("#sites").val(),a=$("#tags").val(),o=$("#regions").val(),r=$("#checkHideUnconnected").is(":checked"),l=$("#locations").val();$.ajax({type:"GET",url:"../../api/plugins/topology-views/search/search/",data:{name:t,"devicerole[]":n,"sites[]":s,"tags[]":a,"regions[]":o,hide_unconnected:r,"locations[]":l},headers:{"X-CSRFToken":csrftoken},contentType:"application/json; charset=utf-8",dataType:"json",beforeSend:function(){new_url=this.url.split("../../api/plugins/topology-views/search/search/?"),new_url=new_url[1],new_url="../../plugins/topology-views/full?"+new_url,btnFullView.classList.remove("disabled"),btnFullView.href=new_url},success:function(e,t,n){$("#status").html('Drawing network'),graph=null,nodes=new vis.DataSet,edges=new vis.DataSet,graph=new vis.Network(container,{nodes:nodes,edges:edges},options),$.each(e.nodes,function(e,t){nodes.add(t)}),$.each(e.edges,function(e,t){edges.add(t)}),graph.fit(),canvas=document.getElementById("visgraph").getElementsByTagName("canvas")[0],graph.on("afterDrawing",function(){$("#status").html('Ready');var e=canvas.toDataURL(MIME_TYPE);downloadButton.href=e,downloadButton.download="topology"}),graph.on("dragEnd",function(e){dragged=this.getPositions(e.nodes),$.each(dragged,function(e,t){$("#coordstatus").html(""),$("#checkSaveCoordinates").is(":checked")&&$.ajax({url:"../../api/plugins/topology-views/save-coords/save_coords/",type:"PATCH",dataType:"json",headers:{"X-CSRFToken":csrftoken},contentType:"application/json; charset=utf-8",processData:!1,data:JSON.stringify({node_id:e,x:t.x,y:t.y}),error:function(e){$("#coordstatus").html('Failed to update coordinates')},success:function(e){$("#coordstatus").html('Updated coordinates')}})})})},error:function(e){$("#status").html('Something went wrong')}})})} \ No newline at end of file diff --git a/netbox_topology_views/static_dev/js/home.js b/netbox_topology_views/static_dev/js/home.js index 9233339..845b5eb 100644 --- a/netbox_topology_views/static_dev/js/home.js +++ b/netbox_topology_views/static_dev/js/home.js @@ -33,6 +33,7 @@ var options = { } }; var selected_regions = []; +var selected_sites = []; function iniPlotboxIndex() { document.addEventListener('DOMContentLoaded', function () { @@ -113,6 +114,25 @@ function startLoadSearchBar() { } } }); + + $('#sites').on('select2:select', function (e) { + var data = e.params.data; + var index = selected_sites.indexOf(data.id.toString()); + if (index == -1) { + selected_sites.push(data.id.toString()); + } + }); + $('#sites').on('select2:unselect', function (e) { + var data = e.params.data; + var index = selected_sites.indexOf(data.id.toString()); + if (index > -1) { + selected_sites.splice(index, 1); + } + }); + $('#sites').on('select2:clear', function (e) { + selected_sites = []; + }); + $('#tags').select2({ allowClear: true, placeholder: "---------", @@ -178,7 +198,6 @@ function startLoadSearchBar() { $('#regions').on('select2:unselect', function (e) { var data = e.params.data; var index = selected_regions.indexOf(data.id.toString()); - console.log(index); if (index > -1) { selected_regions.splice(index, 1); } @@ -187,6 +206,47 @@ function startLoadSearchBar() { selected_regions = []; }); + $('#locations').select2({ + allowClear: true, + placeholder: "---------", + theme: "bootstrap", + multiple: true, + ajax: { + url: function (params) { + var base_url = "../../api/dcim/locations/?brief=true"; + if (selected_sites.length == 0) { + return base_url; + } + else { + for (var i = 0; i < selected_sites.length; i++) { + var tmp = "&site_id=" + selected_sites[i]; + base_url = base_url + tmp; + } + return base_url; + } + + }, + dataType: "json", + type: "GET", + data: function (params) { + var queryParameters = { + q: params.term + } + return queryParameters; + }, + processResults: function (data) { + return { + results: $.map(data.results, function (item) { + return { + text: item.name, + id: item.id + } + }) + }; + } + } + }); + var deviceRolesSelect = $('#device-roles'); $.ajax({ @@ -233,6 +293,7 @@ function handleButtonPress() { var value4 = $("#tags").val(); var value5 = $("#regions").val(); var value6 = $('#checkHideUnconnected').is(":checked"); + var value7 = $("#locations").val(); $.ajax({ type: "GET", url: "../../api/plugins/topology-views/search/search/", @@ -242,7 +303,8 @@ function handleButtonPress() { 'sites[]': value3, 'tags[]': value4, 'regions[]': value5, - 'hide_unconnected': value6 + 'hide_unconnected': value6, + 'locations[]': value7 }, headers: { "X-CSRFToken": csrftoken }, contentType: "application/json; charset=utf-8", diff --git a/netbox_topology_views/templates/netbox_topology_views/index.html b/netbox_topology_views/templates/netbox_topology_views/index.html index d1fd1e5..d1b703c 100644 --- a/netbox_topology_views/templates/netbox_topology_views/index.html +++ b/netbox_topology_views/templates/netbox_topology_views/index.html @@ -41,20 +41,24 @@
+
+
+ +
+ + +
+
- - -
-