224 lines
4.1 KiB
JavaScript
224 lines
4.1 KiB
JavaScript
const sprintf = (...[string, ...args]) => {
|
||
return string.replace(/{(\d+)}/g, (match, number) => args[number] ?? match);
|
||
}
|
||
|
||
const getJSON = async url => {
|
||
const resp = await fetch(url)
|
||
const json = await resp.json()
|
||
return json;
|
||
}
|
||
|
||
const createPopup = async id => {
|
||
const asics = await getJSON('/api/asictypes')
|
||
|
||
asicoptions = ''
|
||
asics.forEach(elem => {
|
||
asicoptions += sprintf('<option value="{0}">{1}</option>', elem['key'], elem['value'])
|
||
})
|
||
|
||
document.querySelector('body').innerHTML += sprintf(popup, id, asicoptions, 'content')
|
||
}
|
||
|
||
const deletePopup = id => {
|
||
document.querySelector('#popup-' + id).remove()
|
||
}
|
||
|
||
const update = async () => {
|
||
let inner = await getStats()
|
||
document.querySelector('.grid').innerHTML = inner
|
||
}
|
||
|
||
const datafn = async () => {
|
||
// return await getJSON('/api/webinit')
|
||
}
|
||
|
||
const data = datafn()
|
||
|
||
console.log(data)
|
||
|
||
const cols = 40
|
||
const rows = 40
|
||
|
||
|
||
const css =
|
||
`<style>
|
||
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:wght@400;500;600;700&display=swap');
|
||
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
font-family: 'Source Code Pro', monospace;
|
||
}
|
||
|
||
body {
|
||
background: #000;
|
||
}
|
||
|
||
input,
|
||
select {
|
||
border: 1px solid #fff;
|
||
background: #000;
|
||
color: #fff;
|
||
padding: 5px 10px;
|
||
}
|
||
|
||
.green {
|
||
background: #0b0 !important;
|
||
}
|
||
|
||
.yellow {
|
||
background: #ff0 !important;
|
||
}
|
||
|
||
.red {
|
||
background: #f11 !important;
|
||
}
|
||
|
||
.darkred {
|
||
background: #300 !important;
|
||
}
|
||
|
||
.header {
|
||
height: 60px;
|
||
background: #222;
|
||
text-align: center;
|
||
margin: 0 0 1px 0;
|
||
display: grid;
|
||
justify-items: center;
|
||
align-content: center;
|
||
}
|
||
|
||
.header-info {
|
||
color: #bbb;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(${cols}, 30px);
|
||
grid-template-rows: repeat(${rows}, 30px);
|
||
grid-gap: 1px;
|
||
margin: auto;
|
||
width: max-content;
|
||
}
|
||
|
||
.cell {
|
||
position: relative;
|
||
background: #111;
|
||
font-size: 9px;
|
||
}
|
||
|
||
.cell:hover {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.cell:hover::after {
|
||
content: '';
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
pointer-events: none;
|
||
background: #ffffff33;
|
||
}
|
||
|
||
.popup {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: grid;
|
||
justify-items: center;
|
||
align-content: center;
|
||
}
|
||
|
||
.popup-bg {
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 100%;
|
||
background: #00000033;
|
||
z-index: 98;
|
||
}
|
||
|
||
.popup-window {
|
||
position: relative;
|
||
height: max-content;
|
||
max-height: 90vh;
|
||
width: max-content;
|
||
max-width: 90vw;
|
||
padding: 40px;
|
||
background: #222;
|
||
z-index: 99;
|
||
}
|
||
</style>
|
||
`
|
||
|
||
const header =
|
||
'<div class="header">'
|
||
+ '<div class="header-info">'
|
||
+ 'Всего устройств: {0}, Предупреждений, {1}, Ошибки: {2}, В сети: {3}, Не в сети: {4}'
|
||
+ '</div>'
|
||
+ '</div>'
|
||
|
||
|
||
const cell =
|
||
'<div class="cell {1}" id="cell-{0}" onclick="createPopup({0})">'
|
||
+ '{2}'
|
||
+ '</div>'
|
||
|
||
const grid =
|
||
'<div class="grid">'
|
||
+ '{0}'
|
||
+ '</div>'
|
||
|
||
const popup =
|
||
'<div class="popup" id="popup-{0}">'
|
||
+ '<div class="popup-bg" onclick="deletePopup({0})"></div>'
|
||
+ '<div class="popup-window">'
|
||
+ '<div class="row">'
|
||
+ '<select>'
|
||
+ '<option value="none">Свободно</option>'
|
||
+ '{1}'
|
||
+ '</select>'
|
||
+ '<input type="text" placeholder="Адрес...">'
|
||
+ '</div>'
|
||
+ '{2}'
|
||
+ '</div>'
|
||
+ '</div>'
|
||
|
||
const getStats = async () => {
|
||
let cells = ''
|
||
let info = await getJSON('/curstatus.json')
|
||
for(let i = 1; i <= cols * rows; i++) {
|
||
if(info.asics[i]?.status == "ok")
|
||
cells += sprintf(cell, i, 'green', info.asics[i]?.hashrate)
|
||
else if(info.asics[i]?.status == "warn")
|
||
cells += sprintf(cell, i, 'yellow', info.asics[i]?.hashrate)
|
||
else if(info.asics[i]?.status == "crit")
|
||
cells += sprintf(cell, i, 'red', info.asics[i]?.hashrate)
|
||
else if(info.asics[i]?.status == "off")
|
||
cells += sprintf(cell, i, 'darkred', '')
|
||
else
|
||
cells += sprintf(cell, i, '', '')
|
||
}
|
||
return cells
|
||
}
|
||
|
||
const run = async () => {
|
||
document.querySelector('body').innerHTML += css
|
||
document.querySelector('body').innerHTML += sprintf(header)
|
||
|
||
let inner = sprintf(grid, await getStats())
|
||
document.querySelector('body').innerHTML += inner
|
||
|
||
setInterval(async () => {
|
||
await update()
|
||
}, 10000)
|
||
}
|
||
|
||
|
||
run()
|