mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-09-10 18:34:09 +08:00
update 2026-05-27 23:25:57
This commit is contained in:
+384
@@ -0,0 +1,384 @@
|
||||
'use strict';
|
||||
'require poll';
|
||||
'require rpc';
|
||||
'require ui';
|
||||
'require view';
|
||||
|
||||
const labelStyleUp = 'background-color:#388438; color:#fff';
|
||||
const labelStyleDown = 'background-color:#767676; color:#fff';
|
||||
|
||||
return view.extend({
|
||||
ifacesArray : [],
|
||||
|
||||
callNetDevice: rpc.declare({
|
||||
object: 'network.device',
|
||||
method: 'status',
|
||||
expect: { '': {} }
|
||||
}),
|
||||
|
||||
formatBytesString(bytes) {
|
||||
let units = (bytes > 10**12) ?
|
||||
`${Number((bytes / 1000 / 1000 / 1000 / 1000).toFixed(2))} ${_('Tb')}` :
|
||||
(bytes > 10**9) ?
|
||||
`${Number((bytes / 1000 / 1000 / 1000).toFixed(2))} ${_('Gb')}` :
|
||||
(bytes > 10**6) ?
|
||||
`${Number((bytes / 1000 / 1000).toFixed(2))} ${_('Mb')}` :
|
||||
`${Number((bytes / 1000).toFixed(2))} ${_('Kb')}`;
|
||||
return `${bytes} (${units})`;
|
||||
},
|
||||
|
||||
setIfacesData(ifacesData) {
|
||||
for(let iface of this.ifacesArray) {
|
||||
let ifaceState = null;
|
||||
let ifacesStatisticsObject = null;
|
||||
|
||||
if(ifacesData[iface] !== undefined) {
|
||||
ifaceState = ifacesData[iface].up;
|
||||
ifacesStatisticsObject = ifacesData[iface].statistics;
|
||||
};
|
||||
|
||||
let state = document.querySelector('[data-ifstat="%s_state"]'.format(iface));
|
||||
state.textContent = (ifaceState) ? _('Interface is up') : _('Interface is down');
|
||||
state.style = (ifaceState) ? labelStyleUp : labelStyleDown;
|
||||
|
||||
if(!ifacesStatisticsObject) continue;
|
||||
|
||||
for(let [k, v] of Object.entries(ifacesStatisticsObject)) {
|
||||
let elem = document.querySelector('[data-ifstat="%s_%s"]'.format(iface, k));
|
||||
if(elem !== null) {
|
||||
if(k == 'rx_bytes' || k == 'tx_bytes') {
|
||||
elem.innerHTML = this.formatBytesString(v);
|
||||
} else {
|
||||
elem.textContent = v;
|
||||
}
|
||||
};
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
update() {
|
||||
return this.callNetDevice().then(ifacesData => {
|
||||
this.setIfacesData(ifacesData);
|
||||
}).catch(e => ui.addNotification(null, E('p', {}, e.message)));
|
||||
},
|
||||
|
||||
load() {
|
||||
return this.callNetDevice().catch(
|
||||
e => ui.addNotification(null, E('p', {}, e.message)));
|
||||
},
|
||||
|
||||
render(ifacesData) {
|
||||
|
||||
let ifacesNode = E('div', { 'class': 'cbi-section fade-in' },
|
||||
E('div', { 'class': 'cbi-section-node' },
|
||||
E('div', { 'class': 'cbi-value' },
|
||||
E('em', {}, _('No interfaces detected'))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
if(ifacesData) {
|
||||
ifacesNode = E('div', { 'class': 'cbi-section fade-in' },
|
||||
E('div', { 'class': 'cbi-section-node' },
|
||||
E('div', { 'class': 'cbi-value' }, [
|
||||
E('div', { 'style': 'width:100%; text-align:right !important' },
|
||||
E('button', {
|
||||
'class': 'btn',
|
||||
'click': () => window.location.reload(),
|
||||
}, _('Refresh interfaces'))
|
||||
)
|
||||
])
|
||||
)
|
||||
);
|
||||
|
||||
let tabsContainer = E('div', { 'class': 'cbi-section-node cbi-section-node-tabbed' });
|
||||
ifacesNode.append(tabsContainer);
|
||||
|
||||
let tab = 0;
|
||||
|
||||
for(let iface in ifacesData) {
|
||||
let ifaceName = iface;
|
||||
let ifacesStatisticsObject = ifacesData[iface].statistics;
|
||||
let ifaceState = ifacesData[iface].up;
|
||||
let ifaceMac = ifacesData[iface].macaddr;
|
||||
|
||||
if(ifaceMac == "00:00:00:00:00:00") {
|
||||
ifaceMac = null;
|
||||
};
|
||||
|
||||
this.ifacesArray.push(iface);
|
||||
this.ifacesArray.sort();
|
||||
|
||||
let ifaceTab = E('div', {
|
||||
'data-tab' : tab,
|
||||
'data-tab-title': ifaceName,
|
||||
});
|
||||
tabsContainer.append(ifaceTab);
|
||||
|
||||
let ifaceTable = E('table', { 'class': 'table' });
|
||||
|
||||
if(ifaceMac) {
|
||||
ifaceTable.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'style': 'width:33%' },
|
||||
_('MAC Address') + ':'),
|
||||
E('td', { 'class': 'td left' }, ifaceMac),
|
||||
]),
|
||||
);
|
||||
};
|
||||
|
||||
ifaceTable.append(
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'style': 'width:33%' },
|
||||
_('State') + ':'),
|
||||
E('td', { 'class': 'td left' },
|
||||
E('span', {
|
||||
'data-ifstat': iface + '_state',
|
||||
'class': 'label',
|
||||
'style': (ifaceState) ? labelStyleUp : labelStyleDown,
|
||||
},
|
||||
(ifaceState) ?
|
||||
_('Interface is up') : _('Interface is down')
|
||||
)
|
||||
),
|
||||
]),
|
||||
);
|
||||
|
||||
let statTable = E('table', { 'class': 'table' }, [
|
||||
E('tr', { 'class': 'tr table-titles' }, [
|
||||
E('th', { 'class': 'th left', 'style': 'width:33%' },
|
||||
_('Parameter')),
|
||||
E('th', { 'class': 'th left', 'style': 'width:33%' },
|
||||
_('Receive')),
|
||||
E('th', { 'class': 'th left' }, _('Transmit')),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('bytes')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_bytes',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_bytes
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_bytes',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_bytes
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('packets')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_packets',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_packets
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_packets',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_packets
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_errors
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_errors
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('dropped')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_dropped',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_dropped
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_dropped',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_dropped
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('compressed')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_compressed',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_compressed
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_compressed',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_compressed
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('fifo errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_fifo_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_fifo_errors
|
||||
),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_fifo_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_fifo_errors
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('multicast')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_multicast',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.multicast
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('crc errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_crc_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_crc_errors
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('frame errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_frame_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_frame_errors
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('length errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_length_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_length_errors
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('missed errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_missed_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_missed_errors
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('over errors')),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_rx_over_errors',
|
||||
'data-title' : _('Receive') },
|
||||
ifacesStatisticsObject.rx_over_errors
|
||||
),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Transmit') },
|
||||
' '),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('collisions')),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Receive') },
|
||||
' '),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_collisions',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.collisions
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('carrier errors')),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Receive') },
|
||||
' '),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_carrier_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_carrier_errors
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('heartbeat errors')),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Receive') },
|
||||
' '),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_heartbeat_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_heartbeat_errors
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('aborted errors')),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Receive') },
|
||||
' '),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_aborted_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_aborted_errors
|
||||
),
|
||||
]),
|
||||
E('tr', { 'class': 'tr' }, [
|
||||
E('td', { 'class': 'td left', 'data-title': _('Parameter') },
|
||||
_('window errors')),
|
||||
E('td', { 'class': 'td left', 'data-title': _('Receive') },
|
||||
' '),
|
||||
E('td', { 'class': 'td left',
|
||||
'data-ifstat': ifaceName + '_tx_window_errors',
|
||||
'data-title' : _('Transmit') },
|
||||
ifacesStatisticsObject.tx_window_errors
|
||||
),
|
||||
]),
|
||||
]);
|
||||
|
||||
ifaceTab.append(E([
|
||||
E('div', { 'class': 'cbi-value' }, ifaceTable),
|
||||
E('div', { 'class': 'cbi-value' }, statTable),
|
||||
]));
|
||||
|
||||
tab++;
|
||||
};
|
||||
|
||||
ui.tabs.initTabGroup(tabsContainer.children);
|
||||
poll.add(L.bind(this.update, this));
|
||||
};
|
||||
|
||||
return E([
|
||||
E('h2', { 'class': 'fade-in' }, _('Interfaces Statistics')),
|
||||
E('div', { 'class': 'cbi-section-descr fade-in' }),
|
||||
ifacesNode,
|
||||
]);
|
||||
},
|
||||
|
||||
handleSaveApply: null,
|
||||
handleSave : null,
|
||||
handleReset : null,
|
||||
});
|
||||
Reference in New Issue
Block a user