diff options
Diffstat (limited to 'modules/luci-mod-status/htdocs/luci-static/resources/view')
6 files changed, 502 insertions, 51 deletions
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..5f838108ef --- /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) { + 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/include/50_dsl.js b/modules/luci-mod-status/htdocs/luci-static/resources/view/status/include/50_dsl.js index 4150b55133..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'), '%t'.format(dsl.line_uptime), - _('Annex'), dsl.annex_s || '-', - _('Profile'), dsl.profile_s || '-', - _('Data Rate'), '%1000.3mb/s / %1000.3mb/s'.format(dsl.data_rate_down, dsl.data_rate_up), - _('Max. Attainable Data Rate (ATTNDR)'), '%1000.3mb/s / %1000.3mb/s'.format(dsl.max_data_rate_down, dsl.max_data_rate_up), - _('Latency'), '%.2f ms / %.2f ms'.format(dsl.latency_down / 1000, dsl.latency_up / 1000), - _('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 9a956a72fe..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 @@ -29,14 +29,14 @@ return baseclass.extend({ 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; }, @@ -99,12 +99,12 @@ return baseclass.extend({ 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'); @@ -134,7 +134,7 @@ return baseclass.extend({ }, [ _('Start WPS') ]) } } - + var badge = renderBadge( icon, '%s: %d dBm / %s: %d%%'.format(_('Signal'), net.getSignal(), _('Quality'), quality), @@ -147,14 +147,14 @@ return baseclass.extend({ _('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())), @@ -340,7 +340,7 @@ return baseclass.extend({ }).render() ) } - else { + else { row.push(E('button', { 'class': 'cbi-button cbi-button-remove', 'click': L.bind(this.handleDelClient, this, networks[i], bss.mac) 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 2ce744c60e..dd58670694 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() { @@ -60,8 +61,8 @@ return view.extend({ E('h4', { 'id': 'rule_%s-%s_%s'.format(is_ipv6 ? 'ipv6' : 'ipv4', table.toLowerCase(), chain) }, title), E('table', { 'class': 'table' }, [ E('tr', { 'class': 'tr table-titles' }, [ - E('th', { 'class': 'th center' }, _('Pkts.')), - E('th', { 'class': 'th center' }, _('Traffic')), + 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')), @@ -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'); @@ -303,6 +332,11 @@ return view.extend({ }, [ _('Hide empty chains') ]), ' ', E('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') ]), 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 9d959f34a5..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 @@ -215,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 a7fa69095c..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 @@ -286,13 +286,13 @@ return view.extend({ 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('td', { 'class': 'td', 'id': 'rate_bw_cur' }, [ '0 Mbit/s' ]), E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Average:') ])), - E('td', { 'class': 'td', 'id': 'rate_bw_avg' }, [ '0 MBit/s' ]), + E('td', { 'class': 'td', 'id': 'rate_bw_avg' }, [ '0 Mbit/s' ]), E('td', { 'class': 'td right top' }, E('strong', {}, [ _('Peak:') ])), - E('td', { 'class': 'td', 'id': 'rate_bw_peak' }, [ '0 MBit/s' ]) + 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); |