summaryrefslogtreecommitdiffhomepage
path: root/modules/luci-mod-status/htdocs/luci-static/resources
diff options
context:
space:
mode:
Diffstat (limited to 'modules/luci-mod-status/htdocs/luci-static/resources')
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/bandwidth.svg (renamed from modules/luci-mod-status/htdocs/luci-static/resources/bandwidth.svg)0
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/channel_analysis.svg19
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/connections.svg (renamed from modules/luci-mod-status/htdocs/luci-static/resources/connections.svg)0
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/load.svg (renamed from modules/luci-mod-status/htdocs/luci-static/resources/load.svg)0
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/wifirate.svg (renamed from modules/luci-mod-status/htdocs/luci-static/resources/wifirate.svg)0
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/svg/wireless.svg (renamed from modules/luci-mod-status/htdocs/luci-static/resources/wireless.svg)0
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/bandwidth.js32
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/channel_analysis.js419
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js68
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js8
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js8
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/30_network.js8
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js129
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js55
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js325
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/iptables.js71
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/load.js46
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/processes.js16
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js54
-rw-r--r--modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js56
20 files changed, 993 insertions, 321 deletions
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/bandwidth.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/bandwidth.svg
index 5a121b85c6..5a121b85c6 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/bandwidth.svg
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/bandwidth.svg
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/svg/channel_analysis.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/channel_analysis.svg
new file mode 100644
index 0000000000..8f01075d0b
--- /dev/null
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/channel_analysis.svg
@@ -0,0 +1,19 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+
+<svg width="100%" height="100%" version="1.1" xmlns="http://www.w3.org/2000/svg">
+ <polyline id="rx" points="" style="fill:blue;fill-opacity:0.4;stroke:blue;stroke-width:1" />
+ <polyline id="tx" points="" style="fill:green;fill-opacity:0.4;stroke:green;stroke-width:1" />
+
+ <line x1="0" y1="25%" x2="100%" y2="25%" style="stroke:black;stroke-width:0.1" />
+ <text id="label_75" x="10" y="24%" style="fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000">-25 dbm</text>
+
+ <line x1="0" y1="50%" x2="100%" y2="50%" style="stroke:black;stroke-width:0.1" />
+ <text id="label_50" x="10" y="49%" style="fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000">-50 dbm</text>
+
+ <line x1="0" y1="75%" x2="100%" y2="75%" style="stroke:black;stroke-width:0.1" />
+ <text id="label_25" x="10" y="74%" style="fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000">-75 dbm</text>
+
+ <line x1="0" y1="90%" x2="100%" y2="90%" style="stroke:black;stroke-width:0.1" />
+ <text id="label_10" x="10" y="89%" style="fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000">-90 dbm</text>
+</svg>
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/connections.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/connections.svg
index 5794e79426..5794e79426 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/connections.svg
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/connections.svg
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/load.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/load.svg
index 716d37617f..716d37617f 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/load.svg
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/load.svg
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/wifirate.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/wifirate.svg
index e75ea614c9..e75ea614c9 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/wifirate.svg
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/wifirate.svg
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/wireless.svg b/modules/luci-mod-status/htdocs/luci-static/resources/svg/wireless.svg
index 00cc2a12f1..00cc2a12f1 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/wireless.svg
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/svg/wireless.svg
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/bandwidth.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/bandwidth.js
index edb934ed93..cb7cf8c23d 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/bandwidth.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/bandwidth.js
@@ -27,7 +27,7 @@ function rate(n, br) {
return view.extend({
load: function() {
return Promise.all([
- this.loadSVG(L.resource('bandwidth.svg')),
+ this.loadSVG(L.resource('svg/bandwidth.svg')),
network.getDevices()
]);
},
@@ -260,26 +260,26 @@ return view.extend({
E('div', { 'class': 'right' }, E('small', { 'id': 'scale' }, '-')),
E('br'),
- E('div', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('Inbound:') ])),
- E('div', { 'class': 'td', 'id': 'rx_bw_cur' }, rate(0, true)),
+ E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('Inbound:') ])),
+ E('td', { 'class': 'td', 'id': 'rx_bw_cur' }, rate(0, true)),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'rx_bw_avg' }, rate(0, true)),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'rx_bw_avg' }, rate(0, true)),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'rx_bw_peak' }, rate(0, true))
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'rx_bw_peak' }, rate(0, true))
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('Outbound:') ])),
- E('div', { 'class': 'td', 'id': 'tx_bw_cur' }, rate(0, true)),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('Outbound:') ])),
+ E('td', { 'class': 'td', 'id': 'tx_bw_cur' }, rate(0, true)),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'tx_bw_avg' }, rate(0, true)),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'tx_bw_avg' }, rate(0, true)),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'tx_bw_peak' }, rate(0, true))
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'tx_bw_peak' }, rate(0, true))
])
])
]));
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/channel_analysis.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/channel_analysis.js
new file mode 100644
index 0000000000..4b321a4f33
--- /dev/null
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/channel_analysis.js
@@ -0,0 +1,419 @@
+'use strict';
+'require view';
+'require poll';
+'require request';
+'require network';
+'require ui';
+'require rpc';
+'require tools.prng as random';
+
+return view.extend({
+ callFrequencyList : rpc.declare({
+ object: 'iwinfo',
+ method: 'freqlist',
+ params: [ 'device' ],
+ expect: { results: [] }
+ }),
+
+ callInfo : rpc.declare({
+ object: 'iwinfo',
+ method: 'info',
+ params: [ 'device' ],
+ expect: { }
+ }),
+
+ render_signal_badge: function(signalPercent, signalValue) {
+ var icon, title, value;
+
+ if (signalPercent < 0)
+ icon = L.resource('icons/signal-none.png');
+ else if (signalPercent == 0)
+ icon = L.resource('icons/signal-0.png');
+ else if (signalPercent < 25)
+ icon = L.resource('icons/signal-0-25.png');
+ else if (signalPercent < 50)
+ icon = L.resource('icons/signal-25-50.png');
+ else if (signalPercent < 75)
+ icon = L.resource('icons/signal-50-75.png');
+ else
+ icon = L.resource('icons/signal-75-100.png');
+
+ value = '%d\xa0%s'.format(signalValue, _('dBm'));
+ title = '%s: %d %s'.format(_('Signal'), signalValue, _('dBm'));
+
+ return E('div', {
+ 'class': 'ifacebadge',
+ 'title': title,
+ 'data-signal': signalValue
+ }, [
+ E('img', { 'src': icon }),
+ value
+ ]);
+ },
+
+ add_wifi_to_graph: function(chan_analysis, res, scanCache, channels, channel_width) {
+ var offset_tbl = chan_analysis.offset_tbl,
+ height = chan_analysis.graph.offsetHeight - 2,
+ step = chan_analysis.col_width,
+ height_diff = (height-(height-(res.signal*-4)));
+
+ if (scanCache[res.bssid].color == null)
+ scanCache[res.bssid].color = random.derive_color(res.bssid);
+
+ if (scanCache[res.bssid].graph == null)
+ scanCache[res.bssid].graph = [];
+
+ channels.forEach(function(channel) {
+ var chan_offset = offset_tbl[channel],
+ points = [
+ (chan_offset-(step*channel_width))+','+height,
+ (chan_offset-(step*(channel_width-1)))+','+height_diff,
+ (chan_offset+(step*(channel_width-1)))+','+height_diff,
+ (chan_offset+(step*(channel_width)))+','+height
+ ];
+
+ if (scanCache[res.bssid].graph[i] == null) {
+ var group = document.createElementNS('http://www.w3.org/2000/svg', 'g'),
+ line = document.createElementNS('http://www.w3.org/2000/svg', 'polyline'),
+ text = document.createElementNS('http://www.w3.org/2000/svg', 'text'),
+ color = scanCache[res.bssid].color;
+
+ line.setAttribute('style', 'fill:'+color+'4f'+';stroke:'+color+';stroke-width:0.5');
+ text.setAttribute('style', 'fill:'+color+';font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
+ text.appendChild(document.createTextNode(res.ssid || res.bssid));
+
+ group.appendChild(line)
+ group.appendChild(text)
+
+ chan_analysis.graph.firstElementChild.appendChild(group);
+ scanCache[res.bssid].graph[i] = { group : group, line : line, text : text };
+ }
+
+ scanCache[res.bssid].graph[i].text.setAttribute('x', chan_offset-step);
+ scanCache[res.bssid].graph[i].text.setAttribute('y', height_diff - 2);
+ scanCache[res.bssid].graph[i].line.setAttribute('points', points);
+ scanCache[res.bssid].graph[i].group.style.zIndex = res.signal*-1;
+ scanCache[res.bssid].graph[i].group.style.opacity = res.stale ? '0.5' : null;
+ })
+ },
+
+ create_channel_graph: function(chan_analysis, freq_tbl, freq) {
+ var is5GHz = freq == '5GHz',
+ columns = is5GHz ? freq_tbl.length * 4 : freq_tbl.length + 3,
+ chan_graph = chan_analysis.graph,
+ G = chan_graph.firstElementChild,
+ step = (chan_graph.offsetWidth - 2) / columns,
+ curr_offset = step;
+
+ function createGraphHLine(graph, pos) {
+ var elem = document.createElementNS('http://www.w3.org/2000/svg', 'line');
+ elem.setAttribute('x1', pos);
+ elem.setAttribute('y1', 0);
+ elem.setAttribute('x2', pos);
+ elem.setAttribute('y2', '100%');
+ elem.setAttribute('style', 'stroke:black;stroke-width:0.1');
+ graph.appendChild(elem);
+ }
+
+ function createGraphText(graph, pos, text) {
+ var elem = document.createElementNS('http://www.w3.org/2000/svg', 'text');
+ elem.setAttribute('y', 15);
+ elem.setAttribute('style', 'fill:#eee; font-size:9pt; font-family:sans-serif; text-shadow:1px 1px 1px #000');
+ elem.setAttribute('x', pos + 5);
+ elem.appendChild(document.createTextNode(text));
+ graph.appendChild(elem);
+ }
+
+ chan_analysis.col_width = step;
+
+ createGraphHLine(G,curr_offset);
+ for (var i=0; i< freq_tbl.length;i++) {
+ var channel = freq_tbl[i]
+ chan_analysis.offset_tbl[channel] = curr_offset+step;
+
+ createGraphHLine(G,curr_offset+step);
+ createGraphText(G,curr_offset+step, channel);
+ curr_offset += step;
+
+ if (is5GHz && freq_tbl[i+1]) {
+ var next_channel = freq_tbl[i+1];
+ /* Check if we are transitioning to another 5Ghz band range */
+ if ((next_channel - channel) == 4) {
+ for (var j=1; j < 4; j++) {
+ chan_analysis.offset_tbl[channel+j] = curr_offset+step;
+ createGraphHLine(G,curr_offset+step);
+ curr_offset += step;
+ }
+ } else {
+ chan_analysis.offset_tbl[channel+1] = curr_offset+step;
+ createGraphHLine(G,curr_offset+step);
+ curr_offset += step;
+
+ chan_analysis.offset_tbl[next_channel-2] = curr_offset+step;
+ createGraphHLine(G,curr_offset+step);
+ curr_offset += step;
+
+ chan_analysis.offset_tbl[next_channel-1] = curr_offset+step;
+ createGraphHLine(G,curr_offset+step);
+ curr_offset += step;
+ }
+ }
+ }
+ createGraphHLine(G,curr_offset+step);
+
+ chan_analysis.tab.addEventListener('cbi-tab-active', L.bind(function(ev) {
+ this.active_tab = ev.detail.tab;
+ }, this));
+ },
+
+ handleScanRefresh: function() {
+ if (!this.active_tab)
+ return;
+
+ var radioDev = this.radios[this.active_tab].dev,
+ table = this.radios[this.active_tab].table,
+ chan_analysis = this.radios[this.active_tab].graph,
+ scanCache = this.radios[this.active_tab].scanCache;
+
+ return Promise.all([
+ radioDev.getScanList(),
+ this.callInfo(radioDev.getName())
+ ]).then(L.bind(function(data) {
+ var results = data[0],
+ local_wifi = data[1];
+
+ var rows = [];
+
+ for (var i = 0; i < results.length; i++) {
+ if (scanCache[results[i].bssid] == null)
+ scanCache[results[i].bssid] = {};
+
+ scanCache[results[i].bssid].data = results[i];
+ }
+
+ if (scanCache[local_wifi.bssid] == null)
+ scanCache[local_wifi.bssid] = {};
+
+ scanCache[local_wifi.bssid].data = local_wifi;
+
+ if (chan_analysis.offset_tbl[local_wifi.channel] != null && local_wifi.center_chan1) {
+ var center_channels = [local_wifi.center_chan1],
+ chan_width_text = local_wifi.htmode.replace(/(V)*HT/,''),
+ chan_width = parseInt(chan_width_text)/10;
+
+ if (local_wifi.center_chan2) {
+ center_channels.push(local_wifi.center_chan2);
+ chan_width = 8;
+ }
+
+ local_wifi.signal = -10;
+ local_wifi.ssid = 'Local Interface';
+
+ this.add_wifi_to_graph(chan_analysis, local_wifi, scanCache, center_channels, chan_width);
+ rows.push([
+ this.render_signal_badge(q, local_wifi.signal),
+ [
+ E('span', { 'style': 'color:'+scanCache[local_wifi.bssid].color }, '⬤ '),
+ local_wifi.ssid
+ ],
+ '%d'.format(local_wifi.channel),
+ '%h MHz'.format(chan_width_text),
+ '%h'.format(local_wifi.mode),
+ '%h'.format(local_wifi.bssid)
+ ]);
+ }
+
+ for (var k in scanCache)
+ if (scanCache[k].stale)
+ results.push(scanCache[k].data);
+
+ results.sort(function(a, b) {
+ var diff = (b.quality - a.quality) || (a.channel - b.channel);
+
+ if (diff)
+ return diff;
+
+ if (a.ssid < b.ssid)
+ return -1;
+ else if (a.ssid > b.ssid)
+ return 1;
+
+ if (a.bssid < b.bssid)
+ return -1;
+ else if (a.bssid > b.bssid)
+ return 1;
+ });
+
+ for (var i = 0; i < results.length; i++) {
+ var res = results[i],
+ qv = res.quality || 0,
+ qm = res.quality_max || 0,
+ q = (qv > 0 && qm > 0) ? Math.floor((100 / qm) * qv) : 0,
+ s = res.stale ? 'opacity:0.5' : '',
+ center_channels = [res.channel],
+ chan_width = 2;
+
+ /* Skip WiFi not supported by the current band */
+ if (chan_analysis.offset_tbl[res.channel] == null)
+ continue;
+
+ res.channel_width = "20 MHz";
+ if (res.ht_operation != null)
+ if (res.ht_operation.channel_width == 2040) { /* 40 MHz Channel Enabled */
+ if (res.ht_operation.secondary_channel_offset == "below") {
+ res.channel_width = "40 MHz";
+ chan_width = 4; /* 40 MHz Channel Used */
+ center_channels[0] -= 2;
+ } else if (res.ht_operation.secondary_channel_offset == "above") {
+ res.channel_width = "40 MHz";
+ chan_width = 4; /* 40 MHz Channel Used */
+ center_channels[0] += 2;
+ } else {
+ res.channel_width = "20 MHz (40 MHz Intolerant)";
+ }
+ }
+
+ if (res.vht_operation != null) {
+ center_channels[0] = res.vht_operation.center_freq_1;
+ if (res.vht_operation.channel_width == 80) {
+ chan_width = 8;
+ res.channel_width = "80 MHz";
+ } else if (res.vht_operation.channel_width == 8080) {
+ res.channel_width = "80+80 MHz";
+ chan_width = 8;
+ center_channels.push(res.vht_operation.center_freq_2);
+ } else if (res.vht_operation.channel_width == 160) {
+ res.channel_width = "160 MHz";
+ chan_width = 16;
+ }
+ }
+
+ this.add_wifi_to_graph(chan_analysis, res, scanCache, center_channels, chan_width);
+
+ rows.push([
+ E('span', { 'style': s }, this.render_signal_badge(q, res.signal)),
+ E('span', { 'style': s }, [
+ E('span', { 'style': 'color:'+scanCache[results[i].bssid].color }, '⬤ '),
+ (res.ssid != null) ? '%h'.format(res.ssid) : E('em', _('hidden'))
+ ]),
+ E('span', { 'style': s }, '%d'.format(res.channel)),
+ E('span', { 'style': s }, '%h'.format(res.channel_width)),
+ E('span', { 'style': s }, '%h'.format(res.mode)),
+ E('span', { 'style': s }, '%h'.format(res.bssid))
+ ]);
+
+ res.stale = true;
+ }
+
+ cbi_update_table(table, rows);
+ }, this))
+ },
+
+ radios : {},
+
+ loadSVG : function(src) {
+ return request.get(src).then(function(response) {
+ if (!response.ok)
+ throw new Error(response.statusText);
+
+ return E('div', {
+ 'id': 'channel_graph',
+ 'style': 'width:100%;height:400px;border:1px solid #000;background:#fff'
+ }, E(response.text()));
+ });
+ },
+
+ load: function() {
+ return Promise.all([
+ this.loadSVG(L.resource('svg/channel_analysis.svg')),
+ network.getWifiDevices().then(L.bind(function(data) {
+ var tasks = [], ret = [];
+
+ for (var i = 0; i < data.length; i++) {
+ ret[data[i].getName()] = { dev : data[i] };
+
+ tasks.push(this.callFrequencyList(data[i].getName())
+ .then(L.bind(function(radio, data) {
+ ret[radio.getName()].freq = data;
+ }, this, data[i])));
+ }
+
+ return Promise.all(tasks).then(function() { return ret; })
+ }, this))
+ ]);
+ },
+
+ render: function(data) {
+ var svg = data[0],
+ wifiDevs = data[1];
+
+ var v = E('div', {}, E('div'));
+
+ for (var ifname in wifiDevs) {
+ var freq_tbl = {
+ ['2.4GHz'] : [],
+ ['5GHz'] : [],
+ };
+
+ /* Split FrequencyList in Bands */
+ wifiDevs[ifname].freq.forEach(function(freq) {
+ if (freq.mhz >= 5000) {
+ freq_tbl['5GHz'].push(freq.channel);
+ } else {
+ freq_tbl['2.4GHz'].push(freq.channel);
+ }
+ });
+
+ for (var freq in freq_tbl) {
+ if (freq_tbl[freq].length == 0)
+ continue;
+
+ var csvg = svg.cloneNode(true),
+ table = E('div', { 'class': 'table' }, [
+ E('div', { 'class': 'tr table-titles' }, [
+ E('div', { 'class': 'th col-2 middle center' }, _('Signal')),
+ E('div', { 'class': 'th col-4 middle left' }, _('SSID')),
+ E('div', { 'class': 'th col-2 middle center hide-xs' }, _('Channel')),
+ E('div', { 'class': 'th col-3 middle left' }, _('Channel Width')),
+ E('div', { 'class': 'th col-2 middle left hide-xs' }, _('Mode')),
+ E('div', { 'class': 'th col-3 middle left hide-xs' }, _('BSSID'))
+ ])
+ ]),
+ tab = E('div', { 'data-tab': ifname+freq, 'data-tab-title': ifname+' ('+freq+')' },
+ [E('br'),csvg,E('br'),table,E('br')]),
+ graph_data = {
+ graph: csvg,
+ offset_tbl: {},
+ col_width: 0,
+ tab: tab,
+ };
+
+ this.radios[ifname+freq] = {
+ dev: wifiDevs[ifname].dev,
+ graph: graph_data,
+ table: table,
+ scanCache: {}
+ };
+
+ cbi_update_table(table, [], E('em', { class: 'spinning' }, _('Starting wireless scan...')));
+
+ v.firstElementChild.appendChild(tab)
+
+ requestAnimationFrame(L.bind(this.create_channel_graph, this, graph_data, freq_tbl[freq], freq));
+ }
+ }
+
+ ui.tabs.initTabGroup(v.firstElementChild.childNodes);
+
+ this.pollFn = L.bind(this.handleScanRefresh, this);
+
+ poll.add(this.pollFn);
+ poll.start();
+
+ return v;
+ },
+
+ handleSaveApply: null,
+ handleSave: null,
+ handleReset: null
+});
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js
index 4c1b097f2b..a87fe53fed 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/connections.js
@@ -36,7 +36,7 @@ Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; };
return view.extend({
load: function() {
return Promise.all([
- this.loadSVG(L.resource('connections.svg'))
+ this.loadSVG(L.resource('svg/connections.svg'))
]);
},
@@ -133,8 +133,8 @@ return view.extend({
rows.push([
c.layer3.toUpperCase(),
c.layer4.toUpperCase(),
- c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src,
- c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst,
+ '%h'.format(c.hasOwnProperty('sport') ? (src + ':' + c.sport) : src),
+ '%h'.format(c.hasOwnProperty('dport') ? (dst + ':' + c.dport) : dst),
'%1024.2mB (%d %s)'.format(c.bytes, c.packets, _('Pkts.'))
]);
}
@@ -321,36 +321,36 @@ return view.extend({
E('div', { 'class': 'right' }, E('small', { 'id': 'scale' }, '-')),
E('br'),
- E('div', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('UDP:') ])),
- E('div', { 'class': 'td', 'id': 'lb_udp_cur' }, [ '0' ]),
+ E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('UDP:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_udp_cur' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_udp_avg' }, [ '0' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_udp_avg' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_udp_peak' }, [ '0' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_udp_peak' }, [ '0' ])
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('TCP:') ])),
- E('div', { 'class': 'td', 'id': 'lb_tcp_cur' }, [ '0' ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('TCP:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_tcp_cur' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_tcp_avg' }, [ '0' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_tcp_avg' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_tcp_peak' }, [ '0' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_tcp_peak' }, [ '0' ])
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid red' }, [ _('Other:') ])),
- E('div', { 'class': 'td', 'id': 'lb_otr_cur' }, [ '0' ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid red' }, [ _('Other:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_otr_cur' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_otr_avg' }, [ '0' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_otr_avg' }, [ '0' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_otr_peak' }, [ '0' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_otr_peak' }, [ '0' ])
])
]),
@@ -376,16 +376,16 @@ return view.extend({
E('br'),
E('div', { 'class': 'cbi-section-node' }, [
- E('div', { 'class': 'table', 'id': 'connections' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th col-2 hide-xs' }, [ _('Network') ]),
- E('div', { 'class': 'th col-2' }, [ _('Protocol') ]),
- E('div', { 'class': 'th col-7' }, [ _('Source') ]),
- E('div', { 'class': 'th col-7' }, [ _('Destination') ]),
- E('div', { 'class': 'th col-4' }, [ _('Transfer') ])
+ E('table', { 'class': 'table', 'id': 'connections' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th col-2 hide-xs' }, [ _('Network') ]),
+ E('th', { 'class': 'th col-2' }, [ _('Protocol') ]),
+ E('th', { 'class': 'th col-7' }, [ _('Source') ]),
+ E('th', { 'class': 'th col-7' }, [ _('Destination') ]),
+ E('th', { 'class': 'th col-4' }, [ _('Transfer') ])
]),
- E('div', { 'class': 'tr placeholder' }, [
- E('div', { 'class': 'td' }, [
+ E('tr', { 'class': 'tr placeholder' }, [
+ E('td', { 'class': 'td' }, [
E('em', {}, [ _('Collecting data...') ])
])
])
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js
index 942b2dd567..ea8f2bb239 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/10_system.js
@@ -65,12 +65,12 @@ return baseclass.extend({
) : null
];
- var table = E('div', { 'class': 'table' });
+ var table = E('table', { 'class': 'table' });
for (var i = 0; i < fields.length; i += 2) {
- table.appendChild(E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
- E('div', { 'class': 'td left' }, [ (fields[i + 1] != null) ? fields[i + 1] : '?' ])
+ table.appendChild(E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
+ E('td', { 'class': 'td left' }, [ (fields[i + 1] != null) ? fields[i + 1] : '?' ])
]));
}
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js
index ceb13b56fa..3e89578002 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/20_memory.js
@@ -43,12 +43,12 @@ return baseclass.extend({
if (swap.total > 0)
fields.push(_('Swap free'), swap.free, swap.total);
- var table = E('div', { 'class': 'table' });
+ var table = E('table', { 'class': 'table' });
for (var i = 0; i < fields.length; i += 3) {
- table.appendChild(E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
- E('div', { 'class': 'td left' }, [
+ table.appendChild(E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
+ E('td', { 'class': 'td left' }, [
(fields[i + 1] != null) ? progressbar(fields[i + 1], fields[i + 2], true) : '?'
])
]));
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/30_network.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/30_network.js
index d528408236..3359ca82cc 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/30_network.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/30_network.js
@@ -81,12 +81,12 @@ return baseclass.extend({
_('Active Connections'), ct_max ? ct_count : null
];
- var ctstatus = E('div', { 'class': 'table' });
+ var ctstatus = E('table', { 'class': 'table' });
for (var i = 0; i < fields.length; i += 2) {
- ctstatus.appendChild(E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
- E('div', { 'class': 'td left' }, [
+ ctstatus.appendChild(E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td left', 'width': '33%' }, [ fields[i] ]),
+ E('td', { 'class': 'td left' }, [
(fields[i + 1] != null) ? progressbar(fields[i + 1], ct_max) : '?'
])
]));
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js
index 603c0d93aa..e06b555e83 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/40_dhcp.js
@@ -1,7 +1,9 @@
'use strict';
'require baseclass';
'require rpc';
+'require uci';
'require network';
+'require validation';
var callLuciDHCPLeases = rpc.declare({
object: 'luci-rpc',
@@ -12,29 +14,85 @@ var callLuciDHCPLeases = rpc.declare({
return baseclass.extend({
title: '',
+ isMACStatic: {},
+ isDUIDStatic: {},
+
load: function() {
return Promise.all([
callLuciDHCPLeases(),
- network.getHostHints()
+ network.getHostHints(),
+ uci.load('dhcp')
]);
},
+ handleCreateStaticLease: function(lease, ev) {
+ ev.currentTarget.classList.add('spinning');
+ ev.currentTarget.disabled = true;
+ ev.currentTarget.blur();
+
+ var cfg = uci.add('dhcp', 'host');
+ uci.set('dhcp', cfg, 'name', lease.hostname || '-');
+ uci.set('dhcp', cfg, 'ip', lease.ipaddr);
+ uci.set('dhcp', cfg, 'mac', lease.macaddr.toUpperCase());
+
+ return uci.save()
+ .then(L.bind(L.ui.changes.init, L.ui.changes))
+ .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
+ },
+
+ handleCreateStaticLease6: function(lease, ev) {
+ ev.currentTarget.classList.add('spinning');
+ ev.currentTarget.disabled = true;
+ ev.currentTarget.blur();
+
+ var cfg = uci.add('dhcp', 'host'),
+ ip6arr = lease.ip6addrs[0] ? validation.parseIPv6(lease.ip6addrs[0]) : null;
+
+ uci.set('dhcp', cfg, 'name', lease.hostname || '-');
+ uci.set('dhcp', cfg, 'duid', lease.duid.toUpperCase());
+ uci.set('dhcp', cfg, 'mac', lease.macaddr);
+ if (ip6arr)
+ uci.set('dhcp', cfg, 'hostid', (ip6arr[6] * 0xFFFF + ip6arr[7]).toString(16));
+
+ return uci.save()
+ .then(L.bind(L.ui.changes.init, L.ui.changes))
+ .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
+ },
+
renderLeases: function(data) {
var leases = Array.isArray(data[0].dhcp_leases) ? data[0].dhcp_leases : [],
leases6 = Array.isArray(data[0].dhcp6_leases) ? data[0].dhcp6_leases : [],
- machints = data[1].getMACHints(false);
-
- var table = E('div', { 'class': 'table lases' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, _('Hostname')),
- E('div', { 'class': 'th' }, _('IPv4-Address')),
- E('div', { 'class': 'th' }, _('MAC-Address')),
- E('div', { 'class': 'th' }, _('Lease time remaining'))
+ machints = data[1].getMACHints(false),
+ hosts = uci.sections('dhcp', 'host');
+
+ for (var i = 0; i < hosts.length; i++) {
+ var host = hosts[i];
+
+ if (host.mac) {
+ var macs = L.toArray(host.mac);
+ for (var j = 0; j < macs.length; j++) {
+ var mac = macs[j].toUpperCase();
+ this.isMACStatic[mac] = true;
+ }
+ }
+ if (host.duid) {
+ var duid = host.duid.toUpperCase();
+ this.isDUIDStatic[duid] = true;
+ }
+ };
+
+ var table = E('table', { 'class': 'table lases' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, _('Hostname')),
+ E('th', { 'class': 'th' }, _('IPv4-Address')),
+ E('th', { 'class': 'th' }, _('MAC-Address')),
+ E('th', { 'class': 'th' }, _('Lease time remaining')),
+ E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
])
]);
- cbi_update_table(table, leases.map(function(lease) {
- var exp;
+ cbi_update_table(table, leases.map(L.bind(function(lease) {
+ var exp, rows;
if (lease.expires === false)
exp = E('em', _('unlimited'));
@@ -43,25 +101,37 @@ return baseclass.extend({
else
exp = '%t'.format(lease.expires);
- return [
+ rows = [
lease.hostname || '-',
lease.ipaddr,
lease.macaddr,
exp
];
- }), E('em', _('There are no active leases')));
-
- var table6 = E('div', { 'class': 'table leases6' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, _('Host')),
- E('div', { 'class': 'th' }, _('IPv6-Address')),
- E('div', { 'class': 'th' }, _('DUID')),
- E('div', { 'class': 'th' }, _('Lease time remaining'))
+
+ if (lease.macaddr != null) {
+ var mac = lease.macaddr.toUpperCase();
+ rows.push(E('button', {
+ 'class': 'cbi-button cbi-button-apply',
+ 'click': L.bind(this.handleCreateStaticLease, this, lease),
+ 'disabled': this.isMACStatic[mac]
+ }, [ _('Set Static') ]));
+ }
+
+ return rows;
+ }, this)), E('em', _('There are no active leases')));
+
+ var table6 = E('table', { 'class': 'table leases6' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, _('Host')),
+ E('th', { 'class': 'th' }, _('IPv6-Address')),
+ E('th', { 'class': 'th' }, _('DUID')),
+ E('th', { 'class': 'th' }, _('Lease time remaining')),
+ E('th', { 'class': 'th cbi-section-actions' }, _('Static Lease'))
])
]);
- cbi_update_table(table6, leases6.map(function(lease) {
- var exp;
+ cbi_update_table(table6, leases6.map(L.bind(function(lease) {
+ var exp, rows;
if (lease.expires === false)
exp = E('em', _('unlimited'));
@@ -80,13 +150,24 @@ return baseclass.extend({
else if (hint)
host = hint[1];
- return [
+ rows = [
host || '-',
lease.ip6addrs ? lease.ip6addrs.join(' ') : lease.ip6addr,
lease.duid,
exp
];
- }), E('em', _('There are no active leases')));
+
+ if (lease.duid != null) {
+ var duid = lease.duid.toUpperCase();
+ rows.push(E('button', {
+ 'class': 'cbi-button cbi-button-apply',
+ 'click': L.bind(this.handleCreateStaticLease6, this, lease),
+ 'disabled': this.isDUIDStatic[duid]
+ }, [ _('Set Static') ]));
+ }
+
+ return rows;
+ }, this)), E('em', _('There are no active leases')));
return E([
E('h3', _('Active DHCP Leases')),
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js
index cafd554f9a..714086f0d7 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js
@@ -2,40 +2,39 @@
'require baseclass';
'require rpc';
-var callLuciDSLStatus = rpc.declare({
- object: 'luci-rpc',
- method: 'getDSLStatus',
+var callDSLMetrics = rpc.declare({
+ object: 'dsl',
+ method: 'metrics',
expect: { '': {} }
});
function renderbox(dsl) {
return E('div', { class: 'ifacebox' }, [
- E('div', { class: 'ifacebox-head center ' + ((dsl.line_state === 'UP') ? 'active' : '') },
+ E('div', { class: 'ifacebox-head center ' + (dsl.up ? 'active' : '') },
E('strong', _('DSL Status'))),
E('div', { class: 'ifacebox-body left' }, [
L.itemlist(E('span'), [
- _('Line State'), '%s [0x%x]'.format(dsl.line_state, dsl.line_state_detail),
- _('Line Mode'), dsl.line_mode_s || '-',
- _('Line Uptime'), dsl.line_uptime_s || '-',
- _('Annex'), dsl.annex_s || '-',
- _('Profile'), dsl.profile_s || '-',
- _('Data Rate'), '%s/s / %s/s'.format(dsl.data_rate_down_s, dsl.data_rate_up_s),
- _('Max. Attainable Data Rate (ATTNDR)'), '%s/s / %s/s'.format(dsl.max_data_rate_down_s, dsl.max_data_rate_up_s),
- _('Latency'), '%s / %s'.format(dsl.latency_num_down, dsl.latency_num_up),
- _('Line Attenuation (LATN)'), '%.1f dB / %.1f dB'.format(dsl.line_attenuation_down, dsl.line_attenuation_up),
- _('Signal Attenuation (SATN)'), '%.1f dB / %.1f dB'.format(dsl.signal_attenuation_down, dsl.signal_attenuation_up),
- _('Noise Margin (SNR)'), '%.1f dB / %.1f dB'.format(dsl.noise_margin_down, dsl.noise_margin_up),
- _('Aggregate Transmit Power (ACTATP)'), '%.1f dB / %.1f dB'.format(dsl.actatp_down, dsl.actatp_up),
- _('Forward Error Correction Seconds (FECS)'), '%d / %d'.format(dsl.errors_fecs_near, dsl.errors_fecs_far),
- _('Errored seconds (ES)'), '%d / %d'.format(dsl.errors_es_near, dsl.errors_es_far),
- _('Severely Errored Seconds (SES)'), '%d / %d'.format(dsl.errors_ses_near, dsl.errors_ses_far),
- _('Loss of Signal Seconds (LOSS)'), '%d / %d'.format(dsl.errors_loss_near, dsl.errors_loss_far),
- _('Unavailable Seconds (UAS)'), '%d / %d'.format(dsl.errors_uas_near, dsl.errors_uas_far),
- _('Header Error Code Errors (HEC)'), '%d / %d'.format(dsl.errors_hec_near, dsl.errors_hec_far),
- _('Non Pre-emptive CRC errors (CRC_P)'), '%d / %d'.format(dsl.errors_crc_p_near, dsl.errors_crc_p_far),
- _('Pre-emptive CRC errors (CRCP_P)'), '%d / %d'.format(dsl.errors_crcp_p_near, dsl.errors_crcp_p_far),
- _('ATU-C System Vendor ID'), dsl.atuc_vendor_id,
- _('Power Management Mode'), dsl.power_mode_s
+ _('Line State'), dsl.state || '-',
+ _('Line Mode'), dsl.mode || '-',
+ _('Line Uptime'), '%t'.format(dsl.uptime),
+ _('Annex'), dsl.annex || '-',
+ _('Data Rate'), '%1000.3mb/s / %1000.3mb/s'.format(dsl.downstream.data_rate, dsl.upstream.data_rate),
+ _('Max. Attainable Data Rate (ATTNDR)'), '%1000.3mb/s / %1000.3mb/s'.format(dsl.downstream.attndr, dsl.upstream.attndr),
+ _('Latency'), '%.2f ms / %.2f ms'.format(dsl.downstream.interleave_delay / 1000, dsl.upstream.interleave_delay / 1000),
+ _('Line Attenuation (LATN)'), '%.1f dB / %.1f dB'.format(dsl.downstream.latn, dsl.upstream.latn),
+ _('Signal Attenuation (SATN)'), '%.1f dB / %.1f dB'.format(dsl.downstream.satn, dsl.upstream.satn),
+ _('Noise Margin (SNR)'), '%.1f dB / %.1f dB'.format(dsl.downstream.snr, dsl.upstream.snr),
+ _('Aggregate Transmit Power (ACTATP)'), '%.1f dB / %.1f dB'.format(dsl.downstream.actatp, dsl.upstream.actatp),
+ _('Forward Error Correction Seconds (FECS)'), '%d / %d'.format(dsl.errors.near.fecs, dsl.errors.far.fecs),
+ _('Errored seconds (ES)'), '%d / %d'.format(dsl.errors.near.es, dsl.errors.far.es),
+ _('Severely Errored Seconds (SES)'), '%d / %d'.format(dsl.errors.near.ses, dsl.errors.far.ses),
+ _('Loss of Signal Seconds (LOSS)'), '%d / %d'.format(dsl.errors.near.loss, dsl.errors.far.loss),
+ _('Unavailable Seconds (UAS)'), '%d / %d'.format(dsl.errors.near.uas, dsl.errors.far.uas),
+ _('Header Error Code Errors (HEC)'), '%d / %d'.format(dsl.errors.near.hec, dsl.errors.far.hec),
+ _('Non Pre-emptive CRC errors (CRC_P)'), '%d / %d'.format(dsl.errors.near.crc_p, dsl.errors.far.crc_p),
+ _('Pre-emptive CRC errors (CRCP_P)'), '%d / %d'.format(dsl.errors.near.crcp_p, dsl.errors.far.crcp_p),
+ _('ATU-C System Vendor ID'), dsl.atu_c.vendor || dsl.atu_c.vendor_id,
+ _('Power Management Mode'), dsl.power_state
])
])
]);
@@ -45,11 +44,11 @@ return baseclass.extend({
title: _('DSL'),
load: function() {
- return L.resolveDefault(callLuciDSLStatus(), {});
+ return L.resolveDefault(callDSLMetrics(), {});
},
render: function(dsl) {
- if (!dsl.line_state)
+ if (!dsl.state)
return null;
return E('div', { 'id': 'dsl_status_table', 'class': 'network-status-table' }, renderbox(dsl));
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js
index deb6f8609f..18172aae94 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/60_wifi.js
@@ -2,120 +2,210 @@
'require baseclass';
'require dom';
'require network';
+'require uci';
+'require fs';
'require rpc';
-var callSessionAccess = rpc.declare({
- object: 'session',
- method: 'access',
- params: [ 'scope', 'object', 'function' ],
- expect: { 'access': false }
-});
+return baseclass.extend({
+ title: _('Wireless'),
-function renderbox(radio, networks) {
- var chan = null,
- freq = null,
- rate = null,
- badges = [];
-
- for (var i = 0; i < networks.length; i++) {
- var net = networks[i],
- is_assoc = (net.getBSSID() != '00:00:00:00:00:00' && net.getChannel() && !net.isDisabled()),
- quality = net.getSignalPercent();
-
- var icon;
- if (net.isDisabled())
- icon = L.resource('icons/signal-none.png');
- else if (quality <= 0)
- icon = L.resource('icons/signal-0.png');
- else if (quality < 25)
- icon = L.resource('icons/signal-0-25.png');
- else if (quality < 50)
- icon = L.resource('icons/signal-25-50.png');
- else if (quality < 75)
- icon = L.resource('icons/signal-50-75.png');
- else
- icon = L.resource('icons/signal-75-100.png');
-
- var badge = renderBadge(
- icon,
- '%s: %d dBm / %s: %d%%'.format(_('Signal'), net.getSignal(), _('Quality'), quality),
- _('SSID'), net.getActiveSSID() || '?',
- _('Mode'), net.getActiveMode(),
- _('BSSID'), is_assoc ? (net.getActiveBSSID() || '-') : null,
- _('Encryption'), is_assoc ? net.getActiveEncryption() : null,
- _('Associations'), is_assoc ? (net.assoclist.length || '-') : null,
- null, is_assoc ? null : E('em', net.isDisabled() ? _('Wireless is disabled') : _('Wireless is not associated')));
-
- badges.push(badge);
-
- chan = (chan != null) ? chan : net.getChannel();
- freq = (freq != null) ? freq : net.getFrequency();
- rate = (rate != null) ? rate : net.getBitRate();
- }
+ WPSTranslateTbl: {
+ Disabled: _('Disabled'),
+ Active: _('Active'),
+ 'Timed-out': _('Timed-out'),
+ Overlap: _('Overlap'),
+ Unknown: _('Unknown')
+ },
- return E('div', { class: 'ifacebox' }, [
- E('div', { class: 'ifacebox-head center ' + (radio.isUp() ? 'active' : '') },
- E('strong', radio.getName())),
- E('div', { class: 'ifacebox-body left' }, [
- L.itemlist(E('span'), [
- _('Type'), radio.getI18n().replace(/^Generic | Wireless Controller .+$/g, ''),
- _('Channel'), chan ? '%d (%.3f %s)'.format(chan, freq, _('GHz')) : '-',
- _('Bitrate'), rate ? '%d %s'.format(rate, _('Mbit/s')) : '-'
- ]),
- E('div', {}, badges)
- ])
- ]);
-}
-
-function wifirate(rt) {
- var s = '%.1f\xa0%s, %d\xa0%s'.format(rt.rate / 1000, _('Mbit/s'), rt.mhz, _('MHz')),
- ht = rt.ht, vht = rt.vht,
- mhz = rt.mhz, nss = rt.nss,
- mcs = rt.mcs, sgi = rt.short_gi;
-
- if (ht || vht) {
- if (vht) s += ', VHT-MCS\xa0%d'.format(mcs);
- if (nss) s += ', VHT-NSS\xa0%d'.format(nss);
- if (ht) s += ', MCS\xa0%s'.format(mcs);
- if (sgi) s += ', ' + _('Short GI').replace(/ /g, '\xa0');
- }
+ callSessionAccess: rpc.declare({
+ object: 'session',
+ method: 'access',
+ params: [ 'scope', 'object', 'function' ],
+ expect: { 'access': false }
+ }),
+
+ wifirate: function(rt) {
+ var s = '%.1f\xa0%s, %d\xa0%s'.format(rt.rate / 1000, _('Mbit/s'), rt.mhz, _('MHz')),
+ ht = rt.ht, vht = rt.vht,
+ mhz = rt.mhz, nss = rt.nss,
+ mcs = rt.mcs, sgi = rt.short_gi;
+
+ if (ht || vht) {
+ if (vht) s += ', VHT-MCS\xa0%d'.format(mcs);
+ if (nss) s += ', VHT-NSS\xa0%d'.format(nss);
+ if (ht) s += ', MCS\xa0%s'.format(mcs);
+ if (sgi) s += ', ' + _('Short GI').replace(/ /g, '\xa0');
+ }
- return s;
-}
+ return s;
+ },
-return baseclass.extend({
- title: _('Wireless'),
+ handleDelClient: function(wifinet, mac, ev, cmd) {
+ var exec = cmd || 'disconnect';
- handleDelClient: function(wifinet, mac, ev) {
dom.parent(ev.currentTarget, '.tr').style.opacity = 0.5;
ev.currentTarget.classList.add('spinning');
ev.currentTarget.disabled = true;
ev.currentTarget.blur();
+ if (exec == 'addlist') {
+ var macs = [ mac ]
+
+ for (var mac in this.iface_maclist) {
+ macs.push(mac)
+ }
+
+ uci.set('wireless', wifinet.sid, 'maclist', macs);
+
+ return uci.save()
+ .then(L.bind(L.ui.changes.init, L.ui.changes))
+ .then(L.bind(L.ui.changes.displayChanges, L.ui.changes));
+ }
+
wifinet.disconnectClient(mac, true, 5, 60000);
},
+ handleGetWPSStatus: function(wifinet) {
+ return rpc.declare({
+ object: 'hostapd.%s'.format(wifinet),
+ method: 'wps_status',
+ })()
+ },
+
+ handleCallWPS: function(wifinet, ev) {
+ ev.currentTarget.classList.add('spinning');
+ ev.currentTarget.disabled = true;
+ ev.currentTarget.blur();
+
+ return rpc.declare({
+ object: 'hostapd.%s'.format(wifinet),
+ method: 'wps_start',
+ })();
+ },
+
+ handleCancelWPS: function(wifinet, ev) {
+ ev.currentTarget.classList.add('spinning');
+ ev.currentTarget.disabled = true;
+ ev.currentTarget.blur();
+
+ return rpc.declare({
+ object: 'hostapd.%s'.format(wifinet),
+ method: 'wps_cancel',
+ })();
+ },
+
+ renderbox: function(radio, networks) {
+ var chan = null,
+ freq = null,
+ rate = null,
+ badges = [];
+
+ for (var i = 0; i < networks.length; i++) {
+ var net = networks[i],
+ is_assoc = (net.getBSSID() != '00:00:00:00:00:00' && net.getChannel() && !net.isDisabled()),
+ quality = net.getSignalPercent();
+
+ var icon;
+ if (net.isDisabled())
+ icon = L.resource('icons/signal-none.png');
+ else if (quality <= 0)
+ icon = L.resource('icons/signal-0.png');
+ else if (quality < 25)
+ icon = L.resource('icons/signal-0-25.png');
+ else if (quality < 50)
+ icon = L.resource('icons/signal-25-50.png');
+ else if (quality < 75)
+ icon = L.resource('icons/signal-50-75.png');
+ else
+ icon = L.resource('icons/signal-75-100.png');
+
+ var WPS_button = null;
+
+ if (this.isWPSEnabled[net.sid]) {
+ if (net.wps_status == 'Active') {
+ WPS_button = E('button', {
+ 'class' : 'cbi-button cbi-button-remove',
+ 'click': L.bind(this.handleCancelWPS, this, net.getIfname()),
+ }, [ _('Stop WPS') ])
+ } else {
+ WPS_button = E('button', {
+ 'class' : 'cbi-button cbi-button-apply',
+ 'click': L.bind(this.handleCallWPS, this, net.getIfname()),
+ }, [ _('Start WPS') ])
+ }
+ }
+
+ var badge = renderBadge(
+ icon,
+ '%s: %d dBm / %s: %d%%'.format(_('Signal'), net.getSignal(), _('Quality'), quality),
+ _('SSID'), net.getActiveSSID() || '?',
+ _('Mode'), net.getActiveMode(),
+ _('BSSID'), is_assoc ? (net.getActiveBSSID() || '-') : null,
+ _('Encryption'), is_assoc ? net.getActiveEncryption() : null,
+ _('Associations'), is_assoc ? (net.assoclist.length || '-') : null,
+ null, is_assoc ? null : E('em', net.isDisabled() ? _('Wireless is disabled') : _('Wireless is not associated')),
+ _('WPS status'), this.WPSTranslateTbl[net.wps_status],
+ '', WPS_button
+ );
+
+ badges.push(badge);
+
+ chan = (chan != null) ? chan : net.getChannel();
+ freq = (freq != null) ? freq : net.getFrequency();
+ rate = (rate != null) ? rate : net.getBitRate();
+ }
+
+ return E('div', { class: 'ifacebox' }, [
+ E('div', { class: 'ifacebox-head center ' + (radio.isUp() ? 'active' : '') },
+ E('strong', radio.getName())),
+ E('div', { class: 'ifacebox-body left' }, [
+ L.itemlist(E('span'), [
+ _('Type'), radio.getI18n().replace(/^Generic | Wireless Controller .+$/g, ''),
+ _('Channel'), chan ? '%d (%.3f %s)'.format(chan, freq, _('GHz')) : '-',
+ _('Bitrate'), rate ? '%d %s'.format(rate, _('Mbit/s')) : '-',
+ ]),
+ E('div', {}, badges)
+ ])
+ ]);
+ },
+
+ isWPSEnabled: {},
+
load: function() {
return Promise.all([
network.getWifiDevices(),
network.getWifiNetworks(),
network.getHostHints(),
- callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'read'),
- callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'write')
- ]).then(function(radios_networks_hints) {
- var tasks = [];
-
- for (var i = 0; i < radios_networks_hints[1].length; i++)
- tasks.push(L.resolveDefault(radios_networks_hints[1][i].getAssocList(), []).then(L.bind(function(net, list) {
+ this.callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'read'),
+ this.callSessionAccess('access-group', 'luci-mod-status-index-wifi', 'write'),
+ uci.load('wireless')
+ ]).then(L.bind(function(data) {
+ var tasks = [],
+ radios_networks_hints = data[1],
+ hasWPS = L.hasSystemFeature('hostapd', 'wps');
+
+ for (var i = 0; i < radios_networks_hints.length; i++) {
+ tasks.push(L.resolveDefault(radios_networks_hints[i].getAssocList(), []).then(L.bind(function(net, list) {
net.assoclist = list.sort(function(a, b) { return a.mac > b.mac });
- }, this, radios_networks_hints[1][i])));
+ }, this, radios_networks_hints[i])));
+
+ if (hasWPS && uci.get('wireless', radios_networks_hints[i].sid, 'wps_pushbutton') == '1') {
+ this.isWPSEnabled[radios_networks_hints[i].sid] = true;
+ tasks.push(L.resolveDefault(this.handleGetWPSStatus(radios_networks_hints[i].getIfname()), null)
+ .then(L.bind(function(net, data) {
+ net.wps_status = data ? data.pbc_status : _('No Data');
+ }, this, radios_networks_hints[i])));
+ }
+ }
return Promise.all(tasks).then(function() {
- return radios_networks_hints;
+ return data;
});
- });
+ }, this));
},
+ isDeviceAdded: {},
+
render: function(data) {
var seen = {},
radios = data[0],
@@ -127,25 +217,36 @@ return baseclass.extend({
var table = E('div', { 'class': 'network-status-table' });
for (var i = 0; i < radios.sort(function(a, b) { a.getName() > b.getName() }).length; i++)
- table.appendChild(renderbox(radios[i],
+ table.appendChild(this.renderbox(radios[i],
networks.filter(function(net) { return net.getWifiDeviceName() == radios[i].getName() })));
if (!table.lastElementChild)
return null;
- var assoclist = E('div', { 'class': 'table assoclist' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th nowrap' }, _('Network')),
- E('div', { 'class': 'th hide-xs' }, _('MAC-Address')),
- E('div', { 'class': 'th' }, _('Host')),
- E('div', { 'class': 'th' }, '%s / %s'.format(_('Signal'), _('Noise'))),
- E('div', { 'class': 'th' }, '%s / %s'.format(_('RX Rate'), _('TX Rate')))
+ var assoclist = E('table', { 'class': 'table assoclist' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th nowrap' }, _('Network')),
+ E('th', { 'class': 'th hide-xs' }, _('MAC-Address')),
+ E('th', { 'class': 'th' }, _('Host')),
+ E('th', { 'class': 'th' }, '%s / %s'.format(_('Signal'), _('Noise'))),
+ E('th', { 'class': 'th' }, '%s / %s'.format(_('RX Rate'), _('TX Rate')))
])
]);
var rows = [];
for (var i = 0; i < networks.length; i++) {
+ var macfilter = uci.get('wireless', networks[i].sid, 'macfilter');
+
+ if (macfilter != null && macfilter != 'disable') {
+ this.isDeviceAdded = {};
+ var macs = L.toArray(uci.get('wireless', networks[i].sid, 'maclist'));
+ for (var j = 0; j < macs.length; j++) {
+ var mac = macs[j].toUpperCase();
+ this.isDeviceAdded[mac] = true;
+ }
+ }
+
for (var k = 0; k < networks[i].assoclist.length; k++) {
var bss = networks[i].assoclist[k],
name = hosthints.getHostnameByMACAddr(bss.mac),
@@ -215,20 +316,36 @@ return baseclass.extend({
])
]),
E('span', {}, [
- E('span', wifirate(bss.rx)),
+ E('span', this.wifirate(bss.rx)),
E('br'),
- E('span', wifirate(bss.tx))
+ E('span', this.wifirate(bss.tx))
])
];
if (networks[i].isClientDisconnectSupported() && hasWritePermission) {
if (assoclist.firstElementChild.childNodes.length < 6)
- assoclist.firstElementChild.appendChild(E('div', { 'class': 'th cbi-section-actions' }));
-
- row.push(E('button', {
- 'class': 'cbi-button cbi-button-remove',
- 'click': L.bind(this.handleDelClient, this, networks[i], bss.mac)
- }, [ _('Disconnect') ]));
+ assoclist.firstElementChild.appendChild(E('th', { 'class': 'th cbi-section-actions' }));
+
+ if (macfilter != null && macfilter != 'disable' && !this.isDeviceAdded[bss.mac]) {
+ row.push(new L.ui.ComboButton('button', {
+ 'addlist': macfilter == 'allow' ? _('Add to Whitelist') : _('Add to Blacklist'),
+ 'disconnect': _('Disconnect')
+ }, {
+ 'click': L.bind(this.handleDelClient, this, networks[i], bss.mac),
+ 'sort': [ 'disconnect', 'addlist' ],
+ 'classes': {
+ 'addlist': 'btn cbi-button cbi-button-remove',
+ 'disconnect': 'btn cbi-button cbi-button-remove'
+ }
+ }).render()
+ )
+ }
+ else {
+ row.push(E('button', {
+ 'class': 'cbi-button cbi-button-remove',
+ 'click': L.bind(this.handleDelClient, this, networks[i], bss.mac)
+ }, [ _('Disconnect') ]));
+ }
}
else {
row.push('-');
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/iptables.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/iptables.js
index 84d2b10556..951c31218d 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/iptables.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/iptables.js
@@ -4,7 +4,8 @@
'require fs';
'require ui';
-var table_names = [ 'Filter', 'NAT', 'Mangle', 'Raw' ];
+var table_names = [ 'Filter', 'NAT', 'Mangle', 'Raw' ],
+ raw_style = 'font-family:monospace;font-size:smaller;text-align:right';
return view.extend({
load: function() {
@@ -58,18 +59,18 @@ return view.extend({
if (!cdiv) {
cdiv = E('div', { 'data-chain': chain }, [
E('h4', { 'id': 'rule_%s-%s_%s'.format(is_ipv6 ? 'ipv6' : 'ipv4', table.toLowerCase(), chain) }, title),
- E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th center' }, _('Pkts.')),
- E('div', { 'class': 'th center' }, _('Traffic')),
- E('div', { 'class': 'th' }, _('Target')),
- E('div', { 'class': 'th' }, _('Prot.')),
- E('div', { 'class': 'th' }, _('In')),
- E('div', { 'class': 'th' }, _('Out')),
- E('div', { 'class': 'th' }, _('Source')),
- E('div', { 'class': 'th' }, _('Destination')),
- E('div', { 'class': 'th' }, _('Options')),
- E('div', { 'class': 'th' }, _('Comment'))
+ E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, _('Pkts.')),
+ E('th', { 'class': 'th' }, _('Traffic')),
+ E('th', { 'class': 'th' }, _('Target')),
+ E('th', { 'class': 'th' }, _('Prot.')),
+ E('th', { 'class': 'th' }, _('In')),
+ E('th', { 'class': 'th' }, _('Out')),
+ E('th', { 'class': 'th' }, _('Source')),
+ E('th', { 'class': 'th' }, _('Destination')),
+ E('th', { 'class': 'th' }, _('Options')),
+ E('th', { 'class': 'th' }, _('Comment'))
])
])
]);
@@ -105,6 +106,7 @@ return view.extend({
var chain_refs = {};
var re = /([^\n]*)\n/g;
var m, m2;
+ var raw = document.querySelector('[data-raw-counters="true"]');
while ((m = re.exec(s)) != null) {
if (m[1].match(/^Chain (.+) \(policy (\w+) (\d+) packets, (\d+) bytes\)$/)) {
@@ -152,12 +154,22 @@ return view.extend({
}) || '-';
current_rules.push([
- '%.2m'.format(pkts).nobr(),
- '%.2mB'.format(bytes).nobr(),
+ E('div', {
+ 'class': 'nowrap',
+ 'style': raw ? raw_style : null,
+ 'data-format': '%.2m',
+ 'data-value': pkts
+ }, (raw ? '%d' : '%.2m').format(pkts)),
+ E('div', {
+ 'class': 'nowrap',
+ 'style': raw ? raw_style : null,
+ 'data-format': '%.2mB',
+ 'data-value': bytes
+ }, (raw ? '%d' : '%.2mB').format(bytes)),
target ? '<span class="target">%s</span>'.format(target) : '-',
proto,
- (indev !== '*') ? '<span class="ifacebadge">%s</span>'.format(indev) : '*',
- (outdev !== '*') ? '<span class="ifacebadge">%s</span>'.format(outdev) : '*',
+ (indev !== '*') ? '<span class="ifacebadge nowrap">%s</span>'.format(indev) : '*',
+ (outdev !== '*') ? '<span class="ifacebadge nowrap">%s</span>'.format(outdev) : '*',
srcnet,
dstnet,
options,
@@ -256,6 +268,23 @@ return view.extend({
}
},
+ handleRawCounters: function(ev) {
+ var btn = ev.currentTarget,
+ raw = (btn.getAttribute('data-raw-counters') === 'false');
+
+ btn.setAttribute('data-raw-counters', raw);
+ btn.firstChild.data = raw ? _('Human-readable counters') : _('Show raw counters');
+ btn.blur();
+
+ document.querySelectorAll('[data-value]')
+ .forEach(function(div) {
+ var fmt = raw ? '%d' : div.getAttribute('data-format');
+
+ div.style = raw ? raw_style : '';
+ div.innerText = fmt.format(div.getAttribute('data-value'));
+ });
+ },
+
handleHideEmpty: function(ev) {
var btn = ev.currentTarget,
hide = (btn.getAttribute('data-hide-empty') === 'false');
@@ -304,6 +333,12 @@ return view.extend({
' ',
E('button', {
'class': 'cbi-button',
+ 'data-raw-counters': false,
+ 'click': ui.createHandlerFn(this, 'handleRawCounters')
+ }, [ _('Show raw counters') ]),
+ ' ',
+ E('button', {
+ 'class': 'cbi-button',
'click': ui.createHandlerFn(this, 'handleCounterReset', has_ip6tables)
}, [ _('Reset Counters') ]),
' ',
@@ -313,7 +348,7 @@ return view.extend({
}, [ _('Restart Firewall') ])
]),
E('div', {}, [
- E('div', { 'data-tab': 'iptables', 'data-tab-title': has_ip6tables ? _('IPv4 Firewall') : null }, [
+ E('div', { 'data-tab': 'iptables', 'data-tab-title': has_ip6tables ? _('IPv4 Firewall') : null, 'data-tab-active': has_ip6tables ? null : true }, [
E('p', {}, E('em', { 'class': 'spinning' }, [ _('Collecting data...') ]))
]),
has_ip6tables ? E('div', { 'data-tab': 'ip6tables', 'data-tab-title': _('IPv6 Firewall') }, [
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/load.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/load.js
index 3b302dc509..2766f5d1b5 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/load.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/load.js
@@ -19,7 +19,7 @@ Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; };
return view.extend({
load: function() {
return Promise.all([
- this.loadSVG(L.resource('load.svg'))
+ this.loadSVG(L.resource('svg/load.svg'))
]);
},
@@ -226,36 +226,36 @@ return view.extend({
E('div', { 'class': 'right' }, E('small', { 'id': 'scale' }, '-')),
E('br'),
- E('div', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #f00' }, [ _('1 Minute Load:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load01_cur' }, [ '0.00' ]),
+ E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #f00' }, [ _('1 Minute Load:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load01_cur' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load01_avg' }, [ '0.00' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load01_avg' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load01_peak' }, [ '0.00' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load01_peak' }, [ '0.00' ])
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #f60' }, [ _('5 Minute Load:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load05_cur' }, [ '0.00' ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #f60' }, [ _('5 Minute Load:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load05_cur' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load05_avg' }, [ '0.00' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load05_avg' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load05_peak' }, [ '0.00' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load05_peak' }, [ '0.00' ])
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #fa0' }, [ _('15 Minute Load:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load15_cur' }, [ '0.00' ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid #fa0' }, [ _('15 Minute Load:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load15_cur' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load15_avg' }, [ '0.00' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load15_avg' }, [ '0.00' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'lb_load15_peak' }, [ '0.00' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'lb_load15_peak' }, [ '0.00' ])
])
])
]);
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/processes.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/processes.js
index 8a77306e57..e7d094a7f9 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/processes.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/processes.js
@@ -64,14 +64,14 @@ return view.extend({
E('h2', _('Processes')),
E('div', { 'class': 'cbi-map-descr' }, _('This list gives an overview over currently running system processes and their status.')),
- E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, _('PID')),
- E('div', { 'class': 'th' }, _('Owner')),
- E('div', { 'class': 'th' }, _('Command')),
- E('div', { 'class': 'th' }, _('CPU usage (%)')),
- E('div', { 'class': 'th' }, _('Memory usage (%)')),
- E('div', { 'class': 'th center nowrap cbi-section-actions' })
+ E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, _('PID')),
+ E('th', { 'class': 'th' }, _('Owner')),
+ E('th', { 'class': 'th' }, _('Command')),
+ E('th', { 'class': 'th' }, _('CPU usage (%)')),
+ E('th', { 'class': 'th' }, _('Memory usage (%)')),
+ E('th', { 'class': 'th center nowrap cbi-section-actions' })
])
])
]);
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js
index 5da5d403b1..ac512bb849 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/routes.js
@@ -135,7 +135,8 @@ return view.extend({
dest,
(v6 ? flags.from : flags.via) || '-',
String(flags.metric || 0),
- flags.table || 'main'
+ flags.table || 'main',
+ flags.proto,
]);
}
@@ -149,39 +150,41 @@ return view.extend({
ip6neigh = data[3].stdout || '',
ip6route = data[4].stdout || '';
- var neigh4tbl = E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, [ _('IPv4-Address') ]),
- E('div', { 'class': 'th' }, [ _('MAC-Address') ]),
- E('div', { 'class': 'th' }, [ _('Interface') ])
+ var neigh4tbl = E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, [ _('IPv4-Address') ]),
+ E('th', { 'class': 'th' }, [ _('MAC-Address') ]),
+ E('th', { 'class': 'th' }, [ _('Interface') ])
])
]);
- var route4tbl = E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, [ _('Network') ]),
- E('div', { 'class': 'th' }, [ _('Target') ]),
- E('div', { 'class': 'th' }, [ _('IPv4-Gateway') ]),
- E('div', { 'class': 'th' }, [ _('Metric') ]),
- E('div', { 'class': 'th' }, [ _('Table') ])
+ var route4tbl = E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, [ _('Network') ]),
+ E('th', { 'class': 'th' }, [ _('Target') ]),
+ E('th', { 'class': 'th' }, [ _('IPv4-Gateway') ]),
+ E('th', { 'class': 'th' }, [ _('Metric') ]),
+ E('th', { 'class': 'th' }, [ _('Table') ]),
+ E('th', { 'class': 'th' }, [ _('Protocol') ]),
])
]);
- var neigh6tbl = E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, [ _('IPv6-Address') ]),
- E('div', { 'class': 'th' }, [ _('MAC-Address') ]),
- E('div', { 'class': 'th' }, [ _('Interface') ])
+ var neigh6tbl = E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, [ _('IPv6-Address') ]),
+ E('th', { 'class': 'th' }, [ _('MAC-Address') ]),
+ E('th', { 'class': 'th' }, [ _('Interface') ])
])
]);
- var route6tbl = E('div', { 'class': 'table' }, [
- E('div', { 'class': 'tr table-titles' }, [
- E('div', { 'class': 'th' }, [ _('Network') ]),
- E('div', { 'class': 'th' }, [ _('Target') ]),
- E('div', { 'class': 'th' }, [ _('Source') ]),
- E('div', { 'class': 'th' }, [ _('Metric') ]),
- E('div', { 'class': 'th' }, [ _('Table') ])
+ var route6tbl = E('table', { 'class': 'table' }, [
+ E('tr', { 'class': 'tr table-titles' }, [
+ E('th', { 'class': 'th' }, [ _('Network') ]),
+ E('th', { 'class': 'th' }, [ _('Target') ]),
+ E('th', { 'class': 'th' }, [ _('Source') ]),
+ E('th', { 'class': 'th' }, [ _('Metric') ]),
+ E('th', { 'class': 'th' }, [ _('Table') ]),
+ E('th', { 'class': 'th' }, [ _('Protocol') ]),
])
]);
@@ -212,4 +215,3 @@ return view.extend({
handleSave: null,
handleReset: null
});
-
diff --git a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js
index 171899262a..0fdd3d56e7 100644
--- a/modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js
+++ b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/wireless.js
@@ -21,8 +21,8 @@ Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; };
return view.extend({
load: function() {
return Promise.all([
- this.loadSVG(L.resource('wireless.svg')),
- this.loadSVG(L.resource('wifirate.svg')),
+ this.loadSVG(L.resource('svg/wireless.svg')),
+ this.loadSVG(L.resource('svg/wifirate.svg')),
network.getWifiDevices().then(function(radios) {
var tasks = [], all_networks = [];
@@ -255,26 +255,26 @@ return view.extend({
E('div', { 'class': 'right' }, E('small', { 'id': 'scale' }, '-')),
E('br'),
- E('div', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('Signal:') ])),
- E('div', { 'class': 'td', 'id': 'rssi_bw_cur' }, [ '0 ' + _('dBm') ]),
+ E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid blue' }, [ _('Signal:') ])),
+ E('td', { 'class': 'td', 'id': 'rssi_bw_cur' }, [ '0 ' + _('dBm') ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'rssi_bw_avg' }, [ '0 ' + _('dBm') ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'rssi_bw_avg' }, [ '0 ' + _('dBm') ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'rssi_bw_peak' }, [ '0 ' + _('dBm') ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'rssi_bw_peak' }, [ '0 ' + _('dBm') ])
]),
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid red' }, [ _('Noise:') ])),
- E('div', { 'class': 'td', 'id': 'noise_bw_cur' }, [ '0 ' + _('dBm') ]),
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid red' }, [ _('Noise:') ])),
+ E('td', { 'class': 'td', 'id': 'noise_bw_cur' }, [ '0 ' + _('dBm') ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'noise_bw_avg' }, [ '0 ' + _('dBm') ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'noise_bw_avg' }, [ '0 ' + _('dBm') ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'noise_bw_peak' }, [ '0 ' + _('dBm') ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'noise_bw_peak' }, [ '0 ' + _('dBm') ])
])
]),
E('br'),
@@ -283,16 +283,16 @@ return view.extend({
E('div', { 'class': 'right' }, E('small', { 'id': 'scale2' }, '-')),
E('br'),
- E('div', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
- E('div', { 'class': 'tr' }, [
- E('div', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('Phy Rate:') ])),
- E('div', { 'class': 'td', 'id': 'rate_bw_cur' }, [ '0 MBit/s' ]),
+ E('table', { 'class': 'table', 'style': 'width:100%;table-layout:fixed' }, [
+ E('tr', { 'class': 'tr' }, [
+ E('td', { 'class': 'td right top' }, E('strong', { 'style': 'border-bottom:2px solid green' }, [ _('Phy Rate:') ])),
+ E('td', { 'class': 'td', 'id': 'rate_bw_cur' }, [ '0 Mbit/s' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
- E('div', { 'class': 'td', 'id': 'rate_bw_avg' }, [ '0 MBit/s' ]),
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])),
+ E('td', { 'class': 'td', 'id': 'rate_bw_avg' }, [ '0 Mbit/s' ]),
- E('div', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
- E('div', { 'class': 'td', 'id': 'rate_bw_peak' }, [ '0 MBit/s' ])
+ E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])),
+ E('td', { 'class': 'td', 'id': 'rate_bw_peak' }, [ '0 Mbit/s' ])
])
])
]));
@@ -318,9 +318,9 @@ return view.extend({
this.updateGraph(ifname, csvg2, [ { line: 'rate', multiply: 0.001 } ], function(svg, info) {
var G = svg.firstElementChild, tab = svg.parentNode;
- G.getElementById('label_25').firstChild.data = '%.2f %s'.format(info.label_25, _('MBit/s'));
- G.getElementById('label_50').firstChild.data = '%.2f %s'.format(info.label_50, _('MBit/s'));
- G.getElementById('label_75').firstChild.data = '%.2f %s'.format(info.label_75, _('MBit/s'));
+ G.getElementById('label_25').firstChild.data = '%.2f %s'.format(info.label_25, _('Mbit/s'));
+ G.getElementById('label_50').firstChild.data = '%.2f %s'.format(info.label_50, _('Mbit/s'));
+ G.getElementById('label_75').firstChild.data = '%.2f %s'.format(info.label_75, _('Mbit/s'));
tab.querySelector('#scale2').firstChild.data = _('(%d minute window, %d second interval)').format(info.timeframe, info.interval);