diff --git a/netbox_topology_views/__init__.py b/netbox_topology_views/__init__.py index eec6841..f086bae 100644 --- a/netbox_topology_views/__init__.py +++ b/netbox_topology_views/__init__.py @@ -4,7 +4,7 @@ class TopologyViewsConfig(PluginConfig): name = 'netbox_topology_views' verbose_name = 'Topology views' description = 'An plugin to render toplogoy maps' - version = '0.4.8' + version = '0.4.9' author = 'Mattijs Vanhaverbeke' author_email = 'author@example.com' base_url = 'topology-views' 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 6bb48bf..ea93b80 100644 --- a/netbox_topology_views/static/netbox_topology_views/js/app.js +++ b/netbox_topology_views/static/netbox_topology_views/js/app.js @@ -1,349 +1 @@ -var graph = null; -var container = null; - -function iniPlotboxFull() { - document.addEventListener('DOMContentLoaded', function () { - container = document.getElementById('fullvisgraph'); - startRender(); - }, false); -} - -function startRender() { - var url = location.search; - - $.ajax({ - type: "GET", - url: "../../api/plugins/topology-views/search/search/" + url, - contentType: "application/json; charset=utf-8", - success: function (data_result, status, xhr) { - graph = null; - nodes = new vis.DataSet(); - edges = new vis.DataSet(); - graph = new vis.Network(container, { nodes: nodes, edges: edges }, options); - $.each(data_result["nodes"], function (index, device) { - nodes.add(device); - }); - $.each(data_result["edges"], function (index, edge) { - edges.add(edge); - }); - graph.fit(); - canvas = document.getElementById('fullvisgraph').getElementsByTagName('canvas')[0]; - }, - error: function (error_result) { - - }, -}); -} -var graph = null; -var container = null; -var downloadButton = null; -var MIME_TYPE = "image/png"; -var canvas = null; -var csrftoken = null; -var nodes = new vis.DataSet(); -var edges = new vis.DataSet(); -var options = { - interaction: { - hover: true, - hoverConnectedEdges: true, - multiselect: false - }, - 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' - } -}; -var 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'); - }, false); -} - -function startLoadSearchBar() { - $('#device-roles').select2({ - allowClear: true, - placeholder: "---------", - theme: "bootstrap", - multiple: true, - ajax: { - url: "../../api/dcim/device-roles/?brief=true", - 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 - } - }) - }; - } - } - }); - $('#sites').select2({ - allowClear: true, - placeholder: "---------", - theme: "bootstrap", - multiple: true, - ajax: { - url: function (params) { - var base_url = "../../api/dcim/sites/?brief=true"; - if (selected_regions.length == 0) { - return base_url; - } - else { - selected_regions.forEach(element => { - var tmp = "®ion_id=" + element; - 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 - } - }) - }; - } - } - }); - $('#tags').select2({ - allowClear: true, - placeholder: "---------", - theme: "bootstrap", - multiple: true, - ajax: { - url: "../../api/extras/tags/?brief=true", - 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 - } - }) - }; - } - } - }); - $('#regions').select2({ - allowClear: true, - placeholder: "---------", - theme: "bootstrap", - multiple: true, - ajax: { - url: "../../api/dcim/regions/?brief=true", - 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 - } - }) - }; - } - } - }); - - $('#regions').on('select2:select', function (e) { - var data = e.params.data; - var index = selected_regions.indexOf(data.id.toString()); - if (index == -1) { - selected_regions.push(data.id.toString()); - } - }); - $('#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); - } - }); - $('#regions').on('select2:clear', function (e) { - selected_regions = []; - }); - - - var deviceRolesSelect = $('#device-roles'); - $.ajax({ - type: 'GET', - url: '../../api/plugins/topology-views/preselectdeviceroles/' - }).then(function (data) { - $.each(data.results, function (index, device_role_to_preload) { - var option = new Option(device_role_to_preload.name, device_role_to_preload.id, true, true); - deviceRolesSelect.append(option).trigger('change'); - deviceRolesSelect.trigger({ - type: 'select2:select', - params: { - data: device_role_to_preload - } - }); - }); - }); - - var tagsSelect = $('#tags'); - $.ajax({ - type: 'GET', - url: '../../api/plugins/topology-views/preselecttags/' - }).then(function (data) { - $.each(data.results, function (index, tags_to_preload) { - var option = new Option(tags_to_preload.name, tags_to_preload.id, true, true); - tagsSelect.append(option).trigger('change'); - tagsSelect.trigger({ - type: 'select2:select', - params: { - data: tags_to_preload - } - }); - }); - }); -} - -function handleButtonPress() { - $("#search-form").submit(function (event) { - $("#status").html('Loading data'); - event.preventDefault(); - var value = $("#name").val(); - var value2 = $("#device-roles").val(); - var value3 = $("#sites").val(); - var value4 = $("#tags").val(); - var value5 = $("#regions").val(); - $.ajax({ - type: "GET", - url: "../../api/plugins/topology-views/search/search/", - data: { - 'name': value, - 'devicerole[]': value2, - 'sites[]': value3, - 'tags[]': value4, - 'regions[]': value5 - }, - 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 (data_result, status, xhr) { - $("#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(data_result["nodes"], function (index, device) { - nodes.add(device); - }); - $.each(data_result["edges"], function (index, edge) { - edges.add(edge); - }); - graph.fit(); - canvas = document.getElementById('visgraph').getElementsByTagName('canvas')[0]; - - graph.on('afterDrawing', function () { - $("#status").html('Ready'); - var image = canvas.toDataURL(MIME_TYPE); - downloadButton.href = image; - downloadButton.download = "topology"; - }); - - graph.on("dragEnd", function (params) { - dragged = this.getPositions(params.nodes); - $.each(dragged, function (node_id, coordinates) { - $("#coordstatus").html(''); - if ($('#checkSaveCoordinates').is(":checked")) { - //nodes.update({ id: node_id, physics: false }); - $.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: false, - data: JSON.stringify({ - 'node_id': node_id, - 'x': coordinates.x, - 'y': coordinates.y - }), - error: function (error_result) { - $("#coordstatus").html('Failed to update coordinates'); - }, - success: function (data_result) { - $("#coordstatus").html('Updated coordinates'); - }, - }); - } - }); - }); - - }, - error: function (error_result) { - $("#status").html('Something went wrong'); - }, - }); - }); -} +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]}})}var graph=null,container=null,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();$.ajax({type:"GET",url:"../../api/plugins/topology-views/search/search/",data:{name:t,"devicerole[]":n,"sites[]":a,"tags[]":s,"regions[]":o},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/netbox_topology_views/js/vendor.js b/netbox_topology_views/static/netbox_topology_views/js/vendor.js index f8188ae..4ee9489 100644 --- a/netbox_topology_views/static/netbox_topology_views/js/vendor.js +++ b/netbox_topology_views/static/netbox_topology_views/js/vendor.js @@ -1,85 +1 @@ -/** - * vis-network - * https://visjs.github.io/vis-network/ - * - * A dynamic, browser-based visualization library. - * - * @version 7.6.4 - * @date 2020-05-08T13:56:29.059Z - * - * @copyright (c) 2011-2017 Almende B.V, http://almende.com - * @copyright (c) 2017-2019 visjs contributors, https://github.com/visjs - * - * @license - * vis.js is dual licensed under both - * - * 1. The Apache 2.0 License - * http://www.apache.org/licenses/LICENSE-2.0 - * - * and - * - * 2. The MIT License - * http://opensource.org/licenses/MIT - * - * vis.js may be distributed under either license. - */ -!function(g,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((g=g||self).vis=g.vis||{})}(this,(function(g){"use strict";var t="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function e(g){return g&&g.__esModule&&Object.prototype.hasOwnProperty.call(g,"default")?g.default:g}function A(g,t){return g(t={exports:{}},t.exports),t.exports}function I(g){return g&&g.default||g}function C(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}var i=function(g){return g&&g.Math==Math&&g},n=i("object"==typeof globalThis&&globalThis)||i("object"==typeof window&&window)||i("object"==typeof self&&self)||i("object"==typeof t&&t)||Function("return this")(),o=function(g){try{return!!g()}catch(g){return!0}},r=!o((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]})),s={}.propertyIsEnumerable,a=Object.getOwnPropertyDescriptor,d={f:a&&!s.call({1:2},1)?function(g){var t=a(this,g);return!!t&&t.enumerable}:s},l=function(g,t){return{enumerable:!(1&g),configurable:!(2&g),writable:!(4&g),value:t}},h={}.toString,c=function(g){return h.call(g).slice(8,-1)},u="".split,f=o((function(){return!Object("z").propertyIsEnumerable(0)}))?function(g){return"String"==c(g)?u.call(g,""):Object(g)}:Object,p=function(g){if(null==g)throw TypeError("Can't call method on "+g);return g},v=function(g){return f(p(g))},y=function(g){return"object"==typeof g?null!==g:"function"==typeof g},m=function(g,t){if(!y(g))return g;var e,A;if(t&&"function"==typeof(e=g.toString)&&!y(A=e.call(g)))return A;if("function"==typeof(e=g.valueOf)&&!y(A=e.call(g)))return A;if(!t&&"function"==typeof(e=g.toString)&&!y(A=e.call(g)))return A;throw TypeError("Can't convert object to primitive value")},b={}.hasOwnProperty,w=function(g,t){return b.call(g,t)},x=n.document,k=y(x)&&y(x.createElement),D=function(g){return k?x.createElement(g):{}},O=!r&&!o((function(){return 7!=Object.defineProperty(D("div"),"a",{get:function(){return 7}}).a})),N=Object.getOwnPropertyDescriptor,Z={f:r?N:function(g,t){if(g=v(g),t=m(t,!0),O)try{return N(g,t)}catch(g){}if(w(g,t))return l(!d.f.call(g,t),g[t])}},M=/#|\.prototype\./,E=function(g,t){var e=T[G(g)];return e==R||e!=B&&("function"==typeof t?o(t):!!t)},G=E.normalize=function(g){return String(g).replace(M,".").toLowerCase()},T=E.data={},B=E.NATIVE="N",R=E.POLYFILL="P",F=E,S={},L=function(g){if("function"!=typeof g)throw TypeError(String(g)+" is not a function");return g},Q=function(g,t,e){if(L(g),void 0===t)return g;switch(e){case 0:return function(){return g.call(t)};case 1:return function(e){return g.call(t,e)};case 2:return function(e,A){return g.call(t,e,A)};case 3:return function(e,A,I){return g.call(t,e,A,I)}}return function(){return g.apply(t,arguments)}},Y=function(g){if(!y(g))throw TypeError(String(g)+" is not an object");return g},W=Object.defineProperty,z={f:r?W:function(g,t,e){if(Y(g),t=m(t,!0),Y(e),O)try{return W(g,t,e)}catch(g){}if("get"in e||"set"in e)throw TypeError("Accessors not supported");return"value"in e&&(g[t]=e.value),g}},P=r?function(g,t,e){return z.f(g,t,l(1,e))}:function(g,t,e){return g[t]=e,g},j=Z.f,V=function(g){var t=function(t,e,A){if(this instanceof g){switch(arguments.length){case 0:return new g;case 1:return new g(t);case 2:return new g(t,e)}return new g(t,e,A)}return g.apply(this,arguments)};return t.prototype=g.prototype,t},X=function(g,t){var e,A,I,C,i,o,r,s,a=g.target,d=g.global,l=g.stat,h=g.proto,c=d?n:l?n[a]:(n[a]||{}).prototype,u=d?S:S[a]||(S[a]={}),f=u.prototype;for(I in t)e=!F(d?I:a+(l?".":"#")+I,g.forced)&&c&&w(c,I),i=u[I],e&&(o=g.noTargetGet?(s=j(c,I))&&s.value:c[I]),C=e&&o?o:t[I],e&&typeof i==typeof C||(r=g.bind&&e?Q(C,n):g.wrap&&e?V(C):h&&"function"==typeof C?Q(Function.call,C):C,(g.sham||C&&C.sham||i&&i.sham)&&P(r,"sham",!0),u[I]=r,h&&(w(S,A=a+"Prototype")||P(S,A,{}),S[A][I]=C,g.real&&f&&!f[I]&&P(f,I,C)))},U=[].slice,_={},H=function(g,t,e){if(!(t in _)){for(var A=[],I=0;I=.1;)(h=+C[a++%i])>s&&(h=s),l=Math.sqrt(h*h/(1+r*r)),t+=l=n<0?-l:l,e+=r*l,!0===d?g.lineTo(t,e):g.moveTo(t,e),s-=h,d=!d}var ig={circle:tg,dashedLine:Cg,database:Ig,diamond:function(g,t,e,A){g.beginPath(),g.lineTo(t,e+A),g.lineTo(t+A,e),g.lineTo(t,e-A),g.lineTo(t-A,e),g.closePath()},ellipse:Ag,ellipse_vis:Ag,hexagon:function(g,t,e,A){g.beginPath();var I=2*Math.PI/6;g.moveTo(t+A,e);for(var C=1;C<6;C++)g.lineTo(t+A*Math.cos(I*C),e+A*Math.sin(I*C));g.closePath()},roundRect:eg,square:function(g,t,e,A){g.beginPath(),g.rect(t-A,e-A,2*A,2*A),g.closePath()},star:function(g,t,e,A){g.beginPath(),e+=.1*(A*=.82);for(var I=0;I<10;I++){var C=I%2==0?1.3*A:.5*A;g.lineTo(t+C*Math.sin(2*I*Math.PI/10),e-C*Math.cos(2*I*Math.PI/10))}g.closePath()},triangle:function(g,t,e,A){g.beginPath(),e+=.275*(A*=1.15);var I=2*A,C=I/2,i=Math.sqrt(3)/6*I,n=Math.sqrt(I*I-C*C);g.moveTo(t,e-(n-i)),g.lineTo(t+C,e+i),g.lineTo(t-C,e+i),g.lineTo(t,e-(n-i)),g.closePath()},triangleDown:function(g,t,e,A){g.beginPath(),e-=.275*(A*=1.15);var I=2*A,C=I/2,i=Math.sqrt(3)/6*I,n=Math.sqrt(I*I-C*C);g.moveTo(t,e+(n-i)),g.lineTo(t+C,e-i),g.lineTo(t-C,e-i),g.lineTo(t,e+(n-i)),g.closePath()}};var ng=A((function(g){function t(g){if(g)return function(g){for(var e in t.prototype)g[e]=t.prototype[e];return g}(g)}g.exports=t,t.prototype.on=t.prototype.addEventListener=function(g,t){return this._callbacks=this._callbacks||{},(this._callbacks["$"+g]=this._callbacks["$"+g]||[]).push(t),this},t.prototype.once=function(g,t){function e(){this.off(g,e),t.apply(this,arguments)}return e.fn=t,this.on(g,e),this},t.prototype.off=t.prototype.removeListener=t.prototype.removeAllListeners=t.prototype.removeEventListener=function(g,t){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var e,A=this._callbacks["$"+g];if(!A)return this;if(1==arguments.length)return delete this._callbacks["$"+g],this;for(var I=0;I0?Hg:_g)(g)},Kg=Math.min,qg=function(g){return g>0?Kg(Jg(g),9007199254740991):0},$g=Math.max,gt=Math.min,tt=function(g,t){var e=Jg(g);return e<0?$g(e+t,0):gt(e,t)},et=function(g){return function(t,e,A){var I,C=v(t),i=qg(C.length),n=tt(A,i);if(g&&e!=e){for(;i>n;)if((I=C[n++])!=I)return!0}else for(;i>n;n++)if((g||n in C)&&C[n]===e)return g||n||0;return!g&&-1}},At={includes:et(!0),indexOf:et(!1)},It=At.indexOf,Ct=function(g,t){var e,A=v(g),I=0,C=[];for(e in A)!w(wg,e)&&w(A,e)&&C.push(e);for(;t.length>I;)w(A,e=t[I++])&&(~It(C,e)||C.push(e));return C},it=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],nt=Object.keys||function(g){return Ct(g,it)},ot=r?Object.defineProperties:function(g,t){Y(g);for(var e,A=nt(t),I=A.length,C=0;I>C;)z.f(g,e=A[C++],t[e]);return g},rt=function(g){return"function"==typeof g?g:void 0},st=function(g,t){return arguments.length<2?rt(S[g])||rt(n[g]):S[g]&&S[g][t]||n[g]&&n[g][t]},at=st("document","documentElement"),dt=bg("IE_PROTO"),lt=function(){},ht=function(g){return"