Network peer updates
-Added a new port_filter setting to the 3 network_page tables which allows showing only results from peers on the selected port -Added a new hide_protocols setting to the 3 network_page tables which allows hiding results from peers on the selected protocols -Added a Port column to the data table on the Network page Connections tab -The data table on the Network page Connections tab is now sortable -The peer sync now refreshes data for peers that existed since last sync -Adding and updating peers now displays the port # in the log output -The /ext/getnetworkpeers api is now sorted by ip4/ip6, address and port which also means all data on the Network page is sorted this way by default as well -The /ext/getnetworkpeers api no longer requires the internal argument for calls originating from the Network page -The Network page now only makes a single call to the /ext/getnetworkpeers api instead of 3 calls -The find_peer and drop_peer functions now requiresa port to distinguish between multiple connections to the same peer on different ports
This commit is contained in:
@@ -505,13 +505,6 @@ app.use('/ext/getsummary', function(req, res) {
|
||||
app.use('/ext/getnetworkpeers', function(req, res) {
|
||||
// check if the getnetworkpeers api is enabled or else check the headers to see if it matches an internal ajax request from the explorer itself (TODO: come up with a more secure method of whitelisting ajax calls from the explorer)
|
||||
if ((settings.api_page.enabled == true && settings.api_page.public_apis.ext.getnetworkpeers.enabled == true) || (req.headers['x-requested-with'] != null && req.headers['x-requested-with'].toLowerCase() == 'xmlhttprequest' && req.headers.referer != null && req.headers.accept.indexOf('text/javascript') > -1 && req.headers.accept.indexOf('application/json') > -1)) {
|
||||
var internal = false;
|
||||
// split url suffix by forward slash and remove blank entries
|
||||
var split = req.url.split('/').filter(function(v) { return v; });
|
||||
// check if this is an internal request
|
||||
if (split.length > 0 && split[0].indexOf('internal') > -1)
|
||||
internal = true;
|
||||
|
||||
// get list of peers
|
||||
db.get_peers(function(peers) {
|
||||
// loop through peers list and remove the mongo _id and __v keys
|
||||
@@ -520,14 +513,21 @@ app.use('/ext/getnetworkpeers', function(req, res) {
|
||||
delete peers[i]['_doc']['__v'];
|
||||
}
|
||||
|
||||
// check if this is an internal request
|
||||
if (internal) {
|
||||
// display data formatted for internal datatable
|
||||
res.json({"data": peers});
|
||||
} else {
|
||||
// display data in more readable format for public api
|
||||
res.json(peers);
|
||||
}
|
||||
// sort ip6 addresses to the bottom
|
||||
peers.sort(function(a, b) {
|
||||
var address1 = a.address.indexOf(':') > -1;
|
||||
var address2 = b.address.indexOf(':') > -1;
|
||||
|
||||
if (address1 < address2)
|
||||
return -1;
|
||||
else if (address1 > address2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
});
|
||||
|
||||
// return peer data
|
||||
res.json(peers);
|
||||
});
|
||||
} else
|
||||
res.end('This method is disabled');
|
||||
|
||||
+5
-5
@@ -1242,8 +1242,8 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
|
||||
find_peer: function(address, cb) {
|
||||
Peers.findOne({address: address}, function(err, peer) {
|
||||
find_peer: function(address, port, cb) {
|
||||
Peers.findOne({address: address, port: port}, function(err, peer) {
|
||||
if (err)
|
||||
return cb(null);
|
||||
else {
|
||||
@@ -1255,8 +1255,8 @@ module.exports = {
|
||||
});
|
||||
},
|
||||
|
||||
drop_peer: function(address, cb) {
|
||||
Peers.deleteOne({address: address}, function(err) {
|
||||
drop_peer: function(address, port, cb) {
|
||||
Peers.deleteOne({address: address, port: port}, function(err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return cb();
|
||||
@@ -1276,7 +1276,7 @@ module.exports = {
|
||||
},
|
||||
|
||||
get_peers: function(cb) {
|
||||
Peers.find({}, function(err, peers) {
|
||||
Peers.find().sort({address: 1, port: 1}).exec(function (err, peers) {
|
||||
if (err)
|
||||
return cb([]);
|
||||
else
|
||||
|
||||
+24
-3
@@ -618,7 +618,14 @@ exports.network_page = {
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
},
|
||||
// addnodes_table: a collection of settings that pertain to the add nodes table on the network page
|
||||
// Table data is populated via the /ext/getnetworkpeers api
|
||||
@@ -626,7 +633,14 @@ exports.network_page = {
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
},
|
||||
// onetry_table: a collection of settings that pertain to the one try table on the network page
|
||||
// Table data is populated via the /ext/getnetworkpeers api
|
||||
@@ -634,7 +648,14 @@ exports.network_page = {
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+18
-5
@@ -436,7 +436,7 @@ if (lib.is_locked([database]) == false) {
|
||||
address = address.replace("[", "").replace("]", "");
|
||||
}
|
||||
|
||||
db.find_peer(address, function(peer) {
|
||||
db.find_peer(address, port, function(peer) {
|
||||
if (peer) {
|
||||
if ((peer['port'] != null && (isNaN(peer['port']) || peer['port'].length < 2)) || peer['country'].length < 1 || peer['country_code'].length < 1) {
|
||||
db.drop_peers(function() {
|
||||
@@ -445,9 +445,22 @@ if (lib.is_locked([database]) == false) {
|
||||
});
|
||||
}
|
||||
|
||||
// peer already exists
|
||||
console.log('Updated peer %s [%s/%s]', address, (i + 1).toString(), body.length.toString());
|
||||
loop.next();
|
||||
// peer already exists and should be refreshed
|
||||
// drop peer
|
||||
db.drop_peer(address, port, function() {
|
||||
// re-add the peer to refresh the data and extend the expiry date
|
||||
db.create_peer({
|
||||
address: address,
|
||||
port: port,
|
||||
protocol: peer.protocol,
|
||||
version: peer.version,
|
||||
country: peer.country,
|
||||
country_code: peer.country_code
|
||||
}, function() {
|
||||
console.log('Updated peer %s:%s [%s/%s]', address, port.toString(), (i + 1).toString(), body.length.toString());
|
||||
loop.next();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
const rateLimitLib = require('../lib/ratelimit');
|
||||
const rateLimit = new rateLimitLib.RateLimit(1, 2000, false);
|
||||
@@ -471,7 +484,7 @@ if (lib.is_locked([database]) == false) {
|
||||
country: geo.country_name,
|
||||
country_code: geo.country_code
|
||||
}, function() {
|
||||
console.log('Added new peer %s [%s/%s]', address, (i + 1).toString(), body.length.toString());
|
||||
console.log('Added new peer %s:%s [%s/%s]', address, port.toString(), (i + 1).toString(), body.length.toString());
|
||||
loop.next();
|
||||
});
|
||||
}
|
||||
|
||||
+24
-3
@@ -702,7 +702,14 @@
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
},
|
||||
// addnodes_table: a collection of settings that pertain to the add nodes table on the network page
|
||||
// Table data is populated via the /ext/getnetworkpeers api
|
||||
@@ -710,7 +717,14 @@
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
},
|
||||
// onetry_table: a collection of settings that pertain to the one try table on the network page
|
||||
// Table data is populated via the /ext/getnetworkpeers api
|
||||
@@ -718,7 +732,14 @@
|
||||
// page_length_options: An array of page length options that determine how many items/records to display in the table at any given time
|
||||
"page_length_options": [ 10, 25, 50, 75, 100 ],
|
||||
// items_per_page: The default amount of items/records to display in the table at any given time
|
||||
"items_per_page": 10
|
||||
"items_per_page": 10,
|
||||
// port_filter: Specify a port number to only allow showing peers on the selected port.
|
||||
// Set this value to 0 to show all peers on any port.
|
||||
"port_filter": 0,
|
||||
// hide_protocols: An array of protocol numbers that will be filtered out of the table results
|
||||
// If a peer connects to the explorer wallet with one of these protocol numbers, that record will not be displayed in this table
|
||||
// Add as many protocol values as necessary in the following format: [ 0, 70803, 70819 ]
|
||||
"hide_protocols": [ ]
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+159
-120
@@ -19,128 +19,166 @@ block content
|
||||
return lengthMenuOpts;
|
||||
}
|
||||
$(document).ready(function() {
|
||||
var setting_txPerPage = parseInt("#{settings.network_page.connections_table.items_per_page}");
|
||||
$('#connections-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.connections_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: '/ext/getnetworkpeers/internal',
|
||||
dataSrc: function (json) {
|
||||
return json.data;
|
||||
}
|
||||
},
|
||||
rowCallback: function (row, data, index) {
|
||||
var flagBlock = '';
|
||||
if (data['country_code'].length > 1) {
|
||||
flagBlock = '<div class="margin-left-5 flag-icon flag-icon-'+data['country_code'].toLowerCase()+'"></div>';
|
||||
}
|
||||
$("td:eq(0)", row).html(data['address']).addClass('breakWord');
|
||||
$("td:eq(1)", row).html(data['protocol']);
|
||||
$("td:eq(2)", row).html(data['version']);
|
||||
$("td:eq(3)", row).html(data['country']+flagBlock);
|
||||
},
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{ data: 'address', width: '25%' },
|
||||
{ data: 'protocol', width: '25%' },
|
||||
{ data: 'version', width:'25%' },
|
||||
{ data: 'country', width: '25%'}
|
||||
]
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: '/ext/getnetworkpeers/internal',
|
||||
dataType: 'json'
|
||||
}).done(function(peers) {
|
||||
var setting_txPerPage = parseInt("#{settings.network_page.connections_table.items_per_page}");
|
||||
var setting_con_port_filter = "#{settings.network_page.connections_table.port_filter}";
|
||||
var setting_con_hide_protocols = !{JSON.stringify(settings.network_page.connections_table.hide_protocols)};
|
||||
var connectionRows = peers;
|
||||
|
||||
if (setting_con_port_filter == null || setting_con_port_filter == '')
|
||||
setting_con_port_filter = '0';
|
||||
|
||||
if (setting_con_port_filter != '0')
|
||||
connectionRows = connectionRows.filter(v => v.port == setting_con_port_filter);
|
||||
|
||||
setting_con_hide_protocols.forEach(function (protocol) {
|
||||
connectionRows = connectionRows.filter(v => v.protocol != protocol);
|
||||
});
|
||||
|
||||
$('#connections-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: true,
|
||||
order: [],
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.connections_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
data: connectionRows,
|
||||
rowCallback: function (row, data, index) {
|
||||
var flagBlock = '';
|
||||
if (data['country_code'].length > 1) {
|
||||
flagBlock = '<div class="margin-left-5 flag-icon flag-icon-'+data['country_code'].toLowerCase()+'"></div>';
|
||||
}
|
||||
$("td:eq(0)", row).html(data['address']).addClass('breakWord');
|
||||
$("td:eq(1)", row).html(data['port']);
|
||||
$("td:eq(2)", row).html(data['protocol']);
|
||||
$("td:eq(3)", row).html(data['version']);
|
||||
$("td:eq(4)", row).html(data['country']+flagBlock);
|
||||
},
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{ data: 'address', width: '20%' },
|
||||
{ data: 'port', width: '20%' },
|
||||
{ data: 'protocol', width: '20%' },
|
||||
{ data: 'version', width:'20%' },
|
||||
{ data: 'country', width: '20%'}
|
||||
]
|
||||
});
|
||||
|
||||
setting_txPerPage = parseInt("#{settings.network_page.addnodes_table.items_per_page}");
|
||||
|
||||
var addNodeRows = [];
|
||||
var setting_add_port_filter = "#{settings.network_page.addnodes_table.port_filter}";
|
||||
var setting_add_hide_protocols = !{JSON.stringify(settings.network_page.addnodes_table.hide_protocols)};
|
||||
var addNodePeers = peers;
|
||||
|
||||
if (setting_add_port_filter == null || setting_add_port_filter == '')
|
||||
setting_add_port_filter = '0';
|
||||
|
||||
if (setting_add_port_filter != '0')
|
||||
addNodePeers = addNodePeers.filter(v => v.port == setting_add_port_filter);
|
||||
|
||||
setting_add_hide_protocols.forEach(function (protocol) {
|
||||
addNodePeers = addNodePeers.filter(v => v.protocol != protocol);
|
||||
});
|
||||
|
||||
for (var i=0; i < addNodePeers.length; i++)
|
||||
addNodeRows.push({'nodes': 'addnode=' + (addNodePeers[i]['address'] != null && addNodePeers[i]['address'].indexOf(':') > -1 ? '[' + addNodePeers[i]['address'] + ']' : addNodePeers[i]['address']) + (addNodePeers[i]['port'] == null ? '' : ':' + addNodePeers[i]['port'])});
|
||||
|
||||
$('#addnodes-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.addnodes_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
data: addNodeRows,
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{data: 'nodes', width: '100%'}
|
||||
],
|
||||
columnDefs: [
|
||||
{targets: '_all', className: 'text-start'}
|
||||
]
|
||||
});
|
||||
|
||||
setting_txPerPage = parseInt("#{settings.network_page.onetry_table.items_per_page}");
|
||||
|
||||
var oneTryRows = [];
|
||||
var setting_one_port_filter = "#{settings.network_page.onetry_table.port_filter}";
|
||||
var setting_one_hide_protocols = !{JSON.stringify(settings.network_page.onetry_table.hide_protocols)};
|
||||
|
||||
if (setting_one_port_filter == null || setting_one_port_filter == '')
|
||||
setting_one_port_filter = '0';
|
||||
|
||||
if (setting_one_port_filter != '0')
|
||||
peers = peers.filter(v => v.port == setting_one_port_filter);
|
||||
|
||||
setting_one_hide_protocols.forEach(function (protocol) {
|
||||
peers = peers.filter(v => v.protocol != protocol);
|
||||
});
|
||||
|
||||
for (var i=0; i < peers.length; i++)
|
||||
oneTryRows.push({'nodes': 'addnode ' + (peers[i]['address'] != null && peers[i]['address'].indexOf(':') > -1 ? '[' + peers[i]['address'] + ']' : peers[i]['address']) + (peers[i]['port'] == null ? '' : ':' + peers[i]['port']) + ' onetry'});
|
||||
|
||||
$('#onetry-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.onetry_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
data: oneTryRows,
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{data: 'nodes', width: '100%'}
|
||||
],
|
||||
columnDefs: [
|
||||
{targets: '_all', className: 'text-start'}
|
||||
]
|
||||
});
|
||||
});
|
||||
setting_txPerPage = parseInt("#{settings.network_page.addnodes_table.items_per_page}");
|
||||
$('#addnodes-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.addnodes_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: '/ext/getnetworkpeers/internal',
|
||||
dataSrc: function (json) {
|
||||
var rows = [];
|
||||
|
||||
for (var i=0; i<json.data.length; i++)
|
||||
rows.push({'nodes': 'addnode=' + (json.data[i]['address'] != null && json.data[i]['address'].indexOf(':') > -1 ? '[' + json.data[i]['address'] + ']' : json.data[i]['address']) + (json.data[i]['port'] == null ? '' : ':' + json.data[i]['port'])});
|
||||
|
||||
return rows;
|
||||
}
|
||||
},
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{data: 'nodes', width: '100%'}
|
||||
],
|
||||
columnDefs: [
|
||||
{targets: '_all', className: 'text-start'}
|
||||
]
|
||||
});
|
||||
setting_txPerPage = parseInt("#{settings.network_page.onetry_table.items_per_page}");
|
||||
$('#onetry-table').dataTable({
|
||||
autoWidth: true,
|
||||
searching: false,
|
||||
ordering: false,
|
||||
responsive: true,
|
||||
lengthChange: true,
|
||||
processing: true,
|
||||
iDisplayLength: setting_txPerPage,
|
||||
lengthMenu: generateLengthMenu(setting_txPerPage, !{JSON.stringify(settings.network_page.onetry_table.page_length_options)}),
|
||||
scrollX: true,
|
||||
language: {
|
||||
paginate: {
|
||||
previous: '<',
|
||||
next: '>'
|
||||
}
|
||||
},
|
||||
ajax: {
|
||||
url: '/ext/getnetworkpeers/internal',
|
||||
dataSrc: function (json) {
|
||||
var rows = [];
|
||||
|
||||
for (var i=0; i<json.data.length; i++)
|
||||
rows.push({'nodes': 'addnode ' + (json.data[i]['address'] != null && json.data[i]['address'].indexOf(':') > -1 ? '[' + json.data[i]['address'] + ']' : json.data[i]['address']) + (json.data[i]['port'] == null ? '' : ':' + json.data[i]['port']) + ' onetry'});
|
||||
|
||||
return rows;
|
||||
}
|
||||
},
|
||||
fnDrawCallback: function(settings) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
},
|
||||
columns: [
|
||||
{data: 'nodes', width: '100%'}
|
||||
],
|
||||
columnDefs: [
|
||||
{targets: '_all', className: 'text-start'}
|
||||
]
|
||||
});
|
||||
$('a[data-bs-toggle="tab"]').on('shown.bs.tab', function (e) {
|
||||
fixDataTableColumns();
|
||||
fixFooterHeightAndPosition();
|
||||
@@ -204,6 +242,7 @@ block content
|
||||
thead
|
||||
tr(class=theadClasses)
|
||||
th.text-center #{settings.locale.net_address}
|
||||
th.text-center='Port'
|
||||
th.text-center #{settings.locale.net_protocol}
|
||||
th.text-center #{settings.locale.net_subversion}
|
||||
th.text-center #{settings.locale.net_country}
|
||||
|
||||
Reference in New Issue
Block a user