Updated node details and settings style

Fixed nav spacing.
Added a header to the storage table.
This commit is contained in:
J-Lassauw authored and Jonas Lassauw committed 2018-12-11 22:31:30 +00:00
1 parent 659b071eb6
commit 1788d72f8f
8 files changed
+88 -83

No files matched your search

+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+4
View File
@@ -21,6 +21,10 @@ nav li {
width: 60px;
height: 34px;
}
.settingsBox {
position: relative;
display: block;
}
/* Hide default HTML checkbox */
.switch input {