Files
luci/protocols/luci-proto-wireguard/htdocs/luci-static/resources/view/wireguard/status.js
Paul Donald ae5d91da90 treewide: vectorise iconography
Clear, crisp, resolution independent vector graphics replace the trusty
microscopic PNG. Some minor CSS changes were needed to constrain images
in some locations to make sure they don't consume too much space.

Iconography taken from Mate desktop theme with minor adjustments:

https://github.com/mate-desktop/mate-icon-theme/

Signed-off-by: Paul Donald <newtwen+github@gmail.com>
2025-06-12 18:55:53 +02:00

176 lines
4.5 KiB
JavaScript

'use strict';
'require view';
'require rpc';
'require poll';
'require dom';
'require ui';
var callGetWgInstances = rpc.declare({
object: 'luci.wireguard',
method: 'getWgInstances'
});
function timestampToStr(timestamp) {
if (timestamp < 1)
return _('Never', 'No WireGuard peer handshake yet');
var seconds = (Date.now() / 1000) - timestamp;
var ago;
if (seconds < 60)
ago = _('%ds ago').format(seconds);
else if (seconds < 3600)
ago = _('%dm ago').format(seconds / 60);
else if (seconds < 86401)
ago = _('%dh ago').format(seconds / 3600);
else
ago = _('over a day ago');
return (new Date(timestamp * 1000)).toUTCString() + ' (' + ago + ')';
}
function handleInterfaceDetails(iface) {
ui.showModal(_('Instance Details'), [
ui.itemlist(E([]), [
_('Name'), iface.name,
_('Public Key'), E('code', [ iface.public_key ]),
_('Listen Port'), iface.listen_port,
_('Firewall Mark'), iface.fwmark != 'off' ? iface.fwmark : E('em', _('none'))
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': ui.hideModal
}, [ _('Dismiss') ])
])
]);
}
function handlePeerDetails(peer) {
ui.showModal(_('Peer Details'), [
ui.itemlist(E([]), [
_('Description'), peer.name,
_('Public Key'), E('code', [ peer.public_key ]),
_('Endpoint'), peer.endpoint,
_('Allowed IPs'), (Array.isArray(peer.allowed_ips) && peer.allowed_ips.length) ? peer.allowed_ips.join(', ') : E('em', _('none')),
_('Received Data'), '%1024mB'.format(peer.transfer_rx),
_('Transmitted Data'), '%1024mB'.format(peer.transfer_tx),
_('Latest Handshake'), timestampToStr(+peer.latest_handshake),
_('Keep-Alive'), (peer.persistent_keepalive != 'off') ? _('every %ds', 'WireGuard keep alive interval').format(+peer.persistent_keepalive) : E('em', _('none')),
]),
E('div', { 'class': 'right' }, [
E('button', {
'class': 'btn cbi-button',
'click': ui.hideModal
}, [ _('Dismiss') ])
])
]);
}
function renderPeerTable(instanceName, peers) {
var t = new L.ui.Table(
[
_('Peer'),
_('Endpoint'),
_('Data Received'),
_('Data Transmitted'),
_('Latest Handshake')
],
{
id: 'peers-' + instanceName
},
E('em', [
_('No peers connected')
])
);
t.update(peers.map(function(peer) {
return [
[
peer.name || '',
E('div', {
'style': 'cursor:pointer',
'click': ui.createHandlerFn(this, handlePeerDetails, peer)
}, [
E('p', [
peer.name ? E('span', [ peer.name ]) : E('em', [ _('Untitled peer') ])
]),
E('span', {
'class': 'ifacebadge hide-sm',
'data-tooltip': _('Public key: %h', 'Tooltip displaying full WireGuard peer public key').format(peer.public_key)
}, [
E('code', [ peer.public_key.replace(/^(.{5}).+(.{6})$/, '$1…$2') ])
])
])
],
peer.endpoint,
[ +peer.transfer_rx, '%1024mB'.format(+peer.transfer_rx) ],
[ +peer.transfer_tx, '%1024mB'.format(+peer.transfer_tx) ],
[ +peer.latest_handshake, timestampToStr(+peer.latest_handshake) ]
];
}));
return t.render();
}
return view.extend({
renderIfaces: function(ifaces) {
var res = [
E('h2', [ _('WireGuard Status') ])
];
for (var instanceName in ifaces) {
res.push(
E('h3', [ _('Instance "%h"', 'WireGuard instance heading').format(instanceName) ]),
E('p', {
'style': 'cursor:pointer',
'click': ui.createHandlerFn(this, handleInterfaceDetails, ifaces[instanceName])
}, [
E('span', { 'class': 'ifacebadge' }, [
E('img', { 'src': L.resource('icons', 'wireguard.svg'), 'style': 'width:32px;height:32px' }),
'\xa0',
instanceName
]),
E('span', { 'style': 'opacity:.8' }, [
' · ',
_('Port %d', 'WireGuard listen port').format(ifaces[instanceName].listen_port),
' · ',
E('code', { 'click': '' }, [ ifaces[instanceName].public_key ])
])
]),
renderPeerTable(instanceName, ifaces[instanceName].peers)
);
}
if (res.length == 1)
res.push(E('p', { 'class': 'center', 'style': 'margin-top:5em' }, [
E('em', [ _('No WireGuard interfaces configured.') ])
]));
return E([], res);
},
render: function() {
poll.add(L.bind(function () {
return callGetWgInstances().then(L.bind(function(ifaces) {
dom.content(
document.querySelector('#view'),
this.renderIfaces(ifaces)
);
}, this));
}, this), 5);
return E([], [
E('h2', [ _('WireGuard Status') ]),
E('p', { 'class': 'center', 'style': 'margin-top:5em' }, [
E('em', [ _('Loading data…') ])
])
]);
},
handleReset: null,
handleSaveApply: null,
handleSave: null
});