improv
This commit is contained in:
parent
45242f8aee
commit
62dc7384aa
Binary file not shown.
|
@ -0,0 +1,48 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 100;
|
||||||
|
src: local('Roboto Thin'), local('Roboto-Thin'), url(Robort_Thin.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 300;
|
||||||
|
src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v15/Hgo13k-tfSpn0qi1SFdUfaCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Roboto'), local('Roboto-Regular'), url(https://fonts.gstatic.com/s/roboto/v15/zN7GBFwfMP4uA6AR0HCoLQ.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
src: local('Roboto Medium'), local('Roboto-Medium'), url(https://fonts.gstatic.com/s/roboto/v15/RxZJdnzeo3R5zSexge8UUaCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Roboto Bold'), local('Roboto-Bold'), url(https://fonts.gstatic.com/s/roboto/v15/d-6IYplOFocCacKzxwXSOKCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 900;
|
||||||
|
src: local('Roboto Black'), local('Roboto-Black'), url(https://fonts.gstatic.com/s/roboto/v15/mnpfi9pxYH-Go5UiibESIqCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Roboto Italic'), local('Roboto-Italic'), url(https://fonts.gstatic.com/s/roboto/v15/W4wDsBUluyw0tK3tykhXEfesZW2xOQ-xsNqO47m55DA.ttf) format('truetype');
|
||||||
|
}
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Roboto';
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'), url(https://fonts.gstatic.com/s/roboto/v15/t6Nd4cfPRhZP44Q5QAjcC50EAVxt0G0biEntp43Qt6E.ttf) format('truetype');
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,20 @@
|
||||||
|
@font-face {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
src: local('Material Icons'), local('MaterialIcons-Regular'), url(icon-font.woff2) format('woff2');
|
||||||
|
}
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: normal;
|
||||||
|
text-transform: none;
|
||||||
|
display: inline-block;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-wrap: normal;
|
||||||
|
direction: ltr;
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,34 @@
|
||||||
|
html, body {
|
||||||
|
font-family: 'Roboto', 'Helvetica', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
.logo {
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
border-radius: 24px;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
container > iframe{
|
||||||
|
border: 0 solid #000;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nodes-table.mdl-data-table td, .nodes-table.mdl-data-table tr{
|
||||||
|
height: 12px;
|
||||||
|
padding-top: 0px;
|
||||||
|
padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
.nodes-table.mdl-data-table .mdl-textfield{
|
||||||
|
/*padding:20px 0 20px 0;*/
|
||||||
|
padding:20px 0 0;
|
||||||
|
margin:0px;
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
28
index.html
28
index.html
|
@ -9,24 +9,21 @@
|
||||||
|
|
||||||
<!-- Add to homescreen for Chrome on Android -->
|
<!-- Add to homescreen for Chrome on Android -->
|
||||||
<meta name="mobile-web-app-capable" content="yes">
|
<meta name="mobile-web-app-capable" content="yes">
|
||||||
<link rel="icon" sizes="192x192" href="images/android-desktop.png">
|
|
||||||
|
|
||||||
<!-- Add to homescreen for Safari on iOS -->
|
<!-- Add to homescreen for Safari on iOS -->
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="Material Design Lite">
|
<meta name="apple-mobile-web-app-title" content="Event Manager">
|
||||||
<link rel="apple-touch-icon-precomposed" href="images/ios-desktop.png">
|
|
||||||
|
|
||||||
<!-- Tile icon for Win8 (144x144 + tile color) -->
|
<!-- Tile icon for Win8 (144x144 + tile color) -->
|
||||||
<meta name="msapplication-TileImage" content="images/touch/ms-touch-icon-144x144-precomposed.png">
|
|
||||||
<meta name="msapplication-TileColor" content="#3372DF">
|
<meta name="msapplication-TileColor" content="#3372DF">
|
||||||
|
|
||||||
<link rel="shortcut icon" href="https://raw.githubusercontent.com/FreifunkBremen/logo/master/notext.png">
|
<link rel="shortcut icon" href="img/logo.png">
|
||||||
|
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en">
|
<!--<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en">-->
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
|
<link rel="stylesheet" href="css/icon.css">
|
||||||
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.pink-amber.min.css">
|
<link rel="stylesheet" href="css/material.pink-amber.min.css">
|
||||||
<link rel="stylesheet" href="styles.css">
|
<link rel="stylesheet" href="css/styles.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
|
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
|
||||||
|
@ -49,8 +46,8 @@
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="mdl-layout__drawer">
|
<div class="mdl-layout__drawer">
|
||||||
<header class="logo">
|
<header>
|
||||||
<img src="https://raw.githubusercontent.com/FreifunkBremen/logo/master/logo.png">
|
<img src="img/logo.png" class="logo"/> Event Manager
|
||||||
</header>
|
</header>
|
||||||
<nav class="mdl-navigation">
|
<nav class="mdl-navigation">
|
||||||
<a class="mdl-navigation__link" href="#nodes"><i class="material-icons mdl-badge mdl-badge--overlap" role="presentation" id="menu_nodes">view_list</i>Nodes</a>
|
<a class="mdl-navigation__link" href="#nodes"><i class="material-icons mdl-badge mdl-badge--overlap" role="presentation" id="menu_nodes">view_list</i>Nodes</a>
|
||||||
|
@ -69,6 +66,13 @@
|
||||||
<button class="mdl-snackbar__action" type="button"></button>
|
<button class="mdl-snackbar__action" type="button"></button>
|
||||||
</div>
|
</div>
|
||||||
<script src="bower_components/material-design-lite/material.min.js"></script>
|
<script src="bower_components/material-design-lite/material.min.js"></script>
|
||||||
<script src="lib/store.js"></script>
|
<script src="js/lib.js"></script>
|
||||||
|
<script src="js/store.js"></script>
|
||||||
|
<script src="js/route/nodes.js"></script>
|
||||||
|
<script src="js/route/aliases.js"></script>
|
||||||
|
<script src="js/route/map.js"></script>
|
||||||
|
<script src="js/route/statistic.js"></script>
|
||||||
|
<script src="js/router.js"></script>
|
||||||
|
<script src="js/init.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
var toast = document.getElementById("toast")
|
||||||
|
|
||||||
|
function notify(key){
|
||||||
|
toast.MaterialSnackbar.showSnackbar({
|
||||||
|
message:"New Nodes with nodeid '"+key+"'!",
|
||||||
|
actionHandler: function(event) {
|
||||||
|
console.log(event)
|
||||||
|
},
|
||||||
|
actionText: 'Edit',
|
||||||
|
timeout: 3000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var refreshButton = document.getElementById("refresh")
|
||||||
|
refreshButton.addEventListener('click', refreshData)
|
|
@ -0,0 +1,24 @@
|
||||||
|
send('GET',"config.json").then(function(config){
|
||||||
|
internal.config = config
|
||||||
|
if(localStorageTest()){
|
||||||
|
internal.nodes = JSON.parse(localStorage.getItem("nodes"))
|
||||||
|
internal.aliases = JSON.parse(localStorage.getItem("aliases"))
|
||||||
|
if(!internal.nodes){
|
||||||
|
send('GET',internal.config.api+"/nodes").then(function(data){
|
||||||
|
internal.nodes = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if(!internal.aliases){
|
||||||
|
send('GET',internal.config.api+"/aliases").then(function(data){
|
||||||
|
internal.aliases = data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
||||||
|
menuNodes.setAttribute("data-badge",Object.keys(internal.nodes).length)
|
||||||
|
setInterval(function () {
|
||||||
|
refreshData()
|
||||||
|
route()
|
||||||
|
}, config.reload);
|
||||||
|
route()
|
||||||
|
})
|
|
@ -0,0 +1,35 @@
|
||||||
|
function send(method,url,data) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
var req = new XMLHttpRequest();
|
||||||
|
req.open(method, url);
|
||||||
|
|
||||||
|
req.onload = function() {
|
||||||
|
if (req.status == 200) {
|
||||||
|
resolve(req.response);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
reject(Error(req.statusText));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
req.onerror = function() {
|
||||||
|
reject(Error("Network Error"));
|
||||||
|
};
|
||||||
|
|
||||||
|
if(data){
|
||||||
|
req.send(JSON.stringify(data));
|
||||||
|
}else{
|
||||||
|
req.send();
|
||||||
|
}
|
||||||
|
}).then(JSON.parse);
|
||||||
|
}
|
||||||
|
function localStorageTest() {
|
||||||
|
var test = 'test'
|
||||||
|
try {
|
||||||
|
localStorage.setItem(test, test)
|
||||||
|
localStorage.removeItem(test)
|
||||||
|
return true
|
||||||
|
} catch(e) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
function routeAliases(){
|
||||||
|
fill = '<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="width:100%">'
|
||||||
|
+ '<thead>'
|
||||||
|
+ '<tr>'
|
||||||
|
+ '<th class="mdl-data-table__cell--non-numeric">Hostname</th>'
|
||||||
|
+ '<th class="mdl-data-table__cell--non-numeric">Location</th>'
|
||||||
|
+ '<th>2.4 Ghz</th>'
|
||||||
|
+ '<th>5 Ghz</th>'
|
||||||
|
+ '</tr>'
|
||||||
|
+ '</thead>'
|
||||||
|
+ '<tbody>'
|
||||||
|
Object.keys(internal.aliases).map(function(key){
|
||||||
|
fill += '<tr>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric">'
|
||||||
|
+ internal.aliases[key].hostname
|
||||||
|
+ '<br/>'
|
||||||
|
+ '<small>'+key+'</small>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric"><i class="material-icons">place</i></td>'
|
||||||
|
+ '<td>'
|
||||||
|
+ 'Ch: '+((internal.aliases[key].freq24 !== undefined)?internal.aliases[key].freq24.channel:'-')
|
||||||
|
+ '<br/>'
|
||||||
|
+ 'Tx: '+((internal.aliases[key].freq24 !== undefined)?internal.aliases[key].freq24.txpower:'-')
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td>'
|
||||||
|
+ 'Ch: '+((internal.aliases[key].freq5 !== undefined)?internal.aliases[key].freq5.channel:'-')
|
||||||
|
+ '<br/>'
|
||||||
|
+ 'TX: '+((internal.aliases[key].freq5 !== undefined)?internal.aliases[key].freq5.txpower:'-')
|
||||||
|
+ '</td>'
|
||||||
|
+ '</tr>'
|
||||||
|
})
|
||||||
|
fill += '</tbody></table>'
|
||||||
|
container.innerHTML = fill
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
function routeMap(){
|
||||||
|
container.innerHTML = "<iframe src="+internal.config.map+"/>"
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
|
||||||
|
function routeNodesPrivEvent(nodeid,attr,attr2){
|
||||||
|
return function (e){
|
||||||
|
var input = e.which || e.keyCode;
|
||||||
|
if (input === 13) { // 13 is enter
|
||||||
|
if(internal.aliases[nodeid] == undefined){
|
||||||
|
internal.aliases[nodeid] = {}
|
||||||
|
}
|
||||||
|
if(attr2 == undefined){
|
||||||
|
internal.aliases[nodeid][attr] = e.srcElement.value
|
||||||
|
}else{
|
||||||
|
if(internal.aliases[nodeid][attr] == undefined){
|
||||||
|
internal.aliases[nodeid][attr] = {}
|
||||||
|
}
|
||||||
|
internal.aliases[nodeid][attr][attr2] = e.srcElement.value
|
||||||
|
}
|
||||||
|
send('POST',internal.config.api+'/aliases/alias/'+nodeid,internal.aliases[nodeid])
|
||||||
|
}
|
||||||
|
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function routeNodes(){
|
||||||
|
fill = '<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp nodes-table">'
|
||||||
|
+ '<thead>'
|
||||||
|
+ '<tr>'
|
||||||
|
+'<th></th>'
|
||||||
|
+ '<th class="mdl-data-table__cell--non-numeric">Hostname</th>'
|
||||||
|
+ '<th>Ports</th>'
|
||||||
|
+ '<th>Freq</th>'
|
||||||
|
+ '<th>Clients</th>'
|
||||||
|
+ '<th>Ch</th>'
|
||||||
|
+ '<th>Tx</th>'
|
||||||
|
+ '<th>Ort</th>'
|
||||||
|
+ '<th>SSH</th>'
|
||||||
|
+ '</tr>'
|
||||||
|
+ '</thead>'
|
||||||
|
+ '<tbody>'
|
||||||
|
Object.keys(internal.nodes).map(function(key){
|
||||||
|
fill += '<tr>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2" style="padding:0px 2px;text-align:center;">'
|
||||||
|
+ '<i class="material-icons" style="color:'+((internal.nodes[key].flags.online)?'green':'red')+';">camera</i></td>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric mdt-table__cell-input" rowspan="2" style="padding-left:0px;">'
|
||||||
|
+ '<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label is-dirty">'
|
||||||
|
+ '<input class="mdl-textfield__input" type="text" id="hostname_'+key+'" value="'+internal.nodes[key].nodeinfo.hostname+'"/>'
|
||||||
|
+ '<label class="mdl-textfield__label" for="hostname_'+key+'">'+key+'</label>'
|
||||||
|
+ '</div>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td rowspan="2">100%</td>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric">2Ghz</td>'
|
||||||
|
+ '<td>'+internal.nodes[key].statistics.clients.wifi24+'</td>'
|
||||||
|
+ '<td>'
|
||||||
|
+ '<input class="mdl-textfield__input" type="number" id="freq24_ch_'+key+'" value="'+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq24.channel:'')+'"/>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td>'
|
||||||
|
+ '<input class="mdl-textfield__input" type="number" id="freq24_tx_'+key+'" value="'+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq24.txpower:'')+'"/>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2"><i class="material-icons">place</i></td>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2">SSH</td>'
|
||||||
|
+ '</tr>'
|
||||||
|
+ '<tr>'
|
||||||
|
+ '<td class="mdl-data-table__cell--non-numeric" style="padding-left:18px;">5Ghz</td>'
|
||||||
|
+ '<td>'+ internal.nodes[key].statistics.clients.wifi5+'</td>'
|
||||||
|
+ '<td>'
|
||||||
|
+ '<input class="mdl-textfield__input" type="number" id="freq5_ch_'+key+'" value="'+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq5.channel:'')+'"/>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '<td style="padding-right:18px;">'
|
||||||
|
+ '<input class="mdl-textfield__input" type="number" id="freq5_tx_'+key+'" value="'+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq5.txpower:'')+'"/>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '</td>'
|
||||||
|
+ '</tr>'
|
||||||
|
})
|
||||||
|
fill += '</tbody></table>'
|
||||||
|
container.innerHTML = fill
|
||||||
|
|
||||||
|
Object.keys(internal.nodes).map(function(key){
|
||||||
|
document.getElementById("hostname_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'hostname',null))
|
||||||
|
document.getElementById("freq24_ch_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'freq24','channel'))
|
||||||
|
document.getElementById("freq24_tx_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'freq24','txpower'))
|
||||||
|
document.getElementById("freq5_ch_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'freq5','channel'))
|
||||||
|
document.getElementById("freq5_tx_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'freq5','txpower'))
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
function routeStatistic(){
|
||||||
|
container.innerHTML = "<iframe src="+internal.config.statistics.all+"/>"
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
function route(){
|
||||||
|
if (location.hash === "#aliases") {
|
||||||
|
routeAliases()
|
||||||
|
}else if (location.hash === "#map") {
|
||||||
|
routeMap()
|
||||||
|
}else if (location.hash === "#statistics") {
|
||||||
|
routeStatistic()
|
||||||
|
}else{
|
||||||
|
routeNodes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
window.addEventListener("hashchange",route)
|
|
@ -0,0 +1,28 @@
|
||||||
|
var internal = {
|
||||||
|
config:{},
|
||||||
|
nodes:{},
|
||||||
|
aliases:{}
|
||||||
|
}
|
||||||
|
//var toast = document.querySelector('#toast');
|
||||||
|
var container = document.getElementById("container")
|
||||||
|
var menuNodes = document.getElementById("menu_nodes")
|
||||||
|
var menuAliases = document.getElementById("menu_aliases")
|
||||||
|
|
||||||
|
|
||||||
|
function refreshData(){
|
||||||
|
send('GET',internal.config.api+"/aliases").then(function(data){
|
||||||
|
internal.aliases = data
|
||||||
|
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
||||||
|
})
|
||||||
|
send('GET',internal.config.api+"/nodes").then(function(data){
|
||||||
|
Object.keys(data).map(function(key){
|
||||||
|
if(typeof internal.nodes[key]=='undefined'){
|
||||||
|
notify(key)
|
||||||
|
}
|
||||||
|
internal.nodes[key] = data[key]
|
||||||
|
})
|
||||||
|
menuNodes.setAttribute("data-badge",Object.keys(internal.nodes).length)
|
||||||
|
})
|
||||||
|
localStorage.setItem("nodes",JSON.stringify(internal.nodes))
|
||||||
|
localStorage.setItem("aliases",JSON.stringify(internal.aliases))
|
||||||
|
}
|
201
lib/store.js
201
lib/store.js
|
@ -1,201 +0,0 @@
|
||||||
function get(url) {
|
|
||||||
return new Promise(function(resolve, reject) {
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
req.open('GET', url);
|
|
||||||
|
|
||||||
req.onload = function() {
|
|
||||||
if (req.status == 200) {
|
|
||||||
resolve(req.response);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reject(Error(req.statusText));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
req.onerror = function() {
|
|
||||||
reject(Error("Network Error"));
|
|
||||||
};
|
|
||||||
|
|
||||||
req.send();
|
|
||||||
}).then(JSON.parse);
|
|
||||||
}
|
|
||||||
function localStorageTest() {
|
|
||||||
var test = 'test'
|
|
||||||
try {
|
|
||||||
localStorage.setItem(test, test)
|
|
||||||
localStorage.removeItem(test)
|
|
||||||
return true
|
|
||||||
} catch(e) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var internal = {
|
|
||||||
config:{},
|
|
||||||
nodes:{},
|
|
||||||
aliases:{},
|
|
||||||
tmp:{
|
|
||||||
aliases_count: 0,
|
|
||||||
nodes_count: 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//var toast = document.querySelector('#toast');
|
|
||||||
var toast = document.getElementById("toast")
|
|
||||||
var container = document.getElementById("container")
|
|
||||||
var refreshButton = document.getElementById("refresh")
|
|
||||||
var menuNodes = document.getElementById("menu_nodes")
|
|
||||||
var menuAliases = document.getElementById("menu_aliases")
|
|
||||||
|
|
||||||
|
|
||||||
function notify(key){
|
|
||||||
toast.MaterialSnackbar.showSnackbar({
|
|
||||||
message:"New Nodes with nodeid '"+key+"'!",
|
|
||||||
actionHandler: function(event) {
|
|
||||||
console.log(event)
|
|
||||||
},
|
|
||||||
actionText: 'Edit',
|
|
||||||
timeout: 3000
|
|
||||||
});
|
|
||||||
}
|
|
||||||
function update(){
|
|
||||||
get(internal.config.api+"/aliases").then(function(data){
|
|
||||||
internal.aliases = data
|
|
||||||
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
|
||||||
})
|
|
||||||
get(internal.config.api+"/nodes").then(function(data){
|
|
||||||
Object.keys(data).map(function(key){
|
|
||||||
if(typeof internal.nodes[key]=='undefined'){
|
|
||||||
notify(key)
|
|
||||||
}
|
|
||||||
internal.nodes[key] = data[key]
|
|
||||||
})
|
|
||||||
menuNodes.setAttribute("data-badge",Object.keys(internal.nodes).length)
|
|
||||||
})
|
|
||||||
localStorage.setItem("nodes",JSON.stringify(internal.nodes))
|
|
||||||
localStorage.setItem("aliases",JSON.stringify(internal.aliases))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function routeNodes(){
|
|
||||||
fill = '<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="width:100%">'
|
|
||||||
+ '<thead>'
|
|
||||||
+ '<tr>'
|
|
||||||
+ '<th class="mdl-data-table__cell--non-numeric">Hostname</th>'
|
|
||||||
+ '<th>Clients</th>'
|
|
||||||
+ '<th>Ports</th>'
|
|
||||||
+ '<th>2.4 Ghz</th>'
|
|
||||||
+ '<th>5 Ghz</th>'
|
|
||||||
+ '<th>Location</th>'
|
|
||||||
+ '<th>SSH</th>'
|
|
||||||
+ '</tr>'
|
|
||||||
+ '</thead>'
|
|
||||||
+ '<tbody>'
|
|
||||||
Object.keys(internal.nodes).map(function(key){
|
|
||||||
fill += '<tr>'
|
|
||||||
+ '<td class="mdl-data-table__cell--non-numeric">'
|
|
||||||
+ '<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label is-dirty">'
|
|
||||||
+ '<input class="mdl-textfield__input" type="text" id="hostname_'+key+'" value="'+internal.nodes[key].nodeinfo.hostname+'"/>'
|
|
||||||
+ '<label class="mdl-textfield__label" for="hostname_'+key+'">'+key+'</label>'
|
|
||||||
+ '</div>'
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td>'
|
|
||||||
+ '2.4 Ghz: '+internal.nodes[key].statistics.clients.wifi24
|
|
||||||
+ '<br/>'
|
|
||||||
+ '5 Ghz: '+internal.nodes[key].statistics.clients.wifi5
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td>100%</td>'
|
|
||||||
+ '<td>'
|
|
||||||
+ 'Ch: '+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq24.channel:'-')
|
|
||||||
+ '<br/>'
|
|
||||||
+ 'Tx: '+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq24.txpower:'-')
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td>'
|
|
||||||
+ 'Ch: '+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq5.channel:'-')
|
|
||||||
+ '<br/>'
|
|
||||||
+ 'TX: '+((internal.nodes[key].nodeinfo.settings !== undefined)?internal.nodes[key].nodeinfo.settings.freq5.txpower:'-')
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td class="mdl-data-table__cell--non-numeric"><i class="material-icons">location</i></td>'
|
|
||||||
+ '<td>SSH</td>'
|
|
||||||
+ '</tr>'
|
|
||||||
})
|
|
||||||
fill += '</tbody></table>'
|
|
||||||
container.innerHTML = fill
|
|
||||||
}
|
|
||||||
function routeAliases(){
|
|
||||||
fill = '<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp" style="width:100%">'
|
|
||||||
+ '<thead>'
|
|
||||||
+ '<tr>'
|
|
||||||
+ '<th class="mdl-data-table__cell--non-numeric">Hostname</th>'
|
|
||||||
+ '<th class="mdl-data-table__cell--non-numeric">Location</th>'
|
|
||||||
+ '<th>2.4 Ghz</th>'
|
|
||||||
+ '<th>5 Ghz</th>'
|
|
||||||
+ '</tr>'
|
|
||||||
+ '</thead>'
|
|
||||||
+ '<tbody>'
|
|
||||||
Object.keys(internal.aliases).map(function(key){
|
|
||||||
fill += '<tr>'
|
|
||||||
+ '<td class="mdl-data-table__cell--non-numeric">'
|
|
||||||
+ internal.aliases[key].hostname
|
|
||||||
+ '<br/>'
|
|
||||||
+ '<small>'+key+'</small>'
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td class="mdl-data-table__cell--non-numeric"><i class="material-icons">location</i></td>'
|
|
||||||
+ '<td>'
|
|
||||||
+ 'Ch: '+((internal.aliases[key].freq24 !== undefined)?internal.aliases[key].freq24.channel:'-')
|
|
||||||
+ '<br/>'
|
|
||||||
+ 'Tx: '+((internal.aliases[key].freq24 !== undefined)?internal.aliases[key].freq24.txpower:'-')
|
|
||||||
+ '</td>'
|
|
||||||
+ '<td>'
|
|
||||||
+ 'Ch: '+((internal.aliases[key].freq5 !== undefined)?internal.aliases[key].freq5.channel:'-')
|
|
||||||
+ '<br/>'
|
|
||||||
+ 'TX: '+((internal.aliases[key].freq5 !== undefined)?internal.aliases[key].freq5.txpower:'-')
|
|
||||||
+ '</td>'
|
|
||||||
+ '</tr>'
|
|
||||||
})
|
|
||||||
fill += '</tbody></table>'
|
|
||||||
container.innerHTML = fill
|
|
||||||
}
|
|
||||||
function routeMap(){
|
|
||||||
container.innerHTML = "<iframe src="+internal.config.map+"/>"
|
|
||||||
}
|
|
||||||
function routeStatistic(){
|
|
||||||
container.innerHTML = "<iframe src="+internal.config.statistics.all+"/>"
|
|
||||||
}
|
|
||||||
function route(){
|
|
||||||
if (location.hash === "#aliases") {
|
|
||||||
routeAliases()
|
|
||||||
}else if (location.hash === "#map") {
|
|
||||||
routeMap()
|
|
||||||
}else if (location.hash === "#statistics") {
|
|
||||||
routeStatistic()
|
|
||||||
}else{
|
|
||||||
routeNodes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
refreshButton.addEventListener('click', update)
|
|
||||||
window.addEventListener("hashchange",route)
|
|
||||||
|
|
||||||
get("config.json").then(function(config){
|
|
||||||
internal.config = config
|
|
||||||
if(localStorageTest()){
|
|
||||||
internal.nodes = JSON.parse(localStorage.getItem("nodes"))
|
|
||||||
internal.aliases = JSON.parse(localStorage.getItem("aliases"))
|
|
||||||
if(!internal.nodes){
|
|
||||||
get(internal.config.api+"/nodes").then(function(data){
|
|
||||||
internal.nodes = data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(!internal.aliases){
|
|
||||||
get(internal.config.api+"/aliases").then(function(data){
|
|
||||||
internal.aliases = data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
|
||||||
menuNodes.setAttribute("data-badge",Object.keys(internal.nodes).length)
|
|
||||||
setInterval(function () {
|
|
||||||
update()
|
|
||||||
}, config.reload);
|
|
||||||
route()
|
|
||||||
})
|
|
23
styles.css
23
styles.css
|
@ -1,23 +0,0 @@
|
||||||
html, body {
|
|
||||||
font-family: 'Roboto', 'Helvetica', sans-serif;
|
|
||||||
}
|
|
||||||
header.logo {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
header.logo img{
|
|
||||||
margin-top: 10px;
|
|
||||||
width:75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
container > iframe{
|
|
||||||
border: 0 solid #000;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue