mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 23:04:52 +09:00
Updated node details and settings style
Fixed nav spacing. Added a header to the storage table.
This commit is contained in:
1 parent
659b071eb6
commit
1788d72f8f
8 files changed
+88
-83
No files matched your search
@@ -9,6 +9,7 @@
|
||||
<link href="/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/external/css/Roboto.css" rel="stylesheet">
|
||||
<link href="https://fonts.googleapis.com/css?family=Orbitron" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.0/css/all.css" integrity="sha384-aOkxzJ5uQz7WBObEZcHvV5JvRW3TUc2rNPA7pe3AwnsUohiw1Vj2Rgx2KSOkF5+h" crossorigin="anonymous">
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/favicon/apple-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/favicon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/favicon/apple-icon-72x72.png">
|
||||
|
||||
+8
-1
@@ -19,7 +19,14 @@
|
||||
<input type="text" class="form-control" id="search" placeholder="search">
|
||||
</div>
|
||||
<div id="contents" class="row w-100">
|
||||
<table class="table table-striped">
|
||||
<table class="table table-striped table-hover">
|
||||
<thead class="thead-dark">
|
||||
<tr>
|
||||
<th scope="col">Icon</th>
|
||||
<th scope="col">Item ID</th>
|
||||
<th scope="col">Quantity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><!-- populated by js --></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -5,10 +5,10 @@
|
||||
<h3 class=" ml-3 nav-title">Clusterio</h3>
|
||||
</a>
|
||||
</div>
|
||||
<div class="nav-item">
|
||||
<div class="nav-item mr-1">
|
||||
<a class="nav-link align-middle" href="/">Storage</a>
|
||||
</div>
|
||||
<div class="nav-item">
|
||||
<div class="nav-item mr-1">
|
||||
<a class="nav-link align-middle" href="/nodes">Slaves</a>
|
||||
</div>
|
||||
<div class="nav-item">
|
||||
|
||||
+2
-57
@@ -1,58 +1,3 @@
|
||||
#header .subbar h6 {
|
||||
display:inline;
|
||||
font-weight:normal;
|
||||
color: #BBB
|
||||
}
|
||||
#header {
|
||||
background-color: #222;
|
||||
color: #DDD;
|
||||
font-family: 'Roboto', sans-serif;
|
||||
padding-left:16px;
|
||||
}
|
||||
#displayBody {
|
||||
margin-left: 16px;
|
||||
}
|
||||
#hero {
|
||||
background-color: #444;
|
||||
height:400px;
|
||||
}
|
||||
#hero .subtitle {
|
||||
margin-left:8px;
|
||||
}
|
||||
|
||||
#header h1 {
|
||||
margin-left: 10px;
|
||||
display:inline-block;
|
||||
}
|
||||
#header .subbar h6 {
|
||||
margin-right: 16px;
|
||||
}
|
||||
#onlineIndicator {
|
||||
background-color:red;
|
||||
height:20px;
|
||||
width:20px;
|
||||
display:inline-block;
|
||||
border-radius:16px;
|
||||
}
|
||||
.productionGraph {
|
||||
background-color:black;
|
||||
}
|
||||
#leftHeroContainer {
|
||||
float:left;
|
||||
}
|
||||
ul {
|
||||
width:300px;
|
||||
list-style:none;
|
||||
max-height:400px;
|
||||
min-height:100px;
|
||||
margin:0;
|
||||
overflow:auto;
|
||||
padding:0;
|
||||
text-indent:10px;
|
||||
}
|
||||
li{
|
||||
line-height:25px;
|
||||
}
|
||||
li:nth-child(even){
|
||||
background:#ccc;
|
||||
#node-stats .breadcrumb-item {
|
||||
height: auto;
|
||||
}
|
||||
+57
-16
@@ -38,22 +38,46 @@ var chartsByID = {};
|
||||
// update the online indicator dot
|
||||
setInterval(function(){
|
||||
getJSON("/api/slaves", function(err, slaveData){
|
||||
let indicator = document.querySelector("#onlineIndicator");
|
||||
let indicator = document.querySelector("#online-indicator");
|
||||
$(indicator).removeClass('fa-signal');
|
||||
$(indicator).removeClass('fa-dizzy');
|
||||
$(indicator).removeClass('fa-plug');
|
||||
if(err){
|
||||
// our request threw an error, most likely master is unavailable so we show yellow indicator
|
||||
indicator.style.backgroundColor = "yellow";
|
||||
indicator.style.color = "yellow";
|
||||
$(indicator).addClass('fa-plug');
|
||||
indicator.title = "Master server unavailable";
|
||||
// compare with Math.floor(x/100000) allows us to check if they are within 10s of each other
|
||||
} else if(Math.floor(slaveData[getParameterByName("instanceID")].time/100000) === Math.floor(Date.now()/100000)){
|
||||
indicator.style.backgroundColor = "green";
|
||||
indicator.style.color = "green";
|
||||
$(indicator).addClass('fa-signal');
|
||||
indicator.title = "Slave is online";
|
||||
} else {
|
||||
indicator.style.backgroundColor = "red";
|
||||
indicator.style.color = "red";
|
||||
$(indicator).addClass('fa-dizzy');
|
||||
indicator.title = "Slave is offline";
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
function regexModDetails(modFileName) {
|
||||
let m;
|
||||
let results = [];
|
||||
const regex = /(.+)_(\d+\.\d+\.\d+)\.zip/gm;
|
||||
while ((m = regex.exec(modFileName)) !== null) {
|
||||
// This is necessary to avoid infinite loops with zero-width matches
|
||||
if (m.index === regex.lastIndex) {
|
||||
regex.lastIndex++;
|
||||
}
|
||||
|
||||
// The result can be accessed through the `m`-variable.
|
||||
m.forEach((match, _) => {
|
||||
results.push(match);
|
||||
});
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
populateSlaveInfo();
|
||||
function populateSlaveInfo(){
|
||||
let instanceID = getParameterByName("instanceID");
|
||||
@@ -86,18 +110,19 @@ function populateSlaveInfo(){
|
||||
}
|
||||
*/
|
||||
let slave = slaveData[instanceID];
|
||||
let HTML = "<div id='header'><div id='onlineIndicator'></div><h1>Name: " + slave.instanceName+"</h1>";
|
||||
HTML += "<div class='subbar'><h6>Host: "+slave.mac+" </h6><h6>Unique: "+slave.unique+" </h6>";
|
||||
let HTML = '<div class="jumbotron mt-5"><div id="header">' +
|
||||
'<h1 class="display-4"><i id="online-indicator" class="mr-3 fas"></i> ' + slave.instanceName+"</h1>";
|
||||
HTML += '<div class="stats" id="node-stats">' +
|
||||
'<nav aria-label="breadcrumb">\n' +
|
||||
' <ol class="breadcrumb"><li class="breadcrumb-item">Host: '+slave.mac+'</li>' +
|
||||
'<li class="breadcrumb-item">Unique: '+slave.unique+'</li>';
|
||||
if(slave.publicIP !== "localhost"){
|
||||
HTML += "<h6>IP: "+slave.publicIP+":"+slave.serverPort+"</h6>";
|
||||
HTML += '<li class="breadcrumb-item">IP: '+slave.publicIP+':'+slave.serverPort+'</li>';
|
||||
} else {
|
||||
HTML += "<h6>This server is not configured for incoming connections</h6>";
|
||||
HTML += '<li class="breadcrumb-item">This server is not configured for incoming connections</li>';
|
||||
}
|
||||
HTML += "</div></div>"; // end of header
|
||||
// left container
|
||||
HTML += "<div id='leftHeroContainer'>";
|
||||
HTML += "<div id='displayBody'><p>Last seen: <span id='lastSeenDate'>"+moment(Number(slave.time)).fromNow()+"</span></p>";
|
||||
HTML += "<p>Online players: "+slave.playerCount+"</p>";
|
||||
HTML += '<li class="breadcrumb-item">Last seen: <span id="lastSeenDate">'+moment(Number(slave.time)).fromNow()+"</span></li>";
|
||||
HTML += '<li class="breadcrumb-item">Online players: '+slave.playerCount+"</li></ol></nav>";
|
||||
|
||||
// detect if remoteMap mod is installed, if it is we want to show the link for it
|
||||
let hasRemoteMap = false;
|
||||
@@ -114,9 +139,25 @@ function populateSlaveInfo(){
|
||||
HTML += "</div>"; // end of displayBody
|
||||
|
||||
// list mods and other metadata
|
||||
HTML += "<h2 class='subtitle'>Mods</h2><ul id='modlist'>";
|
||||
for(let i = 0; i < slave.mods.length; i++){
|
||||
HTML += "<li>"+slave.mods[i].modName+"</li>"
|
||||
HTML += '<h2 class="subtitle d-inline">Mods</h2><a class="btn btn-primary float-right m-2">Fetch Mod Data</a>' +
|
||||
'<table id="modlist" class="table table-striped table-hover">' +
|
||||
' <thead>\n' +
|
||||
' <tr>\n' +
|
||||
' <th scope="col">#</th>\n' +
|
||||
' <th scope="col">Version</th>\n' +
|
||||
' <th scope="col">Filename</th>\n' +
|
||||
' <th scope="col">Summary</th>\n' +
|
||||
' </tr>\n' +
|
||||
' </thead>' +
|
||||
' <tbody>';
|
||||
for(let i = 0; i < slave.mods[0].modName.length; i++){
|
||||
let modRegexResults = regexModDetails(slave.mods[0].modName[i]);
|
||||
HTML += `<tr>
|
||||
<th scope="row">${i + 1}</th>
|
||||
<td>${modRegexResults[2]}</td>
|
||||
<td>${modRegexResults[1]}</td>
|
||||
<td></td>
|
||||
</tr>`
|
||||
}
|
||||
HTML += "</ul>";
|
||||
|
||||
|
||||
+7
-2
@@ -25,7 +25,7 @@
|
||||
for(let id in slaves){
|
||||
let slave = slaves[id];
|
||||
html += `
|
||||
<div id="${id}" class="slaveBox card">
|
||||
<div id="${id}" class="slaveBox card mb-3">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><a href='nodeDetails?instanceID=${id}'>
|
||||
<h2>${slave.instanceName}</h2>
|
||||
@@ -50,17 +50,22 @@
|
||||
for(let i in slaveListingEntries){
|
||||
let button = slaveListingEntries[i];
|
||||
if(button.getHtml && typeof button.getHtml == "function"){
|
||||
html += "<div class=\"plugin-link\">"
|
||||
html += button.getHtml({slave});
|
||||
html += "</div>"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
html += `
|
||||
</div>
|
||||
</div>`
|
||||
`
|
||||
}
|
||||
%>
|
||||
<%- html %>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$('.plugin-link a').addClass('btn btn-primary')
|
||||
</script>
|
||||
</body>
|
||||
+7
-5
@@ -3,6 +3,7 @@ if(localStorage.settings) {
|
||||
let settings = JSON.parse(localStorage.settings);
|
||||
|
||||
let HTML = "";
|
||||
|
||||
for(let key in settings) {
|
||||
HTML += drawSetting(key, settings[key]);
|
||||
}
|
||||
@@ -11,9 +12,9 @@ if(localStorage.settings) {
|
||||
|
||||
window.onload = function(){
|
||||
// loop through all settings and add onclick events for them
|
||||
let thingies = document.querySelectorAll(".settingsBox .switch .slider");
|
||||
for(let i = 0; i < thingies.length; i++) {
|
||||
thingies[i].onclick = function() {
|
||||
let sliders = document.querySelectorAll(".settings-box .switch .slider");
|
||||
for(let i = 0; i < sliders.length; i++) {
|
||||
sliders[i].onclick = function() {
|
||||
let settings = JSON.parse(localStorage.settings);
|
||||
|
||||
// walk through DOM structure created by drawSetting and update localstorage from that
|
||||
@@ -26,8 +27,9 @@ window.onload = function(){
|
||||
};
|
||||
|
||||
function drawSetting(settingText, checked) {
|
||||
let HTML = '<div class="settingsBox">' +
|
||||
'<label class="switch"><input type="checkbox" ' + checked + '' +
|
||||
|
||||
let HTML = '<div class="settings-box">' +
|
||||
'<label class="switch"><input type="checkbox" checked="' + checked + '"' +
|
||||
'><div class="slider round"></div></label><span class="settings-text ml-3 align-middle">' + settingText + '</span></div>';
|
||||
return HTML;
|
||||
}
|
||||
@@ -21,6 +21,10 @@ nav li {
|
||||
width: 60px;
|
||||
height: 34px;
|
||||
}
|
||||
.settingsBox {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Hide default HTML checkbox */
|
||||
.switch input {
|
||||
|
||||
Reference in new issue
Block a user