diff --git a/lib/infobox/main.js b/lib/infobox/main.js index 3e51e61..f2984b7 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -39,9 +39,9 @@ define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Nod self.resetView = destroy; - self.gotoNode = function gotoNode(d, gateways) { + self.gotoNode = function gotoNode(d, nodeDict) { create(); - node = new Node(config, el, router, d, linkScale, gateways); + node = new Node(config, el, router, d, linkScale, nodeDict); node.render(); }; diff --git a/lib/infobox/node.js b/lib/infobox/node.js index a090dfd..98c8b10 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -75,25 +75,25 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'], V.h('i', { props: { className: 'ion-people', title: _.t('node.clients') } }) ]), V.h('span', - { props: { className: 'legend-24ghz'}}, + { props: { className: 'legend-24ghz' } }, [ d.clients_wifi24, V.h('br'), - V.h('span', { props: { className: 'symbol', title: '2,4 Ghz'}}) + V.h('span', { props: { className: 'symbol', title: '2,4 Ghz' } }) ]), V.h('span', - { props: { className: 'legend-5ghz'}}, + { props: { className: 'legend-5ghz' } }, [ d.clients_wifi5, V.h('br'), - V.h('span', { props: { className: 'symbol', title: '5 Ghz'}}) + V.h('span', { props: { className: 'symbol', title: '5 Ghz' } }) ]), V.h('span', - { props: { className: 'legend-others'}}, + { props: { className: 'legend-others' } }, [ d.clients_other, V.h('br'), - V.h('span', { props: { className: 'symbol', title: _.t('others')}}) + V.h('span', { props: { className: 'symbol', title: _.t('others') } }) ]) ]; @@ -184,26 +184,58 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'], return helper.showStat(V, o, subst); } - return function (config, el, router, d, linkScale, gateways) { + return function (config, el, router, d, linkScale, nodeDict) { + function nodeLink(node) { + return V.h('a', { + props: { + className: node.is_online ? 'online' : 'offline', + href: router.generateLink({ node: node.node_id }) + }, on: { + click: function (e) { + router.fullUrl({ node: node.node_id }, e); + } + } + }, node.hostname); + } + + function nodeidLink(nodeid) { + if (nodeDict[nodeid]) { + return nodeLink(nodeDict[nodeid]); + } + return nodeid; + } + + function showGateway(node) { + var gatewayCols = [ + V.h('span', [ + nodeidLink(node.gateway_nexthop), + V.h('br'), + _.t('node.nexthop') + ]), + V.h('span', { props: { className: 'ion-arrow-right-c' } }), + V.h('span', [ + nodeidLink(node.gateway), + V.h('br'), + 'IPv4' + ]), + V.h('span', [ + nodeidLink(node.gateway6), + V.h('br'), + 'IPv6' + ]) + ]; + + return V.h('td', { props: { className: 'gateway' } }, gatewayCols); + } + function renderNeighbourRow(n) { var icons = []; if (helper.hasLocation(n.node)) { icons.push(V.h('span', { props: { className: 'ion-location' } })); } - var name = V.h('a', { - props: { - className: 'online', - href: router.generateLink({ node: n.node.node_id }) - }, on: { - click: function (e) { - router.fullUrl({ node: n.node.node_id }, e); - } - } - }, n.node.hostname); - var td1 = V.h('td', icons); - var td2 = V.h('td', name); + var td2 = V.h('td', nodeLink(n.node)); var td3 = V.h('td', (n.node.clients ? n.node.clients.toString() : '0')); var td4 = V.h('td', { style: { color: linkScale((n.link.source_tq + n.link.target_tq) / 2) } }, helper.showTq(n.link.source_tq) + ' - ' + helper.showTq(n.link.target_tq)); var td5 = V.h('td', helper.showDistance(n.link)); @@ -280,9 +312,9 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'], children.push(helper.attributeEntry(V, 'node.ram', showRAM(d))); } children.push(helper.attributeEntry(V, 'node.ipAddresses', showIPs(d))); - children.push(helper.attributeEntry(V, 'node.selectedGateway', gateways[helper.dictGet(d, ['gateway'])])); children.push(helper.attributeEntry(V, 'node.update', showAutoupdate(d))); children.push(helper.attributeEntry(V, 'node.clients', showClients(d))); + children.push(helper.attributeEntry(V, 'node.gateway', showGateway(d))); var elNew = V.h('table', children); table = V.patch(table, elNew); diff --git a/lib/main.js b/lib/main.js index 789ce60..bf74dda 100644 --- a/lib/main.js +++ b/lib/main.js @@ -7,7 +7,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'], var timestamp; var nodes = []; var links = []; - var gateways = {}; + var nodeDict = {}; for (var i = 0; i < data.length; ++i) { nodes = nodes.concat(data[i].nodes); @@ -28,12 +28,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'], nodes.forEach(function (d) { d.neighbours = []; - if (d.is_gateway && d.network.mesh) { - var mesh = d.network.mesh; - mesh[Object.keys(mesh)[0]].interfaces.tunnel.forEach(function (mac) { - gateways[mac] = d.hostname; - }); - } + nodeDict[d.node_id] = d; }); links.forEach(function (d) { @@ -77,7 +72,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'], links: [], nodes: [] }, - gateways: gateways + nodeDict: nodeDict }; } diff --git a/lib/map/clientlayer.js b/lib/map/clientlayer.js index c970bfa..42e57ef 100644 --- a/lib/map/clientlayer.js +++ b/lib/map/clientlayer.js @@ -56,7 +56,6 @@ define(['leaflet', 'rbush', 'helper'], helper.positionClients(ctx, p, d.startAngle, d.node, startDistance); }); - return tile; } }); diff --git a/lib/proportions.js b/lib/proportions.js index 611543b..260a761 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -13,6 +13,7 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'], var geoTable; var autoTable; var gatewayTable; + var gateway6Table; var siteTable; function count(nodes, key, f) { @@ -78,11 +79,17 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'], self.setData = function setData(data) { var onlineNodes = data.nodes.all.filter(helper.online); var nodes = onlineNodes.concat(data.nodes.lost); - var nodeDict = {}; - data.nodes.all.forEach(function (d) { - nodeDict[d.node_id] = d; - }); + function hostnameOfNodeID(nodeid) { + var gateway = data.nodeDict[nodeid]; + if (gateway) { + return gateway.hostname; + } + return null; + } + + var gatewayDict = count(nodes, ['gateway'], hostnameOfNodeID); + var gateway6Dict = count(nodes, ['gateway6'], hostnameOfNodeID); var statusDict = count(nodes, ['is_online'], function (d) { return d ? 'online' : 'offline'; @@ -102,16 +109,6 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'], return _.t('node.deactivated'); }); - var gatewayDict = count(nodes, ['is_gateway'], function (d) { - for (var mac in data.gateways) { - if (data.gateways.hasOwnProperty(mac) && mac === d) { - d = data.gateways[mac]; - return d; - } - } - return null; - }); - var siteDict = count(nodes, ['nodeinfo', 'site_code'], function (d) { if (config.siteNames) { config.siteNames.forEach(function (t) { @@ -144,7 +141,10 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'], autoTable = fillTable('node.update', autoTable, autoDict.sort(function (a, b) { return b[1] - a[1]; })); - gatewayTable = fillTable('node.gateway', gatewayTable, gatewayDict.sort(function (a, b) { + gatewayTable = fillTable('node.selectedGatewayIPv4', gatewayTable, gatewayDict.sort(function (a, b) { + return b[1] - a[1]; + })); + gateway6Table = fillTable('node.selectedGatewayIPv6', gateway6Table, gateway6Dict.sort(function (a, b) { return b[1] - a[1]; })); siteTable = fillTable('node.site', siteTable, siteDict.sort(function (a, b) { @@ -158,7 +158,8 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'], self.renderSingle(el, 'node.hardware', hwTable); self.renderSingle(el, 'node.visible', geoTable); self.renderSingle(el, 'node.update', autoTable); - self.renderSingle(el, 'node.gateway', gatewayTable); + self.renderSingle(el, 'node.selectedGatewayIPv4', gatewayTable); + self.renderSingle(el, 'node.selectedGatewayIPv6', gateway6Table); self.renderSingle(el, 'node.site', siteTable); if (config.globalInfos) { diff --git a/lib/utils/router.js b/lib/utils/router.js index 1e52204..7d144a4 100644 --- a/lib/utils/router.js +++ b/lib/utils/router.js @@ -3,7 +3,7 @@ define(['Navigo'], function (Navigo) { return function (language) { var init = false; - var objects = { nodes: {}, links: {}, gateways: {} }; + var objects = { nodes: {}, links: {}, nodeDict: {} }; var targets = []; var views = {}; var current = {}; @@ -18,7 +18,7 @@ define(['Navigo'], function (Navigo) { function gotoNode(d) { if (d.nodeId in objects.nodes) { targets.forEach(function (t) { - t.gotoNode(objects.nodes[d.nodeId], objects.gateways); + t.gotoNode(objects.nodes[d.nodeId], objects.nodeDict); }); } } @@ -141,7 +141,7 @@ define(['Navigo'], function (Navigo) { router.setData = function setData(data) { objects.nodes = {}; objects.links = {}; - objects.gateways = data.gateways; + objects.nodeDict = data.nodeDict; data.nodes.all.forEach(function (d) { objects.nodes[d.node_id] = d; diff --git a/locale/en.json b/locale/en.json index da3dc05..db65150 100644 --- a/locale/en.json +++ b/locale/en.json @@ -27,7 +27,9 @@ "systemLoad": "Load average", "ram": "Memory usage", "ipAddresses": "IP addresses", - "selectedGateway": "Selected gateway", + "nexthop": "Nexthop", + "selectedGatewayIPv4": "Selected ipv4-gateway", + "selectedGatewayIPv6": "Selected ipv6-gateway", "link": "Link |||| Links", "node": "Node |||| Nodes", "new": "New nodes", diff --git a/scss/modules/_infobox.scss b/scss/modules/_infobox.scss index 5bf25e3..6e97048 100644 --- a/scss/modules/_infobox.scss +++ b/scss/modules/_infobox.scss @@ -1,5 +1,6 @@ .infobox { - .clients { + .clients, + .gateway { display: flex; span { @@ -7,7 +8,8 @@ text-align: center; } - .ion-people { + .ion-people, + .ion-arrow-right-c { font-size: 1.5em; } }