684 lines
No EOL
28 KiB
HTML
684 lines
No EOL
28 KiB
HTML
<!DOCTYPE html>
|
|
<html lang=\"en\">
|
|
<head>
|
|
<meta charset=\"utf-8\">
|
|
<title>XMRigCC Dashboard</title>
|
|
|
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.16/css/dataTables.bootstrap.min.css">
|
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.5.0/css/buttons.bootstrap.min.css">
|
|
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/select/1.2.4/css/select.dataTables.min.css">
|
|
<link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
|
|
|
|
<style>
|
|
.right{text-align:right;}
|
|
.left{text-align:left;}
|
|
.center{text-align:center; padding-bottom: 50pt}
|
|
.center-tab{text-align: center; vertical-align: middle;}
|
|
.online { color: green}
|
|
.offline { color: red}
|
|
.paused { color: yellow}
|
|
.toggle { border-radius: 2px;}
|
|
.toggle .toggle-handle { border-radius: 2px; }
|
|
|
|
form label
|
|
{
|
|
display:block;
|
|
margin-bottom: 5px;
|
|
text-align: left;
|
|
}
|
|
|
|
form label span {
|
|
display:inline-block;
|
|
margin-left: .5rem;
|
|
text-align: left;
|
|
}
|
|
|
|
form label input {
|
|
vertical-align: top;
|
|
}
|
|
</style>
|
|
|
|
<script type="text/javascript" language="javascript" src="https://code.jquery.com/jquery-1.12.4.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.0/js/dataTables.buttons.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/buttons/1.5.0/js/buttons.bootstrap.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdn.datatables.net/select/1.2.4/js/dataTables.select.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.6.1/jquery.timeago.min.js"></script>
|
|
<script type="text/javascript" language="javascript" src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.2.1/moment-duration-format.min.js"></script>
|
|
<script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
|
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
|
<script src="https://use.fontawesome.com/6b3cdfc597.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
var TRESHOLD_IN_MS = 60 * 1000;
|
|
var RELOAD_INTERVAL_IN_MS = 10 * 1000;
|
|
|
|
var latestRelease = "";
|
|
var currentServerTime = 0;
|
|
var clockDrift = 0;
|
|
|
|
$.fn.dataTable.ext.search.push(
|
|
function( settings, data, dataIndex ) {
|
|
|
|
var hideOffline = $('#hideOffline').prop('checked');
|
|
var showNotification = $('#showOfflineNotification').prop('checked');
|
|
|
|
var clientId = settings.aoData[dataIndex]._aData.client_status.client_id;
|
|
var lastStatus = settings.aoData[dataIndex]._aData.client_status.last_status_update * 1000;
|
|
|
|
var online = isOnline(lastStatus);
|
|
|
|
if (!online) {
|
|
var threshold = currentServerTime - (TRESHOLD_IN_MS + RELOAD_INTERVAL_IN_MS);
|
|
if (lastStatus > threshold && showNotification) {
|
|
$("#notificationBar").after('<div class="alert alert-danger alert-dismissable fade in">' +
|
|
'<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>' +
|
|
'<strong>Miner ' + clientId + ' just went offline!</strong> Last update: ' + new Date(lastStatus) +
|
|
'</div>');
|
|
}
|
|
}
|
|
|
|
return (online || !hideOffline);
|
|
}
|
|
);
|
|
|
|
$(document).ready(function() {
|
|
|
|
var table = $('#clientStatusList').DataTable({
|
|
dom: "<'row'<'col-sm-9'B><'col-sm-3'f>><'row'<'col-sm-12't>><'row'<'col-sm-10'i><'col-sm-2'<'#serverTime'>>>",
|
|
bPaginate: false,
|
|
ajax: {
|
|
url: "/admin/getClientStatusList",
|
|
dataSrc: 'client_status_list'
|
|
},
|
|
deferRender: true,
|
|
columns: [
|
|
{
|
|
data: null,
|
|
defaultContent: '',
|
|
className: 'select-checkbox',
|
|
orderable: false
|
|
},
|
|
{data: "client_status.client_id", render: clientInfo},
|
|
{data: "client_status.current_pool"},
|
|
{data: "client_status.current_status", render: clientStatus},
|
|
{data: "client_status.current_algo_name"},
|
|
{data: "client_status.hashrate_short", render: round, className: "right"},
|
|
{data: "client_status.hashrate_medium", render: round, className: "right"},
|
|
{data: "client_status.hashrate_long", render: round, className: "right"},
|
|
{data: "client_status.hashrate_highest", render: round, className: "right"},
|
|
{data: "client_status.hashes_total", className: "right"},
|
|
{data: "client_status.avg_time", className: "right"},
|
|
{data: "client_status.shares_good", className: "right"},
|
|
{data: "client_status.shares_total", className: "right"},
|
|
{data: "client_status.uptime", render: uptime},
|
|
{data: "client_status.last_status_update", render: laststatus},
|
|
{
|
|
data: null,
|
|
defaultContent:
|
|
"<td class='center-tab'><button type='button' id='EDIT' class='btn btn-xs btn-primary' data-toggle='tooltip' title='Edit miner config'><i class='fa fa-edit'></i></button></td>",
|
|
orderable: false,
|
|
className: "center-tab"
|
|
}
|
|
],
|
|
rowId: 'client_status.client_id',
|
|
select: {
|
|
style: "multi"
|
|
},
|
|
order: [1, 'asc'],
|
|
lengthChange: false,
|
|
buttons: [
|
|
{
|
|
text: '<i class="fa fa-download"> Pull miner config</i>',
|
|
className: 'btn-default',
|
|
enabled: false,
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("PUBLISH_CONFIG", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-upload"> Push miner config</i>',
|
|
className: 'btn-primary',
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("UPDATE_CONFIG", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-play"> Start miner</i>',
|
|
className: 'btn-success',
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("START", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-pause"> Pause miner</i>',
|
|
className: 'btn-warning',
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("STOP", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-repeat"> Restart miner</i>',
|
|
className: 'btn-info',
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("RESTART", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-power-off"> Shutdown miner</i>',
|
|
className: 'btn-danger',
|
|
enabled: false,
|
|
action: function () {
|
|
table.rows({selected: true}).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
sendAction("SHUTDOWN", data.client_status.client_id);
|
|
});
|
|
}
|
|
},
|
|
{
|
|
text: '<i class="fa fa-edit"> Multi miner editor</i>',
|
|
className: 'btn-primary',
|
|
enabled: false,
|
|
action: function () {
|
|
$('#multiMinerEditor').modal('show');
|
|
}
|
|
}
|
|
],
|
|
|
|
"footerCallback": function (row, data, start, end, display) {
|
|
var api = this.api();
|
|
|
|
var sumHashrateShort = 0;
|
|
var sumHashrateMedium = 0;
|
|
var sumHashrateLong = 0;
|
|
var sumHashrateHighest = 0;
|
|
var sumHashesTotal = 0;
|
|
var avgTimeTotal = 0;
|
|
var sumSharesGood = 0;
|
|
var sumSharedTotal = 0;
|
|
|
|
sumHashrateShort = api
|
|
.column(5, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumHashrateMedium = api
|
|
.column(6, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumHashrateLong = api
|
|
.column(7, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumHashrateHighest = api
|
|
.column(8, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumHashesTotal = api
|
|
.column(9, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
avgTimeTotal = api
|
|
.column(10, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return (a + b) / 2;
|
|
}, 0);
|
|
|
|
sumSharesGood = api
|
|
.column(11, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumSharedTotal = api
|
|
.column(12, {page: 'current'})
|
|
.data()
|
|
.reduce(function (a, b) {
|
|
return a + b;
|
|
}, 0);
|
|
|
|
sumHashrateShort = round(sumHashrateShort);
|
|
sumHashrateMedium = round(sumHashrateMedium);
|
|
sumHashrateLong = round(sumHashrateLong);
|
|
sumHashrateHighest = round(sumHashrateHighest);
|
|
avgTimeTotal = round(avgTimeTotal);
|
|
|
|
// update footer
|
|
$(api.column(5).footer()).html(sumHashrateShort);
|
|
$(api.column(6).footer()).html(sumHashrateMedium);
|
|
$(api.column(7).footer()).html(sumHashrateLong);
|
|
$(api.column(8).footer()).html(sumHashrateHighest);
|
|
$(api.column(9).footer()).html(sumHashesTotal);
|
|
$(api.column(10).footer()).html(avgTimeTotal);
|
|
$(api.column(11).footer()).html(sumSharesGood);
|
|
$(api.column(12).footer()).html(sumSharedTotal);
|
|
}
|
|
});
|
|
|
|
table.on('xhr.dt', function ( e, settings, json, xhr ) {
|
|
// check version
|
|
if (latestRelease === "" && json !== undefined) {
|
|
$.ajax({
|
|
url: "https://api.github.com/repos/Bendr0id/xmrigCC/releases/latest",
|
|
type: 'GET',
|
|
dataType: "json",
|
|
success: function (release) {
|
|
latestRelease = release.tag_name;
|
|
if (latestRelease !== json.current_version) {
|
|
$("#updateNotificationBar").html('<div class="alert alert-info alert-dismissable fade in">' +
|
|
'<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>' +
|
|
'<a href="https://github.com/Bendr0id/xmrigCC/releases/latest"><strong>Update!</strong> XMRigCC v' + latestRelease + ' is available for download\n</a>' +
|
|
'</div>');
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
currentServerTime = settings.json.current_server_time * 1000;
|
|
clockDrift = new Date().getTime() - currentServerTime;
|
|
|
|
$('#serverTime').html("<div class='dataTables_info'>" + new Date(currentServerTime) + "</div>");
|
|
});
|
|
|
|
table.on('select', function () {
|
|
var selectedRows = table.rows({selected: true}).count();
|
|
|
|
table.button(0).enable(selectedRows > 0);
|
|
table.button(1).enable(selectedRows > 0);
|
|
table.button(2).enable(selectedRows > 0);
|
|
table.button(3).enable(selectedRows > 0);
|
|
table.button(4).enable(selectedRows > 0);
|
|
table.button(5).enable(selectedRows > 0);
|
|
table.button(6).enable(selectedRows > 0);
|
|
});
|
|
|
|
table.on('deselect', function () {
|
|
var selectedRows = table.rows({selected: true}).count();
|
|
|
|
table.button(0).enable(selectedRows > 0);
|
|
table.button(1).enable(selectedRows > 0);
|
|
table.button(2).enable(selectedRows > 0);
|
|
table.button(3).enable(selectedRows > 0);
|
|
table.button(4).enable(selectedRows > 0);
|
|
table.button(5).enable(selectedRows > 0);
|
|
table.button(6).enable(selectedRows > 0);
|
|
});
|
|
|
|
table.buttons().container().appendTo('#clientStatusList_wrapper .col-sm-6:eq(0)');
|
|
|
|
$('#hideOffline').change(function() {
|
|
table.draw();
|
|
});
|
|
|
|
$('#clientStatusList tbody').on( 'click', 'button', function () {
|
|
var data = table.row( $(this).parents('tr') ).data();
|
|
var clientId = data['client_status']['client_id'];
|
|
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "/admin/getClientConfig?clientId=" + clientId,
|
|
dataType:"json",
|
|
success: function(jsonClientConfig) {
|
|
var htmlContent = "<div class='form-group' id='editor' data-value='" + clientId + "'>" +
|
|
"<label for='config'>Config for: " + clientId + "</label>"+
|
|
"<textarea class='form-control' rows='20' id='config'>" +
|
|
JSON.stringify(jsonClientConfig,undefined, 2) +
|
|
"</textarea>" +
|
|
"</div>";
|
|
|
|
$('#minerEditor').find('.modal-body').html(htmlContent);
|
|
$('#minerEditor').modal('show');
|
|
},
|
|
error: function (data) {
|
|
setError('<strong>Unable to fetch ' + clientId + '_config.json</strong> - Please make sure that you pulled the config before!');
|
|
}
|
|
});
|
|
});
|
|
|
|
$('#minerEditorSave').click(function(event) {
|
|
var clientId = $('#minerEditor').find('.form-group')["0"].dataset.value;
|
|
var clientConfig = $('#config').val();
|
|
|
|
setClientConfig(clientId, clientConfig);
|
|
});
|
|
|
|
$('#multiMinerEditorReplace').click(function(event) {
|
|
table.rows({ selected: true }).eq(0).each(function (index) {
|
|
var row = table.row(index);
|
|
var data = row.data();
|
|
|
|
var clientId = data['client_status']['client_id'];
|
|
var search = $('#search').val();
|
|
var replacement = $('#replacement').val();
|
|
|
|
$.ajax({
|
|
type: "GET",
|
|
url: "/admin/getClientConfig?clientId=" + clientId,
|
|
dataType:"json",
|
|
success: function(jsonClientConfig) {
|
|
jsonClientConfig = JSON.stringify(jsonClientConfig,undefined, 2);
|
|
jsonClientConfig = jsonClientConfig.replace(new RegExp(search.trim(), 'g'), replacement.trim()).trim();
|
|
|
|
setClientConfig(clientId, jsonClientConfig);
|
|
},
|
|
error: function (data) {
|
|
setError('<strong>Unable to fetch ' + clientId + '_config.json</strong> - Please make sure that you pulled the config before!');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
$('#selectAllTop,#selectAllBottom').click( function() {
|
|
if ($("#selectAllTop").hasClass("fa fa-square-o")) {
|
|
$("#selectAllTop").removeClass("fa fa-square-o").addClass("fa fa-check-square-o");
|
|
$("#selectAllBottom").removeClass("fa fa-square-o").addClass("fa fa-check-square-o");
|
|
|
|
table.rows().select();
|
|
} else {
|
|
$("#selectAllTop").removeClass("fa fa-check-square-o").addClass("fa fa-square-o");
|
|
$("#selectAllBottom").removeClass("fa fa-check-square-o").addClass("fa fa-square-o");
|
|
|
|
table.rows().deselect();
|
|
}
|
|
});
|
|
|
|
setInterval(function () {
|
|
table.ajax.reload();
|
|
}, RELOAD_INTERVAL_IN_MS);
|
|
});
|
|
|
|
function sendAction(action, clientId) {
|
|
$.ajax({
|
|
type: "POST",
|
|
url: "/admin/setClientCommand?clientId=" + clientId,
|
|
dataType:"text",
|
|
data: '{"control_command":{"command": "' + action + '"}}',
|
|
success: function(data){
|
|
setSuccess('<strong>Successfully send ' + action + ' to ' + clientId +'</strong> - It can take up to 30s until the command is processed.');
|
|
},
|
|
error: function (data) {
|
|
setError('<strong>Failed to send ' + action + ' to ' + clientId + '</strong> \nError: ' + JSON.stringify(data,undefined, 2));
|
|
}
|
|
});
|
|
}
|
|
|
|
function uptime( data, type, row ) {
|
|
if (type !== 'sort') {
|
|
return moment.duration(data, "milliseconds");
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function laststatus( data, type, row ) {
|
|
if (type !== 'sort') {
|
|
var date = new Date(data*1000 - clockDrift);
|
|
return '<span data-toggle="tooltip" title="' + date + '">' + jQuery.timeago(date) + '</span>';
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function clientStatus( data, type, row ) {
|
|
var lastStatus = row.client_status.last_status_update * 1000;
|
|
|
|
if (isOnline(lastStatus)) {
|
|
return data;
|
|
} else {
|
|
return "OFFLINE";
|
|
}
|
|
}
|
|
|
|
function clientInfo( data, type, row ) {
|
|
if (type !== 'sort') {
|
|
var tooltip = "CPU: " + row.client_status.cpu_brand + " (" + row.client_status.cpu_sockets + ") [" + row.client_status.cpu_cores + " cores / " + row.client_status.cpu_threads + " threads]";
|
|
tooltip += '\n';
|
|
tooltip += "CPU Flags: " + (row.client_status.cpu_has_aes ? "AES-NI " : "");
|
|
tooltip += (row.client_status.cpu_is_x64 ? "x64" : "");
|
|
tooltip += '\n';
|
|
tooltip += "CPU Cache L2/L3: " + (row.client_status.cpu_l2 / 1024) + " MB/"+ (row.client_status.cpu_l3 / 1024) + " MB";
|
|
tooltip += '\n';
|
|
tooltip += "Huge Pages: " + (row.client_status.hugepages_available ? " available, " : " unavailable, ");
|
|
tooltip += (row.client_status.hugepages_enabled ? "enabled" : "disabled");
|
|
tooltip += '\n';
|
|
tooltip += "Used Threads: " + row.client_status.current_threads;
|
|
tooltip += (row.client_status.hash_factor > 1 ? " [" + row.client_status.hash_factor + "x multi hash mode]" :"");
|
|
tooltip += '\n';
|
|
tooltip += "Client IP: " + row.client_status.external_ip;
|
|
tooltip += '\n';
|
|
tooltip += "Version: " + row.client_status.version;
|
|
tooltip += '\n';
|
|
tooltip += "Status: ";
|
|
|
|
var lastStatus = row.client_status.last_status_update * 1000;
|
|
|
|
if (isOnline(lastStatus)) {
|
|
tooltip += "Online";
|
|
return '<span data-toggle="tooltip" title="'+ tooltip + '"><div class="online">' + data + '</div></span>';
|
|
}
|
|
else {
|
|
tooltip += "Offline";
|
|
return '<span data-toggle="tooltip" title="'+ tooltip + '"><div class="offline">' + data + '</div></span>';
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function round( data, type, row ) {
|
|
return Math.round(data * 100) / 100;
|
|
}
|
|
|
|
function isOnline(lastStatus) {
|
|
var threshold = currentServerTime - TRESHOLD_IN_MS;
|
|
if (lastStatus > threshold) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function setSuccess(info) {
|
|
$("#statusBar").after('<div class="alert alert-success" role="alert">' +
|
|
'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' +
|
|
info + '</div>');
|
|
|
|
window.setTimeout(function() {
|
|
$(".alert-success").fadeTo(500, 0).slideUp(500, function(){
|
|
$(".alert-success").alert('close');
|
|
});
|
|
}, 5000);
|
|
}
|
|
|
|
function setError(error) {
|
|
$("#statusBar").after('<div class="alert alert-danger" role="alert">' +
|
|
'<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' +
|
|
error + '</div>');
|
|
|
|
window.setTimeout(function() {
|
|
$(".alert-danger").fadeTo(500, 0).slideUp(500, function(){
|
|
$(".alert-danger").alert('close');
|
|
});
|
|
}, 10000);
|
|
}
|
|
|
|
function setClientConfig(clientId, clientConfig) {
|
|
$.ajax({
|
|
url: "/admin/setClientConfig?clientId=" + clientId,
|
|
type: 'POST',
|
|
dataType: "text",
|
|
data: clientConfig,
|
|
success: function(data){
|
|
setSuccess('<strong>Successfully updated config for: ' + clientId + '</strong> - You need push the config to the miner to apply the config.');
|
|
},
|
|
error: function (data) {
|
|
setError('<strong>Failed to update config for: ' + clientId + '</strong> \nError: ' + JSON.stringify(data,undefined, 2));
|
|
}
|
|
});
|
|
}
|
|
</script>
|
|
|
|
</head>
|
|
<body>
|
|
<br/>
|
|
<div style="width: 95%; margin:0 auto;">
|
|
<div id="updateNotificationBar"></div>
|
|
<div id="notificationBar"></div>
|
|
<div id="statusBar"></div>
|
|
|
|
<div class="center">
|
|
<h1>XMRigCC Dashboard</h1>
|
|
</div>
|
|
|
|
<form style="padding-bottom: 25px">
|
|
<label><input id="hideOffline" type="checkbox" checked data-toggle="toggle" data-size="mini" data-onstyle="success" data-offstyle="danger"/><span>Hide offline miners</span></label>
|
|
<label><input id="showOfflineNotification" type="checkbox" checked data-toggle="toggle" data-size="mini" data-onstyle="success" data-offstyle="danger" /><span>Notify when miner went offline</span></label>
|
|
</form>
|
|
|
|
<table id="clientStatusList" class="table table-striped table-bordered" cellspacing="0" width="100%">
|
|
<thead>
|
|
<tr>
|
|
<th class="center" width="2%"><i class="fa fa-square-o" id="selectAllTop"></i></th>
|
|
<th>Miner Id</th>
|
|
<th>Pool</th>
|
|
<th>Status</th>
|
|
<th>Algo</th>
|
|
|
|
<th>Hashrate</th>
|
|
<th>Hashrate 1m</th>
|
|
<th>Hashrate 15m</th>
|
|
|
|
<th>Hashrate Highest</th>
|
|
<th>Hashes Total</th>
|
|
<th>Avg. Time</th>
|
|
|
|
<th>Shares Good</th>
|
|
<th>Shares Total</th>
|
|
<th>Last Update</th>
|
|
<th>Edit</th>
|
|
</tr>
|
|
</thead>
|
|
<tfoot>
|
|
<tr>
|
|
<th class="center" width="2%"><i class="fa fa-square-o" id="selectAllBottom"></i></th>
|
|
<th class="left">Total:</th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
<th></th>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
|
|
<br/>
|
|
<div class="modal fade" id="minerEditor" role="dialog">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4 class="modal-title">Miner editor</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="minerEditorSave" type="button" class="btn btn-success" data-dismiss="modal">Save</button>
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal fade" id="multiMinerEditor" role="dialog">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal">×</button>
|
|
<h4 class="modal-title">Multi miner editor</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="alert alert-danger fade in">
|
|
<strong>Warning!</strong> - If you don't know what you are doing, [Cancel].
|
|
</div>
|
|
<h5 class="modal-title">
|
|
This will search for <strong>"x"</strong> and replace with <strong>"y"</strong> in all selected miners config<br/><br/>
|
|
<div class="alert alert-info fade in">
|
|
<strong>If you accidentally pressed [Replace], no worries just PULL again all miner configs. Don't PUSH it!</strong>
|
|
</div>
|
|
</h5>
|
|
<div class='form-group'>
|
|
<label for='search'>Search for:</label>
|
|
<textarea class='form-control' rows='2' cols="1" id='search'></textarea>
|
|
<label for='replacement'>Replace with:</label>
|
|
<textarea class='form-control' rows='2' id='replacement'></textarea>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button id="multiMinerEditorReplace" type="button" class="btn btn-success" data-dismiss="modal">Replace</button>
|
|
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html> |