diff options
author | Helge Mader <ma@dev.tdt.de> | 2022-02-03 13:48:10 +0100 |
---|---|---|
committer | Helge Mader <ma@dev.tdt.de> | 2022-02-03 13:48:10 +0100 |
commit | 164e98c7d9708da55c0c7641f4d409faaeaef4ec (patch) | |
tree | 862a77352f0325d6b36de8806252a7fb5a58defa /applications/luci-app-vnstat2/htdocs | |
parent | 4b5da809e03b2321d8362a289aa1b4979f8e8a71 (diff) |
uci-app-vnstat2: refactoring
This is a huge change to the already existing vnstat2 LuCI module with some
improvements and some new features.
"Graphs Page":
- Implementation of refreshing the graphs.
- Only in the UCI configuration existing interfaces will be shown in any
case. Before this change, all interfaces existing in the database were
shown.
- Introduced a button to clear the statistics for all interfaces (in fact
this is removing and adding again the interfaces from/to the database).
Before clearing the data a confirmation dialog is shown.
- Show user hint if service is not running, so no updating of graphs.
- "Error image" for a graph which can not be loaded
General:
- Updated translations, added missing translations for ./po/de
- Renamed the menu entry from "vnStat Traffic Monitor" to "Traffic Monitor" only
Signed-off-by: Helge Mader <ma@dev.tdt.de>
Diffstat (limited to 'applications/luci-app-vnstat2/htdocs')
-rw-r--r-- | applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js | 115 |
1 files changed, 93 insertions, 22 deletions
diff --git a/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js b/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js index 7ac3b3f7e7..7113c4119e 100644 --- a/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js +++ b/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js @@ -1,9 +1,65 @@ // This is free software, licensed under the Apache License, Version 2.0 'use strict'; +'require poll'; 'require view'; 'require fs'; 'require ui'; +'require uci'; +'require rpc'; + +var RefreshIfaces = ""; +var RefreshTabs = ['s', 't', '5', 'h', 'd', 'm', 'y']; + +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: [ 'name' ], + expect: { '': {} } +}); + +var isReadonlyView = !L.hasViewPermission() || null; + +function RefreshGraphs() { + RefreshTabs.forEach(function (id) { + RefreshIfaces.forEach(function (iface) { + fs.exec_direct('/usr/bin/vnstati', [ '-' + id, '-i', iface, '-o', '-' ], 'blob').then(function(res) { + document.getElementById('graph_' + id + '_' + iface).src = URL.createObjectURL(res); + }); + }); + }); +} + +function IfacesResetData(ev) { + ui.showModal(_('Delete data for ALL interfaces'), [ + E('p', _('The data will be removed from the database permanently. This cannot be undone.')), + E('div', { 'class': 'right' }, [ + E('div', { + 'class': 'btn', + 'click': L.hideModal + }, _('Cancel')), + ' ', + E('div', { + 'class': 'btn cbi-button-negative', + 'click': function(ev) { + var if_count = 0; + + RefreshIfaces.forEach(function (iface) { + fs.exec_direct('/usr/bin/vnstat', [ '--remove', '-i', iface, '--force' ], 'blob').then(function() { + fs.exec_direct('/usr/bin/vnstat', [ '--add', '-i', iface ], 'blob').then(function() { + if_count++; + if (if_count == RefreshIfaces.length) { + RefreshGraphs(); + } + }); + }); + }); + ui.hideModal(); + } + }, _('Delete')) + ]) + ]); +} return view.extend({ renderTab: function(ifaces, style, title) { @@ -16,41 +72,41 @@ return view.extend({ ]); ifaces.forEach(function(iface) { - tab.appendChild(E('span', {}, E('img', { 'data-iface': iface, 'style': 'visibility:hidden; margin:5px 10px' }))); fs.exec_direct('/usr/bin/vnstati', [ '-'+style, '-i', iface, '-o', '-' ], 'blob').then(function(res) { var img = tab.querySelector('img[data-iface="%s"]'.format(iface)); img.src = URL.createObjectURL(res); + img.alt = _('Could not load graph, no data available: ') + iface; + img.align = 'middle'; img.style.visibility = 'visible'; + img.id = 'graph_' + style + '_' + iface; tab.firstElementChild.style.display = 'none'; }); + tab.appendChild(E('span', {}, E('img', { 'data-iface': iface, 'style': 'visibility:hidden; margin:5px 10px' }))); }); return tab; }, load: function() { - return fs.exec_direct('/usr/bin/vnstat', [ '--json', 'f', '1' ], 'text').then(function(res) { - var json = null; - - try { - json = JSON.parse(res) - } - catch(e) { - throw new Error(res.replace(/^Error: /, '')); - } - - return (L.isObject(json) ? L.toArray(json.interfaces) : []).map(function(iface) { - return iface.name; - }).sort(); - }).catch(function(err) { - ui.addNotification(null, E('p', { 'style': 'white-space:pre' }, [err])); - return []; - }); + return Promise.all([ + L.resolveDefault(callServiceList('vnstat'), {}), + uci.load('vnstat'), + ]); }, - render: function(ifaces) { + render: function(data) { + var ifaces = uci.get_first('vnstat', 'vnstat', 'interface') || []; + var isRunning = false; + + try { + isRunning = data[0]['vnstat']['instances']['instance1']['running']; + } catch (e) { } + var view = E([], [ E('h2', [_('vnStat Graphs')]), + + (isRunning == false) ? E('p', { 'class': 'alert-message warning' }, _('Warning: The service is not running, graphs will not be updated!')):E('p'), + E('div', ifaces.length ? [ this.renderTab(ifaces, 's', _('Summary')), this.renderTab(ifaces, 't', _('Top')), @@ -58,13 +114,28 @@ return view.extend({ this.renderTab(ifaces, 'h', _('Hourly')), this.renderTab(ifaces, 'd', _('Daily')), this.renderTab(ifaces, 'm', _('Monthly')), - this.renderTab(ifaces, 'y', _('Yearly')) - ] : [ E('em', [_('No monitored interfaces have been found. Go to the configuration to enable monitoring for one or more interfaces.')]) ]) + this.renderTab(ifaces, 'y', _('Yearly')), + ] : [ E('em', [_('No monitored interfaces have been found. Go to the configuration to enable monitoring for one or more interfaces.')]) ]), ]); - if (ifaces.length) + if (ifaces.length) { ui.tabs.initTabGroup(view.lastElementChild.childNodes); + view.appendChild(E('div', { 'class': 'right' }, [ + E('br'), + E('button', { + 'class': 'cbi-button cbi-button-neutral', + 'click': IfacesResetData, + 'disabled': isReadonlyView + }, [ _('Clear data for all interfaces') ]) + ])); + } + + // Preserve the interfaces for the poll/refresh function + RefreshIfaces = ifaces; + + poll.add(RefreshGraphs, 60); + return view; }, |