[TASK] rewrite table (#10)
This commit is contained in:
parent
7c5d117784
commit
861531712c
|
@ -2,15 +2,13 @@ db_type = "sqlite3"
|
||||||
db_connection = "/tmp/freifunkmanager.db"
|
db_connection = "/tmp/freifunkmanager.db"
|
||||||
|
|
||||||
webserver_bind = ":8080"
|
webserver_bind = ":8080"
|
||||||
webroot = "./webroot"
|
webroot = "./webroot/"
|
||||||
|
|
||||||
secret = "passw0rd"
|
secret = "passw0rd"
|
||||||
|
|
||||||
ssh_key = "~/.ssh/id_rsa"
|
ssh_key = "~/.ssh/id_rsa"
|
||||||
ssh_ipaddress_suffix = "fd2f:"
|
ssh_ipaddress_suffix = "fd2f:"
|
||||||
ssh_timeout = "1m"
|
ssh_timeout = "1m"
|
||||||
ssh_config_all = false
|
|
||||||
ssh_yanic_update = true
|
|
||||||
|
|
||||||
# enable receiving
|
# enable receiving
|
||||||
yanic_enable = true
|
yanic_enable = true
|
||||||
|
|
|
@ -41,14 +41,18 @@ table th > input {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
table th.sortable.sort-down:after {
|
table th.sort-header:after {
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
table th.sort-header.sort-down:after {
|
||||||
content: " \25BC"
|
content: " \25BC"
|
||||||
}
|
}
|
||||||
table th.sortable.sort-up:after {
|
table th.sort-header.sort-up:after {
|
||||||
content: " \25B2"
|
content: " \25B2"
|
||||||
}
|
}
|
||||||
table th.sortable:not(.sort-down):not(.sort-up):after {
|
table th.sort-header:not(.sort-down):not(.sort-up):after {
|
||||||
content: " \25B4\25BE";
|
content: " \25B4\25BE";
|
||||||
|
color: grey;
|
||||||
}
|
}
|
||||||
table.nodes, table.stats {
|
table.nodes, table.stats {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -66,11 +70,11 @@ table.nodes tbody tr:nth-child(odd) {
|
||||||
table.nodes tbody tr:hover {
|
table.nodes tbody tr:hover {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
}
|
}
|
||||||
table.nodes tbody tr.offline td:first-child,
|
table.nodes tbody tr td.offline,
|
||||||
table.nodes tbody tr.offline:hover td:first-child{
|
table.nodes tbody tr td.offline:hover{
|
||||||
background: #dc0067;
|
background: #dc0067;
|
||||||
}
|
}
|
||||||
table.nodes tbody tr.unseen:first-child{
|
table.nodes tbody tr td.unseen{
|
||||||
background: #009ee0;
|
background: #009ee0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,9 +107,10 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
input[readonly] {
|
|
||||||
|
input {
|
||||||
border: none;
|
border: none;
|
||||||
border-bottom: 1px solid;
|
border-bottom: 1px solid grey;
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
|
|
@ -16,6 +16,7 @@ export function getNode (nodeid) {
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
node._wireless = cNode.wireless;
|
node._wireless = cNode.wireless;
|
||||||
node.lastseen = cNode.lastseen;
|
node.lastseen = cNode.lastseen;
|
||||||
|
node.statistics = cNode.statistics;
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
import * as V from 'superfine';
|
||||||
|
|
||||||
|
export default class Table {
|
||||||
|
|
||||||
|
constructor (el, properties, headings, sortIndex, renderRow) {
|
||||||
|
this.sortReverse = false;
|
||||||
|
this.el = el;
|
||||||
|
this.headings = headings;
|
||||||
|
this.sortIndex = sortIndex;
|
||||||
|
this.renderRow = renderRow;
|
||||||
|
this.properties = properties;
|
||||||
|
this.maxDisplayedRows = localStorage.getItem("maxDisplayedRows");
|
||||||
|
|
||||||
|
if (this.maxDisplayedRows == null) {
|
||||||
|
this.maxDisplayedRows = 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sortTable(i) {
|
||||||
|
this.sortReverse = i === this.sortIndex ? !this.sortReverse : false;
|
||||||
|
this.sortIndex = i;
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
render () {
|
||||||
|
const children = [],
|
||||||
|
self = this;
|
||||||
|
|
||||||
|
|
||||||
|
if (this.data.length !== 0) {
|
||||||
|
const th = this.headings.map((d, i) => {
|
||||||
|
const properties = {};
|
||||||
|
|
||||||
|
let name = d.name;
|
||||||
|
|
||||||
|
if (d.class) {
|
||||||
|
properties.class += ' ' + d.class;
|
||||||
|
properties.title = name;
|
||||||
|
name = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d.sort) {
|
||||||
|
return V.h('th', properties, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
properties.onclick = () => self.sortTable(i);
|
||||||
|
properties.class = 'sort-header';
|
||||||
|
|
||||||
|
if (self.sortIndex === i) {
|
||||||
|
properties.class += self.sortReverse ? ' sort-up' : ' sort-down';
|
||||||
|
}
|
||||||
|
|
||||||
|
return V.h('th', properties, name);
|
||||||
|
});
|
||||||
|
let rows = this.data.slice(0).sort(this.headings[this.sortIndex].sort);
|
||||||
|
|
||||||
|
if (this.headings[this.sortIndex].reverse ? !this.sortReverse : this.sortReverse) {
|
||||||
|
rows = rows.reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxDisplayedRows = rows.length;
|
||||||
|
if (this.maxDisplayedRows != -1) {
|
||||||
|
maxDisplayedRows = Math.min(this.maxDisplayedRows, maxDisplayedRows);
|
||||||
|
}
|
||||||
|
|
||||||
|
var visibleRows = [];
|
||||||
|
for (let i = 0; i < maxDisplayedRows; i += 1) {
|
||||||
|
visibleRows.push(rows[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
children.push(V.h('thead', {}, V.h('tr', {}, th)));
|
||||||
|
children.push(V.h('tbody', {}, visibleRows.map(this.renderRow)));
|
||||||
|
children.push(V.h('tfoot', {}, V.h('tr', {}, V.h('td',{colspan: th.length},
|
||||||
|
[V.h('span',{}, maxDisplayedRows + " of " + rows.length + " nodes. Show: ")].concat(
|
||||||
|
[["5", 5], ["10", 10], ["20", 20], ["50", 50], ["All", -1]].map((item)=>
|
||||||
|
V.h('a',{
|
||||||
|
class: 'btn',
|
||||||
|
onclick:()=> {
|
||||||
|
this.maxDisplayedRows = item[1];
|
||||||
|
localStorage.setItem("maxDisplayedRows", this.maxDisplayedRows);
|
||||||
|
}
|
||||||
|
}, item[0])
|
||||||
|
))
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
|
V.render(this.vel, this.vel = V.h('table',this.properties, children), this.el);
|
||||||
|
}
|
||||||
|
|
||||||
|
setData(d) {
|
||||||
|
this.data = d;
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,8 @@ import * as gui from '../gui';
|
||||||
import * as lib from '../lib';
|
import * as lib from '../lib';
|
||||||
import * as socket from '../socket';
|
import * as socket from '../socket';
|
||||||
import * as store from '../store';
|
import * as store from '../store';
|
||||||
|
import * as V from 'superfine';
|
||||||
|
import Table from '../table';
|
||||||
import config from '../config';
|
import config from '../config';
|
||||||
import View from '../view';
|
import View from '../view';
|
||||||
import {FromNowAgo} from '../lib';
|
import {FromNowAgo} from '../lib';
|
||||||
|
@ -11,374 +13,212 @@ export class ListView extends View {
|
||||||
|
|
||||||
constructor () {
|
constructor () {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
this.debouncer = new lib.Debouncer(1000, "list render");
|
this.debouncer = new lib.Debouncer(1000, "list render");
|
||||||
this.maxDisplayedNodes = localStorage.getItem("maxDisplayedNodes");
|
|
||||||
if (this.maxDisplayedNodes == null) {
|
|
||||||
this.maxDisplayedNodes = 20;
|
|
||||||
}
|
|
||||||
const table = domlib.newAt(this.el, 'table'),
|
|
||||||
thead = domlib.newAt(table, 'thead');
|
|
||||||
|
|
||||||
this.tbody = domlib.newAt(table, 'tbody');
|
this.filter = domlib.newAt(this.el, 'input', {
|
||||||
|
'placeholder': 'Search',
|
||||||
// eslint-disable-next-line one-var
|
'style': 'width: 100%;border: 0px; border-bottom: 2px inset;',
|
||||||
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');
|
|
||||||
|
|
||||||
cell1.innerHTML = 'Lastseen';
|
|
||||||
cell1.addEventListener('click', () => {
|
|
||||||
this.sortTable(cell1);
|
|
||||||
});
|
});
|
||||||
|
this.filter.addEventListener('keyup', () => {
|
||||||
cell2.classList.add('sortable');
|
|
||||||
this.nodeidFilter = domlib.newAt(cell2, 'input');
|
|
||||||
this.nodeidFilter.setAttribute('placeholder', 'NodeID');
|
|
||||||
this.nodeidFilter.setAttribute('size', '9');
|
|
||||||
this.nodeidFilter.addEventListener('keyup', () => {
|
|
||||||
this.render();
|
|
||||||
});
|
|
||||||
cell2.addEventListener('dblclick', () => {
|
|
||||||
this.sortTable(cell2);
|
|
||||||
});
|
|
||||||
this.nodeidFilter.addEventListener('focusin', () => {
|
|
||||||
this.editing = true;
|
|
||||||
});
|
|
||||||
this.nodeidFilter.addEventListener('focusout', () => {
|
|
||||||
this.editing = false;
|
|
||||||
this.render();
|
this.render();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.table = new Table(domlib.newAt(this.el, 'div'),{
|
||||||
cell3.classList.add('sortable');
|
class: 'nodes',
|
||||||
cell3.classList.add('hostname');
|
},[
|
||||||
this.hostnameFilter = domlib.newAt(cell3, 'input');
|
{
|
||||||
this.hostnameFilter.setAttribute('placeholder', 'Hostname');
|
name:'Lastseen',
|
||||||
this.hostnameFilter.addEventListener('keyup', () => {
|
sort: (a, b) => new Date(a.lastseen) - new Date(b.lastseen),
|
||||||
this.render();
|
reverse: false
|
||||||
});
|
},
|
||||||
cell3.addEventListener('dblclick', () => {
|
{
|
||||||
this.sortTable(cell3);
|
name:'NodeID',
|
||||||
});
|
sort: (a, b) => a.node_id.localeCompare(b.node_id),
|
||||||
this.hostnameFilter.addEventListener('focusin', () => {
|
reverse: false
|
||||||
this.editing = true;
|
},
|
||||||
});
|
{
|
||||||
this.hostnameFilter.addEventListener('focusout', () => {
|
name:'Hostname',
|
||||||
this.editing = false;
|
sort: (a, b) => a.hostname.localeCompare(b.hostname),
|
||||||
this.render();
|
reverse: false
|
||||||
});
|
},
|
||||||
|
{ name:'Freq' },
|
||||||
cell4.innerHTML = 'Freq';
|
{
|
||||||
|
name:'CurCh',
|
||||||
|
sort: (a, b) => (a._wireless ? a._wireless.channel24 : 0) - (b._wireless ? b._wireless.channel24 : 0),
|
||||||
cell5.innerHTML = 'CurChannel';
|
reverse: false
|
||||||
cell5.classList.add('sortable');
|
},
|
||||||
cell5.addEventListener('click', () => {
|
{
|
||||||
this.sortTable(cell5);
|
name:'Channel',
|
||||||
});
|
sort: (a, b) => a.wireless.channel24 - b.wireless.channel24,
|
||||||
|
reverse: false
|
||||||
|
},
|
||||||
cell6.innerHTML = 'Channel';
|
{
|
||||||
cell6.classList.add('sortable');
|
name:'CurPW',
|
||||||
cell6.addEventListener('click', () => {
|
sort: (a, b) => (a._wireless ? a._wireless.txpower24 : 0) - (b._wireless ? b._wireless.txpower24 : 0),
|
||||||
this.sortTable(cell6);
|
reverse: false
|
||||||
});
|
},
|
||||||
|
{
|
||||||
cell7.innerHTML = 'CurPower';
|
name:'Power',
|
||||||
cell7.classList.add('sortable');
|
sort: (a, b) => a.wireless.txpower24 - b.wireless.txpower24,
|
||||||
cell7.addEventListener('click', () => {
|
reverse: false
|
||||||
this.sortTable(cell7);
|
},
|
||||||
});
|
{
|
||||||
|
name:'Clients',
|
||||||
cell8.innerHTML = 'Power';
|
sort: (a, b) => a.statistics.clients.wifi24 - b.statistics.clients.wifi24,
|
||||||
cell8.classList.add('sortable');
|
reverse: false
|
||||||
cell8.addEventListener('click', () => {
|
},
|
||||||
this.sortTable(cell8);
|
{
|
||||||
});
|
name:'ChanUtil',
|
||||||
|
sort: (a, b) => (a.statistics.wireless ? a.statistics.wireless.filter((d) => d.frequency < 5000)[0].ChanUtil || 0 : 0) - (b.statistics.wireless ? b.statistics.wireless.filter((d) => d.frequency < 5000)[0].ChanUtil || 0 : 0),
|
||||||
|
reverse: false
|
||||||
cell9.innerHTML = 'Clients';
|
},
|
||||||
cell9.classList.add('sortable');
|
{ name:'Options' }
|
||||||
cell9.addEventListener('click', () => {
|
], 1, this.renderRow.bind(this));
|
||||||
this.sortTable(cell9);
|
|
||||||
});
|
|
||||||
|
|
||||||
cell10.innerHTML = 'ChanUtil';
|
|
||||||
cell10.classList.add('sortable');
|
|
||||||
cell10.addEventListener('click', () => {
|
|
||||||
this.sortTable(cell10);
|
|
||||||
});
|
|
||||||
cell11.innerHTML = 'Option';
|
|
||||||
|
|
||||||
table.classList.add('nodes');
|
|
||||||
|
|
||||||
this.footerNote = domlib.newAt(this.el, 'span');
|
|
||||||
|
|
||||||
var footerLinkContents = [["5", 5], ["10", 10], ["20", 20], ["50", 50], ["All", -1]];
|
|
||||||
for (var i = 0; i < footerLinkContents.length; i++) {
|
|
||||||
var link = domlib.newAt(this.el, 'a', null, footerLinkContents[i][0]);
|
|
||||||
link.classList.add('btn');
|
|
||||||
const newValue = footerLinkContents[i][1];
|
|
||||||
link.addEventListener('click', () => {
|
|
||||||
this.maxDisplayedNodes = newValue;
|
|
||||||
localStorage.setItem("maxDisplayedNodes", this.maxDisplayedNodes);
|
|
||||||
this.render();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line id-length
|
|
||||||
sort (sortIndex, sortReverse) {
|
|
||||||
function sortNumber (aNum, bNum) {
|
|
||||||
return aNum - bNum;
|
|
||||||
}
|
|
||||||
return (a, b) => {
|
|
||||||
if (!sortIndex) {
|
|
||||||
return a.node_id.localeCompare(b.node_id);
|
|
||||||
}
|
|
||||||
if (sortIndex.classList.contains("hostname")) {
|
|
||||||
return a.hostname.localeCompare(b.hostname);
|
|
||||||
}
|
|
||||||
switch (sortIndex.innerText) {
|
|
||||||
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':
|
|
||||||
if(a.statistics.wireless === null) return 1;
|
|
||||||
if(b.statistics.wireless === null) return -1;
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
if (!sortReverse) {
|
|
||||||
aMax = aMax.reverse();
|
|
||||||
bMax = bMax.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
return bMax[0] - aMax[0];
|
|
||||||
default:
|
|
||||||
return a.node_id.localeCompare(b.node_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
renderRow (node) {
|
renderRow (node) {
|
||||||
const startdate = new Date(),
|
const startdate = new Date(),
|
||||||
tr = document.createElement('tr'),
|
channel24Options = [],
|
||||||
lastseen = domlib.newAt(tr, 'td'),
|
channel5Options = [];
|
||||||
nodeID = domlib.newAt(tr, 'td'),
|
|
||||||
hostname = domlib.newAt(tr, 'td'),
|
|
||||||
hostnameInput = domlib.newAt(hostname, 'input'),
|
|
||||||
freq = domlib.newAt(tr, 'td'),
|
|
||||||
curchannel = domlib.newAt(tr, 'td'),
|
|
||||||
channel = domlib.newAt(tr, 'td'),
|
|
||||||
channel24Input = domlib.newAt(domlib.newAt(channel, 'span'), 'select'),
|
|
||||||
channel5Input = domlib.newAt(domlib.newAt(channel, 'span'), 'select'),
|
|
||||||
curpower = domlib.newAt(tr, 'td'),
|
|
||||||
power = domlib.newAt(tr, 'td'),
|
|
||||||
power24Input = domlib.newAt(domlib.newAt(power, 'span'), 'input'),
|
|
||||||
power5Input = domlib.newAt(domlib.newAt(power, 'span'), 'input'),
|
|
||||||
client = domlib.newAt(tr, 'td'),
|
|
||||||
chanUtil = domlib.newAt(tr, 'td'),
|
|
||||||
option = domlib.newAt(tr, 'td'),
|
|
||||||
edit = domlib.newAt(option, 'div');
|
|
||||||
|
|
||||||
startdate.setMinutes(startdate.getMinutes() - config.node.offline);
|
startdate.setMinutes(startdate.getMinutes() - config.node.offline);
|
||||||
if (new Date(node.lastseen) < startdate) {
|
|
||||||
tr.classList.add('offline');
|
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
|
||||||
} else if (!node._wireless) {
|
|
||||||
tr.classList.add('unseen');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
lastseen.textContent = FromNowAgo(node.lastseen);
|
|
||||||
|
|
||||||
nodeID.textContent = node.node_id;
|
|
||||||
|
|
||||||
hostnameInput.value = node.hostname;
|
|
||||||
hostnameInput.readOnly = true;
|
|
||||||
hostnameInput.setAttribute('placeholder', 'Hostname');
|
|
||||||
hostnameInput.addEventListener('dblclick', () => {
|
|
||||||
this.editing = true;
|
|
||||||
hostnameInput.readOnly = false;
|
|
||||||
});
|
|
||||||
hostnameInput.addEventListener('focusout', () => {
|
|
||||||
if (hostnameInput.readOnly) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.editing = false;
|
|
||||||
hostnameInput.readOnly = true;
|
|
||||||
const old = node.hostname;
|
|
||||||
node.hostname = hostnameInput.value;
|
|
||||||
socket.sendnode(node, (msg)=>{
|
|
||||||
if (!msg.body) {
|
|
||||||
node.hostname = old;
|
|
||||||
hostnameInput.value = old;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
domlib.newAt(freq, 'span').textContent = '2.4 Ghz';
|
|
||||||
domlib.newAt(freq, 'span').textContent = '5 Ghz';
|
|
||||||
|
|
||||||
/* eslint-disable no-underscore-dangle */
|
|
||||||
if (node._wireless) {
|
|
||||||
domlib.newAt(curchannel, 'span').textContent = node._wireless.channel24 || '-';
|
|
||||||
domlib.newAt(curchannel, 'span').textContent = node._wireless.channel5 || '-';
|
|
||||||
}
|
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (i = 0; i < store.channelsWifi24.length; i++) {
|
for (i = 0; i < store.channelsWifi24.length; i++) {
|
||||||
const opt = domlib.newAt(channel24Input,'option',{
|
channel24Options.push(V.h('option', {
|
||||||
'value': store.channelsWifi24[i],
|
'value': store.channelsWifi24[i],
|
||||||
},store.channelsWifi24[i]);
|
'selected': (store.channelsWifi24[i] === node.wireless.channel24),
|
||||||
|
}, store.channelsWifi24[i]));
|
||||||
if(store.channelsWifi24[i] === node.wireless.channel24) {
|
|
||||||
opt.selected = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
channel24Input.addEventListener('focusin', () => {
|
|
||||||
this.editing = true;
|
|
||||||
});
|
|
||||||
channel24Input.addEventListener('focusout', () => {
|
|
||||||
this.editing = false;
|
|
||||||
const old = node.wireless.channel24;
|
|
||||||
node.wireless.channel24 = parseInt(channel24Input.value, 10);
|
|
||||||
socket.sendnode(node, (msg)=>{
|
|
||||||
if (!msg.body) {
|
|
||||||
node.wireless.channel24 = old;
|
|
||||||
channel24Input.value = old;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
for (i = 0; i < store.channelsWifi5.length; i++) {
|
for (i = 0; i < store.channelsWifi5.length; i++) {
|
||||||
const opt = domlib.newAt(channel5Input,'option',{
|
channel5Options.push(V.h('option', {
|
||||||
'value': store.channelsWifi5[i],
|
'value': store.channelsWifi5[i],
|
||||||
},store.channelsWifi5[i]);
|
'selected': (store.channelsWifi5[i] === node.wireless.channel5),
|
||||||
|
}, store.channelsWifi5[i]));
|
||||||
if(store.channelsWifi5[i] === node.wireless.channel5) {
|
|
||||||
opt.selected = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
channel5Input.addEventListener('focusin', () => {
|
|
||||||
this.editing = true;
|
|
||||||
});
|
|
||||||
channel5Input.addEventListener('focusout', () => {
|
|
||||||
this.editing = false;
|
|
||||||
const old = node.wireless.channel5;
|
|
||||||
node.wireless.channel5 = parseInt(channel5Input.value, 10);
|
|
||||||
socket.sendnode(node, (msg)=>{
|
|
||||||
if (!msg.body) {
|
|
||||||
node.wireless.channel5 = old;
|
|
||||||
channel5Input.value = old;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/* eslint-disable no-underscore-dangle */
|
|
||||||
if (node._wireless) {
|
|
||||||
domlib.newAt(curpower, 'span').textContent = node._wireless.txpower24 || '-';
|
|
||||||
domlib.newAt(curpower, 'span').textContent = node._wireless.txpower5 || '-';
|
|
||||||
}
|
|
||||||
/* eslint-enable no-underscore-dangle */
|
|
||||||
|
|
||||||
power24Input.value = node.wireless.txpower24 || '';
|
|
||||||
power24Input.type = 'number';
|
|
||||||
power24Input.min = 1;
|
|
||||||
power24Input.max = 23;
|
|
||||||
power24Input.setAttribute('placeholder', '-');
|
|
||||||
power24Input.addEventListener('focusout', () => {
|
|
||||||
this.editing = false;
|
|
||||||
const old = node.wireless.txpower24;
|
|
||||||
node.wireless.txpower24 = parseInt(power24Input.value, 10);
|
|
||||||
socket.sendnode(node, (msg)=>{
|
|
||||||
if (!msg.body) {
|
|
||||||
node.wireless.txpower24 = old;
|
|
||||||
power24Input.value = old;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
power5Input.value = node.wireless.txpower5 || '';
|
|
||||||
power5Input.type = 'number';
|
|
||||||
power5Input.min = 1;
|
|
||||||
power5Input.max = 23;
|
|
||||||
power5Input.setAttribute('placeholder', '-');
|
|
||||||
power5Input.addEventListener('focusout', () => {
|
|
||||||
this.editing = false;
|
|
||||||
const old = node.wireless.txpower5;
|
|
||||||
node.wireless.txpower5 = parseInt(power5Input.value, 10);
|
|
||||||
socket.sendnode(node, (msg)=>{
|
|
||||||
if (!msg.body) {
|
|
||||||
node.wireless.txpower5 = old;
|
|
||||||
power5Input.value = old;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
domlib.newAt(client, 'span').textContent = node.statistics.clients.wifi24;
|
|
||||||
domlib.newAt(client, 'span').textContent = node.statistics.clients.wifi5;
|
|
||||||
|
|
||||||
/* eslint-disable id-length, no-magic-numbers,one-var */
|
|
||||||
const chanUtil24 = node.statistics.wireless
|
|
||||||
? node.statistics.wireless.filter((d) => d.frequency < 5000)[0] || {}
|
|
||||||
: {},
|
|
||||||
chanUtil5 = node.statistics.wireless
|
|
||||||
? node.statistics.wireless.filter((d) => d.frequency > 5000)[0] || {}
|
|
||||||
: {};
|
|
||||||
/* eslint-enable id-length, no-magic-numbers,one-var */
|
|
||||||
|
|
||||||
domlib.newAt(chanUtil, 'span').textContent = chanUtil24.ChanUtil || '-';
|
|
||||||
domlib.newAt(chanUtil, 'span').textContent = chanUtil5.ChanUtil || '-';
|
|
||||||
|
|
||||||
edit.classList.add('btn');
|
|
||||||
edit.textContent = 'Edit';
|
|
||||||
edit.addEventListener('click', () => {
|
|
||||||
gui.router.navigate(gui.router.generate('node', {'nodeID': node.node_id}));
|
|
||||||
});
|
|
||||||
|
|
||||||
return tr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
return V.h('tr', {},[
|
||||||
|
V.h('td', {
|
||||||
|
'class':(new Date(node.lastseen) < startdate)?'offline':(!node._wireless)?'unseen':''
|
||||||
|
}, FromNowAgo(node.lastseen)),
|
||||||
|
V.h('td', {}, node.node_id),
|
||||||
|
V.h('td', {}, V.h('input',{
|
||||||
|
'value': this._hostname || node.hostname,
|
||||||
|
'oninput':(e) => {
|
||||||
|
this._hostname = e.target.value;
|
||||||
|
},
|
||||||
|
'onfocusout':(e) => {
|
||||||
|
delete this._hostname;
|
||||||
|
|
||||||
sortTable (head) {
|
const old = node.hostname;
|
||||||
if (this.sortIndex) {
|
node.hostname = e.target.value;
|
||||||
this.sortIndex.classList.remove('sort-up', 'sort-down');
|
socket.sendnode(node, (msg)=>{
|
||||||
}
|
if (!msg.body) {
|
||||||
this.sortReverse = head === this.sortIndex
|
node.hostname = old;
|
||||||
? !this.sortReverse
|
e.target.value = old;
|
||||||
: false;
|
}
|
||||||
this.sortIndex = head;
|
});
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {},'2.4 GHz'),
|
||||||
|
V.h('span', {},'5 GHz')
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, node._wireless ? node._wireless.channel24 || '-':'-'),
|
||||||
|
V.h('span', {}, node._wireless ? node._wireless.channel5 || '-':'-')
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, V.h('select',{
|
||||||
|
'onfocusout':(e) => {
|
||||||
|
const old = node.wireless.channel24;
|
||||||
|
node.wireless.channel24 = parseInt(e.target.value, 10);
|
||||||
|
socket.sendnode(node, (msg)=>{
|
||||||
|
if (!msg.body) {
|
||||||
|
node.wireless.channel24 = old;
|
||||||
|
e.target.value = old;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, channel24Options)),
|
||||||
|
V.h('span', {}, V.h('select',{
|
||||||
|
'onfocusout':(e) => {
|
||||||
|
const old = node.wireless.channel5;
|
||||||
|
node.wireless.channel5 = parseInt(e.target.value, 10);
|
||||||
|
socket.sendnode(node, (msg)=>{
|
||||||
|
if (!msg.body) {
|
||||||
|
node.wireless.channel5 = old;
|
||||||
|
e.target.value = old;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, channel5Options))
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, node._wireless ? node._wireless.txpower24 || '-':'-'),
|
||||||
|
V.h('span', {}, node._wireless ? node._wireless.txpower5 || '-':'-')
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, V.h('input',{
|
||||||
|
'type': 'number',
|
||||||
|
'min': 0,
|
||||||
|
'max': 23,
|
||||||
|
'value': this._txpower24 || node.wireless.txpower24,
|
||||||
|
'oninput':(e) => {
|
||||||
|
this._txpower24 = e.target.value;
|
||||||
|
},
|
||||||
|
'onfocusout':(e) => {
|
||||||
|
delete this._txpower24;
|
||||||
|
|
||||||
this.sortIndex.classList.add(this.sortReverse
|
const old = node.wireless.txpower24;
|
||||||
? 'sort-up'
|
node.wireless.txpower24 = parseInt(e.target.value, 10);
|
||||||
: 'sort-down');
|
socket.sendnode(node, (msg)=>{
|
||||||
|
if (!msg.body) {
|
||||||
|
node.wireless.txpower24 = old;
|
||||||
|
e.target.value = old;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
V.h('span', {}, V.h('input',{
|
||||||
|
'type': 'number',
|
||||||
|
'min': 0,
|
||||||
|
'max': 23,
|
||||||
|
'value': this._txpower5 || node.wireless.txpower5,
|
||||||
|
'oninput':(e) => {
|
||||||
|
this._txpower5 = e.target.value;
|
||||||
|
},
|
||||||
|
'onfocusout':(e) => {
|
||||||
|
delete this._txpower5;
|
||||||
|
|
||||||
this.render();
|
const old = node.wireless.txpower5;
|
||||||
|
node.wireless.txpower5 = parseInt(e.target.value, 10);
|
||||||
|
socket.sendnode(node, (msg)=>{
|
||||||
|
if (!msg.body) {
|
||||||
|
node.wireless.txpower5 = old;
|
||||||
|
e.target.value = old;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, node.statistics.clients.wifi24),
|
||||||
|
V.h('span', {}, node.statistics.clients.wifi5)
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('span', {}, node.statistics.wireless ? (node.statistics.wireless.filter((d) => d.frequency < 5000)[0] || {ChanUtil: '-'}).ChanUtil : '-'),
|
||||||
|
V.h('span', {}, node.statistics.wireless ? (node.statistics.wireless.filter((d) => d.frequency > 5000)[0] || {ChanUtil: '-'}).ChanUtil : '-'),
|
||||||
|
]),
|
||||||
|
V.h('td', {}, [
|
||||||
|
V.h('a',{
|
||||||
|
'class':'btn',
|
||||||
|
'href':gui.router.generate('node', {'nodeID': node.node_id})
|
||||||
|
}, 'Edit')
|
||||||
|
]),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
@ -386,41 +226,17 @@ export class ListView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
renderView () {
|
renderView () {
|
||||||
if (this.editing && this.tbody) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while(this.tbody.hasChildNodes()) {
|
|
||||||
this.tbody.removeChild(this.tbody.firstElementChild);
|
|
||||||
}
|
|
||||||
let nodes = store.getNodes();
|
let nodes = store.getNodes();
|
||||||
|
|
||||||
if (this.hostnameFilter && this.hostnameFilter.value !== '') {
|
if (this.filter && this.filter.value !== '') {
|
||||||
// eslint-disable-next-line id-length
|
// eslint-disable-next-line id-length
|
||||||
nodes = nodes.filter((d) => d.hostname.toLowerCase().indexOf(this.hostnameFilter.value.toLowerCase()) > -1);
|
nodes = nodes.filter((d) => {
|
||||||
}
|
return d.node_id.toLowerCase().indexOf(this.filter.value.toLowerCase()) > -1 ||
|
||||||
if (this.nodeidFilter && this.nodeidFilter.value !== '') {
|
d.hostname.toLowerCase().indexOf(this.filter.value.toLowerCase()) > -1 ||
|
||||||
// eslint-disable-next-line id-length
|
d.owner.toLowerCase().indexOf(this.filter.value.toLowerCase()) > -1
|
||||||
nodes = nodes.filter((d) => d.node_id.indexOf(this.nodeidFilter.value.toLowerCase()) > -1);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = nodes.sort(this.sort(this.sortIndex, this.sortReverse));
|
this.table.setData(nodes);
|
||||||
|
|
||||||
if (this.sortReverse) {
|
|
||||||
nodes = nodes.reverse();
|
|
||||||
}
|
|
||||||
|
|
||||||
var numDisplayedNodes = nodes.length;
|
|
||||||
if (this.maxDisplayedNodes != -1) {
|
|
||||||
numDisplayedNodes = Math.min(this.maxDisplayedNodes, numDisplayedNodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
var fragment = document.createDocumentFragment();
|
|
||||||
for (let i = 0; i < numDisplayedNodes; i += 1) {
|
|
||||||
const row = this.renderRow(nodes[i]);
|
|
||||||
fragment.appendChild(row);
|
|
||||||
}
|
|
||||||
this.tbody.appendChild(fragment);
|
|
||||||
|
|
||||||
this.footerNote.innerHTML = numDisplayedNodes + " of " + nodes.length + " nodes. Show: ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
|
|
||||||
import * as domlib from '../domlib';
|
|
||||||
import * as gui from '../gui';
|
import * as gui from '../gui';
|
||||||
import * as socket from '../socket';
|
import * as socket from '../socket';
|
||||||
import * as store from '../store';
|
import * as store from '../store';
|
||||||
|
|
Loading…
Reference in New Issue