luci/applications/luci-app-vnstat2/htdocs/luci-static/resources/view/vnstat2/graphs.js
Helge Mader 164e98c7d9 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>
2022-02-03 13:48:10 +01:00

145 lines
4 KiB
JavaScript

// 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) {
var tab = E('div', {
'class': 'cbi-section',
'data-tab': style,
'data-tab-title': title
}, [
E('p', {}, E('em', { 'class': 'spinning' }, [ _('Loading graphs…') ]))
]);
ifaces.forEach(function(iface) {
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 Promise.all([
L.resolveDefault(callServiceList('vnstat'), {}),
uci.load('vnstat'),
]);
},
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')),
this.renderTab(ifaces, '5', _('5 Minute')),
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.')]) ]),
]);
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;
},
handleSave: null,
handleSaveApply: null,
handleReset: null
});