redesign UI
This commit is contained in:
parent
9b39bac8d7
commit
2f41d7a2ea
2
build.rs
2
build.rs
@ -30,7 +30,7 @@ fn pack_debug_page() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let js = std::str::from_utf8(&out)?;
|
let js = std::str::from_utf8(&out)?;
|
||||||
|
|
||||||
let css = Minifier::default().minify(&css, Level::Three).unwrap();
|
let css = Minifier::default().minify(&css, Level::One).unwrap();
|
||||||
|
|
||||||
let (start, end) = html
|
let (start, end) = html
|
||||||
.split_once("<!--INSERT SVG HERE-->")
|
.split_once("<!--INSERT SVG HERE-->")
|
||||||
|
@ -1 +1 @@
|
|||||||
<svg><g transform="translate(-38.3 -51.4)"><path d="m98.8 55.1-6.52 6.52-3.78-3.78 6.52-6.52zm-7.49 20.5-8.5 8.5-16.8-16.8 8.5-8.5zm-16.9 0.0741a11.9 11.9 45 0 1 0.0256-16.8 11.9 11.9 45 0 1 16.8-0.0256 11.9 11.9 45 0 1-0.0256 16.8 11.9 11.9 45 0 1-16.8 0.0256zm-36.2 32.6 6.52-6.52 3.78 3.78-6.52 6.52zm19.7-25.3 8.39-8.39 1.88 1.88-8.39 8.39zm7.46 7.5 8.39-8.39 1.88 1.88-8.39 8.39zm-19.7-2.72 8.5-8.5 16.8 16.8-8.5 8.5zm16.9-0.0741a11.9 11.9 45 0 1-0.0256 16.8 11.9 11.9 45 0 1-16.8 0.0256 11.9 11.9 45 0 1 0.0256-16.8 11.9 11.9 45 0 1 16.8-0.0256z"/></g></svg>
|
<svg version="1.1" viewBox="0 0 60.59 60.734" xmlns="http://www.w3.org/2000/svg"><g transform="translate(-38.21,-51.32)"><path d="m98.8 55.1-6.52 6.52-3.78-3.78 6.52-6.52zm-7.49 20.5-8.5 8.5-16.8-16.8 8.5-8.5zm-16.9 0.0741a11.9 11.9 45 0 1 0.0256-16.8 11.9 11.9 45 0 1 16.8-0.0256 11.9 11.9 45 0 1-0.0256 16.8 11.9 11.9 45 0 1-16.8 0.0256zm-36.2 32.6 6.52-6.52 3.78 3.78-6.52 6.52zm19.7-25.3 8.39-8.39 1.88 1.88-8.39 8.39zm7.46 7.5 8.39-8.39 1.88 1.88-8.39 8.39zm-19.7-2.72 8.5-8.5 16.8 16.8-8.5 8.5zm16.9-0.0741a11.9 11.9 45 0 1-0.0256 16.8 11.9 11.9 45 0 1-16.8 0.0256 11.9 11.9 45 0 1 0.0256-16.8 11.9 11.9 45 0 1 16.8-0.0256z"/></g></svg>
|
||||||
|
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 643 B |
@ -10,25 +10,26 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="header">
|
<div class="content">
|
||||||
<p id="free_ports" />
|
|
||||||
<p id="last_change" />
|
|
||||||
</div>
|
|
||||||
<div id="connected_box">
|
|
||||||
<div id="connected" class="hidden"><!--INSERT SVG HERE--></div>
|
|
||||||
<p id="last_ping" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table id="table">
|
<div id="header">
|
||||||
<tr>
|
<p id="free_ports" />
|
||||||
<th onclick="sort(this,'number')">Nummer</th>
|
<!--<p id="last_change" />-->
|
||||||
<th onclick="sort(this,'port')">Port</th>
|
<div id="connected" class="hidden"><!--INSERT SVG HERE--></div>
|
||||||
<th onclick="sort(this,'status')">Zustand</th>
|
<p id="last_ping" />
|
||||||
<th onclick="sort(this,'name')">Name</th>
|
</div>
|
||||||
<th onclick="sort(this,'rejector')">Meldung</th>
|
|
||||||
<th onclick="sort(this,'last_change')">Letzte Änderung</th>
|
<table id="table">
|
||||||
</tr>
|
<tr>
|
||||||
</table>
|
<th onclick="sort(this,'name')">Name</th>
|
||||||
|
<th onclick="sort(this,'number')">Nummer</th>
|
||||||
|
<th onclick="sort(this,'port')">Port</th>
|
||||||
|
<th onclick="sort(this,'status')">Zustand</th>
|
||||||
|
<th onclick="sort(this,'last_change')">Seit</th>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
62
web/main.css
62
web/main.css
@ -2,40 +2,52 @@ body {
|
|||||||
background-color: #eee;
|
background-color: #eee;
|
||||||
}
|
}
|
||||||
|
|
||||||
#connected_box {
|
.last_change {
|
||||||
position: absolute;
|
text-align: right;
|
||||||
top: 5%;
|
|
||||||
right: 5%;
|
|
||||||
width: 5%;
|
|
||||||
height: 5%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#free_ports,
|
.last_change .unit {
|
||||||
#last_change {
|
padding-left: 1ch;
|
||||||
|
min-width: 8ch;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#last_ping,
|
||||||
|
#connected,
|
||||||
#free_ports {
|
#free_ports {
|
||||||
margin-right: 10%;
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#connected svg {
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
border: 1px solid black;
|
border: 1px solid black;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
border-spacing: 0;
|
border-spacing: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
font-size: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
th::after {
|
th::after {
|
||||||
@ -55,20 +67,24 @@ th:not(.sort)::after {
|
|||||||
content: "\25bc";
|
content: "\25bc";
|
||||||
}
|
}
|
||||||
|
|
||||||
.number {
|
td {
|
||||||
text-align: right;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.port {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.visible {
|
.visible {
|
||||||
opacity: 1;
|
opacity: 0;
|
||||||
transition: opacity 500ms linear;
|
/*transition: opacity 500ms linear;*/
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
opacity: 0.2;
|
opacity: 1;
|
||||||
transition: opacity 6000ms linear;
|
transition: opacity 5000ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connected {
|
||||||
|
fill: rgb(224, 32, 6)
|
||||||
}
|
}
|
98
web/main.js
98
web/main.js
@ -13,13 +13,44 @@ window.onload = () => {
|
|||||||
let evtSource;
|
let evtSource;
|
||||||
let table = [];
|
let table = [];
|
||||||
|
|
||||||
|
let last_update = new Date();
|
||||||
|
|
||||||
let direction = -1;
|
let direction = -1;
|
||||||
let oldkey = "last_change";
|
let oldkey = "last_change";
|
||||||
|
|
||||||
table_elem.firstChild.firstChild.lastChild.className = "sort sort-down";
|
table_elem.firstChild.firstChild.lastChild.className = "sort sort-down";
|
||||||
|
|
||||||
console.log(oldkey, direction);
|
|
||||||
|
|
||||||
|
let time_ago = ms => {
|
||||||
|
|
||||||
|
let value = ms / 1000;
|
||||||
|
// let prev = 0;
|
||||||
|
let unit = 0;
|
||||||
|
|
||||||
|
let factors = [
|
||||||
|
[1, 'Sekunde', 'n'],
|
||||||
|
[60, 'Minute', 'n'],
|
||||||
|
[60, 'Stunde', 'n'],
|
||||||
|
[24, 'Tag', 'e'],
|
||||||
|
[7, 'Woche', 'n'],
|
||||||
|
[4.348214, 'Monat', 'e'],
|
||||||
|
[12, 'Jahr', 'e'],
|
||||||
|
];
|
||||||
|
|
||||||
|
for (let i in factors) {
|
||||||
|
let factor = factors[i][0];
|
||||||
|
let new_value = Math.floor(value / factor);
|
||||||
|
if (new_value == 0) break;
|
||||||
|
|
||||||
|
// prev = Math.floor(value % factor);
|
||||||
|
value = new_value;
|
||||||
|
unit = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
let factor = factors[unit];
|
||||||
|
|
||||||
|
return [value, factors[unit][1] + (value == 1 ? "" : factor[2])];
|
||||||
|
}
|
||||||
|
|
||||||
sort = (element, key) => {
|
sort = (element, key) => {
|
||||||
|
|
||||||
@ -59,6 +90,7 @@ window.onload = () => {
|
|||||||
let fmt = Intl.DateTimeFormat('de-DE', { dateStyle: 'medium', timeStyle: 'medium' });
|
let fmt = Intl.DateTimeFormat('de-DE', { dateStyle: 'medium', timeStyle: 'medium' });
|
||||||
|
|
||||||
let format_date = date => fmt.format(date).replace(', ', ' ');
|
let format_date = date => fmt.format(date).replace(', ', ' ');
|
||||||
|
let format_time = date => fmt.format(date).split(', ', 2)[1];
|
||||||
|
|
||||||
let print_table = () => {
|
let print_table = () => {
|
||||||
while(table_elem.children.length > 1) {
|
while(table_elem.children.length > 1) {
|
||||||
@ -68,21 +100,47 @@ window.onload = () => {
|
|||||||
for (let row of table) {
|
for (let row of table) {
|
||||||
|
|
||||||
let tr = document.createElement("tr");
|
let tr = document.createElement("tr");
|
||||||
|
|
||||||
let values = [
|
let values = [
|
||||||
|
row.name === null ? "?" : row.name,
|
||||||
row.number,
|
row.number,
|
||||||
row.port,
|
row.port,
|
||||||
row.status,
|
row.status,
|
||||||
row.name || "?",
|
time_ago(last_update - row.last_change)
|
||||||
row.rejector || "",
|
|
||||||
format_date(row.last_change)
|
|
||||||
];
|
];
|
||||||
|
|
||||||
for(let value of values) {
|
let names = [
|
||||||
|
"name",
|
||||||
|
"number",
|
||||||
|
"port",
|
||||||
|
"status",
|
||||||
|
"last_change"
|
||||||
|
];
|
||||||
|
|
||||||
|
for(let i in values) {
|
||||||
|
let value = values[i];
|
||||||
|
let name = names[i];
|
||||||
|
|
||||||
let td = document.createElement("td");
|
let td = document.createElement("td");
|
||||||
td.innerText = value;
|
td.className = name;
|
||||||
td.className = Number.isInteger(value) ? "number" : "text";
|
|
||||||
|
if (name == "last_change") {
|
||||||
|
let [number, unit] = value;
|
||||||
|
|
||||||
|
let span = document.createElement("span");
|
||||||
|
// span.className = "value";
|
||||||
|
span.innerText = number;
|
||||||
|
td.appendChild(span);
|
||||||
|
|
||||||
|
span = document.createElement("span");
|
||||||
|
span.className = "unit";
|
||||||
|
span.innerText = unit;
|
||||||
|
td.appendChild(span);
|
||||||
|
} else {
|
||||||
|
td.innerText = value;
|
||||||
|
}
|
||||||
tr.appendChild(td);
|
tr.appendChild(td);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table_elem.appendChild(tr)
|
table_elem.appendChild(tr)
|
||||||
@ -95,7 +153,7 @@ window.onload = () => {
|
|||||||
const allowed_ports = data.allowed_ports.map(x => x.end - x.start + 1).reduce((a,b) => a + b, 0);
|
const allowed_ports = data.allowed_ports.map(x => x.end - x.start + 1).reduce((a,b) => a + b, 0);
|
||||||
free_ports.innerText = `Freie Ports: ${allowed_ports - Object.keys(data.allocated_ports).length - data.errored_ports.length}`;
|
free_ports.innerText = `Freie Ports: ${allowed_ports - Object.keys(data.allocated_ports).length - data.errored_ports.length}`;
|
||||||
|
|
||||||
last_change.innerHTML = `Letzte Änderung: ${format_date(new Date(+data.last_update * 1000))}`;
|
// last_change.innerHTML = `Letzte Änderung: ${format_date(new Date(+data.last_update * 1000))}`;
|
||||||
|
|
||||||
table = [];
|
table = [];
|
||||||
|
|
||||||
@ -116,7 +174,7 @@ window.onload = () => {
|
|||||||
|
|
||||||
switch(status) {
|
switch(status) {
|
||||||
case "disconnected":
|
case "disconnected":
|
||||||
status = "getrennt";
|
status = rejector ? `getrennt: ${rejector}` : "getrennt";
|
||||||
break;
|
break;
|
||||||
case "idle":
|
case "idle":
|
||||||
status = "bereit";
|
status = "bereit";
|
||||||
@ -130,19 +188,20 @@ window.onload = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (let [timestamp, port] of data.errored_ports) {
|
for (let [timestamp, port] of data.errored_ports) {
|
||||||
table.push({port, number: null, status: "Fehler", last_change: new Date(timestamp * 1000), rejector: null, name: null})
|
table.push({port, number: null, status: "Fehler", last_change: new Date(timestamp * 1000), rejector: null, name: ""})
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(table);
|
console.log(table);
|
||||||
|
|
||||||
|
|
||||||
do_sort(oldkey, direction);
|
do_sort(oldkey, direction);
|
||||||
|
|
||||||
print_table();
|
print_table();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
let format_event = event => format_date(new Date(+event.data * 1000));
|
let format_event = (event, method) => (method || format_date)(new Date(+event.data * 1000));
|
||||||
|
|
||||||
|
let display_disconnected;
|
||||||
|
|
||||||
let connect_event_source = () => {
|
let connect_event_source = () => {
|
||||||
|
|
||||||
@ -154,7 +213,9 @@ window.onload = () => {
|
|||||||
|
|
||||||
evtSource = new EventSource("/events");
|
evtSource = new EventSource("/events");
|
||||||
evtSource.addEventListener("change", event => {
|
evtSource.addEventListener("change", event => {
|
||||||
last_ping.innerText = `Letzter Serverkontakt: ${format_event(event)}`;
|
last_ping.innerText = `Stand: ${format_event(event, format_time)}`;
|
||||||
|
|
||||||
|
last_update = new Date(+event.data * 1000);
|
||||||
|
|
||||||
fetch("/data")
|
fetch("/data")
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
@ -165,10 +226,15 @@ window.onload = () => {
|
|||||||
clearTimeout(ping_timeout);
|
clearTimeout(ping_timeout);
|
||||||
ping_timeout = setTimeout(connect_event_source, timeout_duration);
|
ping_timeout = setTimeout(connect_event_source, timeout_duration);
|
||||||
|
|
||||||
|
last_update = new Date(+event.data * 1000);
|
||||||
|
|
||||||
last_ping.innerText = `Letzter Serverkontakt: ${format_event(event)}`;
|
last_ping.innerText = `Stand: ${format_event(event, format_time)}`;
|
||||||
connected.className = "visible";
|
connected.className = "visible";
|
||||||
setTimeout(() => connected.className = "hidden", 1000);
|
|
||||||
|
print_table();
|
||||||
|
|
||||||
|
clearTimeout(display_disconnected);
|
||||||
|
display_disconnected = setTimeout(() => connected.className = "hidden", 5000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user