[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) {
|
||||
main(jsonData);
|
||||
/** global: config */
|
||||
window.config = jsonData;
|
||||
main();
|
||||
});
|
||||
|
@ -6,10 +6,69 @@
|
||||
"nodeZoom": 18,
|
||||
"labelZoom": 13,
|
||||
"clientZoom": 15,
|
||||
"nodeInfobox": {
|
||||
"contact": false,
|
||||
"hardwareUsage": true
|
||||
"nodeAttr": [
|
||||
// value can be a node attribute (1 depth) or a a function in utils/node with prefix show
|
||||
{
|
||||
"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": [
|
||||
"en",
|
||||
"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) {
|
||||
'use strict';
|
||||
|
||||
return function (config, linkScale, sidebar, router) {
|
||||
return function (linkScale, sidebar) {
|
||||
var self = this;
|
||||
var el;
|
||||
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) {
|
||||
'use strict';
|
||||
|
||||
return function (config, router, language) {
|
||||
return function (language) {
|
||||
var self = this;
|
||||
var content;
|
||||
var contentDiv;
|
||||
@ -38,7 +38,7 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
|
||||
function addContent(K) {
|
||||
removeContent();
|
||||
|
||||
content = new K(config, linkScale, sidebar.getWidth, router, buttons);
|
||||
content = new K(linkScale, sidebar.getWidth, buttons);
|
||||
content.render(contentDiv);
|
||||
|
||||
fanout.add(content);
|
||||
@ -77,18 +77,18 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
|
||||
|
||||
buttons.appendChild(buttonToggle);
|
||||
|
||||
var title = new Title(config);
|
||||
var title = new Title();
|
||||
|
||||
var header = new Container('header');
|
||||
var infobox = new Infobox(config, sidebar, router, linkScale);
|
||||
var infobox = new Infobox(sidebar, linkScale);
|
||||
var tabs = new Tabs();
|
||||
var overview = new Container();
|
||||
var legend = new Legend(config, language);
|
||||
var newnodeslist = new SimpleNodelist('new', 'firstseen', router, _.t('node.new'));
|
||||
var lostnodeslist = new SimpleNodelist('lost', 'lastseen', router, _.t('node.missing'));
|
||||
var nodelist = new Nodelist(router);
|
||||
var linklist = new Linklist(linkScale, router);
|
||||
var statistics = new Proportions(config, fanout);
|
||||
var legend = new Legend(language);
|
||||
var newnodeslist = new SimpleNodelist('new', 'firstseen', _.t('node.new'));
|
||||
var lostnodeslist = new SimpleNodelist('lost', 'lastseen', _.t('node.missing'));
|
||||
var nodelist = new Nodelist();
|
||||
var linklist = new Linklist(linkScale);
|
||||
var statistics = new Proportions(fanout);
|
||||
var about = new About();
|
||||
|
||||
fanoutUnfiltered.add(legend);
|
||||
|
@ -13,7 +13,7 @@ define(['helper', 'snabbdom'], function (helper, V) {
|
||||
return helper.showStat(V, o, subst);
|
||||
}
|
||||
|
||||
return function (config, el, router, d, linkScale) {
|
||||
return function (el, d, linkScale) {
|
||||
var self = this;
|
||||
var header = document.createElement('div');
|
||||
var table = document.createElement('table');
|
||||
|
@ -1,7 +1,7 @@
|
||||
define(['helper'], function (helper) {
|
||||
'use strict';
|
||||
|
||||
return function (config, el, router, d) {
|
||||
return function (el, d) {
|
||||
var sidebarTitle = document.createElement('h2');
|
||||
sidebarTitle.textContent = _.t('location.location');
|
||||
el.appendChild(sidebarTitle);
|
||||
|
@ -1,7 +1,7 @@
|
||||
define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Node, location) {
|
||||
'use strict';
|
||||
|
||||
return function (config, sidebar, router, linkScale) {
|
||||
return function (sidebar, linkScale) {
|
||||
var self = this;
|
||||
var el;
|
||||
var node;
|
||||
@ -41,19 +41,19 @@ define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Nod
|
||||
|
||||
self.gotoNode = function gotoNode(d, nodeDict) {
|
||||
create();
|
||||
node = new Node(config, el, router, d, linkScale, nodeDict);
|
||||
node = new Node(el, d, linkScale, nodeDict);
|
||||
node.render();
|
||||
};
|
||||
|
||||
self.gotoLink = function gotoLink(d) {
|
||||
create();
|
||||
link = new Link(config, el, router, d, linkScale);
|
||||
link = new Link(el, d, linkScale);
|
||||
link.render();
|
||||
};
|
||||
|
||||
self.gotoLocation = function gotoLocation(d) {
|
||||
create();
|
||||
location(config, el, router, d);
|
||||
location(el, d);
|
||||
};
|
||||
|
||||
self.setData = function setData(d) {
|
||||
|
@ -1,137 +1,8 @@
|
||||
define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
||||
function (SortTable, V, d3Interpolate, moment, helper) {
|
||||
define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper', 'utils/node'],
|
||||
function (SortTable, V, d3Interpolate, moment, helper, nodef) {
|
||||
'use strict';
|
||||
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) {
|
||||
var subst = {};
|
||||
subst['{NODE_ID}'] = d.node_id;
|
||||
@ -141,7 +12,7 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
||||
return helper.showStat(V, o, subst);
|
||||
}
|
||||
|
||||
return function (config, el, router, d, linkScale, nodeDict) {
|
||||
return function (el, d, linkScale, nodeDict) {
|
||||
function nodeLink(node) {
|
||||
return V.h('a', {
|
||||
props: {
|
||||
@ -249,23 +120,24 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
|
||||
|
||||
var children = [];
|
||||
|
||||
children.push(helper.attributeEntry(V, 'node.status', showStatus(d)));
|
||||
children.push(helper.attributeEntry(V, 'node.gateway', d.is_gateway ? 'ja' : undefined));
|
||||
children.push(helper.attributeEntry(V, 'node.coordinates', showGeoURI(d)));
|
||||
children.push(helper.attributeEntry(V, 'node.contact', d.owner));
|
||||
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)));
|
||||
config.nodeAttr.forEach(function (row) {
|
||||
var field = d[row.value];
|
||||
if (nodef['show' + row.value] !== undefined) {
|
||||
field = nodef['show' + row.value](d);
|
||||
}
|
||||
children.push(helper.attributeEntry(V, 'node.ipAddresses', showIPs(d)));
|
||||
children.push(helper.attributeEntry(V, 'node.update', showAutoupdate(d)));
|
||||
children.push(helper.attributeEntry(V, 'node.clients', showClients(d)));
|
||||
|
||||
if (field) {
|
||||
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)));
|
||||
|
||||
var elNew = V.h('table', children);
|
||||
|
@ -1,7 +1,7 @@
|
||||
define(['helper'], function (helper) {
|
||||
'use strict';
|
||||
|
||||
return function (config, language) {
|
||||
return function (language) {
|
||||
var self = this;
|
||||
var stats = document.createTextNode('');
|
||||
var timestamp = document.createTextNode('');
|
||||
|
@ -28,7 +28,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
|
||||
reverse: true
|
||||
}];
|
||||
|
||||
return function (linkScale, router) {
|
||||
return function (linkScale) {
|
||||
var table = new SortTable(headings, 2, renderRow);
|
||||
V = V.default;
|
||||
|
||||
|
@ -2,7 +2,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
||||
function (moment, Router, L, GUI, helper, Language) {
|
||||
'use strict';
|
||||
|
||||
return function (config) {
|
||||
return function () {
|
||||
function handleData(data) {
|
||||
var timestamp;
|
||||
var nodes = [];
|
||||
@ -72,8 +72,8 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
||||
};
|
||||
}
|
||||
|
||||
var language = new Language(config);
|
||||
var router = new Router(language);
|
||||
var language = new Language();
|
||||
window.router = new Router(language);
|
||||
|
||||
config.dataPath.forEach(function (d, i) {
|
||||
config.dataPath[i] += 'meshviewer.json';
|
||||
@ -88,7 +88,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
|
||||
|
||||
update()
|
||||
.then(function (d) {
|
||||
var gui = new GUI(config, router, language);
|
||||
var gui = new GUI(language);
|
||||
gui.setData(d);
|
||||
router.setData(d);
|
||||
router.resolve();
|
||||
|
@ -8,7 +8,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
||||
minZoom: 0
|
||||
};
|
||||
|
||||
return function (config, linkScale, sidebar, router, buttons) {
|
||||
return function (linkScale, sidebar, buttons) {
|
||||
var self = this;
|
||||
var savedView;
|
||||
|
||||
@ -57,7 +57,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
||||
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('locationerror', button.locationError);
|
||||
@ -175,7 +175,7 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
|
||||
linkDict = {};
|
||||
|
||||
clientLayer.setData(data);
|
||||
labelLayer.setData(data, map, nodeDict, linkDict, linkScale, router, config);
|
||||
labelLayer.setData(data, map, nodeDict, linkDict, linkScale);
|
||||
|
||||
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 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 };
|
||||
}
|
||||
|
||||
function mkMarker(dict, iconFunc, router) {
|
||||
function mkMarker(dict, iconFunc) {
|
||||
return function (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) {
|
||||
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]);
|
||||
}
|
||||
|
||||
@ -136,12 +136,12 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
||||
this.prepareLabels();
|
||||
}
|
||||
},
|
||||
setData: function (data, map, nodeDict, linkDict, linkScale, router, config) {
|
||||
var iconOnline = getIcon(config, 'online');
|
||||
var iconOffline = getIcon(config, 'offline');
|
||||
var iconLost = getIcon(config, 'lost');
|
||||
var iconAlert = getIcon(config, 'alert');
|
||||
var iconNew = getIcon(config, 'new');
|
||||
setData: function (data, map, nodeDict, linkDict, linkScale) {
|
||||
var iconOnline = getIcon('online');
|
||||
var iconOffline = getIcon('offline');
|
||||
var iconLost = getIcon('lost');
|
||||
var iconAlert = getIcon('alert');
|
||||
var iconNew = getIcon('new');
|
||||
// Check if init or data is already set
|
||||
if (groupLines) {
|
||||
groupOffline.clearLayers();
|
||||
@ -151,7 +151,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
||||
groupLines.clearLayers();
|
||||
}
|
||||
|
||||
var lines = addLinksToMap(linkDict, linkScale, data.links, router);
|
||||
var lines = addLinksToMap(linkDict, linkScale, data.links);
|
||||
groupLines = L.featureGroup(lines).addTo(map);
|
||||
|
||||
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 () {
|
||||
return iconOnline;
|
||||
}, router));
|
||||
}));
|
||||
|
||||
var markersOffline = nodesOffline.map(mkMarker(nodeDict, function () {
|
||||
return iconOffline;
|
||||
}, router));
|
||||
}));
|
||||
|
||||
var markersNew = nodesNew.map(mkMarker(nodeDict, function () {
|
||||
return iconNew;
|
||||
}, router));
|
||||
}));
|
||||
|
||||
var markersLost = nodesLost.map(mkMarker(nodeDict, function (d) {
|
||||
var age = moment(data.now).diff(d.lastseen, 'days', true);
|
||||
@ -180,7 +180,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
|
||||
return iconLost;
|
||||
}
|
||||
return null;
|
||||
}, router));
|
||||
}));
|
||||
|
||||
groupOffline = L.featureGroup(markersOffline).addTo(map);
|
||||
groupLost = L.featureGroup(markersLost).addTo(map);
|
||||
|
@ -47,7 +47,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
|
||||
reverse: true
|
||||
}];
|
||||
|
||||
return function (router) {
|
||||
return function () {
|
||||
function renderRow(d) {
|
||||
var td0Content = '';
|
||||
if (helper.hasLocation(d)) {
|
||||
|
@ -2,7 +2,7 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
|
||||
function (d3Interpolate, V, Filter, helper) {
|
||||
'use strict';
|
||||
|
||||
return function (config, filterManager) {
|
||||
return function (filterManager) {
|
||||
var self = this;
|
||||
var scale = d3Interpolate.interpolate('#770038', '#dc0067');
|
||||
V = V.default;
|
||||
|
@ -2,7 +2,7 @@ define(['moment', 'snabbdom', 'helper'], function (moment, V, helper) {
|
||||
'use strict';
|
||||
V = V.default;
|
||||
|
||||
return function (nodes, field, router, title) {
|
||||
return function (nodes, field, title) {
|
||||
var self = this;
|
||||
var el;
|
||||
var tbody;
|
||||
|
@ -1,7 +1,7 @@
|
||||
define(function () {
|
||||
'use strict';
|
||||
|
||||
return function (config) {
|
||||
return function () {
|
||||
function setTitle(d) {
|
||||
var title = [config.siteName];
|
||||
|
||||
|
@ -118,7 +118,6 @@ define({
|
||||
value
|
||||
]);
|
||||
},
|
||||
|
||||
showStat: function showStat(V, o, subst) {
|
||||
var content;
|
||||
subst = typeof subst !== 'undefined' ? subst : {};
|
||||
|
@ -1,6 +1,6 @@
|
||||
define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
|
||||
'use strict';
|
||||
return function (config) {
|
||||
return function () {
|
||||
var router;
|
||||
|
||||
function languageSelect(el) {
|
||||
@ -60,6 +60,7 @@ define(['polyglot', 'moment', 'helper'], function (Polyglot, moment, helper) {
|
||||
|
||||
function init(r) {
|
||||
router = r;
|
||||
/** global: _ */
|
||||
window._ = new Polyglot({ locale: getLocale(router.getLang()), allowMissing: true });
|
||||
helper.getJSON('locale/' + _.locale() + '.json?' + config.cacheBreaker).then(setTranslation);
|
||||
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