[TASK] Dynamic node attributes via config
This commit is contained in:
parent
c407f2e334
commit
6091a8b82c
4
app.js
4
app.js
@ -37,5 +37,7 @@ require.config({
|
|||||||
});
|
});
|
||||||
|
|
||||||
require(['main'], function (main) {
|
require(['main'], function (main) {
|
||||||
main(jsonData);
|
/** global: config */
|
||||||
|
window.config = jsonData;
|
||||||
|
main();
|
||||||
});
|
});
|
||||||
|
@ -6,10 +6,69 @@
|
|||||||
"nodeZoom": 18,
|
"nodeZoom": 18,
|
||||||
"labelZoom": 13,
|
"labelZoom": 13,
|
||||||
"clientZoom": 15,
|
"clientZoom": 15,
|
||||||
"nodeInfobox": {
|
"nodeAttr": [
|
||||||
"contact": false,
|
// value can be a node attribute (1 depth) or a a function in utils/node with prefix show
|
||||||
"hardwareUsage": true
|
{
|
||||||
|
"name": "node.status",
|
||||||
|
"value": "Status"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "node.gateway",
|
||||||
|
"value": "Gateway"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.coordinates",
|
||||||
|
"value": "GeoURI"
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// "name": "node.contact",
|
||||||
|
// "value": "owner"
|
||||||
|
// },
|
||||||
|
{
|
||||||
|
"name": "node.hardware",
|
||||||
|
"value": "model"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.primaryMac",
|
||||||
|
"value": "mac"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.firmware",
|
||||||
|
"value": "Firmware"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.uptime",
|
||||||
|
"value": "Uptime"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.firstSeen",
|
||||||
|
"value": "FirstSeen"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.systemLoad",
|
||||||
|
"value": "Load"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.ram",
|
||||||
|
"value": "RAM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.ipAddresses",
|
||||||
|
"value": "IPs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.update",
|
||||||
|
"value": "Autoupdate"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.site",
|
||||||
|
"value": "Site"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "node.clients",
|
||||||
|
"value": "Clients"
|
||||||
|
}
|
||||||
|
],
|
||||||
"supportedLocale": [
|
"supportedLocale": [
|
||||||
"en",
|
"en",
|
||||||
"de",
|
"de",
|
||||||
|
@ -2,7 +2,7 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
|
|||||||
function (d3Selection, d3Force, d3Zoom, d3Drag, d3Timer, d3Ease, d3Interpolate, math, draw) {
|
function (d3Selection, d3Force, d3Zoom, d3Drag, d3Timer, d3Ease, d3Interpolate, math, draw) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, linkScale, sidebar, router) {
|
return function (linkScale, sidebar) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var el;
|
var el;
|
||||||
var canvas;
|
var canvas;
|
||||||
|
20
lib/gui.js
20
lib/gui.js
@ -7,7 +7,7 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
|
|||||||
Title, About, DataDistributor, FilterGUI, HostnameFilter) {
|
Title, About, DataDistributor, FilterGUI, HostnameFilter) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, router, language) {
|
return function (language) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var content;
|
var content;
|
||||||
var contentDiv;
|
var contentDiv;
|
||||||
@ -38,7 +38,7 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
|
|||||||
function addContent(K) {
|
function addContent(K) {
|
||||||
removeContent();
|
removeContent();
|
||||||
|
|
||||||
content = new K(config, linkScale, sidebar.getWidth, router, buttons);
|
content = new K(linkScale, sidebar.getWidth, buttons);
|
||||||
content.render(contentDiv);
|
content.render(contentDiv);
|
||||||
|
|
||||||
fanout.add(content);
|
fanout.add(content);
|
||||||
@ -77,18 +77,18 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
|
|||||||
|
|
||||||
buttons.appendChild(buttonToggle);
|
buttons.appendChild(buttonToggle);
|
||||||
|
|
||||||
var title = new Title(config);
|
var title = new Title();
|
||||||
|
|
||||||
var header = new Container('header');
|
var header = new Container('header');
|
||||||
var infobox = new Infobox(config, sidebar, router, linkScale);
|
var infobox = new Infobox(sidebar, linkScale);
|
||||||
var tabs = new Tabs();
|
var tabs = new Tabs();
|
||||||
var overview = new Container();
|
var overview = new Container();
|
||||||
var legend = new Legend(config, language);
|
var legend = new Legend(language);
|
||||||
var newnodeslist = new SimpleNodelist('new', 'firstseen', router, _.t('node.new'));
|
var newnodeslist = new SimpleNodelist('new', 'firstseen', _.t('node.new'));
|
||||||
var lostnodeslist = new SimpleNodelist('lost', 'lastseen', router, _.t('node.missing'));
|
var lostnodeslist = new SimpleNodelist('lost', 'lastseen', _.t('node.missing'));
|
||||||
var nodelist = new Nodelist(router);
|
var nodelist = new Nodelist();
|
||||||
var linklist = new Linklist(linkScale, router);
|
var linklist = new Linklist(linkScale);
|
||||||
var statistics = new Proportions(config, fanout);
|
var statistics = new Proportions(fanout);
|
||||||
var about = new About();
|
var about = new About();
|
||||||
|
|
||||||
fanoutUnfiltered.add(legend);
|
fanoutUnfiltered.add(legend);
|
||||||
|
@ -13,7 +13,7 @@ define(['helper', 'snabbdom'], function (helper, V) {
|
|||||||
return helper.showStat(V, o, subst);
|
return helper.showStat(V, o, subst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return function (config, el, router, d, linkScale) {
|
return function (el, d, linkScale) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var header = document.createElement('div');
|
var header = document.createElement('div');
|
||||||
var table = document.createElement('table');
|
var table = document.createElement('table');
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define(['helper'], function (helper) {
|
define(['helper'], function (helper) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, el, router, d) {
|
return function (el, d) {
|
||||||
var sidebarTitle = document.createElement('h2');
|
var sidebarTitle = document.createElement('h2');
|
||||||
sidebarTitle.textContent = _.t('location.location');
|
sidebarTitle.textContent = _.t('location.location');
|
||||||
el.appendChild(sidebarTitle);
|
el.appendChild(sidebarTitle);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Node, location) {
|
define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Node, location) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, sidebar, router, linkScale) {
|
return function (sidebar, linkScale) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var el;
|
var el;
|
||||||
var node;
|
var node;
|
||||||
@ -41,19 +41,19 @@ define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Nod
|
|||||||
|
|
||||||
self.gotoNode = function gotoNode(d, nodeDict) {
|
self.gotoNode = function gotoNode(d, nodeDict) {
|
||||||
create();
|
create();
|
||||||
node = new Node(config, el, router, d, linkScale, nodeDict);
|
node = new Node(el, d, linkScale, nodeDict);
|
||||||
node.render();
|
node.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
self.gotoLink = function gotoLink(d) {
|
self.gotoLink = function gotoLink(d) {
|
||||||
create();
|
create();
|
||||||
link = new Link(config, el, router, d, linkScale);
|
link = new Link(el, d, linkScale);
|
||||||
link.render();
|
link.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
self.gotoLocation = function gotoLocation(d) {
|
self.gotoLocation = function gotoLocation(d) {
|
||||||
create();
|
create();
|
||||||
location(config, el, router, d);
|
location(el, d);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.setData = function setData(d) {
|
self.setData = function setData(d) {
|
||||||
|
@ -1,137 +1,8 @@
|
|||||||
define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper', 'utils/node'],
|
||||||
function (SortTable, V, d3Interpolate, moment, helper) {
|
function (SortTable, V, d3Interpolate, moment, helper, nodef) {
|
||||||
'use strict';
|
'use strict';
|
||||||
V = V.default;
|
V = V.default;
|
||||||
|
|
||||||
function showGeoURI(d) {
|
|
||||||
if (!helper.hasLocation(d)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return V.h('td',
|
|
||||||
V.h('a',
|
|
||||||
{ props: { href: 'geo:' + d.location.latitude + ',' + d.location.longitude } },
|
|
||||||
Number(d.location.latitude.toFixed(6)) + ', ' + Number(d.location.longitude.toFixed(6))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showStatus(d) {
|
|
||||||
return V.h('td',
|
|
||||||
{ props: { className: d.is_online ? 'online' : 'offline' } },
|
|
||||||
_.t((d.is_online ? 'node.lastOnline' : 'node.lastOffline'), {
|
|
||||||
time: d.lastseen.fromNow(),
|
|
||||||
date: d.lastseen.format('DD.MM.YYYY, H:mm:ss')
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function showFirmware(d) {
|
|
||||||
return [
|
|
||||||
helper.dictGet(d, ['firmware', 'release']),
|
|
||||||
helper.dictGet(d, ['firmware', 'base'])
|
|
||||||
].filter(function (n) {
|
|
||||||
return n !== null;
|
|
||||||
}).join(' / ') || undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showSite(d, config) {
|
|
||||||
var rt = d.site_code;
|
|
||||||
if (config.siteNames) {
|
|
||||||
config.siteNames.forEach(function (t) {
|
|
||||||
if (d.site_code === t.site) {
|
|
||||||
rt = t.name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return rt;
|
|
||||||
}
|
|
||||||
|
|
||||||
function showClients(d) {
|
|
||||||
if (!d.is_online) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
var clients = [
|
|
||||||
V.h('span', [
|
|
||||||
d.clients > 0 ? d.clients : _.t('none'),
|
|
||||||
V.h('br'),
|
|
||||||
V.h('i', { props: { className: 'ion-people', title: _.t('node.clients') } })
|
|
||||||
]),
|
|
||||||
V.h('span',
|
|
||||||
{ 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: 'legend-5ghz' } },
|
|
||||||
[
|
|
||||||
d.clients_wifi5,
|
|
||||||
V.h('br'),
|
|
||||||
V.h('span', { props: { className: 'symbol', title: '5 Ghz' } })
|
|
||||||
]),
|
|
||||||
V.h('span',
|
|
||||||
{ props: { className: 'legend-others' } },
|
|
||||||
[
|
|
||||||
d.clients_other,
|
|
||||||
V.h('br'),
|
|
||||||
V.h('span', { props: { className: 'symbol', title: _.t('others') } })
|
|
||||||
])
|
|
||||||
];
|
|
||||||
|
|
||||||
return V.h('td', { props: { className: 'clients' } }, clients);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showIPs(d) {
|
|
||||||
var string = [];
|
|
||||||
var ips = d.network.addresses;
|
|
||||||
ips.sort();
|
|
||||||
ips.forEach(function (ip, i) {
|
|
||||||
if (i > 0) {
|
|
||||||
string.push(V.h('br'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ip.indexOf('fe80:') !== 0) {
|
|
||||||
string.push(V.h('a', { props: { href: 'http://[' + ip + ']/', target: '_blank' } }, ip));
|
|
||||||
} else {
|
|
||||||
string.push(ip);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return V.h('td', string);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showBar(v, width, warning) {
|
|
||||||
return V.h('span',
|
|
||||||
{ props: { className: 'bar' + (warning ? ' warning' : '') } },
|
|
||||||
[
|
|
||||||
V.h('span',
|
|
||||||
{
|
|
||||||
style: { width: (width * 100) + '%' }
|
|
||||||
}),
|
|
||||||
V.h('label', v)
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showLoad(d) {
|
|
||||||
if (!('loadavg' in d)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return showBar(d.loadavg.toFixed(2), d.loadavg % 1, d.loadavg >= d.nproc);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showRAM(d) {
|
|
||||||
if (!('memory_usage' in d)) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
return showBar(Math.round(d.memory_usage * 100) + ' %', d.memory_usage, d.memory_usage >= 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showAutoupdate(d) {
|
|
||||||
return d.autoupdater.enabled ? _.t('node.activated', { branch: d.autoupdater.branch }) : _.t('node.deactivated');
|
|
||||||
}
|
|
||||||
|
|
||||||
function showStatImg(o, d) {
|
function showStatImg(o, d) {
|
||||||
var subst = {};
|
var subst = {};
|
||||||
subst['{NODE_ID}'] = d.node_id;
|
subst['{NODE_ID}'] = d.node_id;
|
||||||
@ -141,7 +12,7 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
|||||||
return helper.showStat(V, o, subst);
|
return helper.showStat(V, o, subst);
|
||||||
}
|
}
|
||||||
|
|
||||||
return function (config, el, router, d, linkScale, nodeDict) {
|
return function (el, d, linkScale, nodeDict) {
|
||||||
function nodeLink(node) {
|
function nodeLink(node) {
|
||||||
return V.h('a', {
|
return V.h('a', {
|
||||||
props: {
|
props: {
|
||||||
@ -249,23 +120,24 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
|||||||
|
|
||||||
var children = [];
|
var children = [];
|
||||||
|
|
||||||
children.push(helper.attributeEntry(V, 'node.status', showStatus(d)));
|
config.nodeAttr.forEach(function (row) {
|
||||||
children.push(helper.attributeEntry(V, 'node.gateway', d.is_gateway ? 'ja' : undefined));
|
var field = d[row.value];
|
||||||
children.push(helper.attributeEntry(V, 'node.coordinates', showGeoURI(d)));
|
if (nodef['show' + row.value] !== undefined) {
|
||||||
children.push(helper.attributeEntry(V, 'node.contact', d.owner));
|
field = nodef['show' + row.value](d);
|
||||||
children.push(helper.attributeEntry(V, 'node.hardware', d.model));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.primaryMac', d.network.mac));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.firmware', showFirmware(d)));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.site', showSite(d, config)));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.uptime', moment.utc(d.uptime).local().fromNow(true)));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.firstSeen', d.firstseen.fromNow(true)));
|
|
||||||
if (config.nodeInfobox && config.nodeInfobox.hardwareUsage) {
|
|
||||||
children.push(helper.attributeEntry(V, 'node.systemLoad', showLoad(d)));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.ram', showRAM(d)));
|
|
||||||
}
|
}
|
||||||
children.push(helper.attributeEntry(V, 'node.ipAddresses', showIPs(d)));
|
|
||||||
children.push(helper.attributeEntry(V, 'node.update', showAutoupdate(d)));
|
if (field) {
|
||||||
children.push(helper.attributeEntry(V, 'node.clients', showClients(d)));
|
if (typeof field !== 'object') {
|
||||||
|
field = V.h('td', field);
|
||||||
|
}
|
||||||
|
|
||||||
|
children.push(V.h('tr', [
|
||||||
|
V.h('th', _.t(row.name)),
|
||||||
|
field
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
children.push(helper.attributeEntry(V, 'node.gateway', showGateway(d)));
|
children.push(helper.attributeEntry(V, 'node.gateway', showGateway(d)));
|
||||||
|
|
||||||
var elNew = V.h('table', children);
|
var elNew = V.h('table', children);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define(['helper'], function (helper) {
|
define(['helper'], function (helper) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, language) {
|
return function (language) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var stats = document.createTextNode('');
|
var stats = document.createTextNode('');
|
||||||
var timestamp = document.createTextNode('');
|
var timestamp = document.createTextNode('');
|
||||||
|
@ -28,7 +28,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
|
|||||||
reverse: true
|
reverse: true
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return function (linkScale, router) {
|
return function (linkScale) {
|
||||||
var table = new SortTable(headings, 2, renderRow);
|
var table = new SortTable(headings, 2, renderRow);
|
||||||
V = V.default;
|
V = V.default;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
|||||||
function (moment, Router, L, GUI, helper, Language) {
|
function (moment, Router, L, GUI, helper, Language) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config) {
|
return function () {
|
||||||
function handleData(data) {
|
function handleData(data) {
|
||||||
var timestamp;
|
var timestamp;
|
||||||
var nodes = [];
|
var nodes = [];
|
||||||
@ -72,8 +72,8 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var language = new Language(config);
|
var language = new Language();
|
||||||
var router = new Router(language);
|
window.router = new Router(language);
|
||||||
|
|
||||||
config.dataPath.forEach(function (d, i) {
|
config.dataPath.forEach(function (d, i) {
|
||||||
config.dataPath[i] += 'meshviewer.json';
|
config.dataPath[i] += 'meshviewer.json';
|
||||||
@ -88,7 +88,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
|||||||
|
|
||||||
update()
|
update()
|
||||||
.then(function (d) {
|
.then(function (d) {
|
||||||
var gui = new GUI(config, router, language);
|
var gui = new GUI(language);
|
||||||
gui.setData(d);
|
gui.setData(d);
|
||||||
router.setData(d);
|
router.setData(d);
|
||||||
router.resolve();
|
router.resolve();
|
||||||
|
@ -8,7 +8,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
|||||||
minZoom: 0
|
minZoom: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
return function (config, linkScale, sidebar, router, buttons) {
|
return function (linkScale, sidebar, buttons) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var savedView;
|
var savedView;
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
|||||||
baseLayers[d.name] = d.layer;
|
baseLayers[d.name] = d.layer;
|
||||||
});
|
});
|
||||||
|
|
||||||
var button = new Button(config, map, router, buttons);
|
var button = new Button(map, buttons);
|
||||||
|
|
||||||
map.on('locationfound', button.locationFound);
|
map.on('locationfound', button.locationFound);
|
||||||
map.on('locationerror', button.locationError);
|
map.on('locationerror', button.locationError);
|
||||||
@ -175,7 +175,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
|||||||
linkDict = {};
|
linkDict = {};
|
||||||
|
|
||||||
clientLayer.setData(data);
|
clientLayer.setData(data);
|
||||||
labelLayer.setData(data, map, nodeDict, linkDict, linkScale, router, config);
|
labelLayer.setData(data, map, nodeDict, linkDict, linkScale);
|
||||||
|
|
||||||
updateView(true);
|
updateView(true);
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@ define(['map/clientlayer', 'map/labellayer', 'leaflet', 'map/locationmarker'],
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return function (config, map, router, buttons) {
|
return function (map, buttons) {
|
||||||
var userLocation;
|
var userLocation;
|
||||||
|
|
||||||
var locateUserButton = new LocateButton(function (d) {
|
var locateUserButton = new LocateButton(function (d) {
|
||||||
|
@ -76,7 +76,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
return { minX: x, minY: y, maxX: x + width, maxY: y + height };
|
return { minX: x, minY: y, maxX: x + width, maxY: y + height };
|
||||||
}
|
}
|
||||||
|
|
||||||
function mkMarker(dict, iconFunc, router) {
|
function mkMarker(dict, iconFunc) {
|
||||||
return function (d) {
|
return function (d) {
|
||||||
var m = L.circleMarker([d.location.latitude, d.location.longitude], iconFunc(d));
|
var m = L.circleMarker([d.location.latitude, d.location.longitude], iconFunc(d));
|
||||||
|
|
||||||
@ -95,7 +95,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function addLinksToMap(dict, linkScale, graph, router) {
|
function addLinksToMap(dict, linkScale, graph) {
|
||||||
graph = graph.filter(function (d) {
|
graph = graph.filter(function (d) {
|
||||||
return 'distance' in d && d.type.indexOf('vpn') !== 0;
|
return 'distance' in d && d.type.indexOf('vpn') !== 0;
|
||||||
});
|
});
|
||||||
@ -125,7 +125,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getIcon(config, color) {
|
function getIcon(color) {
|
||||||
return Object.assign({}, config.icon.base, config.icon[color]);
|
return Object.assign({}, config.icon.base, config.icon[color]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,12 +136,12 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
this.prepareLabels();
|
this.prepareLabels();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
setData: function (data, map, nodeDict, linkDict, linkScale, router, config) {
|
setData: function (data, map, nodeDict, linkDict, linkScale) {
|
||||||
var iconOnline = getIcon(config, 'online');
|
var iconOnline = getIcon('online');
|
||||||
var iconOffline = getIcon(config, 'offline');
|
var iconOffline = getIcon('offline');
|
||||||
var iconLost = getIcon(config, 'lost');
|
var iconLost = getIcon('lost');
|
||||||
var iconAlert = getIcon(config, 'alert');
|
var iconAlert = getIcon('alert');
|
||||||
var iconNew = getIcon(config, 'new');
|
var iconNew = getIcon('new');
|
||||||
// Check if init or data is already set
|
// Check if init or data is already set
|
||||||
if (groupLines) {
|
if (groupLines) {
|
||||||
groupOffline.clearLayers();
|
groupOffline.clearLayers();
|
||||||
@ -151,7 +151,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
groupLines.clearLayers();
|
groupLines.clearLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
var lines = addLinksToMap(linkDict, linkScale, data.links, router);
|
var lines = addLinksToMap(linkDict, linkScale, data.links);
|
||||||
groupLines = L.featureGroup(lines).addTo(map);
|
groupLines = L.featureGroup(lines).addTo(map);
|
||||||
|
|
||||||
var nodesOnline = helper.subtract(data.nodes.online, data.nodes.new).filter(helper.hasLocation);
|
var nodesOnline = helper.subtract(data.nodes.online, data.nodes.new).filter(helper.hasLocation);
|
||||||
@ -161,15 +161,15 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
|
|
||||||
var markersOnline = nodesOnline.map(mkMarker(nodeDict, function () {
|
var markersOnline = nodesOnline.map(mkMarker(nodeDict, function () {
|
||||||
return iconOnline;
|
return iconOnline;
|
||||||
}, router));
|
}));
|
||||||
|
|
||||||
var markersOffline = nodesOffline.map(mkMarker(nodeDict, function () {
|
var markersOffline = nodesOffline.map(mkMarker(nodeDict, function () {
|
||||||
return iconOffline;
|
return iconOffline;
|
||||||
}, router));
|
}));
|
||||||
|
|
||||||
var markersNew = nodesNew.map(mkMarker(nodeDict, function () {
|
var markersNew = nodesNew.map(mkMarker(nodeDict, function () {
|
||||||
return iconNew;
|
return iconNew;
|
||||||
}, router));
|
}));
|
||||||
|
|
||||||
var markersLost = nodesLost.map(mkMarker(nodeDict, function (d) {
|
var markersLost = nodesLost.map(mkMarker(nodeDict, function (d) {
|
||||||
var age = moment(data.now).diff(d.lastseen, 'days', true);
|
var age = moment(data.now).diff(d.lastseen, 'days', true);
|
||||||
@ -180,7 +180,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
|||||||
return iconLost;
|
return iconLost;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}, router));
|
}));
|
||||||
|
|
||||||
groupOffline = L.featureGroup(markersOffline).addTo(map);
|
groupOffline = L.featureGroup(markersOffline).addTo(map);
|
||||||
groupLost = L.featureGroup(markersLost).addTo(map);
|
groupLost = L.featureGroup(markersLost).addTo(map);
|
||||||
|
@ -47,7 +47,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
|
|||||||
reverse: true
|
reverse: true
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return function (router) {
|
return function () {
|
||||||
function renderRow(d) {
|
function renderRow(d) {
|
||||||
var td0Content = '';
|
var td0Content = '';
|
||||||
if (helper.hasLocation(d)) {
|
if (helper.hasLocation(d)) {
|
||||||
|
@ -2,7 +2,7 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
|
|||||||
function (d3Interpolate, V, Filter, helper) {
|
function (d3Interpolate, V, Filter, helper) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config, filterManager) {
|
return function (filterManager) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var scale = d3Interpolate.interpolate('#770038', '#dc0067');
|
var scale = d3Interpolate.interpolate('#770038', '#dc0067');
|
||||||
V = V.default;
|
V = V.default;
|
||||||
|
@ -2,7 +2,7 @@ define(['moment', 'snabbdom', 'helper'], function (moment, V, helper) {
|
|||||||
'use strict';
|
'use strict';
|
||||||
V = V.default;
|
V = V.default;
|
||||||
|
|
||||||
return function (nodes, field, router, title) {
|
return function (nodes, field, title) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var el;
|
var el;
|
||||||
var tbody;
|
var tbody;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
define(function () {
|
define(function () {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
return function (config) {
|
return function () {
|
||||||
function setTitle(d) {
|
function setTitle(d) {
|
||||||
var title = [config.siteName];
|
var title = [config.siteName];
|
||||||
|
|
||||||
|
@ -118,7 +118,6 @@ define({
|
|||||||
value
|
value
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
showStat: function showStat(V, o, subst) {
|
showStat: function showStat(V, o, subst) {
|
||||||
var content;
|
var content;
|
||||||
subst = typeof subst !== 'undefined' ? subst : {};
|
subst = typeof subst !== 'undefined' ? subst : {};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
|
define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
|
||||||
'use strict';
|
'use strict';
|
||||||
return function (config) {
|
return function () {
|
||||||
var router;
|
var router;
|
||||||
|
|
||||||
function languageSelect(el) {
|
function languageSelect(el) {
|
||||||
@ -60,6 +60,7 @@ define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
|
|||||||
|
|
||||||
function init(r) {
|
function init(r) {
|
||||||
router = r;
|
router = r;
|
||||||
|
/** global: _ */
|
||||||
window._ = new Polyglot({ locale: getLocale(router.getLang()), allowMissing: true });
|
window._ = new Polyglot({ locale: getLocale(router.getLang()), allowMissing: true });
|
||||||
helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation);
|
helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation);
|
||||||
document.querySelector('html').setAttribute('lang', _.locale());
|
document.querySelector('html').setAttribute('lang', _.locale());
|
||||||
|
149
lib/utils/node.js
Normal file
149
lib/utils/node.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
define(['snabbdom', 'helper', 'moment'], function (V, helper, moment) {
|
||||||
|
'use strict';
|
||||||
|
V = V.default;
|
||||||
|
|
||||||
|
var self = {};
|
||||||
|
|
||||||
|
function showBar(v, width, warning) {
|
||||||
|
return V.h('span',
|
||||||
|
{ props: { className: 'bar' + (warning ? ' warning' : '') } },
|
||||||
|
[
|
||||||
|
V.h('span',
|
||||||
|
{
|
||||||
|
style: { width: (width * 100) + '%' }
|
||||||
|
}),
|
||||||
|
V.h('label', v)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.showStatus = function showStatus(d) {
|
||||||
|
return V.h('td',
|
||||||
|
{ props: { className: d.is_online ? 'online' : 'offline' } },
|
||||||
|
_.t((d.is_online ? 'node.lastOnline' : 'node.lastOffline'), {
|
||||||
|
time: d.lastseen.fromNow(),
|
||||||
|
date: d.lastseen.format('DD.MM.YYYY, H:mm:ss')
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showGeoURI = function showGeoURI(d) {
|
||||||
|
if (!helper.hasLocation(d)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return V.h('td',
|
||||||
|
V.h('a',
|
||||||
|
{ props: { href: 'geo:' + d.location.latitude + ',' + d.location.longitude } },
|
||||||
|
Number(d.location.latitude.toFixed(6)) + ', ' + Number(d.location.longitude.toFixed(6))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showGateway = function showGateway(d) {
|
||||||
|
return d.is_gateway ? _.t('yes') : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showFirmware = function showFirmware(d) {
|
||||||
|
return [
|
||||||
|
helper.dictGet(d, ['firmware', 'release']),
|
||||||
|
helper.dictGet(d, ['firmware', 'base'])
|
||||||
|
].filter(function (n) {
|
||||||
|
return n !== null;
|
||||||
|
}).join(' / ') || undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showUptime = function showUptime(d) {
|
||||||
|
return moment.utc(d.uptime).local().fromNow(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showFirstSeen = function showFirstSeen(d) {
|
||||||
|
return d.firstseen.fromNow(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showLoad = function showLoad(d) {
|
||||||
|
if (!d.loadavg) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return showBar(d.loadavg.toFixed(2), d.loadavg % 1, d.loadavg >= d.nproc);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showRAM = function showRAM(d) {
|
||||||
|
if (!d.memory_usage) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return showBar(Math.round(d.memory_usage * 100) + ' %', d.memory_usage, d.memory_usage >= 0.8);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showSite = function showSite(d) {
|
||||||
|
var rt = d.site_code;
|
||||||
|
if (config.siteNames) {
|
||||||
|
config.siteNames.forEach(function (t) {
|
||||||
|
if (d.site_code === t.site) {
|
||||||
|
rt = t.name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return rt;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showClients = function showClients(d) {
|
||||||
|
if (!d.is_online) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
var clients = [
|
||||||
|
V.h('span', [
|
||||||
|
d.clients > 0 ? d.clients : _.t('none'),
|
||||||
|
V.h('br'),
|
||||||
|
V.h('i', { props: { className: 'ion-people', title: _.t('node.clients') } })
|
||||||
|
]),
|
||||||
|
V.h('span',
|
||||||
|
{ 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: 'legend-5ghz' } },
|
||||||
|
[
|
||||||
|
d.clients_wifi5,
|
||||||
|
V.h('br'),
|
||||||
|
V.h('span', { props: { className: 'symbol', title: '5 Ghz' } })
|
||||||
|
]),
|
||||||
|
V.h('span',
|
||||||
|
{ props: { className: 'legend-others' } },
|
||||||
|
[
|
||||||
|
d.clients_other,
|
||||||
|
V.h('br'),
|
||||||
|
V.h('span', { props: { className: 'symbol', title: _.t('others') } })
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
return V.h('td', { props: { className: 'clients' } }, clients);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showIPs = function showIPs(d) {
|
||||||
|
var string = [];
|
||||||
|
var ips = d.network.addresses;
|
||||||
|
ips.sort();
|
||||||
|
ips.forEach(function (ip, i) {
|
||||||
|
if (i > 0) {
|
||||||
|
string.push(V.h('br'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ip.indexOf('fe80:') !== 0) {
|
||||||
|
string.push(V.h('a', { props: { href: 'http://[' + ip + ']/', target: '_blank' } }, ip));
|
||||||
|
} else {
|
||||||
|
string.push(ip);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return V.h('td', string);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.showAutoupdate = function showAutoupdate(d) {
|
||||||
|
return d.autoupdater.enabled ? _.t('node.activated', { branch: d.autoupdater.branch }) : _.t('node.deactivated');
|
||||||
|
};
|
||||||
|
|
||||||
|
return self;
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user