From a4045b50a63f17b2598e0fee36ea8fe8a71630d3 Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Tue, 16 May 2017 19:18:35 +0200 Subject: [PATCH] eslint all (with some exludes) --- webroot/.eslintrc | 35 +++ webroot/css/main.css | 184 ++++++++-------- webroot/css/map.css | 36 +-- webroot/index.html | 87 ++++---- webroot/js/config.js | 128 ++++++----- webroot/js/domlib.js | 32 +-- webroot/js/gui.js | 148 +++++++------ webroot/js/gui_list.js | 433 ++++++++++++++++++++----------------- webroot/js/gui_map.js | 292 ++++++++++++++----------- webroot/js/gui_node.js | 285 +++++++++++++----------- webroot/js/gui_skelView.js | 47 ++-- webroot/js/gui_stats.js | 110 +++++----- webroot/js/notify.js | 96 ++++---- webroot/js/socket.js | 121 ++++++----- webroot/js/store.js | 70 +++--- 15 files changed, 1180 insertions(+), 924 deletions(-) create mode 100644 webroot/.eslintrc diff --git a/webroot/.eslintrc b/webroot/.eslintrc new file mode 100644 index 0000000..c923bba --- /dev/null +++ b/webroot/.eslintrc @@ -0,0 +1,35 @@ +{ + extends: eslint:all, + rules: { + no-tabs: [off], + indent: [error, tab], + quotes: [error, single], + padded-blocks: [error, { blocks: never }], + no-console: [error, { allow: [log, warn, error] }], + func-style: [error, declaration], + object-curly-newline: off, + wrap-iife: [error, inside], + object-shorthand: ["error", "always", { "avoidQuotes": true }], + require-jsdoc: [off], + max-statements: [off], + no-magic-numbers: ["error", { "ignore": [0,1,-1] }], + sort-vars: [off], + max-len: [off], + id-length: [error, { exceptions: ["i"] }], + no-ternary: [off] + + }, + env: { + es6: true + }, + globals: { + L: true, + moment: true, + Navigo: true, + document: true, + window: true, + location: true, + navigator: true, + console: true, + } +} diff --git a/webroot/css/main.css b/webroot/css/main.css index 83de703..c945704 100644 --- a/webroot/css/main.css +++ b/webroot/css/main.css @@ -1,180 +1,180 @@ body { - position: relative; - margin: 0px; - font-size: 15px; - color: #333; - line-height: 1.3; - font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; + position: relative; + margin: 0px; + font-size: 15px; + color: #333; + line-height: 1.3; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; } .status { - float: right; - background: #009ee0; - width: 50px; - height: 50px; + float: right; + background: #009ee0; + width: 50px; + height: 50px; } .status.connecting { - background: #ffb400; + background: #ffb400; } .status.offline { - background: #dc0067; + background: #dc0067; } span.online { - color: #009ee0; + color: #009ee0; } span.offline { - color: #dc0067; + color: #dc0067; } h1 { - border-bottom: 4px solid #dc0067; + border-bottom: 4px solid #dc0067; } header { - background-color: #373636; - max-width: 100%; - height: 50px; + background-color: #373636; + max-width: 100%; + height: 50px; } header > div { - display: inline-block; + display: inline-block; } nav { - display: inline-block; - font-weight: 700; - width: 100%; + display: inline-block; + font-weight: 700; + width: 100%; } nav ul { - padding: 0; - margin: 0; - list-style-type: none; + padding: 0; + margin: 0; + list-style-type: none; } nav li { - float:left; - display: inline-block; + float:left; + display: inline-block; } nav li:hover, nav.active { - background: rgba(255, 255, 255, 0.2); + background: rgba(255, 255, 255, 0.2); } nav li a, nav li span { - display: inline-block; - cursor: pointer; - text-decoration: none !important; - text-align: center; - text-transform: uppercase; - color: inherit; - box-sizing: border-box; - padding: 1.1em .5em; - height: 50px; + display: inline-block; + cursor: pointer; + text-decoration: none !important; + text-align: center; + text-transform: uppercase; + color: inherit; + box-sizing: border-box; + padding: 1.1em .5em; + height: 50px; } nav > ul > .item-1 { - background: #ffb400; - color: #000; + background: #ffb400; + color: #000; } nav > ul > .item-2 { - background: #dc0067; - color: #fff; + background: #dc0067; + color: #fff; } nav > ul > .item-3 { - background: #ccc; - color: #000; + background: #ccc; + color: #000; } .notifications { - position: absolute; - right: 1em; + position: absolute; + right: 1em; } .notify { - position: relative; - min-height: 1em; - margin: 1em 0; - padding: 1em 1.5em; - color: rgba(0,0,0,.87); - -webkit-transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; - transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; - box-shadow: 0 0 0 1px rgba(34,36,38,.22) inset, 0 0 0 0 transparent; - background: #ccc; - color: #000; + position: relative; + min-height: 1em; + margin: 1em 0; + padding: 1em 1.5em; + color: rgba(0,0,0,.87); + -webkit-transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; + transition: opacity .1s ease,color .1s ease,background .1s ease,box-shadow .1s ease; + box-shadow: 0 0 0 1px rgba(34,36,38,.22) inset, 0 0 0 0 transparent; + background: #ccc; + color: #000; } .notify.success { - background: #009ee0; - color: #fff; + background: #009ee0; + color: #fff; } .notify.warn { - background: #ffb400; - color: #000; + background: #ffb400; + color: #000; } .notify.error { - background: #dc0067; - color: #fff; + background: #dc0067; + color: #fff; } thead { - font-size: 1.3em; - font-weight: bold; - cursor: default; + font-size: 1.3em; + font-weight: bold; + cursor: default; } thead tr th{ - border-bottom: 4px solid #dc0067; + border-bottom: 4px solid #dc0067; } table th > input { - border: none; - color: #000; - font-weight: bold; - background: #fff; + border: none; + color: #000; + font-weight: bold; + background: #fff; } table th.sortable.sort-down:after { - content: " \25BC" + content: " \25BC" } table th.sortable.sort-up:after { - content: " \25B2" + content: " \25B2" } table th.sortable:not(.sort-down):not(.sort-up):after { - content: " \25B4\25BE"; + content: " \25B4\25BE"; } table.nodes, table.stats { - width: 100%; + width: 100%; } table.nodes td > span{ - display: block; + display: block; } table.nodes tbody tr:nth-child(even) { - background: #eee; + background: #eee; } table.nodes tbody tr:nth-child(odd) { - background: #fff; + background: #fff; } table.nodes tbody tr:hover { - background: #ccc; + background: #ccc; } table.nodes tbody tr.offline{ - background: #ffb400; + background: #ffb400; } table.nodes tbody tr.offline:hover{ - background: #dc0067; + background: #dc0067; } table tr.line td,table tr.line th { - border-bottom: 1px solid #ffb400; + border-bottom: 1px solid #ffb400; } table.stats td { - text-align: center; + text-align: center; } .btn { - display: inline-block; - padding: .3em .5em; - border-radius: 1em; - color: #fff; - background-color: #dc0067; - text-align: center; - cursor: pointer; + display: inline-block; + padding: .3em .5em; + border-radius: 1em; + color: #fff; + background-color: #dc0067; + text-align: center; + cursor: pointer; } .btn:hover { - background: lighten(#dc0067, 5%); + background: lighten(#dc0067, 5%); } a.btn:hover { - text-decoration: none; + text-decoration: none; } a { - color: #dc0067; - text-decoration: none; + color: #dc0067; + text-decoration: none; } diff --git a/webroot/css/map.css b/webroot/css/map.css index ea20aee..2d4c447 100644 --- a/webroot/css/map.css +++ b/webroot/css/map.css @@ -1,42 +1,42 @@ .leaflet-container .node { - width: 3px; - height: 3px; - background-color: rgba(0,0,255,0.5); - border: 2px solid white; - border-radius: 10px; + width: 3px; + height: 3px; + background-color: rgba(0,0,255,0.5); + border: 2px solid white; + border-radius: 10px; } .leaflet-container .node.offline { - background-color: rgba(255,0,0,0.5); + background-color: rgba(255,0,0,0.5); } .leaflet-container .node.client24 { - border-left: 3px solid green; + border-left: 3px solid green; } .leaflet-container .node.client5 { - border-border: 3px solid green; + border-border: 3px solid green; } .leaflet-container .node.client24-warn { - border-left: 3px solid yellow; + border-left: 3px solid yellow; } .leaflet-container .node.client5-warn { - border-border: 3px solid yellow; + border-border: 3px solid yellow; } .leaflet-container .node.client24-crit { - border-left: 3px solid red; + border-left: 3px solid red; } .leaflet-container .node.client5-crit { - border-border: 3px solid red; + border-border: 3px solid red; } .leaflet-container .nodeicon-label { - font-size: 12px; - font-weight: lighter; + font-size: 12px; + font-weight: lighter; } .leaflet-container .nodeicon-label table { - width: 100%; + width: 100%; } .leaflet-container .nodeicon-label td { - border-top: 1px solid #999; - text-align: right; + border-top: 1px solid #999; + text-align: right; } .leaflet-container .nodeicon-label td:first-child { - text-align: left; + text-align: left; } diff --git a/webroot/index.html b/webroot/index.html index d8d63c5..89fb38b 100644 --- a/webroot/index.html +++ b/webroot/index.html @@ -1,47 +1,46 @@ - - - - FreifunkManager - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
- - + + + + FreifunkManager + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+
+ + diff --git a/webroot/js/config.js b/webroot/js/config.js index 94fbdaf..3727b91 100644 --- a/webroot/js/config.js +++ b/webroot/js/config.js @@ -1,60 +1,88 @@ /* exported config */ -var config = { - title: 'FreifunkManager - Breminale', - backend: 'ws://'+location.host+'/websocket', - map: { - view: {bound: [53.07093, 8.79464], zoom: 17}, - maxZoom: 20, - tileLayer: 'https://tiles.bremen.freifunk.net/{z}/{x}/{y}.png', - /* heatmap settings +/* eslint no-magic-numbers: "off"*/ +/* eslint sort-keys: "off"*/ + +const config = { + 'title': 'FreifunkManager - Breminale', + 'backend': `ws://${location.host}/websocket`, + 'map': { + 'view': { + 'bound': [53.07093, 8.79464], + 'zoom': 17 + }, + 'maxZoom': 20, + 'tileLayer': 'https://tiles.bremen.freifunk.net/{z}/{x}/{y}.png', + + /* Heatmap settings size: in meters (default: 30km) opacity: in percent/100 (default: 1) gradientTexture: url-to-texture-image (default: false) alphaRange: change transparency in heatmap (default: 1) autoresize: resize heatmap when map size changes (default: false) */ - heatmap: { - wifi24: {size: 230, opacity: 0.5, alphaRange: 1}, - wifi5: {size: 230, opacity: 0.5, alphaRange: 1} - }, - icon:{ - warn:{wifi24:20,wifi5:20}, - crit:{wifi24:30,wifi5:30} - }, - geojson: { - url: 'http://events.ffhb.de/data/ground.geojson', - pointToLayer: function (feature, latlng){ - feature.properties.radius = 10; - return L.circleMarker(latlng, feature.properties); - }, - onEachFeature: function(feature, layer) { - if(feature.properties.name.length >0){ - layer.bindTooltip(feature.properties.name); - } - }, - style: function(feature){ - if(feature.geometry.type === 'LineString' || feature.geometry.type === 'Polygon'){ - return { - color: feature.properties.stroke, - opacity:feature.properties['stroke-opacity'], - fillColor: feature.properties.fill, - fillOpacity:feature.properties['fill-opacity'], - stroke: true, - weight: feature.properties['stroke-width'], - lineCap: 'round', - lineJoin: 'round' - }; - } - return { - color: feature.properties['marker-color'], - fillColor: feature.properties['marker-color'], - fillOpacity: 0.2, - weight: 2, - stroke: true - }; - } - } - }, + 'heatmap': { + 'wifi24': { + 'size': 230, + 'opacity': 0.5, + 'alphaRange': 1 + }, + 'wifi5': { + 'size': 230, + 'opacity': 0.5, + 'alphaRange': 1 + } + }, + 'icon': { + 'warn': { + 'wifi24': 20, + 'wifi5': 20 + }, + 'crit': { + 'wifi24': 30, + 'wifi5': 30 + } + }, + 'geojson': { + 'url': 'http://events.ffhb.de/data/ground.geojson', + 'pointToLayer': function pointToLayer (feature, latlng) { + 'use strict'; + feature.properties.radius = 10; + + return L.circleMarker(latlng, feature.properties); + }, + 'onEachFeature': function onEachFeature (feature, layer) { + 'use strict'; + + if (feature.properties.name.length > 0) { + layer.bindTooltip(feature.properties.name); + } + }, + 'style': function style (feature) { + 'use strict'; + + if (feature.geometry.type === 'LineString' || feature.geometry.type === 'Polygon') { + return { + 'color': feature.properties.stroke, + 'opacity': feature.properties['stroke-opacity'], + 'fillColor': feature.properties.fill, + 'fillOpacity': feature.properties['fill-opacity'], + 'stroke': true, + 'weight': feature.properties['stroke-width'], + 'lineCap': 'round', + 'lineJoin': 'round' + }; + } + + return { + 'color': feature.properties['marker-color'], + 'fillColor': feature.properties['marker-color'], + 'fillOpacity': 0.2, + 'weight': 2, + 'stroke': true + }; + } + } + } }; diff --git a/webroot/js/domlib.js b/webroot/js/domlib.js index a3c1835..584754c 100644 --- a/webroot/js/domlib.js +++ b/webroot/js/domlib.js @@ -1,16 +1,22 @@ /* exported domlin */ -var domlib = {}; -(function(){ - domlib.newAt = function(at,eltype) { - var el = document.createElement(eltype); - at.appendChild(el); - return el; - }; - domlib.removeChildren = function(el) { - if(el) - while(el.firstChild) { - el.removeChild(el.firstChild); - } - }; +const domlib = {}; + +(function init () { + 'use strict'; + + domlib.newAt = function newAt (at, eltype) { + const el = document.createElement(eltype); + + at.appendChild(el); + + return el; + }; + domlib.removeChildren = function removeChildren (el) { + if (el) { + while (el.firstChild) { + el.removeChild(el.firstChild); + } + } + }; })(); diff --git a/webroot/js/gui.js b/webroot/js/gui.js index 219389f..af1e74b 100644 --- a/webroot/js/gui.js +++ b/webroot/js/gui.js @@ -1,74 +1,100 @@ /* exported gui,router */ /* globals socket,notify,domlib,guiList,guiMap,guiStats,guiNode */ -var gui = {}; -var router = new Navigo(null, true, '#'); -(function(){ - var currentView = {bind:function(){},render:function(){}}; +const gui = {}, + router = new Navigo(null, true, '#'); - function render() { - var status = document.getElementsByClassName('status')[0]; - if (status === undefined){ - console.log("unable to render, render later"); - window.setTimeout(render,100); - return; - } - status.classList.remove('connecting','offline'); - if(socket.readyState !== 1){ - status.classList.add(((socket.readyState===0 || socket.readyState===2)?'connecting':(socket.readyState===1)?'':'offline')); - } - notify.bind(document.getElementsByClassName('notifications')[0]); +(function init () { + 'use strict'; - currentView.render(); - router.resolve(); - } + const GUI_RENDER_DEBOUNCER_TIME = 100; - function setView(c){ - currentView = c; - var main = document.querySelector('main'); - domlib.removeChildren(main); - currentView.bind(main); - currentView.render(); - } + let currentView = { + 'bind': function bind () { + console.warn('Do not run dummies'); + }, + // eslint-disable-next-line func-name-matching + 'render': function renderDummy () { + console.warn('DO not run dummies'); + } + }; - router.on({ - '/list': function () { - setView(guiList); - }, - '/map':function(){ - setView(guiMap); - }, - '/statistics':function(){ - setView(guiStats); - }, - '/n/:nodeID': { - as: 'node', - uses: function (params) { - guiNode.setNodeID(params['nodeID'].toLowerCase()); - setView(guiNode); - } - }, - }); - router.on(function () { - router.navigate('/list'); - }); + function renderView () { + // eslint-disable-next-line prefer-destructuring + const status = document.getElementsByClassName('status')[0]; - gui.render = function () { - var timeout; + if (!status) { + console.log('unable to render, render later'); + window.setTimeout(renderView, GUI_RENDER_DEBOUNCER_TIME); - function reset () { - timeout = null; - } + return; + } + status.classList.remove('connecting', 'offline'); + if (socket.readyState !== 1) { + let statusClass = 'offline'; - if (timeout){ - console("skip rendering, because to often"); - window.clearTimeout(timeout); - } else { - render(); - } - timeout = window.setTimeout(reset, 100); - }; + // eslint-disable-next-line no-magic-numbers + if (socket.readyState === 0 || socket.readyState === 2) { + statusClass = 'connecting'; + } + status.classList.add(statusClass); + } - window.onload = gui.render; + // eslint-disable-next-line prefer-destructuring + notify.bind(document.getElementsByClassName('notifications')[0]); + + currentView.render(); + router.resolve(); + } + + function setView (toView) { + currentView = toView; + const main = document.querySelector('main'); + + domlib.removeChildren(main); + currentView.bind(main); + currentView.render(); + } + + router.on({ + '/list': function routerList () { + setView(guiList); + }, + '/map': function routerMap () { + setView(guiMap); + }, + '/n/:nodeID': { + 'as': 'node', + // eslint-disable-next-line func-name-matching + 'uses': function routerNode (params) { + guiNode.setNodeID(params.nodeID.toLowerCase()); + setView(guiNode); + } + }, + '/statistics': function routerStats () { + setView(guiStats); + } + }); + router.on(() => { + router.navigate('/list'); + }); + + gui.render = function render () { + let timeout = false; + + function reset () { + timeout = null; + } + + if (timeout) { + console('skip rendering, because to often'); + window.clearTimeout(timeout); + } else { + renderView(); + } + timeout = window.setTimeout(reset, GUI_RENDER_DEBOUNCER_TIME); + }; + + window.onload = gui.render; })(); diff --git a/webroot/js/gui_list.js b/webroot/js/gui_list.js index 553e05a..e8ff989 100644 --- a/webroot/js/gui_list.js +++ b/webroot/js/gui_list.js @@ -1,239 +1,278 @@ /* exported guiList */ /* global domlib,store,router */ -var guiList = {}; +const guiList = {}; -(function(){ - var view = guiList; - var container, el; +(function init () { + 'use strict'; - var tbody; - var sortReverse = false; - var sortIndex; + const view = guiList; - var hostnameFilter, nodeidFilter; + let container = null, + el = null, + tbody = null, + sortReverse = false, + sortIndex = null, + hostnameFilter = null, + nodeidFilter = null; - function sort(a,b){ - function sortNumber(a,b){ - return a - b; - } - if(sortIndex === undefined) - return a.node_id.localeCompare(b.node_id); - switch (sortIndex.innerHTML) { - case "Lastseen": - return a.lastseen - b.lastseen; - case "CurPower": - return a._wireless.txpower24 - b._wireless.txpower24; - case "Power": - return a.wireless.txpower24 - b.wireless.txpower24; - case "CurChannel": - return a._wireless.channel24 - b._wireless.channel24; - case "Channel": - return a.wireless.channel24 - b.wireless.channel24; - case "Clients": - return a.statistics.clients.wifi24 - b.statistics.clients.wifi24; - case "ChanUtil": - var aMax = a.statistics.wireless.map(function(d){ - return d.ChanUtil; - }).sort(sortNumber); + // eslint-disable-next-line id-length + function sort (a, b) { + function sortNumber (aNum, bNum) { + return aNum - bNum; + } + if (!sortIndex) { + return a.node_id.localeCompare(b.node_id); + } + switch (sortIndex.innerHTML) { + case 'Lastseen': + return a.lastseen - b.lastseen; + case 'CurPower': + // eslint-disable-next-line no-underscore-dangle + return a._wireless.txpower24 - b._wireless.txpower24; + case 'Power': + return a.wireless.txpower24 - b.wireless.txpower24; + case 'CurChannel': + // eslint-disable-next-line no-underscore-dangle + return a._wireless.channel24 - b._wireless.channel24; + case 'Channel': + return a.wireless.channel24 - b.wireless.channel24; + case 'Clients': + return a.statistics.clients.wifi24 - b.statistics.clients.wifi24; + // eslint-disable-next-line no-case-declarations + case 'ChanUtil': + // eslint-disable-next-line id-length + let aMax = a.statistics.wireless.map((d) => + d.ChanUtil + ).sort(sortNumber), + // eslint-disable-next-line id-length + bMax = b.statistics.wireless.map((d) => + d.ChanUtil + ).sort(sortNumber); - var bMax = b.statistics.wireless.map(function(d){ - return d.ChanUtil; - }).sort(sortNumber); + if (!sortReverse) { + aMax = aMax.reverse(); + bMax = bMax.reverse(); + } - if(!sortReverse){ - aMax = aMax.reverse(); - bMax = bMax.reverse(); - } - return bMax[0] - aMax[0]; - case "Hostname": - return a.hostname.localeCompare(b.hostname); - default: - return a.node_id.localeCompare(b.node_id); - } - } + return bMax[0] - aMax[0]; + case 'Hostname': + return a.hostname.localeCompare(b.hostname); + default: + return a.node_id.localeCompare(b.node_id); + } + } - function renderRow(node){ - var tr = document.createElement('tr'); - var startdate = new Date(); - startdate.setMinutes(startdate.getMinutes() - 1); - if(new Date(node.lastseen) < startdate) - tr.classList.add('offline'); + function renderRow (node) { + const startdate = new Date(), + tr = document.createElement('tr'), + lastseen = domlib.newAt(tr, 'td'), + nodeID = domlib.newAt(tr, 'td'), + hostname = domlib.newAt(tr, 'td'), + freq = domlib.newAt(tr, 'td'), + curchannel = domlib.newAt(tr, 'td'), + channel = domlib.newAt(tr, 'td'), + curpower = domlib.newAt(tr, 'td'), + power = domlib.newAt(tr, 'td'), + client = domlib.newAt(tr, 'td'), + chanUtil = domlib.newAt(tr, 'td'), + option = domlib.newAt(tr, 'td'), + edit = domlib.newAt(option, 'div'); - domlib.newAt(tr,'td').innerHTML = moment(node.lastseen).fromNow(true); - domlib.newAt(tr,'td').innerHTML = node.node_id; + startdate.setMinutes(startdate.getMinutes() - 1); + if (new Date(node.lastseen) < startdate) { + tr.classList.add('offline'); + } - domlib.newAt(tr,'td').innerHTML = node.hostname; + lastseen.innerHTML = moment(node.lastseen).fromNow(true); - var freq = domlib.newAt(tr,'td'); - domlib.newAt(freq,'span').innerHTML = '2.4 Ghz'; - domlib.newAt(freq,'span').innerHTML = '5 Ghz'; + nodeID.innerHTML = node.node_id; - var curchannel = domlib.newAt(tr,'td'); - domlib.newAt(curchannel,'span').innerHTML = node._wireless.channel24||'-'; - domlib.newAt(curchannel,'span').innerHTML = node._wireless.channel5||'-'; + hostname.innerHTML = node.hostname; - var channel = domlib.newAt(tr,'td'); - domlib.newAt(channel,'span').innerHTML = node.wireless.channel24||'-'; - domlib.newAt(channel,'span').innerHTML = node.wireless.channel5||'-'; + domlib.newAt(freq, 'span').innerHTML = '2.4 Ghz'; + domlib.newAt(freq, 'span').innerHTML = '5 Ghz'; - var curpower = domlib.newAt(tr,'td'); - domlib.newAt(curpower,'span').innerHTML = node._wireless.txpower24||'-'; - domlib.newAt(curpower,'span').innerHTML = node._wireless.txpower5||'-'; + /* eslint-disable no-underscore-dangle */ + domlib.newAt(curchannel, 'span').innerHTML = node._wireless.channel24 || '-'; + domlib.newAt(curchannel, 'span').innerHTML = node._wireless.channel5 || '-'; + /* eslint-enable no-underscore-dangle */ - var power = domlib.newAt(tr,'td'); - domlib.newAt(power,'span').innerHTML = node.wireless.txpower24||'-'; - domlib.newAt(power,'span').innerHTML = node.wireless.txpower5||'-'; + domlib.newAt(channel, 'span').innerHTML = node.wireless.channel24 || '-'; + domlib.newAt(channel, 'span').innerHTML = node.wireless.channel5 || '-'; - var client = domlib.newAt(tr,'td'); - domlib.newAt(client,'span').innerHTML = node.statistics.clients.wifi24; - domlib.newAt(client,'span').innerHTML = node.statistics.clients.wifi5; + /* eslint-disable no-underscore-dangle */ + domlib.newAt(curpower, 'span').innerHTML = node._wireless.txpower24 || '-'; + domlib.newAt(curpower, 'span').innerHTML = node._wireless.txpower5 || '-'; + /* eslint-enable no-underscore-dangle */ - var chanUtil = domlib.newAt(tr,'td'); - var chanUtil24 = node.statistics.wireless.filter(function(d){ - return d.frequency < 5000; - })[0] || {}; - var chanUtil5 = node.statistics.wireless.filter(function(d){ - return d.frequency > 5000; - })[0] || {}; - domlib.newAt(chanUtil,'span').innerHTML = chanUtil24.ChanUtil||'-'; - domlib.newAt(chanUtil,'span').innerHTML = chanUtil5.ChanUtil||'-'; + domlib.newAt(power, 'span').innerHTML = node.wireless.txpower24 || '-'; + domlib.newAt(power, 'span').innerHTML = node.wireless.txpower5 || '-'; - var option = domlib.newAt(tr,'td'); - var edit = domlib.newAt(option,'div'); - edit.classList.add('btn'); - edit.innerHTML = 'Edit'; - edit.addEventListener('click',function(){ - router.navigate(router.generate('node', { nodeID: node.node_id })); - }); + domlib.newAt(client, 'span').innerHTML = node.statistics.clients.wifi24; + domlib.newAt(client, 'span').innerHTML = node.statistics.clients.wifi5; - return tr; - } + /* eslint-disable id-length, no-magic-numbers,one-var */ + const chanUtil24 = node.statistics.wireless.filter((d) => d.frequency < 5000)[0] || {}, + chanUtil5 = node.statistics.wireless.filter((d) => d.frequency > 5000)[0] || {}; + /* eslint-enable id-length, no-magic-numbers,one-var */ - function update(){ - domlib.removeChildren(tbody); - var nodes = store.getNodes(); + domlib.newAt(chanUtil, 'span').innerHTML = chanUtil24.ChanUtil || '-'; + domlib.newAt(chanUtil, 'span').innerHTML = chanUtil5.ChanUtil || '-'; - if(hostnameFilter && hostnameFilter.value != "") - nodes = nodes.filter(function(d){ - return d.hostname.toLowerCase().indexOf(hostnameFilter.value) > -1; - }); - if(nodeidFilter && nodeidFilter.value != "") - nodes = nodes.filter(function(d){ - return d.node_id.indexOf(nodeidFilter.value) > -1; - }); + edit.classList.add('btn'); + edit.innerHTML = 'Edit'; + edit.addEventListener('click', () => { + router.navigate(router.generate('node', {'nodeID': node.node_id})); + }); - nodes = nodes.sort(sort); + return tr; + } - if(sortReverse) - nodes = nodes.reverse(); + function update () { + domlib.removeChildren(tbody); + let nodes = store.getNodes(); - for(var i=0; i d.hostname.toLowerCase().indexOf(hostnameFilter.value) > -1); + } + if (nodeidFilter && nodeidFilter.value !== '') { + // eslint-disable-next-line id-length + nodes = nodes.filter((d) => d.node_id.indexOf(nodeidFilter.value) > -1); + } - function sortTable(head) { - if(sortIndex) - sortIndex.classList.remove("sort-up","sort-down"); - sortReverse = head === sortIndex ? !sortReverse : false; - sortIndex = head; - sortIndex.classList.add(sortReverse ? 'sort-up' : 'sort-down'); + nodes = nodes.sort(sort); - update(); - } + if (sortReverse) { + nodes = nodes.reverse(); + } - view.bind = function(el) { - container = el; - }; + for (let i = 0; i < nodes.length; i += 1) { + const row = renderRow(nodes[i]); - view.render = function(){ - if (container === undefined){ - return; - } else if (el !== undefined){ - container.appendChild(el); - update(); - return; - } - console.log("generate new view for list"); - el = domlib.newAt(container,'div'); + tbody.appendChild(row); + } + } - var table = domlib.newAt(el,'table'); - var thead = domlib.newAt(table,'thead'); - tbody = domlib.newAt(table,'tbody'); + function sortTable (head) { + if (sortIndex) { + sortIndex.classList.remove('sort-up', 'sort-down'); + } + sortReverse = head === sortIndex + ? !sortReverse + : false; + sortIndex = head; - var tr = domlib.newAt(thead,'tr'); + sortIndex.classList.add(sortReverse + ? 'sort-up' + : 'sort-down'); - var cell1 = domlib.newAt(tr,'th'); - cell1.innerHTML = "Lastseen"; - cell1.addEventListener('click', function(){ - sortTable(cell1); - }); + update(); + } - var cell2 = domlib.newAt(tr,'th'); - cell2.classList.add('sortable'); - nodeidFilter = domlib.newAt(cell2,'input'); - nodeidFilter.setAttribute("placeholder","NodeID"); - nodeidFilter.setAttribute("size","9"); - nodeidFilter.addEventListener('keyup', update); - cell2.addEventListener('dblclick', function(){ - sortTable(cell2); - }); + view.bind = function bind (bindEl) { + container = bindEl; + }; - var cell3 = domlib.newAt(tr,'th'); - cell3.classList.add('sortable'); - hostnameFilter = domlib.newAt(cell3,'input'); - hostnameFilter.setAttribute("placeholder","Hostname"); - hostnameFilter.addEventListener('keyup', update); - cell3.addEventListener('dblclick', function(){ - sortTable(cell3); - }); + view.render = function render () { + if (!container) { + return; + } else if (el) { + container.appendChild(el); + update(); - domlib.newAt(tr,'th').innerHTML = 'Freq'; + return; + } + console.log('generate new view for list'); + el = domlib.newAt(container, 'div'); - var cell4 = domlib.newAt(tr,'th'); - cell4.innerHTML = "CurChannel"; - cell4.classList.add('sortable'); - cell4.addEventListener('click', function(){ - sortTable(cell4); - }); - var cell5 = domlib.newAt(tr,'th'); - cell5.innerHTML = "Channel"; - cell5.classList.add('sortable'); - cell5.addEventListener('click', function(){ - sortTable(cell5); - }); + const table = domlib.newAt(el, 'table'), + thead = domlib.newAt(table, 'thead'); - var cell6 = domlib.newAt(tr,'th'); - cell6.innerHTML = "CurPower"; - cell6.classList.add('sortable'); - cell6.addEventListener('click', function(){ - sortTable(cell6); - }); - var cell7 = domlib.newAt(tr,'th'); - cell7.innerHTML = "Power"; - cell7.classList.add('sortable'); - cell7.addEventListener('click', function(){ - sortTable(cell7); - }); + tbody = domlib.newAt(table, 'tbody'); - var cell8 = domlib.newAt(tr,'th'); - cell8.innerHTML = "Clients"; - cell8.classList.add('sortable'); - cell8.addEventListener('click', function(){ - sortTable(cell8); - }); - var cell9 = domlib.newAt(tr,'th'); - cell9.innerHTML = "ChanUtil"; - cell9.classList.add('sortable'); - cell9.addEventListener('click', function(){ - sortTable(cell9); - }); - domlib.newAt(tr,'th').innerHTML = "Option"; + // eslint-disable-next-line one-var + const tr = domlib.newAt(thead, 'tr'), + cell1 = domlib.newAt(tr, 'th'), + cell2 = domlib.newAt(tr, 'th'), + cell3 = domlib.newAt(tr, 'th'), + cell4 = domlib.newAt(tr, 'th'), + cell5 = domlib.newAt(tr, 'th'), + cell6 = domlib.newAt(tr, 'th'), + cell7 = domlib.newAt(tr, 'th'), + cell8 = domlib.newAt(tr, 'th'), + cell9 = domlib.newAt(tr, 'th'), + cell10 = domlib.newAt(tr, 'th'), + cell11 = domlib.newAt(tr, 'th'); - table.classList.add('nodes'); + cell1.innerHTML = 'Lastseen'; + cell1.addEventListener('click', () => { + sortTable(cell1); + }); - update(); - }; + cell2.classList.add('sortable'); + nodeidFilter = domlib.newAt(cell2, 'input'); + nodeidFilter.setAttribute('placeholder', 'NodeID'); + nodeidFilter.setAttribute('size', '9'); + nodeidFilter.addEventListener('keyup', update); + cell2.addEventListener('dblclick', () => { + sortTable(cell2); + }); + + + cell3.classList.add('sortable'); + hostnameFilter = domlib.newAt(cell3, 'input'); + hostnameFilter.setAttribute('placeholder', 'Hostname'); + hostnameFilter.addEventListener('keyup', update); + cell3.addEventListener('dblclick', () => { + sortTable(cell3); + }); + + cell4.innerHTML = 'Freq'; + + + cell5.innerHTML = 'CurChannel'; + cell5.classList.add('sortable'); + cell5.addEventListener('click', () => { + sortTable(cell4); + }); + + + cell6.innerHTML = 'Channel'; + cell6.classList.add('sortable'); + cell6.addEventListener('click', () => { + sortTable(cell5); + }); + + cell7.innerHTML = 'CurPower'; + cell7.classList.add('sortable'); + cell7.addEventListener('click', () => { + sortTable(cell6); + }); + + cell8.innerHTML = 'Power'; + cell8.classList.add('sortable'); + cell8.addEventListener('click', () => { + sortTable(cell7); + }); + + + cell9.innerHTML = 'Clients'; + cell9.classList.add('sortable'); + cell9.addEventListener('click', () => { + sortTable(cell8); + }); + + cell10.innerHTML = 'ChanUtil'; + cell10.classList.add('sortable'); + cell10.addEventListener('click', () => { + sortTable(cell9); + }); + cell11.innerHTML = 'Option'; + + table.classList.add('nodes'); + + update(); + }; })(); diff --git a/webroot/js/gui_map.js b/webroot/js/gui_map.js index c06f7f8..4ba7c3e 100644 --- a/webroot/js/gui_map.js +++ b/webroot/js/gui_map.js @@ -1,148 +1,176 @@ /* exported guiMap */ /* global config,store,domlib,socket */ -var guiMap = {}; +const guiMap = {}; -(function(){ - var view = guiMap; - var container, el; +(function init () { + 'use strict'; - var geoJsonLayer, nodeLayer, clientLayer24, clientLayer5;//, draggingNodeID; + const view = guiMap, + WINDOW_HEIGHT_MENU = 50; - function addNode (node){ - /* - https://github.com/Leaflet/Leaflet/issues/4484 - if(node.node_id === draggingNodeID){ - return - } - */ - if(node.location === undefined || node.location.latitude === undefined || node.location.longitude === undefined) { - return; - } - var className = 'node'; - var startdate = new Date(); - startdate.setMinutes(startdate.getMinutes() - 1); - if(new Date(node.lastseen) < startdate) { - className += ' offline'; - } - var wifi24='-',wifi5='-',ch24='-',ch5='-',tx24='-',tx5='-'; - if(node.statistics && node.statistics.clients){ - wifi24 = node.statistics.clients.wifi24; + let container = null, + el = null, - if(wifi24 < config.map.icon.warn.wifi24 && wifi24 > 0){ - className += ' client24'; - } else if(wifi24 < config.map.icon.crit.wifi24 && wifi24 >= config.map.icon.warn.wifi24){ - className += ' client24-warn'; - } else if(wifi24 >= config.map.icon.crit.wifi24){ - className += ' client24-crit'; - } + geoJsonLayer = null, + nodeLayer = null, + clientLayer24 = null, + clientLayer5 = null; + // , draggingNodeID=null; - wifi5 = node.statistics.clients.wifi5; - if(config.map.icon.warn.wifi5 < 20 && wifi5 > 0){ - className += ' client5'; - } else if(wifi5 < config.map.icon.crit.wifi5 && wifi5 >= config.map.icon.warn.wifi5){ - className += ' client5-warn'; - } else if(wifi5 >= config.map.icon.crit.wifi5){ - className += ' client5-crit'; - } - } + function addNode (node) { + /* eslint-disable-line https://github.com/Leaflet/Leaflet/issues/4484 + if(node.node_id === draggingNodeID){ + return + } + */ - var nodemarker = L.marker([node.location.latitude, node.location.longitude], { - icon: L.divIcon({className: className}), - draggable: true - }); - nodemarker.bindTooltip(node.hostname+'
('+node.node_id+')'+ - ''+ - ''+ - ''+ - ''+ - '
ClChTx
2.4G'+wifi24+''+ch24+''+tx24+'
5G'+wifi5+''+ch5+''+tx5+'
'+ - '
' - ); - /* - nodemarker.on('dragstart',function(){ - draggingNodeID = node.node_id; - }) - */ - nodemarker.on('dragend',function(){ - // draggingNodeID = undefined; - var pos = nodemarker.getLatLng(); - node.location = { - 'latitude': pos.lat, - 'longitude': pos.lng - }; - socket.sendnode(node); - }); - nodeLayer.addLayer(nodemarker); - } + if (!node.location || !node.location.latitude || !node.location.longitude) { + return; + } + let className = 'node', + wifi24 = '-', + wifi5 = '-'; + const startdate = new Date(), + ch24 = node.wireless.channel24 || '-', + ch5 = node.wireless.channel5 || '-', + tx24 = node.wireless.txpower24 || '-', + tx5 = node.wireless.txpower5 || '-'; - function update() { - geoJsonLayer.refresh(); - nodeLayer.clearLayers(); - - var nodes = store.getNodes(); - for(var i=0; i 0) { + className += ' client24'; + } else if (wifi24 < config.map.icon.crit.wifi24 && wifi24 >= config.map.icon.warn.wifi24) { + className += ' client24-warn'; + } else if (wifi24 >= config.map.icon.crit.wifi24) { + className += ' client24-crit'; + } + // eslint-disable-next-line prefer-destructuring + wifi5 = node.statistics.clients.wifi5; - window.addEventListener("resize",function(){ - el.style.height = (window.innerHeight - 50 )+"px"; - map.invalidateSize(); - }); + if (wifi5 < config.map.icon.warn.wifi5 && wifi5 > 0) { + className += ' client5'; + } else if (wifi5 < config.map.icon.crit.wifi5 && wifi5 >= config.map.icon.warn.wifi5) { + className += ' client5-warn'; + } else if (wifi5 >= config.map.icon.crit.wifi5) { + className += ' client5-crit'; + } + } - update(); - }; + // eslint-disable-next-line one-var + const nodemarker = L.marker([node.location.latitude, node.location.longitude], { + 'draggable': true, + 'icon': L.divIcon({'className': className}) + }); + + nodemarker.bindTooltip(`${node.hostname}
(${node.node_id})` + + '' + + '' + + `` + + `` + + '
ClChTx
2.4G${wifi24}${ch24}${tx24}
5G${wifi5}${ch5}${tx5}
' + + '
' + ); + + /* + Nodemarker.on('dragstart',function(){ + draggingNodeID = node.node_id; + }) + */ + nodemarker.on('dragend', () => { + // DraggingNodeID = undefined; + const pos = nodemarker.getLatLng(); + + node.location = { + 'latitude': pos.lat, + 'longitude': pos.lng + }; + socket.sendnode(node); + }); + nodeLayer.addLayer(nodemarker); + } + + function update () { + geoJsonLayer.refresh(); + nodeLayer.clearLayers(); + + const nodes = store.getNodes(); + + for (let i = 0; i < nodes.length; i += 1) { + addNode(nodes[i]); + } + + + clientLayer24.setData(nodes.map((node) => { + if (!node.location || !node.location.latitude || !node.location.longitude) { + return null; + } + + return [node.location.latitude, node.location.longitude, node.statistics.clients.wifi24 || 0]; + })); + + clientLayer5.setData(nodes.map((node) => { + if (!node.location || !node.location.latitude || !node.location.longitude) { + return null; + } + + return [node.location.latitude, node.location.longitude, node.statistics.clients.wifi5 || 0]; + })); + } + + view.bind = function bind (bindEl) { + container = bindEl; + }; + + view.render = function render () { + if (!container) { + return; + } else if (el) { + container.appendChild(el); + update(); + + return; + } + console.log('generate new view for map'); + el = domlib.newAt(container, 'div'); + + el.style.height = `${window.innerHeight - WINDOW_HEIGHT_MENU}px`; + + const map = L.map(el).setView(config.map.view.bound, config.map.view.zoom), + layerControl = L.control.layers().addTo(map); + + L.tileLayer(config.map.tileLayer, { + 'maxZoom': config.map.maxZoom + }).addTo(map); + + + geoJsonLayer = L.geoJson.ajax(config.map.geojson.url, config.map.geojson); + + nodeLayer = L.layerGroup(); + /* eslint-disable new-cap */ + clientLayer24 = new L.webGLHeatmap(config.map.heatmap.wifi24); + clientLayer5 = new L.webGLHeatmap(config.map.heatmap.wifi5); + /* eslint-enable new-cap */ + layerControl.addOverlay(geoJsonLayer, 'geojson'); + layerControl.addOverlay(nodeLayer, 'Nodes'); + layerControl.addOverlay(clientLayer24, 'Clients 2.4 Ghz'); + layerControl.addOverlay(clientLayer5, 'Clients 5 Ghz'); + nodeLayer.addTo(map); + + window.addEventListener('resize', () => { + el.style.height = `${window.innerHeight - WINDOW_HEIGHT_MENU}px`; + map.invalidateSize(); + }); + + update(); + }; })(); diff --git a/webroot/js/gui_node.js b/webroot/js/gui_node.js index 6b5d35b..e7ce11e 100644 --- a/webroot/js/gui_node.js +++ b/webroot/js/gui_node.js @@ -1,142 +1,179 @@ /* exported guiNode */ /* globals store, socket, domlib, config,notify */ -var guiNode = {}; -(function(){ - var view = guiNode; - var container, el; +const guiNode = {}; - var titleName,titleID,ago; - var marker, map, geoJsonLayer; - var btnGPS, editLocationGPS, storePosition; - var current_node_id, editing = false; +(function init () { + 'use strict'; - function updatePosition(lat, lng){ - if(!lat || !lng) { - lat = storePosition.latitude || false; - lng = storePosition.longitude || false; - if(!lat || !lng) - return; - } - var node = store.getNode(current_node_id); - node.location = {latitude:lat,longitude:lng}; - socket.sendnode(node); - } + const view = guiNode; - function update(){ - geoJsonLayer.refresh(); - titleID.innerHTML = current_node_id; - var node = store.getNode(current_node_id); - if(node === undefined){ - console.log("node not found: "+current_node_id); - return; - } - var startdate = new Date(); - startdate.setMinutes(startdate.getMinutes() - 1); - if(new Date(node.lastseen) < startdate){ - ago.classList.add('offline'); - ago.classList.remove('online'); - }else{ - ago.classList.remove('offline'); - ago.classList.add('online'); - } - ago.innerHTML = moment(node.lastseen).fromNow() + ' ('+node.lastseen+')'; - if(editLocationGPS || editing || node.location === undefined || node.location.latitude === undefined || node.location.longitude === undefined) { - return; - } - titleName.innerHTML = node.hostname; - var latlng = [node.location.latitude,node.location.longitude]; - map.setView(latlng); - marker.setLatLng(latlng); - marker.setOpacity(1); - } + let container = null, + el = null, - view.setNodeID = function (nodeID){ - current_node_id = nodeID; - }; + titleName = null, + titleID = null, + ago = null, - view.bind = function(el) { - container = el; - }; - view.render = function render(){ - if (container === undefined){ - return; - } else if (el !== undefined){ - container.appendChild(el); - update(); - return; - } - console.log("generate new view for node"); - el = domlib.newAt(container,'div'); + marker = null, + map = null, + geoJsonLayer = null, + btnGPS = null, - var title = domlib.newAt(el,'h1'); - titleName = domlib.newAt(title,'span'); - title.appendChild(document.createTextNode(" - ")); - titleID = domlib.newAt(title,'i'); + editLocationGPS = null, + storePosition = null, + currentNodeID = null, + editing = false; - var lastseen = domlib.newAt(el,'p'); - domlib.newAt(lastseen,'span').innerHTML = "Lastseen: "; - ago = domlib.newAt(lastseen,'span'); + function updatePosition (lat, lng) { + const node = store.getNode(currentNodeID), + newLat = lat || storePosition.latitude || false, + newlng = lng || storePosition.longitude || false; - var mapEl = domlib.newAt(el,'div'); - mapEl.style.height = '300px'; - map = L.map(mapEl).setView(config.map.view.bound, config.map.view.zoom); + if (!newLat || !newlng) { + return; + } - L.tileLayer(config.map.tileLayer, { - maxZoom: config.map.maxZoom, - }).addTo(map); - geoJsonLayer = L.geoJson.ajax(config.map.geojson.url, config.map.geojson).addTo(map); + node.location = { + 'latitude': newLat, + 'longitude': newlng + }; + socket.sendnode(node); + } - marker = L.marker(config.map.view.bound,{draggable:true,opacity:0.5}).addTo(map); - marker.on('dragstart', function(){ - editing = true; - }); - marker.on('dragend', function(){ - editing = false; - var pos = marker.getLatLng(); - updatePosition(pos.lat,pos.lng); - }); + function update () { + geoJsonLayer.refresh(); + titleID.innerHTML = currentNodeID; + const node = store.getNode(currentNodeID), + startdate = new Date(); + + if (!node) { + console.log(`node not found: ${currentNodeID}`); + + return; + } + + startdate.setMinutes(startdate.getMinutes() - 1); + if (new Date(node.lastseen) < startdate) { + ago.classList.add('offline'); + ago.classList.remove('online'); + } else { + ago.classList.remove('offline'); + ago.classList.add('online'); + } + ago.innerHTML = `${moment(node.lastseen).fromNow()} (${node.lastseen})`; + if (editLocationGPS || editing || !node.location || !node.location.latitude || !node.location.longitude) { + return; + } + titleName.innerHTML = node.hostname; + // eslint-disable-next-line one-var + const latlng = [node.location.latitude, node.location.longitude]; + + map.setView(latlng); + marker.setLatLng(latlng); + marker.setOpacity(1); + } + + view.setNodeID = function setNodeID (nodeID) { + currentNodeID = nodeID; + }; + + view.bind = function bind (bindEl) { + container = bindEl; + }; + + view.render = function render () { + if (!container) { + return; + } else if (el) { + container.appendChild(el); + update(); + + return; + } + console.log('generate new view for node'); + el = domlib.newAt(container, 'div'); + + const title = domlib.newAt(el, 'h1'), + lastseen = domlib.newAt(el, 'p'), + mapEl = domlib.newAt(el, 'div'); + + titleName = domlib.newAt(title, 'span'); + title.appendChild(document.createTextNode(' - ')); + titleID = domlib.newAt(title, 'i'); - btnGPS = domlib.newAt(el,'span'); - btnGPS.classList.add('btn'); - btnGPS.innerHTML = "Start follow position"; - btnGPS.addEventListener('click',function(){ - if(editLocationGPS){ - if(btnGPS.innerHTML == "Stop following") - updatePosition(); - btnGPS.innerHTML = "Start follow position"; - navigator.geolocation.clearWatch(editLocationGPS); - editLocationGPS = false; - return; - } - btnGPS.innerHTML = 'Following position'; - if (navigator.geolocation !== undefined) - editLocationGPS = navigator.geolocation.watchPosition( - function geo_success(position) { - btnGPS.innerHTML = "Stop following"; - storePosition = position.coords; - var latlng = [position.coords.latitude, position.coords.longitude]; - marker.setLatLng(latlng); - map.setView(latlng); - }, - function geo_error(error) { - switch (error.code) { - case error.TIMEOUT: - notify.send("error","Find Location timeout"); - break; - } - }, - { - enableHighAccuracy: true, - maximumAge: 30000, - timeout: 27000 - }); - else - notify.send("error","Browser did not support Location"); - }); + domlib.newAt(lastseen, 'span').innerHTML = 'Lastseen: '; + ago = domlib.newAt(lastseen, 'span'); - update(); - }; + mapEl.style.height = '300px'; + map = L.map(mapEl).setView(config.map.view.bound, config.map.view.zoom); + + L.tileLayer(config.map.tileLayer, { + 'maxZoom': config.map.maxZoom + }).addTo(map); + + geoJsonLayer = L.geoJson.ajax(config.map.geojson.url, + config.map.geojson); + geoJsonLayer.addTo(map); + + marker = L.marker(config.map.view.bound, {'draggable': true, + 'opacity': 0.5}).addTo(map); + + marker.on('dragstart', () => { + editing = true; + }); + + marker.on('dragend', () => { + editing = false; + const pos = marker.getLatLng(); + + updatePosition(pos.lat, pos.lng); + }); + + + btnGPS = domlib.newAt(el, 'span'); + btnGPS.classList.add('btn'); + btnGPS.innerHTML = 'Start follow position'; + btnGPS.addEventListener('click', () => { + if (editLocationGPS) { + if (btnGPS.innerHTML === 'Stop following') { + updatePosition(); + } + btnGPS.innerHTML = 'Start follow position'; + navigator.geolocation.clearWatch(editLocationGPS); + editLocationGPS = false; + + return; + } + btnGPS.innerHTML = 'Following position'; + if (navigator.geolocation) { + editLocationGPS = navigator.geolocation.watchPosition((position) => { + btnGPS.innerHTML = 'Stop following'; + storePosition = position.coords; + const latlng = [position.coords.latitude, position.coords.longitude]; + + marker.setLatLng(latlng); + map.setView(latlng); + }, (error) => { + switch (error.code) { + case error.TIMEOUT: + notify.send('error', 'Find Location timeout'); + break; + default: + console.error('a navigator geolocation error: ', error); + } + }, + { + 'enableHighAccuracy': true, + 'maximumAge': 30000, + 'timeout': 27000 + }); + } else { + notify.send('error', 'Browser did not support Location'); + } + }); + update(); + }; })(); diff --git a/webroot/js/gui_skelView.js b/webroot/js/gui_skelView.js index f37b0ce..5ec0a92 100644 --- a/webroot/js/gui_skelView.js +++ b/webroot/js/gui_skelView.js @@ -1,28 +1,33 @@ /* exported guiSkel */ /* globals domlib */ -var guiSkel = {}; +const guiSkel = {}; -(function(){ - var view = guiSkel; - var container, el; +(function init () { + 'use strict'; - function update(){ - } + const view = guiSkel; + let container = null, + el = null; - view.bind = function(el) { - container = el; - }; - view.render = function render(){ - if (container === undefined){ - return; - } else if (el !== undefined){ - container.appendChild(el); - update(); - return; - } - console.log("generate new view for skel"); - el = domlib.newAt(container,'div'); + function update () { + console.warn('Do not run dummies'); + } - update(); - }; + view.bind = function bind (bindEl) { + container = bindEl; + }; + view.render = function render () { + if (!container) { + return; + } else if (el) { + container.appendChild(el); + update(); + + return; + } + console.log('generate new view for skel'); + el = domlib.newAt(container, 'div'); + + update(); + }; })(); diff --git a/webroot/js/gui_stats.js b/webroot/js/gui_stats.js index 0e53bf8..c8469c6 100644 --- a/webroot/js/gui_stats.js +++ b/webroot/js/gui_stats.js @@ -1,64 +1,74 @@ /* exported guiStats */ /* globals store, domlib */ -var guiStats = {}; +const guiStats = {}; -(function(){ - var view = guiStats; - var container, el; +(function init () { + 'use strict'; - var nodes, clients, clientsWifi,clientsWifi24, clientsWifi5; + const view = guiStats; - function update(){ - nodes.innerHTML = store.stats.Nodes; - clients.innerHTML = store.stats.Clients; - clientsWifi.innerHTML = store.stats.ClientsWifi; - clientsWifi24.innerHTML = store.stats.ClientsWifi24; - clientsWifi5.innerHTML = store.stats.ClientsWifi5; - } + let container = null, + el = null, - view.bind = function(el) { - container = el; - }; - view.render = function(){ - if (container === undefined){ - return; - } else if (el !== undefined){ - container.appendChild(el); - update(); - return; - } - console.log("generate new view for stats"); - el = domlib.newAt(container,'div'); - domlib.newAt(el,'h1').innerHTML = "Statistics"; + nodes = null, + clients = null, + clientsWifi = null, + clientsWifi24 = null, + clientsWifi5 = null; - var table = domlib.newAt(el,'table'); - table.classList.add("stats"); + function update () { + nodes.innerHTML = store.stats.Nodes; + clients.innerHTML = store.stats.Clients; + clientsWifi.innerHTML = store.stats.ClientsWifi; + clientsWifi24.innerHTML = store.stats.ClientsWifi24; + clientsWifi5.innerHTML = store.stats.ClientsWifi5; + } - var tr,title; + view.bind = function bind (bindEl) { + container = bindEl; + }; - tr = domlib.newAt(table,'tr'); - title = domlib.newAt(tr,'th'); - title.innerHTML = "Nodes"; - title.setAttribute("colspan","2"); - nodes = domlib.newAt(tr,'td'); + view.render = function render () { + if (!container) { + return; + } else if (el) { + container.appendChild(el); + update(); - tr = domlib.newAt(table,'tr'); - title = domlib.newAt(tr,'th'); - title.innerHTML = "Clients"; - title.setAttribute("colspan","2"); - clients = domlib.newAt(tr,'td'); + return; + } + console.log('generate new view for stats'); + el = domlib.newAt(container, 'div'); + domlib.newAt(el, 'h1').innerHTML = 'Statistics'; - tr = domlib.newAt(table,'tr'); - tr.classList.add("line"); - domlib.newAt(tr,'th').innerHTML = "Wifi"; - domlib.newAt(tr,'th').innerHTML = "2.4 Ghz"; - domlib.newAt(tr,'th').innerHTML = "5 Ghz"; + const table = domlib.newAt(el, 'table'); - tr = domlib.newAt(table,'tr'); - clientsWifi = domlib.newAt(tr,'td'); - clientsWifi24 = domlib.newAt(tr,'td'); - clientsWifi5 = domlib.newAt(tr,'td'); + table.classList.add('stats'); - update(); - }; + let tr = domlib.newAt(table, 'tr'), + title = domlib.newAt(tr, 'th'); + + title.innerHTML = 'Nodes'; + title.setAttribute('colspan', '2'); + nodes = domlib.newAt(tr, 'td'); + + tr = domlib.newAt(table, 'tr'); + title = domlib.newAt(tr, 'th'); + title.innerHTML = 'Clients'; + title.setAttribute('colspan', '2'); + clients = domlib.newAt(tr, 'td'); + + tr = domlib.newAt(table, 'tr'); + tr.classList.add('line'); + domlib.newAt(tr, 'th').innerHTML = 'Wifi'; + domlib.newAt(tr, 'th').innerHTML = '2.4 Ghz'; + domlib.newAt(tr, 'th').innerHTML = '5 Ghz'; + + tr = domlib.newAt(table, 'tr'); + clientsWifi = domlib.newAt(tr, 'td'); + clientsWifi24 = domlib.newAt(tr, 'td'); + clientsWifi5 = domlib.newAt(tr, 'td'); + + update(); + }; })(); diff --git a/webroot/js/notify.js b/webroot/js/notify.js index ccbdbfe..470d3e4 100644 --- a/webroot/js/notify.js +++ b/webroot/js/notify.js @@ -1,51 +1,67 @@ /* exported notify */ -var notify = {}; +const notify = {}; -(function(){ - var container; - var messages = []; +(function init () { + 'use strict'; - if ("Notification" in window) { - window.Notification.requestPermission(); - } + const DELAY_OF_NOTIFY = 15000, + MAX_MESSAGE_SHOW = 10, + messages = []; - function removeLast (){ - messages.splice(0, 1); - if(container!==undefined && container.firstElementChild) - container.removeChild(container.firstElementChild); - } + let container = null; - function renderMsg(msg){ - var msgBox = document.createElement('div'); - msgBox.classList.add("notify",msg.type); - msgBox.innerHTML = msg.text; - container.appendChild(msgBox); - msgBox.addEventListener('click', function(){ - container.removeChild(msgBox); - if (messages.indexOf(msg) !== -1) { - messages.splice(messages.indexOf(msg), 1); - } - }); - } + if ('Notification' in window) { + window.Notification.requestPermission(); + } - window.setInterval(removeLast,15000); + function removeLast () { + messages.splice(0, 1); + if (container && container.firstElementChild) { + container.removeChild(container.firstElementChild); + } + } - notify.bind = function(el) { - container = el; - }; + function renderMsg (msg) { + const msgBox = document.createElement('div'); - notify.send = function(type, text){ - if("Notification" in window && window.Notification.permission === "granted") { - new window.Notification(text,{body:type,icon:'/img/logo.jpg'}); - return; - } - if(messages.length > 10){ - removeLast(); - } - var msg = {type:type,text:text}; - messages.push(msg); - renderMsg(msg); - }; + msgBox.classList.add('notify', msg.type); + msgBox.innerHTML = msg.text; + container.appendChild(msgBox); + msgBox.addEventListener('click', () => { + container.removeChild(msgBox); + if (messages.indexOf(msg) !== -1) { + messages.splice(messages.indexOf(msg), 1); + } + }); + } + window.setInterval(removeLast, DELAY_OF_NOTIFY); + + notify.bind = function bind (el) { + container = el; + }; + + notify.send = function send (type, text) { + if ('Notification' in window && + window.Notification.permission === 'granted') { + // eslint-disable-next-line no-new + new window.Notification(text, { + 'body': type, + 'icon': '/img/logo.jpg' + }); + + return; + } + if (messages.length > MAX_MESSAGE_SHOW) { + removeLast(); + } + const msg = { + 'text': text, + 'type': type + }; + + messages.push(msg); + renderMsg(msg); + }; })(); diff --git a/webroot/js/socket.js b/webroot/js/socket.js index 27c074c..893139d 100644 --- a/webroot/js/socket.js +++ b/webroot/js/socket.js @@ -1,64 +1,77 @@ /* exported socket */ -/*globals notify,gui,store,config*/ -var socket = {readyState:0}; +/* globals notify,gui,store,config*/ +let socket = {'readyState': 0}; -(function(){ +(function init () { + 'use strict'; - function onerror(err) { - console.warn(err); - if(socket.readyState !== 3){ - notify.send("error","Es gibt Übertragungsprobleme!"); - gui.render(); - } - } + const RECONNECT_AFTER = 5000; - function onopen() { - gui.render(); - } + function onerror (err) { + console.warn(err); + // eslint-disable-next-line no-magic-numbers + if (socket.readyState !== 3) { + notify.send('error', 'Es gibt Übertragungsprobleme!'); + gui.render(); + } + } - function onmessage(e) { - var msg = JSON.parse(e.data); - switch (msg.type) { - case "current": - store.updateNode(msg.node,true); - break; - case "to-update": - store.updateNode(msg.node); - break; - case "stats": - if(msg.body) { - store.stats = msg.body; - } - break; - default: - notify.send("warn","unable to identify message: "+e); - break; - } - gui.render(); - } + function onopen () { + gui.render(); + } - function onclose(){ - console.log("socket closed by server"); - notify.send("warn","Es besteht ein Verbindungsproblem!"); - gui.render(); - window.setTimeout(connect, 5000); - } + function onmessage (raw) { + const msg = JSON.parse(raw.data); - function sendnode(node) { - var msg = {type:"to-update",node:node}; - var string = JSON.stringify(msg); - socket.send(string); - notify.send("success","Node '"+node.node_id+"' mit neuen Werten wurde übermittelt."); - } + switch (msg.type) { + case 'current': + store.updateNode(msg.node, true); + break; + case 'to-update': + store.updateNode(msg.node); + break; + case 'stats': + if (msg.body) { + store.stats = msg.body; + } + break; + default: + notify.send('warn', `unable to identify message: ${raw}`); + break; + } + gui.render(); + } - function connect() { - socket = new window.WebSocket(config.backend); - socket.onopen = onopen; - socket.onerror = onerror; - socket.onmessage = onmessage; - socket.onclose = onclose; - socket.sendnode = sendnode; - } + function onclose () { + console.log('socket closed by server'); + notify.send('warn', 'Es besteht ein Verbindungsproblem!'); + gui.render(); + // eslint-disable-next-line no-use-before-define + window.setTimeout(connect, RECONNECT_AFTER); + } - connect(); + function sendnode (node) { + const notifyMsg = `Einstellungen für '${node.node_id}' gespeichert.`, + socketMsg = JSON.stringify({ + 'node': node, + 'type': 'to-update' + }); + + + socket.send(socketMsg); + + + notify.send('success', notifyMsg); + } + + function connect () { + socket = new window.WebSocket(config.backend); + socket.onopen = onopen; + socket.onerror = onerror; + socket.onmessage = onmessage; + socket.onclose = onclose; + socket.sendnode = sendnode; + } + + connect(); })(); diff --git a/webroot/js/store.js b/webroot/js/store.js index b7a2959..858296d 100644 --- a/webroot/js/store.js +++ b/webroot/js/store.js @@ -1,38 +1,52 @@ /* exported store */ -var store = { - _list:{}, - _toupdate:{}, - stats:{"Clients":0,"ClientsWifi":0,"ClientsWifi24":0,"ClientsWifi5":0,"Gateways":0,"Nodes":0,"Firmwares":{},"Models":{}} + +const store = { + 'stats': { + 'Clients': 0, + 'ClientsWifi': 0, + 'ClientsWifi24': 0, + 'ClientsWifi5': 0, + 'Firmwares': {}, + 'Gateways': 0, + 'Models': {}, + 'Nodes': 0 + } }; -(function(){ +(function init () { + 'use strict'; - function getNode(nodeid){ - var node; - if (store._toupdate[nodeid]) { - node = store._toupdate[nodeid]; - } else if (store._list[nodeid]){ - node = store._list[nodeid]; - }else{ - return; - } - node._wireless = store._list[nodeid].wireless; - return node; - } + const list = {}, + toupdate = {}; - store.updateNode = function updateReal(node, real){ - if(real){ - store._list[node.node_id] = node; - }else{ - store._toupdate[node.node_id] = node; - } - }; + function getNode (nodeid) { + let node = {}; - store.getNode = getNode; + if (toupdate[nodeid]) { + node = toupdate[nodeid]; + } else if (list[nodeid]) { + node = list[nodeid]; + } else { + return null; + } + // eslint-disable-next-line no-underscore-dangle + node._wireless = list[nodeid].wireless; - store.getNodes = function() { - return Object.keys(store._list).map(getNode); - }; + return node; + } + store.updateNode = function updateNode (node, real) { + if (real) { + list[node.node_id] = node; + } else { + toupdate[node.node_id] = node; + } + }; + + store.getNode = getNode; + + store.getNodes = function getNodes () { + return Object.keys(list).map(getNode); + }; })();