moved routes into dashboard.js
This commit is contained in:
parent
04cc1c1df3
commit
97481b0b75
7 changed files with 286 additions and 217 deletions
|
@ -54,16 +54,16 @@ export const containerCard = (data) => {
|
|||
<div class="ms-auto lh-1">
|
||||
<div class="card-actions btn-actions">
|
||||
<div class="card-actions btn-actions">
|
||||
<button class="btn-action" title="Start" data-hx-get="/action" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="start" value="${state}" ${disable}><!-- player-play -->
|
||||
<button class="btn-action" title="Start" data-hx-post="/start" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="${state}" ${disable}><!-- player-play -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-play" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M7 4v16l13 -8z"></path></svg>
|
||||
</button>
|
||||
<button class="btn-action" title="Stop" data-hx-get="/action" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="stop" value="${state}" ${disable}><!-- player-stop -->
|
||||
<button class="btn-action" title="Stop" data-hx-post="/stop" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="${state}" ${disable}><!-- player-stop -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-stop" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M5 5m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"></path></svg>
|
||||
</button>
|
||||
<button class="btn-action" title="Pause" data-hx-get="/action" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="pause" value="${state}" ${disable}><!-- player-pause -->
|
||||
<button class="btn-action" title="Pause" data-hx-post="/pause" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="${state}" ${disable}><!-- player-pause -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-player-pause" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M6 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path><path d="M14 5m0 1a1 1 0 0 1 1 -1h2a1 1 0 0 1 1 1v12a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1z"></path></svg>
|
||||
</button>
|
||||
<button class="btn-action" title="Restart" data-hx-get="/action" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="restart" value="${state}" ${disable}><!-- reload -->
|
||||
<button class="btn-action" title="Restart" data-hx-post="/restart" data-hx-trigger="click" data-hx-swap="none" name="${name}" id="${state}" ${disable}><!-- reload -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-reload" width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M19.933 13.041a8 8 0 1 1 -9.925 -8.788c3.899 -1 7.935 1.007 9.425 4.747"></path><path d="M20 4v5h-5"></path></svg>
|
||||
</button>
|
||||
<div class="dropdown">
|
||||
|
|
|
@ -1,23 +1,244 @@
|
|||
import { docker, event } from "../server.js";
|
||||
import { Readable } from 'stream';
|
||||
import { Permission, Container } from '../database/models.js';
|
||||
import { modal } from '../components/modal.js';
|
||||
import { permissionsModal } from '../components/permissions_modal.js';
|
||||
import { cpu, ram, tx, rx, disk } from '../server.js';
|
||||
import { dockerContainerStats } from 'systeminformation';
|
||||
|
||||
|
||||
|
||||
export const Dashboard = (req, res) => {
|
||||
|
||||
|
||||
res.render("dashboard", {
|
||||
name: req.session.user,
|
||||
role: req.session.role,
|
||||
avatar: req.session.avatar,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export const searchDashboard = (req, res) => {
|
||||
// console.log(req.params);
|
||||
res.render("dashboard", {
|
||||
name: req.session.user,
|
||||
role: req.session.role,
|
||||
avatar: req.session.avatar,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export const Start = (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let state = req.header('hx-trigger');
|
||||
|
||||
if (state == 'stopped') {
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.start();
|
||||
} else if (state == 'paused') {
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.unpause();
|
||||
}
|
||||
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
|
||||
export const Stop = (req, res) => {
|
||||
|
||||
console.log(`Clicked on stop`);
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
let state = req.header('hx-trigger');
|
||||
|
||||
if (state != 'stopped') {
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.stop();
|
||||
}
|
||||
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
export const Pause = (req, res) => {
|
||||
|
||||
console.log(`Clicked on pause`);
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
let state = req.header('hx-trigger');
|
||||
|
||||
if (state == 'running') {
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.pause();
|
||||
} else if (state == 'paused') {
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.unpause();
|
||||
}
|
||||
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
export const Restart = (req, res) => {
|
||||
|
||||
console.log(`Clicked on restart`);
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
var containerName = docker.getContainer(name);
|
||||
containerName.restart();
|
||||
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const Logs = (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
function containerLogs (data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let logString = '';
|
||||
var options = {
|
||||
follow: false,
|
||||
stdout: true,
|
||||
stderr: false,
|
||||
timestamps: false
|
||||
};
|
||||
var containerName = docker.getContainer(data);
|
||||
containerName.logs(options, function (err, stream) {
|
||||
if (err) { reject(err); return; }
|
||||
const readableStream = Readable.from(stream);
|
||||
readableStream.on('data', function (chunk) {
|
||||
logString += chunk.toString('utf8');
|
||||
});
|
||||
readableStream.on('end', function () {
|
||||
resolve(logString);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
containerLogs(name).then((data) => {
|
||||
res.send(`<pre>${data}</pre> `)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export const Modal = async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let id = req.header('hx-trigger');
|
||||
|
||||
if (id == 'permissions') {
|
||||
let containerPermissions = await Permission.findAll({ where: {containerName: name}});
|
||||
let form = permissionsModal();
|
||||
res.send(form);
|
||||
return;
|
||||
}
|
||||
|
||||
let containerId = docker.getContainer(name);
|
||||
let containerInfo = await containerId.inspect();
|
||||
let ports_list = [];
|
||||
try {
|
||||
for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) {
|
||||
let ports = {
|
||||
check: 'checked',
|
||||
external: value[0].HostPort,
|
||||
internal: key.split('/')[0],
|
||||
protocol: key.split('/')[1]
|
||||
}
|
||||
ports_list.push(ports);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
let external_port = ports_list[0]?.external || 0;
|
||||
let internal_port = ports_list[0]?.internal || 0;
|
||||
|
||||
let container_info = {
|
||||
name: containerInfo.Name.slice(1),
|
||||
state: containerInfo.State.Status,
|
||||
image: containerInfo.Config.Image,
|
||||
external_port: external_port,
|
||||
internal_port: internal_port,
|
||||
ports: ports_list,
|
||||
link: 'localhost',
|
||||
}
|
||||
let form = modal(container_info);
|
||||
res.send(form);
|
||||
|
||||
}
|
||||
|
||||
export const searchDashboard = (req, res) => {
|
||||
|
||||
// console.log(req.params);
|
||||
export const Stats = async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let color = req.header('hx-trigger');
|
||||
let value = 0;
|
||||
switch (name) {
|
||||
case 'CPU': value = cpu;
|
||||
break;
|
||||
case 'RAM': value = ram;
|
||||
break;
|
||||
case 'TX': value = tx;
|
||||
break;
|
||||
case 'RX': value = rx;
|
||||
break;
|
||||
case 'DISK': value = disk;
|
||||
break;
|
||||
}
|
||||
let info = `<div class="font-weight-medium">
|
||||
<label class="cpu-text mb-1">${name} ${value}%</label>
|
||||
</div>
|
||||
<div class="cpu-bar meter animate ${color}">
|
||||
<span style="width:${value}%"><span></span></span>
|
||||
</div>`;
|
||||
res.send(info);
|
||||
}
|
||||
|
||||
res.render("dashboard", {
|
||||
name: req.session.user,
|
||||
role: req.session.role,
|
||||
avatar: req.session.avatar,
|
||||
});
|
||||
|
||||
|
||||
export const Hide = async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let id = req.header('hx-trigger');
|
||||
|
||||
let exists = await Container.findOne({ where: {name: name}});
|
||||
if (!exists) {
|
||||
const newContainer = await Container.create({ name: name, visibility: false, });
|
||||
} else {
|
||||
exists.update({ visibility: false });
|
||||
}
|
||||
event = true;
|
||||
eventInfo = 'docker';
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
|
||||
export const Reset = async (req, res) => {
|
||||
Container.update({ visibility: true }, { where: {} });
|
||||
event = true;
|
||||
eventInfo = 'docker';
|
||||
res.send("ok");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let stats = {};
|
||||
export const Chart = async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
// create an empty array if it doesn't exist
|
||||
if (!stats[name]) {
|
||||
stats[name] = { cpuArray: Array(15).fill(0), ramArray: Array(15).fill(0) };
|
||||
}
|
||||
// get the stats
|
||||
const info = await dockerContainerStats(name);
|
||||
// update the arrays
|
||||
stats[name].cpuArray.push(Math.round(info[0].cpuPercent));
|
||||
stats[name].ramArray.push(Math.round(info[0].memPercent));
|
||||
// slice them down to the last 15 values
|
||||
stats[name].cpuArray = stats[name].cpuArray.slice(-15);
|
||||
stats[name].ramArray = stats[name].ramArray.slice(-15);
|
||||
// replace the chart with the new data
|
||||
let chart = `
|
||||
<script>
|
||||
${name}chart.updateSeries([{
|
||||
data: [${stats[name].cpuArray}]
|
||||
}, {
|
||||
data: [${stats[name].ramArray}]
|
||||
}])
|
||||
</script>`
|
||||
res.send(chart);
|
||||
}
|
|
@ -19,3 +19,14 @@ export const Supporters = async (req, res) => {
|
|||
|
||||
|
||||
}
|
||||
|
||||
|
||||
let thanks = 0;
|
||||
export const Thanks = async (req, res) => {
|
||||
thanks++;
|
||||
let data = thanks.toString();
|
||||
if (thanks > 999) {
|
||||
data = 'Did you really click 1000 times?!';
|
||||
}
|
||||
res.send(data);
|
||||
}
|
|
@ -4,7 +4,7 @@ export const router = express.Router();
|
|||
// Controllers
|
||||
import { Login, submitLogin, Logout } from "../controllers/login.js";
|
||||
import { Register, submitRegister } from "../controllers/register.js";
|
||||
import { Dashboard, searchDashboard } from "../controllers/dashboard.js";
|
||||
import { Dashboard, searchDashboard, Start, Stop, Pause, Restart, Logs, Modal, Stats, Hide, Reset, Chart } from "../controllers/dashboard.js";
|
||||
import { Apps, appSearch } from "../controllers/apps.js";
|
||||
import { Users } from "../controllers/users.js";
|
||||
import { Images, removeImage } from "../controllers/images.js";
|
||||
|
@ -13,7 +13,7 @@ import { Volumes, removeVolume } from "../controllers/volumes.js";
|
|||
import { Account } from "../controllers/account.js";
|
||||
import { Variables } from "../controllers/variables.js";
|
||||
import { Settings } from "../controllers/settings.js";
|
||||
import { Supporters } from "../controllers/supporters.js";
|
||||
import { Supporters, Thanks } from "../controllers/supporters.js";
|
||||
import { Syslogs } from "../controllers/syslogs.js";
|
||||
import { Portal } from "../controllers/portal.js"
|
||||
|
||||
|
@ -29,13 +29,22 @@ const auth = (req, res, next) => {
|
|||
// Routes
|
||||
router.get("/login", Login);
|
||||
router.post("/login", submitLogin);
|
||||
router.get("/logout", Logout);
|
||||
|
||||
router.get("/register", Register);
|
||||
router.post("/register", submitRegister);
|
||||
router.get("/logout", Logout);
|
||||
|
||||
router.get("/", auth, Dashboard);
|
||||
router.post("/", auth, searchDashboard);
|
||||
router.post("/start", auth, Start);
|
||||
router.post("/stop", auth, Stop);
|
||||
router.post("/pause", auth, Pause);
|
||||
router.post("/restart", auth, Restart);
|
||||
router.get("/logs", auth, Logs);
|
||||
router.get ("/modal", auth, Modal);
|
||||
router.get("/stats", auth, Stats);
|
||||
router.post("/hide", auth, Hide);
|
||||
router.post("/reset", auth, Reset);
|
||||
router.get("/chart", auth, Chart);
|
||||
|
||||
|
||||
router.get("/images", auth, Images);
|
||||
router.post("/removeImage", removeImage);
|
||||
|
@ -58,7 +67,9 @@ router.get("/syslogs", auth, Syslogs);
|
|||
router.get("/account", Account);
|
||||
router.get("/variables", auth, Variables);
|
||||
router.get("/settings", auth, Settings);
|
||||
|
||||
router.get("/supporters", Supporters);
|
||||
router.post("/thank", Thanks);
|
||||
|
||||
|
||||
// Functions
|
||||
|
|
212
server.js
212
server.js
|
@ -3,15 +3,14 @@ import session from 'express-session';
|
|||
import memorystore from 'memorystore';
|
||||
import ejs from 'ejs';
|
||||
import Docker from 'dockerode';
|
||||
import { Readable } from 'stream';
|
||||
import { router } from './router/index.js';
|
||||
import { sequelize, Container, Permission } from './database/models.js';
|
||||
import { currentLoad, mem, networkStats, fsSize, dockerContainerStats, dockerImages, networkInterfaces } from 'systeminformation';
|
||||
import { sequelize, Container } from './database/models.js';
|
||||
import { currentLoad, mem, networkStats, fsSize } from 'systeminformation';
|
||||
import { containerCard } from './components/containerCard.js';
|
||||
import { modal } from './components/modal.js';
|
||||
import { permissionsModal } from './components/permissions_modal.js';
|
||||
export var docker = new Docker();
|
||||
|
||||
export { event, sse, cpu, ram, tx, rx, disk }
|
||||
|
||||
const app = express();
|
||||
const MemoryStore = memorystore(session);
|
||||
const port = process.env.PORT || 8000;
|
||||
|
@ -56,8 +55,6 @@ app.listen(port, async () => {
|
|||
|
||||
let [ cpu, ram, tx, rx, disk ] = [0, 0, 0, 0, 0];
|
||||
let [ hidden, cardList, sentList ] = ['', '', ''];
|
||||
let thanks = 0;
|
||||
|
||||
let event = false;
|
||||
let sse = false;
|
||||
let eventInfo = '';
|
||||
|
@ -80,38 +77,6 @@ let serverMetrics = async () => {
|
|||
}
|
||||
setInterval(serverMetrics, 1000);
|
||||
|
||||
|
||||
router.get('/stats', async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let color = req.header('hx-trigger');
|
||||
let value = 0;
|
||||
|
||||
switch (name) {
|
||||
case 'CPU':
|
||||
value = cpu;
|
||||
break;
|
||||
case 'RAM':
|
||||
value = ram;
|
||||
break;
|
||||
case 'TX':
|
||||
value = tx;
|
||||
break;
|
||||
case 'RX':
|
||||
value = rx;
|
||||
break;
|
||||
case 'DISK':
|
||||
value = disk;
|
||||
break;
|
||||
}
|
||||
let info = `<div class="font-weight-medium">
|
||||
<label class="cpu-text mb-1">${name} ${value}%</label>
|
||||
</div>
|
||||
<div class="cpu-bar meter animate ${color}">
|
||||
<span style="width:${value}%"><span></span></span>
|
||||
</div>`;
|
||||
res.send(info);
|
||||
});
|
||||
|
||||
// Get hidden containers
|
||||
async function getHidden() {
|
||||
hidden = await Container.findAll({ where: {visibility:false}});
|
||||
|
@ -192,175 +157,36 @@ router.get('/containers', async (req, res) => {
|
|||
res.send(cardList);
|
||||
});
|
||||
|
||||
// Dashboard controls
|
||||
router.get('/action', async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let id = req.header('hx-trigger');
|
||||
let value = req.query[name];
|
||||
var containerName = docker.getContainer(name);
|
||||
if ((id == 'start') && (value == 'stopped')) {
|
||||
containerName.start();
|
||||
} else if ((id == 'start') && (value == 'paused')) {
|
||||
containerName.unpause();
|
||||
} else if ((id == 'stop') && (value != 'stopped')) {
|
||||
containerName.stop();
|
||||
} else if ((id == 'pause') && (value == 'running')) {
|
||||
containerName.pause();
|
||||
} else if ((id == 'pause') && (value == 'paused')) {
|
||||
containerName.unpause();
|
||||
} else if (id == 'restart') {
|
||||
containerName.restart();
|
||||
}
|
||||
});
|
||||
|
||||
router.get('/hide', async (req, res) => {
|
||||
let name = req.header('hx-trigger-name');
|
||||
let id = req.header('hx-trigger');
|
||||
if (id == 'hide') {
|
||||
let exists = await Container.findOne({ where: {name: name}});
|
||||
if (!exists) {
|
||||
const newContainer = await Container.create({ name: name, visibility: false, });
|
||||
} else {
|
||||
exists.update({ visibility: false });
|
||||
}
|
||||
} else if (id == 'reset') {
|
||||
Container.update({ visibility: true }, { where: {} });
|
||||
}
|
||||
event = true;
|
||||
eventInfo = 'docker';
|
||||
});
|
||||
|
||||
router.get('/logs', async (req, res) => {
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
|
||||
function containerLogs (data) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let logString = '';
|
||||
var options = {
|
||||
follow: false,
|
||||
stdout: true,
|
||||
stderr: false,
|
||||
timestamps: false
|
||||
};
|
||||
var containerName = docker.getContainer(data);
|
||||
containerName.logs(options, function (err, stream) {
|
||||
if (err) { reject(err); return; }
|
||||
const readableStream = Readable.from(stream);
|
||||
readableStream.on('data', function (chunk) {
|
||||
logString += chunk.toString('utf8');
|
||||
});
|
||||
readableStream.on('end', function () {
|
||||
resolve(logString);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
containerLogs(name).then((data) => {
|
||||
res.send(`<pre>${data}</pre> `)
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
router.get('/sse_event', (req, res) => {
|
||||
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive', });
|
||||
let eventCheck = setInterval(async () => {
|
||||
if (sse == true) {
|
||||
sse = false;
|
||||
console.log(`event: ${eventInfo}`);
|
||||
res.write(`event: ${eventInfo}\n`);
|
||||
res.write(`data: there was an event!\n\n`);
|
||||
sse = false;
|
||||
}
|
||||
}, 1000);
|
||||
req.on('close', () => {
|
||||
clearInterval(eventCheck);
|
||||
});
|
||||
return;
|
||||
});
|
||||
|
||||
router.get('/modal', async (req, res) => {
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
let id = req.header('hx-trigger');
|
||||
|
||||
if (id == 'permissions') {
|
||||
let containerPermissions = await Permission.findAll({ where: {containerName: name}});
|
||||
|
||||
|
||||
let form = permissionsModal();
|
||||
res.send(form);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let containerId = docker.getContainer(name);
|
||||
let containerInfo = await containerId.inspect();
|
||||
let ports_list = [];
|
||||
try {
|
||||
for (const [key, value] of Object.entries(containerInfo.HostConfig.PortBindings)) {
|
||||
let ports = {
|
||||
check: 'checked',
|
||||
external: value[0].HostPort,
|
||||
internal: key.split('/')[0],
|
||||
protocol: key.split('/')[1]
|
||||
}
|
||||
ports_list.push(ports);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
let external_port = ports_list[0]?.external || 0;
|
||||
let internal_port = ports_list[0]?.internal || 0;
|
||||
|
||||
let container_info = {
|
||||
name: containerInfo.Name.slice(1),
|
||||
state: containerInfo.State.Status,
|
||||
image: containerInfo.Config.Image,
|
||||
external_port: external_port,
|
||||
internal_port: internal_port,
|
||||
ports: ports_list,
|
||||
router.get('/installing', async (req, res) => {
|
||||
|
||||
let install_info = {
|
||||
name: 'App Name',
|
||||
service: '',
|
||||
id: '',
|
||||
state: 'Installing',
|
||||
image: '',
|
||||
external_port: 0,
|
||||
internal_port: 0,
|
||||
ports: '',
|
||||
link: 'localhost',
|
||||
}
|
||||
|
||||
let form = modal(container_info);
|
||||
res.send(form);
|
||||
});
|
||||
|
||||
|
||||
let stats = {};
|
||||
router.get('/chart', async (req, res) => {
|
||||
|
||||
let name = req.header('hx-trigger-name');
|
||||
// create an empty array if it doesn't exist
|
||||
if (!stats[name]) {
|
||||
stats[name] = { cpuArray: Array(15).fill(0), ramArray: Array(15).fill(0) };
|
||||
}
|
||||
// get the stats
|
||||
const info = await dockerContainerStats(name);
|
||||
// update the arrays
|
||||
stats[name].cpuArray.push(Math.round(info[0].cpuPercent));
|
||||
stats[name].ramArray.push(Math.round(info[0].memPercent));
|
||||
// slice them down to the last 15 values
|
||||
stats[name].cpuArray = stats[name].cpuArray.slice(-15);
|
||||
stats[name].ramArray = stats[name].ramArray.slice(-15);
|
||||
// replace the chart with the new data
|
||||
let chart = `
|
||||
<script>
|
||||
${name}chart.updateSeries([{
|
||||
data: [${stats[name].cpuArray}]
|
||||
}, {
|
||||
data: [${stats[name].ramArray}]
|
||||
}])
|
||||
</script>`
|
||||
res.send(chart);
|
||||
});
|
||||
|
||||
|
||||
|
||||
router.get('/thank', async (req, res) => {
|
||||
thanks++;
|
||||
let data = thanks.toString();
|
||||
if (thanks > 999) {
|
||||
data = 'Did you really click 1000 times?!';
|
||||
}
|
||||
res.send(data);
|
||||
let card = containerCard(install_info);
|
||||
res.send(card);
|
||||
});
|
|
@ -22,7 +22,7 @@
|
|||
</head>
|
||||
<body >
|
||||
|
||||
<div class="page">
|
||||
<div class="page" hx-ext="sse" sse-connect="/sse_event">
|
||||
|
||||
<%- include('navbar.html') %>
|
||||
|
||||
|
@ -137,15 +137,15 @@
|
|||
</div>
|
||||
|
||||
<!-- HTMX -->
|
||||
<div class="col-12" hx-ext="sse" sse-connect="/sse_event">
|
||||
<div class="col-12">
|
||||
<div class="row row-cards" data-hx-get="/containers" data-hx-trigger="load, sse:docker" data-hx-swap="innerHTML">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- HTMX -->
|
||||
<div class="col-12" hx-ext="sse" sse-connect="/sse_event">
|
||||
<div class="row row-cards" data-hx-get="/installing" data-hx-trigger="load, sse:install" data-hx-swap="innerHTML">
|
||||
<div class="col-12">
|
||||
<div class="row row-cards" data-hx-get="/installing" data-hx-trigger="sse:install" data-hx-swap="innerHTML">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -50,9 +50,9 @@
|
|||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
|
||||
<span type="button" class="avatar avatar-md bg-green-lt" hx-trigger="load, click" hx-get="/thank" hx-target="#count" name="MM" title="Micheal M" style="margin-right: 5px;">mm</span>
|
||||
<span type="button" class="avatar avatar-md bg-green-lt" hx-trigger="load, click" hx-post="/thank" hx-target="#count" name="MM" title="Micheal M" style="margin-right: 5px;">mm</span>
|
||||
|
||||
<span type="button" class="avatar avatar-md bg-cyan-lt" hx-trigger="click" hx-get="/thank" hx-target="#count" name="PD" title="Peter D" style="margin-right: 5px;">pd</span>
|
||||
<span type="button" class="avatar avatar-md bg-cyan-lt" hx-trigger="click" hx-post="/thank" hx-target="#count" name="PD" title="Peter D" style="margin-right: 5px;">pd</span>
|
||||
|
||||
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue