rewrite
This commit is contained in:
parent
7b6510e697
commit
77e67618a9
|
@ -1,2 +1,5 @@
|
|||
data/
|
||||
api/
|
||||
node_modules/
|
||||
bower_components
|
||||
config.json
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
'use strict';
|
||||
module.exports = function (grunt) {
|
||||
// Load grunt tasks automatically, when needed
|
||||
require('jit-grunt')(grunt, {
|
||||
useminPrepare: 'grunt-usemin',
|
||||
});
|
||||
require('time-grunt')(grunt);
|
||||
|
||||
grunt.initConfig({
|
||||
open: {
|
||||
public: {
|
||||
url: 'http://localhost:8080'
|
||||
}
|
||||
},
|
||||
connect:{
|
||||
public:{
|
||||
options:{
|
||||
port:8080,
|
||||
hostname:'*',
|
||||
base:['.']
|
||||
}
|
||||
}
|
||||
},
|
||||
jshint: {
|
||||
files: ['Gruntfile.js', 'js/**/*.js'],
|
||||
options: {
|
||||
reporter: require('jshint-stylish')
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
livereload: {
|
||||
files: [
|
||||
'js/**/*.js',
|
||||
'css/**/*.css',
|
||||
],
|
||||
options: {
|
||||
livereload: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.registerTask('default', ['connect:public','open:public','watch']);
|
||||
|
||||
};
|
|
@ -16,10 +16,12 @@
|
|||
"tests"
|
||||
],
|
||||
"dependencies": {
|
||||
"material-design-lite": "^1.1.3",
|
||||
"tablesort": "https://github.com/tristen/tablesort.git#v3.0.2",
|
||||
"dialog-polyfill": "^0.4.3",
|
||||
"Leaflet.label": "~0.2.1",
|
||||
"leaflet": "~0.7.3",
|
||||
"moment": "~2.9.0"
|
||||
"moment": "~2.9.0",
|
||||
"requirejs": "^2.2.0",
|
||||
"font-awesome": "^4.6.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
"reload":60000,
|
||||
"map":"http://localhost:8080/meshviewer",
|
||||
"editmap":{
|
||||
"icon":{
|
||||
"warn":{"wifi24":20,"wifi5":20},
|
||||
"crit":{"wifi24":30,"wifi5":30}
|
||||
},
|
||||
"view":[53.0702,8.815],
|
||||
"zoom":16,
|
||||
"geojson":"/data/meshviewer.geojson",
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
@font-face {
|
||||
font-family: 'FontAwesome';
|
||||
src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?v=4.6.3');
|
||||
src: url('../bower_components/font-awesome/fonts/fontawesome-webfont.eot?#iefix&v=4.6.3') format('embedded-opentype'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff2?v=4.6.3') format('woff2'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.woff?v=4.6.3') format('woff'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.ttf?v=4.6.3') format('truetype'), url('../bower_components/font-awesome/fonts/fontawesome-webfont.svg?v=4.6.3#fontawesomeregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
|
||||
body{
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
border: 0px;
|
||||
outline: 0px;
|
||||
background: rgba(0, 0, 0, 0.12);
|
||||
}
|
||||
.content, .content > .map{
|
||||
width:100%;
|
||||
height:100%;
|
||||
position: absolute;
|
||||
}
|
||||
header.menu{
|
||||
position: absolute;;
|
||||
top:12px;
|
||||
right:12px;
|
||||
z-index: 3000;
|
||||
}
|
||||
i.icon{
|
||||
font: normal normal normal 12px/1 FontAwesome;
|
||||
}
|
||||
header.menu .icons i{
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0.4em 0 0 0.4em;
|
||||
margin-left: 12pt;
|
||||
border-radius: 0.9em;
|
||||
background: rgba(255,255,255,0.7);
|
||||
border: none;
|
||||
height: 1.4em;
|
||||
width: 1.4em;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24);
|
||||
font: normal normal normal 24px/1 FontAwesome;
|
||||
}
|
||||
header.menu .icons i span{
|
||||
font-size: 12px;
|
||||
position: relative;
|
||||
top:12px;
|
||||
left:-24px;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow-x: visible;
|
||||
width: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
.sidebar.hidden{
|
||||
display: none;
|
||||
}
|
||||
.sidebar .icon i{
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
right: 12px;
|
||||
width: 1.6em;
|
||||
z-index: 3000;
|
||||
color: black;
|
||||
font: normal normal normal 24px/1 FontAwesome;
|
||||
}
|
||||
.sidebar{
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
z-index: 2000;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
box-shadow: 0 3px 6px rgba(0,0,0,0.16),0 3px 6px rgba(0,0,0,0.23);
|
||||
width: 320pt;
|
||||
}
|
||||
@media screen and (max-width: 630pt){
|
||||
.sidebar{
|
||||
top: 500px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
.nodeicon{
|
||||
background-color: rgba(0,255,0,0.5);
|
||||
border: 2px solid white;
|
||||
border-radius: 10px;
|
||||
width:3px;
|
||||
height: 3px;
|
||||
}
|
||||
.nodeicon-label{
|
||||
font-size: 12px;
|
||||
font-weight: lighter;
|
||||
}
|
||||
.nodeicon-label table{
|
||||
}
|
||||
.nodeicon.offline{
|
||||
background-color: rgba(255,0,0,0.5);
|
||||
}
|
||||
.nodeicon.select{
|
||||
background-color: green;
|
||||
}
|
||||
.nodeicon.select.offline{
|
||||
background-color: red;
|
||||
border-color: black;
|
||||
}
|
||||
.nodeicon.client24{
|
||||
border-left: 3px solid blue;
|
||||
}
|
||||
.nodeicon.client5{
|
||||
border-right: 3px solid blue;
|
||||
}
|
||||
.nodeicon.client24-warn{
|
||||
border-left: 3px solid yellow;
|
||||
}
|
||||
.nodeicon.client5-warn{
|
||||
border-right: 3px solid yellow;
|
||||
}
|
||||
.nodeicon.client24-crit{
|
||||
border-left: 3px solid red;
|
||||
}
|
||||
.nodeicon.client5-crit{
|
||||
border-right: 3px solid red;
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
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;
|
||||
}
|
||||
|
||||
#dialog-editNode{
|
||||
min-width:75%;
|
||||
}
|
||||
#dialog-editNode-map{
|
||||
height:300px;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="app.js"></script>
|
||||
<script>
|
||||
console.log("Version: #revision#")
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
<iframe src="<% this.public.config.map %>"/>
|
|
@ -0,0 +1 @@
|
|||
<iframe src="<% this.public.config.statistics.all %>"/>
|
102
index.html
102
index.html
|
@ -1,100 +1,14 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="description" content="A front-end template that helps you build fast, modern mobile web apps.">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||
<title>Eventmanager</title>
|
||||
|
||||
<!-- Add to homescreen for Chrome on Android -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
|
||||
<!-- Add to homescreen for Safari on iOS -->
|
||||
<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-title" content="Event Manager">
|
||||
|
||||
<!-- Tile icon for Win8 (144x144 + tile color) -->
|
||||
<meta name="msapplication-TileColor" content="#3372DF">
|
||||
|
||||
<link rel="shortcut icon" href="img/logo.png">
|
||||
|
||||
<link rel="stylesheet" href="bower_components/leaflet/dist/leaflet.css" />
|
||||
<link rel="stylesheet" href="bower_components/Leaflet.label/dist/leaflet.label.css" />
|
||||
<link rel="stylesheet" href="css/font.css" />
|
||||
<link rel="stylesheet" href="css/icon.css" />
|
||||
<link rel="stylesheet" href="css/material.pink-amber.min.css" />
|
||||
<link rel="stylesheet" href="bower_components/dialog-polyfill/dialog-polyfill.css" />
|
||||
<link rel="stylesheet" href="css/styles.css" />
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
<link rel="stylesheet" href="bower_components/leaflet/dist/leaflet.css">
|
||||
<link rel="stylesheet" href="bower_components/Leaflet.label/dist/leaflet.label.css">
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<script src="bower_components/requirejs/require.js" data-main="js/app"></script>
|
||||
<script src="//localhost:35729/livereload.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-drawer mdl-layout--fixed-header">
|
||||
<header class="mdl-layout__header">
|
||||
<div class="mdl-layout__header-row">
|
||||
<span class="mdl-layout-title"></span>
|
||||
<div class="mdl-layout-spacer"></div>
|
||||
<div class="mdl-textfield mdl-js-textfield mdl-textfield--expandable">
|
||||
<label class="mdl-button mdl-js-button mdl-button--icon" for="search">
|
||||
<i class="material-icons">search</i>
|
||||
</label>
|
||||
<div class="mdl-textfield__expandable-holder">
|
||||
<input class="mdl-textfield__input" type="text" id="search">
|
||||
<label class="mdl-textfield__label" for="search">Enter Node name</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="lastLoad">
|
||||
</div>
|
||||
<label class="mdl-button mdl-js-button mdl-button--icon" id="refresh">
|
||||
<i class="material-icons">refresh</i>
|
||||
</label>
|
||||
</div>
|
||||
</header>
|
||||
<div class="mdl-layout__drawer">
|
||||
<span class="mdl-layout-title">
|
||||
<img src="img/logo.png" class="logo"/> Event Manager
|
||||
</span>
|
||||
<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="#aliases"><i class="material-icons mdl-badge mdl-badge--overlap" role="presentation" id="menu_aliases">replay</i>Undone Changes</a>
|
||||
<a class="mdl-navigation__link" href="#map"><i class="material-icons" role="presentation">map</i>Map</a>
|
||||
<a class="mdl-navigation__link" href="#statistics"><i class="material-icons" role="presentation">trending_up</i>Statistic</a>
|
||||
</nav>
|
||||
</div>
|
||||
<main class="mdl-layout__content mdl-color--grey-100">
|
||||
<div class="mdl-grid demo-content" id="container">
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
<div id="toast" class="mdl-js-snackbar mdl-snackbar">
|
||||
<div class="mdl-snackbar__text"></div>
|
||||
<button class="mdl-snackbar__action" type="button"></button>
|
||||
</div>
|
||||
<dialog class="mdl-dialog" id="dialog-editNode">
|
||||
<h4 class="mdl-dialog__title">Loading...</h4>
|
||||
<div class="mdl-dialog__content">
|
||||
<p>Loading...</p>
|
||||
</div>
|
||||
<div id="dialog-editNode-map"></div>
|
||||
<div class="mdl-dialog__actions">
|
||||
<button type="button" class="mdl-button save">Save</button>
|
||||
<button type="button" class="mdl-button close">Close</button>
|
||||
</div>
|
||||
</dialog>
|
||||
<script src="bower_components/leaflet/dist/leaflet.js"></script>
|
||||
<script src="bower_components/Leaflet.label/dist/leaflet.label.js"></script>
|
||||
<script src="bower_components/material-design-lite/material.min.js"></script>
|
||||
<script src="bower_components/dialog-polyfill/dialog-polyfill.js"></script>
|
||||
<script src="bower_components/moment/min/moment.min.js"></script>
|
||||
<script src="js/lib.js"></script>
|
||||
<script src="js/store.js"></script>
|
||||
<script src="js/global.js"></script>
|
||||
<script src="js/editModel.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>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
require.config({
|
||||
baseUrl: "js",
|
||||
paths: {
|
||||
"leaflet": "../bower_components/leaflet/dist/leaflet",
|
||||
"leaflet.label": "../bower_components/Leaflet.label/dist/leaflet.label",
|
||||
"moment": "../bower_components/moment/min/moment-with-locales.min",
|
||||
},
|
||||
shim: {
|
||||
}
|
||||
})
|
||||
require(["main", "helper/lib"], function (main) {
|
||||
send("GET","config.json").then(main)
|
||||
})
|
|
@ -0,0 +1,136 @@
|
|||
define(['leaflet','leaflet.label','controller/sidebar'],function(leaflet,leaflet_label,Sidebar){
|
||||
var data,currentNode
|
||||
return function(el,config){
|
||||
var mapEl = document.createElement("div")
|
||||
mapEl.classList.add("map")
|
||||
|
||||
var sideBarEl = document.createElement("div")
|
||||
var bar = Sidebar(sideBarEl,config)
|
||||
|
||||
var map = leaflet.map(mapEl,{zoomControl:false}).setView([51.505, -0.09], 13)
|
||||
var layergeojson,layernodes
|
||||
|
||||
|
||||
|
||||
leaflet.tileLayer(
|
||||
config.editmap.tiles.url,
|
||||
config.editmap.tiles.option).addTo(map)
|
||||
map.setView(config.editmap.view,config.editmap.zoom)
|
||||
|
||||
var geoJsonOption = {
|
||||
pointToLayer: function (feature, latlng){
|
||||
feature.properties.radius = 10
|
||||
return leaflet.circleMarker(latlng, feature.properties)
|
||||
},
|
||||
onEachFeature: function(feature, layer) {
|
||||
layer.bindLabel(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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodeIcon = leaflet.divIcon({className: 'nodeicon'})
|
||||
|
||||
|
||||
render = function(){
|
||||
console.log("render")
|
||||
if(layernodes)
|
||||
layernodes.clearLayers()
|
||||
if(layergeojson)
|
||||
layergeojson.clearLayers()
|
||||
if(data.geojson !== undefined){
|
||||
layergeojson = leaflet.geoJson(data.geojson,geoJsonOption).addTo(map)
|
||||
map._onResize()
|
||||
}
|
||||
|
||||
var nodes = Object.keys(data.nodes).filter(function(key){
|
||||
return data.nodes[key].nodeinfo !== undefined && data.nodes[key].nodeinfo.location !== undefined
|
||||
}).map(function(key){
|
||||
node = data.nodes[key]
|
||||
var m = leaflet.marker([node.nodeinfo.location.latitude,node.nodeinfo.location.longitude],{
|
||||
draggable: true,
|
||||
icon: nodeIcon
|
||||
})
|
||||
|
||||
var className = 'nodeicon'
|
||||
if(node.flags !== undefined && !node.flags.online)
|
||||
className += ' offline'
|
||||
var wifi24="-",wifi5="-",ch24="-",ch5="-",tx24="-",tx5="-"
|
||||
if(node.statistics !== undefined && node.statistics.clients !== undefined){
|
||||
wifi24 = node.statistics.clients.wifi24
|
||||
if(wifi24 < config.editmap.icon.warn.wifi24 && wifi24 > 0)
|
||||
className += ' client24'
|
||||
else if(wifi24 < config.editmap.icon.crit.wifi24 && wifi24 >= config.editmap.icon.warn.wifi24)
|
||||
className += ' client24-warn'
|
||||
else if(wifi24 >= config.editmap.icon.crit.wifi24)
|
||||
className += ' client24-crit'
|
||||
|
||||
wifi5 = node.statistics.clients.wifi5
|
||||
if(config.editmap.icon.warn.wifi5 < 20 && wifi5 > 0)
|
||||
className += ' client5'
|
||||
else if(wifi5 < config.editmap.icon.crit.wifi5 && wifi5 >= config.editmap.icon.warn.wifi5)
|
||||
className += ' client5-warn'
|
||||
else if(wifi5 >= config.editmap.icon.crit.wifi5)
|
||||
className += ' client5-crit'
|
||||
}
|
||||
if(node.nodeinfo.wireless !== undefined){
|
||||
ch24 = (node.nodeinfo.wireless.channel24)?node.nodeinfo.wireless.channel24:'-'
|
||||
ch5 = (node.nodeinfo.wireless.channel5)?node.nodeinfo.wireless.channel5:'-'
|
||||
tx24 = (node.nodeinfo.wireless.txpower24)?node.nodeinfo.wireless.txpower24:'-'
|
||||
tx5 = (node.nodeinfo.wireless.txpower5)?node.nodeinfo.wireless.txpower5:'-'
|
||||
}
|
||||
|
||||
m.bindLabel(node.nodeinfo.hostname+" <div class=\"nodeicon-label\">("+key+")"+
|
||||
"<table><tr><td></td><td>Cl</td><td>Ch</td><td>Tx</td></tr>"+
|
||||
"<tr><td>2.4 Ghz</td><td>"+wifi24+"</td><td>"+ch24+"</td><td>"+tx24+"</td></tr>"+
|
||||
"<tr><td>5 Ghz</td><td>"+wifi5+"</td><td>"+ch5+"</td><td>"+tx5+"</td></tr>"+
|
||||
"</table>"+
|
||||
"</div>"
|
||||
)
|
||||
if(currentNode && currentNode == key){
|
||||
className += ' select'
|
||||
map.setView(m.getLatLng(),config.editmap.zoom)
|
||||
bar.setSelected(key)
|
||||
}
|
||||
m.setIcon(leaflet.divIcon({className: className}))
|
||||
m.on("click", function(){
|
||||
window.location.href = "#map/"+key
|
||||
currentNode = key
|
||||
render()
|
||||
})
|
||||
return m
|
||||
})
|
||||
layernodes = leaflet.featureGroup(nodes).addTo(map)
|
||||
}
|
||||
|
||||
return {
|
||||
storageNotify: function(d){
|
||||
data = d
|
||||
bar.storageNotify(d)
|
||||
render()
|
||||
},
|
||||
controller: function(){
|
||||
currentNode = arguments[0]
|
||||
el.innerHTML = ""
|
||||
el.appendChild(sideBarEl)
|
||||
el.appendChild(mapEl)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,13 @@
|
|||
define(function(){
|
||||
var data
|
||||
return function(el,config){
|
||||
return {
|
||||
storageNotify: function(d){
|
||||
data = d
|
||||
},
|
||||
controller: function(){
|
||||
el.innerHTML = "Not implemented"
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,99 @@
|
|||
define(["helper/lib"],function(){
|
||||
var data,nodeid,current
|
||||
return function(el,config){
|
||||
var sidebar = document.createElement("div")
|
||||
sidebar.classList.add("sidebar")
|
||||
sidebar.classList.add("hidden")
|
||||
el.appendChild(sidebar)
|
||||
|
||||
var controll = document.createElement("div")
|
||||
controll.classList.add("icon")
|
||||
sidebar.appendChild(controll)
|
||||
|
||||
var close = document.createElement('i')
|
||||
close.innerHTML = "\uf00d"
|
||||
controll.appendChild(close)
|
||||
close.addEventListener("click",function(){
|
||||
window.location.href = "#map"
|
||||
nodeid = undefined
|
||||
render()
|
||||
})
|
||||
|
||||
var content = document.createElement("div")
|
||||
content.classList.add("content")
|
||||
sidebar.appendChild(content)
|
||||
|
||||
var lblNodeid = document.createElement("h4")
|
||||
content.appendChild(lblNodeid)
|
||||
|
||||
|
||||
var inHostname = document.createElement("input")
|
||||
content.appendChild(inHostname)
|
||||
|
||||
|
||||
var table = document.createElement("table")
|
||||
table.innerHTML = "<tr><td></td><td>Cl</td><td>Ch</td><td>Tx</td></tr>"
|
||||
var row24 = document.createElement("tr")
|
||||
row24.innerHTML = "<td>2.4 Ghz</td>"
|
||||
var cellClient24 = document.createElement("td")
|
||||
row24.appendChild(cellClient24)
|
||||
var cellCh24 = document.createElement("td")
|
||||
row24.appendChild(cellCh24)
|
||||
var cellTx24 = document.createElement("td")
|
||||
row24.appendChild(cellTx24)
|
||||
table.appendChild(row24)
|
||||
|
||||
var row5 = document.createElement("tr")
|
||||
row5.innerHTML = "<td>5 Ghz</td>"
|
||||
var cellClient5 = document.createElement("td")
|
||||
row5.appendChild(cellClient5)
|
||||
var cellCh5 = document.createElement("td")
|
||||
row5.appendChild(cellCh5)
|
||||
var cellTx5 = document.createElement("td")
|
||||
row5.appendChild(cellTx5)
|
||||
table.appendChild(row5)
|
||||
|
||||
content.appendChild(table)
|
||||
|
||||
var btnSave = document.createElement("button")
|
||||
var saveIcon = document.createElement('i')
|
||||
saveIcon.classList.add("icon")
|
||||
saveIcon.innerHTML = "\uf0c7"
|
||||
btnSave.appendChild(saveIcon)
|
||||
btnSave.innerHTML += " save"
|
||||
content.appendChild(btnSave)
|
||||
|
||||
btnSave.addEventListener("click",function(a) {
|
||||
console.log(inHostname.value)
|
||||
})
|
||||
|
||||
var render = function(){
|
||||
if(nodeid !== undefined){
|
||||
node = data.nodes[nodeid]
|
||||
sidebar.classList.remove("hidden")
|
||||
lblNodeid.innerHTML = "Nodeid:"+nodeid
|
||||
inHostname.value = (data.aliases[nodeid] !== undefined && data.aliases[nodeid].hostname !==undefined)?data.aliases[nodeid].hostname:node.nodeinfo.hostname
|
||||
|
||||
cellClient24.innerHTML = (node.statistics !== undefined && node.statistics.clients !== undefined)?node.statistics.clients.wifi24:'-'
|
||||
cellClient5.innerHTML = (node.statistics !== undefined && node.statistics.clients !== undefined)?node.statistics.clients.wifi5:'-'
|
||||
cellCh24.innerHTML = (node.nodeinfo.wireless && node.nodeinfo.wireless.channel24)?node.nodeinfo.wireless.channel24:'-'
|
||||
cellCh5.innerHTML = (node.nodeinfo.wireless && node.nodeinfo.wireless.channel5)?node.nodeinfo.wireless.channel5:'-'
|
||||
cellTx24.innerHTML = (node.nodeinfo.wireless && node.nodeinfo.wireless.txpower24)?node.nodeinfo.wireless.txpower24:'-'
|
||||
cellTx5.innerHTML = (node.nodeinfo.wireless && node.nodeinfo.wireless.txpower5)?node.nodeinfo.wireless.txpower5:'-'
|
||||
|
||||
}else{
|
||||
sidebar.classList.add("hidden")
|
||||
}
|
||||
}
|
||||
return {
|
||||
storageNotify: function(d){
|
||||
data = d
|
||||
render()
|
||||
},
|
||||
setSelected: function(id){
|
||||
nodeid = id
|
||||
render()
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
|
@ -1,98 +0,0 @@
|
|||
var dialogEditNode = document.getElementById("dialog-editNode")
|
||||
dialogEditNodeClose = document.querySelector('#dialog-editNode .close')
|
||||
dialogEditNodeSave = document.querySelector('#dialog-editNode .save')
|
||||
dialogEditNodeTitle = document.querySelector('#dialog-editNode .mdl-dialog__title')
|
||||
dialogEditNodeContent = document.querySelector('#dialog-editNode .mdl-dialog__content')
|
||||
|
||||
dialogEditNodeMap = L.map('dialog-editNode-map').setView([51.505, -0.09], 13);
|
||||
var dialogEditNodeMapCurrent
|
||||
|
||||
function createModel(){
|
||||
if (! dialogEditNode.showModal) {
|
||||
dialogPolyfill.registerDialog(dialogEditNode);
|
||||
}
|
||||
|
||||
//MAP Part
|
||||
dialogEditNodeMap.setView(internal.config.editmap.view,internal.config.editmap.zoom)
|
||||
L.tileLayer(internal.config.editmap.tiles.url,internal.config.editmap.tiles.option).addTo(dialogEditNodeMap)
|
||||
send("GET",internal.config.editmap.geojson).then(function(data){
|
||||
L.geoJson(data,{
|
||||
pointToLayer: function (feature, latlng){
|
||||
feature.properties.radius = 10
|
||||
return L.circleMarker(latlng, feature.properties)
|
||||
},
|
||||
onEachFeature: function(feature, layer) {
|
||||
layer.bindLabel(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
|
||||
}
|
||||
}
|
||||
}).addTo(dialogEditNodeMap)
|
||||
})
|
||||
dialogEditNodeMapCurrent = L.marker(internal.config.editmap.view,{
|
||||
draggable: true
|
||||
}).addTo(dialogEditNodeMap)
|
||||
|
||||
|
||||
|
||||
|
||||
dialogEditNodeClose.addEventListener('click',function(){
|
||||
dialogEditNode.close()
|
||||
})
|
||||
dialogEditNodeSave.addEventListener('click',function(e){
|
||||
nodeid = dialogEditNodeContent.querySelector('input[name="nodeid"]').value
|
||||
if(internal.aliases[nodeid] == undefined){
|
||||
internal.aliases[nodeid] = {}
|
||||
}
|
||||
if(internal.aliases[nodeid].location == undefined){
|
||||
internal.aliases[nodeid].location = {}
|
||||
}
|
||||
pos = dialogEditNodeMapCurrent.getLatLng()
|
||||
console.log(pos)
|
||||
internal.aliases[nodeid].location.latitude = pos.lat
|
||||
internal.aliases[nodeid].location.longitude = pos.lng
|
||||
internal.aliases[nodeid].hostname = dialogEditNodeContent.querySelector('input[name="hostname"]').value
|
||||
console.log("save",internal.aliases[nodeid],dialogEditNodeMapCurrent.getLatLng())
|
||||
send('POST',internal.config.api+'/aliases/alias/'+nodeid,internal.aliases[nodeid]).then(function(){
|
||||
dialogEditNode.close()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function editModel(key){
|
||||
dialogEditNodeTitle.innerHTML = 'Edit Node: '+key
|
||||
fill = '<input type="hidden" name="nodeid" value="'+key+'"/>'
|
||||
+ '<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label is-dirty">'
|
||||
+ '<input class="mdl-textfield__input" type="text" name="hostname" value="'+internal.nodes[key].nodeinfo.hostname+'"/>'
|
||||
+ '<label class="mdl-textfield__label" for="hostname">Hostname</label>'
|
||||
+'</div>'
|
||||
dialogEditNodeContent.innerHTML = fill
|
||||
if(internal.nodes[key].nodeinfo.location != undefined){
|
||||
pos = [internal.nodes[key].nodeinfo.location.latitude, internal.nodes[key].nodeinfo.location.longitude]
|
||||
dialogEditNodeMapCurrent.setLatLng(pos)
|
||||
dialogEditNodeMap.setView(pos)
|
||||
}else{
|
||||
dialogEditNodeMapCurrent.setLatLng(internal.config.editmap.view)
|
||||
dialogEditNodeMap.setView(internal.config.editmap.view)
|
||||
}
|
||||
dialogEditNodeMapCurrent.bindLabel("Move Node: "+key)
|
||||
|
||||
dialogEditNode.showModal()
|
||||
//WOrkaround
|
||||
dialogEditNodeMap._onResize()
|
||||
}
|
25
js/global.js
25
js/global.js
|
@ -1,25 +0,0 @@
|
|||
var toast = document.getElementById("toast")
|
||||
|
||||
function notify(key){
|
||||
console.log("new node:",key)
|
||||
toast.MaterialSnackbar.showSnackbar({
|
||||
message:"New Nodes with nodeid '"+key+"'!",
|
||||
actionHandler: function(event) {
|
||||
editModel(key)
|
||||
},
|
||||
actionText: 'Edit',
|
||||
timeout: 3000
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
var refreshButton = document.getElementById("refresh")
|
||||
refreshButton.addEventListener('click', refreshData)
|
||||
|
||||
|
||||
var lastload = document.getElementById("lastLoad")
|
||||
function updateTimes(){
|
||||
lastload.innerHTML = moment(internal.lastload).fromNow()
|
||||
}
|
||||
updateTimes();
|
||||
setInterval(updateTimes, 1000);
|
|
@ -7,9 +7,6 @@ function send(method,url,data) {
|
|||
if (req.status == 200) {
|
||||
resolve(req.response);
|
||||
}
|
||||
else {
|
||||
reject(Error(req.statusText));
|
||||
}
|
||||
};
|
||||
|
||||
req.onerror = function() {
|
||||
|
@ -21,7 +18,11 @@ function send(method,url,data) {
|
|||
}else{
|
||||
req.send();
|
||||
}
|
||||
}).then(JSON.parse);
|
||||
}).then(function(data){
|
||||
if(data[0]=='{')
|
||||
return JSON.parse(data)
|
||||
return data
|
||||
});
|
||||
}
|
||||
function localStorageTest() {
|
||||
var test = 'test'
|
|
@ -0,0 +1,85 @@
|
|||
define(function(){
|
||||
return {
|
||||
routes: [],
|
||||
mode: null,
|
||||
root: '/',
|
||||
config: function(options) {
|
||||
this.mode = options && options.mode && options.mode == 'history'
|
||||
&& !!(history.pushState) ? 'history' : 'hash';
|
||||
this.root = options && options.root ? '/' + this.clearSlashes(options.root) + '/' : '/';
|
||||
return this;
|
||||
},
|
||||
getFragment: function() {
|
||||
var fragment = '';
|
||||
if(this.mode === 'history') {
|
||||
fragment = this.clearSlashes(decodeURI(location.pathname + location.search));
|
||||
fragment = fragment.replace(/\?(.*)$/, '');
|
||||
fragment = this.root != '/' ? fragment.replace(this.root, '') : fragment;
|
||||
} else {
|
||||
var match = window.location.href.match(/#(.*)$/);
|
||||
fragment = match ? match[1] : '';
|
||||
}
|
||||
return this.clearSlashes(fragment);
|
||||
},
|
||||
clearSlashes: function(path) {
|
||||
return path.toString().replace(/\/$/, '').replace(/^\//, '');
|
||||
},
|
||||
add: function(re, handler) {
|
||||
if(typeof re == 'function') {
|
||||
handler = re;
|
||||
re = '';
|
||||
}
|
||||
this.routes.push({ re: re, handler: handler});
|
||||
return this;
|
||||
},
|
||||
remove: function(param) {
|
||||
for(var i=0, r; i<this.routes.length, r = this.routes[i]; i++) {
|
||||
if(r.handler === param || r.re.toString() === param.toString()) {
|
||||
this.routes.splice(i, 1);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
flush: function() {
|
||||
this.routes = [];
|
||||
this.mode = null;
|
||||
this.root = '/';
|
||||
return this;
|
||||
},
|
||||
check: function(f) {
|
||||
var fragment = f || this.getFragment();
|
||||
for(var i=0; i<this.routes.length; i++) {
|
||||
var match = fragment.match(this.routes[i].re);
|
||||
if(match) {
|
||||
match.shift();
|
||||
this.routes[i].handler.apply({}, match);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
listen: function() {
|
||||
var self = this;
|
||||
var current = self.getFragment();
|
||||
var fn = function() {
|
||||
if(current !== self.getFragment()) {
|
||||
current = self.getFragment();
|
||||
self.check(current);
|
||||
}
|
||||
}
|
||||
clearInterval(this.interval);
|
||||
this.interval = setInterval(fn, 50);
|
||||
return this;
|
||||
},
|
||||
navigate: function(path) {
|
||||
path = path ? path : '';
|
||||
if(this.mode === 'history') {
|
||||
history.pushState(null, null, this.root + this.clearSlashes(path));
|
||||
} else {
|
||||
window.location.href = window.location.href.replace(/#(.*)$/, '') + '#' + path;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
};
|
||||
})
|
|
@ -0,0 +1,62 @@
|
|||
define(["helper/lib","moment"],function(lib,moment){
|
||||
return function(config){
|
||||
var data = {nodes:{},aliases:{},geojson:{}}
|
||||
var notifies = [], notifiesNew = []
|
||||
|
||||
var notify = function(){
|
||||
for(var i=0; i<notifies.length;i++)
|
||||
notifies[i].storageNotify(data)
|
||||
}
|
||||
var notifyNew = function(key,data){
|
||||
for(var i=0; i<notifiesNew.length;i++)
|
||||
notifiesNew[i].storageNotifyNew(key,data)
|
||||
}
|
||||
|
||||
var refresh = function(){
|
||||
send('GET',config.editmap.geojson).then(function(d){
|
||||
data.geojson = d
|
||||
notify()
|
||||
})
|
||||
send('GET',config.api+"/aliases").then(function(d){
|
||||
data.aliases = d
|
||||
localStorage.setItem("aliases",JSON.stringify(data.aliases))
|
||||
notify()
|
||||
})
|
||||
send('GET',config.api+"/nodes").then(function(d){
|
||||
Object.keys(d).map(function(key){
|
||||
if(data.nodes == undefined && data.nodes[key]== undefined){
|
||||
notifyNew(key,data[key])
|
||||
}
|
||||
data.nodes[key] = d[key]
|
||||
})
|
||||
data.lastload = new Date()
|
||||
localStorage.setItem("nodes",JSON.stringify(data.nodes))
|
||||
notify()
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
setTimeSinceUpdate:function(str){
|
||||
var interval
|
||||
clearInterval(interval);
|
||||
interval = setInterval(function(){
|
||||
str.innerHTML = moment().diff(data.lastload,"seconds")+" sec"
|
||||
}, 100);
|
||||
},
|
||||
addNotify: function(handler){
|
||||
notifies.push(handler)
|
||||
},
|
||||
addNotifyNew: function(handler){
|
||||
notifiesNew.push(handler)
|
||||
},
|
||||
autorefresh: function(timer){
|
||||
var interval
|
||||
clearInterval(interval);
|
||||
interval = setInterval(function(){
|
||||
refresh()
|
||||
}, timer);
|
||||
},
|
||||
refresh: refresh
|
||||
}
|
||||
}
|
||||
})
|
26
js/init.js
26
js/init.js
|
@ -1,26 +0,0 @@
|
|||
send('GET',"config.json").then(function(config){
|
||||
internal.config = config
|
||||
createModel()
|
||||
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
|
||||
internal.lastload = new Date()
|
||||
})
|
||||
}
|
||||
if(!internal.aliases){
|
||||
send('GET',internal.config.api+"/aliases").then(function(data){
|
||||
internal.aliases = data
|
||||
})
|
||||
}
|
||||
}else{
|
||||
refreshData()
|
||||
}
|
||||
updateBange()
|
||||
setInterval(function () {
|
||||
refreshData()
|
||||
}, config.reload);
|
||||
route()
|
||||
})
|
|
@ -0,0 +1,32 @@
|
|||
define(["helper/router","helper/storage","menu","controller/nodes","controller/map"],
|
||||
function (Router, storage, menu, controllerNodes, controllerMap) {
|
||||
return function(config){
|
||||
var store = storage(config)
|
||||
store.refresh()
|
||||
store.autorefresh(config.reload)
|
||||
|
||||
document.title = "eventmanager"
|
||||
|
||||
|
||||
menu(document.body,store)
|
||||
el = document.createElement("div")
|
||||
el.classList.add("content")
|
||||
document.body.appendChild(el)
|
||||
|
||||
|
||||
var map = controllerMap(el,config)
|
||||
store.addNotify(map)
|
||||
|
||||
var nodes = controllerNodes(el,config)
|
||||
store.addNotify(nodes)
|
||||
|
||||
Router.config({
|
||||
mode: 'hash'
|
||||
})
|
||||
.add(/list/, nodes.controller)
|
||||
.add(/map\/(.*)/, map.controller)
|
||||
.add(/map/, map.controller)
|
||||
.add(nodes.controller)
|
||||
.check().listen()
|
||||
}
|
||||
})
|
|
@ -0,0 +1,42 @@
|
|||
define(function(){
|
||||
return function(el,store){
|
||||
menu = document.createElement("header")
|
||||
menu.classList.add("menu")
|
||||
right = document.createElement("div")
|
||||
right.classList.add("icons")
|
||||
menu.appendChild(right)
|
||||
el.appendChild(menu)
|
||||
|
||||
var buttonList = document.createElement("i")
|
||||
buttonList.innerHTML = ""
|
||||
buttonList.onclick = function () {
|
||||
window.location.href = "#list"
|
||||
}
|
||||
right.appendChild(buttonList)
|
||||
|
||||
var buttonMap = document.createElement("i")
|
||||
buttonMap.innerHTML = '\uf278'
|
||||
buttonMap.onclick = function () {
|
||||
window.location.href = "#map"
|
||||
}
|
||||
right.appendChild(buttonMap)
|
||||
|
||||
var buttonStatistic = document.createElement("i")
|
||||
buttonStatistic.innerHTML = ""
|
||||
buttonStatistic.onclick = function () {
|
||||
window.location.href = "#statistics"
|
||||
}
|
||||
right.appendChild(buttonStatistic)
|
||||
|
||||
|
||||
var buttonRefresh = document.createElement("i")
|
||||
buttonRefresh.innerHTML = ""
|
||||
var refreshtime = document.createElement("span")
|
||||
store.setTimeSinceUpdate(refreshtime)
|
||||
buttonRefresh.appendChild(refreshtime)
|
||||
buttonRefresh.onclick = function () {
|
||||
store.refresh()
|
||||
}
|
||||
right.appendChild(buttonRefresh)
|
||||
}
|
||||
})
|
|
@ -1,35 +0,0 @@
|
|||
function routeAliases(){
|
||||
fill = '<table class="mdl-data-table mdl-js-data-table mdl-shadow--2dp nodes-table">'
|
||||
+ '<thead>'
|
||||
+ '<tr>'
|
||||
+ '<th class="mdl-data-table__cell--non-numeric">Hostname</th>'
|
||||
+ '<th>Freq</th>'
|
||||
+ '<th>Channel</th>'
|
||||
+ '<th>Power</th>'
|
||||
+ '<th class="mdl-data-table__cell--non-numeric">Location</th>'
|
||||
+ '<th class="mdl-data-table__cell--non-numeric">SSH</th>'
|
||||
+ '</tr>'
|
||||
+ '</thead>'
|
||||
+ '<tbody>'
|
||||
Object.keys(internal.aliases).map(function(key){
|
||||
fill += '<tr>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2">'
|
||||
+ internal.aliases[key].hostname
|
||||
+ '<br/>'
|
||||
+ '<small>'+key+'</small>'
|
||||
+ '</td>'
|
||||
+ '<td>2.4 Ghz</td>'
|
||||
+ '<td>'+((internal.aliases[key].wireless !== undefined && internal.aliases[key].wireless.channel2 !== undefined)?internal.aliases[key].wireless.channel2:'-')+ '</td>'
|
||||
+ '<td>'+((internal.aliases[key].wireless !== undefined && internal.aliases[key].wireless.txpower2 !== undefined)?internal.aliases[key].wireless.txpower2:'-')+ '</td>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2">'+((internal.aliases[key].location)?'<i class="material-icons">place</i>':'')+'</td>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2">'+sshUrl(key)+'</td>'
|
||||
+ '</tr>'
|
||||
+ '<tr>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" style="padding-left:18px;">5Ghz</td>'
|
||||
+ '<td>'+((internal.aliases[key].wireless !== undefined && internal.aliases[key].wireless.channel5 !== undefined)?internal.aliases[key].wireless.channel5:'-')+ '</td>'
|
||||
+ '<td style="padding-right:18px;">'+((internal.aliases[key].wireless !== undefined && internal.aliases[key].wireless.txpower5 !== undefined)?internal.aliases[key].wireless.txpower5:'-')+ '</td>'
|
||||
+ '</tr>'
|
||||
})
|
||||
fill += '</tbody></table>'
|
||||
container.innerHTML = fill
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
function routeMap(){
|
||||
container.innerHTML = "<iframe src="+internal.config.map+"/>"
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
|
||||
function routeNodesPrivEvent(nodeid,attr,attr2){
|
||||
return function (e){
|
||||
var input = e.which || e.keyCode;
|
||||
if (input === 13) { // 13 is enter
|
||||
value = e.target.value || e.srcElement.value || ''
|
||||
if(internal.aliases[nodeid] == undefined){
|
||||
internal.aliases[nodeid] = {}
|
||||
}
|
||||
if(attr2 == undefined){
|
||||
internal.aliases[nodeid][attr] = value
|
||||
}else{
|
||||
if(internal.aliases[nodeid][attr] == undefined){
|
||||
internal.aliases[nodeid][attr] = {}
|
||||
}
|
||||
if(attr == "wireless")
|
||||
value = parseInt(value)
|
||||
internal.aliases[nodeid][attr][attr2] = 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>Edit</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;">'
|
||||
+ '<span style="font-size:20px;color:'+((internal.nodes[key].flags.online)?'green':'red')+';">●</span><br/>'
|
||||
+ moment(internal.nodes[key].lastseen).fromNow(true)
|
||||
+'</td>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric mdt-table__cell-input" rowspan="2">'
|
||||
+ '<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.wireless !== undefined && internal.nodes[key].nodeinfo.wireless.channel2 !== undefined)?internal.nodes[key].nodeinfo.wireless.channel2:'')+'"/>'
|
||||
+ '</td>'
|
||||
+ '<td>'
|
||||
+ '<input class="mdl-textfield__input" type="number" id="freq24_tx_'+key+'" value="'+((internal.nodes[key].nodeinfo.wireless !== undefined && internal.nodes[key].nodeinfo.wireless.txpower2 !== undefined)?internal.nodes[key].nodeinfo.wireless.txpower2:'')+'"/>'
|
||||
+ '</td>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2"><i class="material-icons" id="edit_'+key+'">edit</i></td>'
|
||||
+ '<td class="mdl-data-table__cell--non-numeric" rowspan="2">'+sshUrl(key)+'</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.wireless !== undefined && internal.nodes[key].nodeinfo.wireless.channel5 !== undefined)?internal.nodes[key].nodeinfo.wireless.channel5:'')+'"/>'
|
||||
+ '</td>'
|
||||
+ '<td style="padding-right:18px;">'
|
||||
+ '<input class="mdl-textfield__input" type="number" id="freq5_tx_'+key+'" value="'+((internal.nodes[key].nodeinfo.wireless !== undefined && internal.nodes[key].nodeinfo.wireless.txpower5 !== undefined)?internal.nodes[key].nodeinfo.wireless.txpower5:'')+'"/>'
|
||||
+ '</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,'wireless','channel2'))
|
||||
document.getElementById("freq24_tx_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'wireless','txpower2'))
|
||||
document.getElementById("freq5_ch_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'wireless','channel5'))
|
||||
document.getElementById("freq5_tx_"+key).addEventListener('keypress', routeNodesPrivEvent(key,'wireless','txpower5'))
|
||||
document.getElementById("edit_"+key).addEventListener('click', function(){
|
||||
editModel(key)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
function routeStatistic(){
|
||||
container.innerHTML = "<iframe src="+internal.config.statistics.all+"/>"
|
||||
}
|
16
js/router.js
16
js/router.js
|
@ -1,16 +0,0 @@
|
|||
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)
|
40
js/store.js
40
js/store.js
|
@ -1,40 +0,0 @@
|
|||
var internal = {
|
||||
config:{},
|
||||
nodes:{},
|
||||
aliases:{},
|
||||
lastload:0
|
||||
}
|
||||
//var toast = document.querySelector('#toast');
|
||||
var container = document.getElementById("container")
|
||||
var menuNodes = document.getElementById("menu_nodes")
|
||||
var menuAliases = document.getElementById("menu_aliases")
|
||||
|
||||
|
||||
|
||||
function updateBange(){
|
||||
if(internal.nodes && Object.keys(internal.nodes))
|
||||
menuNodes.setAttribute("data-badge",Object.keys(internal.nodes).length)
|
||||
if(internal.aliases && Object.keys(internal.aliases))
|
||||
menuAliases.setAttribute("data-badge",Object.keys(internal.aliases).length)
|
||||
}
|
||||
|
||||
function refreshData(){
|
||||
console.log("load new files")
|
||||
send('GET',internal.config.api+"/aliases").then(function(data){
|
||||
internal.aliases = data
|
||||
updateBange()
|
||||
localStorage.setItem("aliases",JSON.stringify(internal.aliases))
|
||||
})
|
||||
return send('GET',internal.config.api+"/nodes").then(function(data){
|
||||
Object.keys(data).map(function(key){
|
||||
if(internal.nodes[key]== undefined){
|
||||
notify(key,data[key])
|
||||
}
|
||||
internal.nodes[key] = data[key]
|
||||
})
|
||||
updateBange()
|
||||
internal.lastload = new Date()
|
||||
localStorage.setItem("nodes",JSON.stringify(internal.nodes))
|
||||
route()
|
||||
})
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "eventmanager",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "Gruntfile.js",
|
||||
"dependencies": {
|
||||
"grunt": "^1.0.1",
|
||||
"grunt-bower-install-simple": "^1.2.3",
|
||||
"grunt-contrib-connect": "^1.0.2",
|
||||
"grunt-contrib-jshint": "^1.0.0",
|
||||
"grunt-contrib-uglify": "^1.0.1",
|
||||
"grunt-contrib-watch": "^1.0.0",
|
||||
"grunt-eslint": "^18.1.0",
|
||||
"grunt-open": "^0.2.3",
|
||||
"jit-grunt": "^0.10.0",
|
||||
"jshint-stylish": "^2.2.0",
|
||||
"time-grunt": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"start": "grunt"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/FreifunkBremen/eventmanager.git"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"bugs": {
|
||||
"url": "https://github.com/FreifunkBremen/eventmanager/issues"
|
||||
},
|
||||
"homepage": "https://github.com/FreifunkBremen/eventmanager#readme"
|
||||
}
|
Loading…
Reference in New Issue