Working install cards and fixes for dashboard.js

This commit is contained in:
lllllllillllllillll 2024-03-18 17:14:47 -07:00
parent 8b8e30772f
commit 5c6e2a9eaa
6 changed files with 64 additions and 19 deletions

View file

@ -8,7 +8,6 @@
* Dynamically generated avatars.
* Updated database models.
* Persistent Database.
* Removed automatic volume creation.
## v0.40 (Feb 26th 2024) - HTMX rewrite
* Pages rewritten to use HTMX.

View file

@ -105,6 +105,10 @@ async function createCard (details) {
state_color = 'orange';
trigger = 'data-hx-trigger="load"';
break;
case 'installing':
state_color = 'blue';
trigger = 'data-hx-trigger="load"';
break;
}
// if (name.startsWith('dweebui')) { disable = 'disabled=""'; }
let card = readFileSync('./views/partials/containerCard.html', 'utf8');
@ -124,6 +128,30 @@ let [ cardList, newCards, containersArray, sentArray, updatesArray ] = [ '', '',
let hidden = await Container.findAll({ where: {visibility:false}});
hidden = hidden.map((container) => container.name);
export async function addCard (name, state) {
console.log(`Adding card for ${name}: ${state}`);
let details = {
name: name,
image: name,
service: name,
state: 'installing',
external_port: 0,
internal_port: 0,
ports: [],
link: 'localhost',
}
createCard(details).then(card => {
cardList += card;
});
}
// HTMX server-side events
export const SSE = (req, res) => {
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
@ -180,7 +208,7 @@ export const SSE = (req, res) => {
sentArray = containersArray.slice();
}
}, 1000);
}, 500);
req.on('close', () => {
@ -211,14 +239,6 @@ export const Chart = async (req, res) => {
res.send(chart);
}
export const Installs = async (req, res) => {
let name = req.header('hx-trigger-name');
let all_containers = '';
res.send('ok');
}
export const updateCards = async (req, res) => {
console.log('updateCards called');
res.send(newCards);
@ -232,13 +252,21 @@ export const Containers = async (req, res) => {
export const Card = async (req, res) => {
let name = req.header('hx-trigger-name');
console.log(`Updated card for ${name}`);
console.log(`${name} requesting updated card`);
// return nothing if in hidden or not found in containersArray
if (hidden.includes(name) || !containersArray.find(c => c.container === name)) {
res.send('');
return;
} else {
let details = await containerInfo(name);
let card = await createCard(details);
res.send(card);
}
}
function status (state) {
let status = `<span class="text-yellow align-items-center lh-1">
<svg xmlns="http://www.w3.org/2000/svg" class="icon-tabler icon-tabler-point-filled" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"> <path stroke="none" d="M0 0h24v24H0z" fill="none"></path> <path d="M12 7a5 5 0 1 1 -4.995 5.217l-.005 -.217l.005 -.217a5 5 0 0 1 4.995 -4.783z" stroke-width="0" fill="currentColor"></path></svg>
@ -322,6 +350,10 @@ export const Action = async (req, res) => {
} else if ((action == 'pause') && (state == 'paused')) {
var containerName = docker.getContainer(name);
containerName.unpause();
res.send(status('starting'));
} else if ((action == 'pause') && (state == 'running')) {
var containerName = docker.getContainer(name);
containerName.pause();
res.send(status('pausing'));
// Restart
} else if (action == 'restart') {

View file

@ -4,6 +4,7 @@ import { execSync } from "child_process";
import { docker } from "../server.js";
import DockerodeCompose from "dockerode-compose";
import { Syslog } from "../database/models.js";
import { addCard } from "../controllers/dashboard.js";
// This entire page hurts to look at.
export const Install = async (req, res) => {
@ -20,6 +21,8 @@ export const Install = async (req, res) => {
let docker_volumes = [];
addCard(name, 'installing');
if (image.startsWith('https://')){
mkdirSync(`./appdata/${name}`, { recursive: true });
execSync(`curl -o ./appdata/${name}/${name}_stack.yml -L ${image}`);
@ -89,6 +92,13 @@ export const Install = async (req, res) => {
compose_file += `\n - ${data[`volume_${i}_bind`]}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
}
// if bind is empty create a docker volume (ex container_name_config:/config) convert any '/' in container name to '_'
else if ((data[`volume${i}`] == 'on') && (data[`volume_${i}_bind`] == '') && (data[`volume_${i}_container`] != '')) {
let volume_name = data[`volume_${i}_container`].replace(/\//g, '_');
compose_file += `\n - ${name}_${volume_name}:${data[`volume_${i}_container`]}:${data[`volume_${i}_readwrite`]}`
docker_volumes.push(`${name}_${volume_name}`);
}
}
// Environment variables

View file

@ -10,7 +10,8 @@ export const Uninstall = async (req, res) => {
if (confirm == 'Yes') {
var containerName = docker.getContainer(`${service_name}`);
let containerName = docker.getContainer(service_name);
console.log(`Stopping ${service_name}...`)
try {
await containerName.stop();
} catch {
@ -18,6 +19,7 @@ export const Uninstall = async (req, res) => {
}
try {
console.log(`Removing ${service_name}...`);
containerName.remove();
const syslog = await Syslog.create({
@ -38,7 +40,10 @@ export const Uninstall = async (req, res) => {
ip: req.socket.remoteAddress
});
}
} else {
console.log(`Didn't confirm uninstallation of ${service_name}...`);
}
res.redirect('/');
}

View file

@ -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, Logs, Modals, Stats, Chart, Installs, SSE, Card, updateCards, Containers, Action } from "../controllers/dashboard.js";
import { Dashboard, Logs, Modals, Stats, Chart, SSE, Card, updateCards, Containers, Action } from "../controllers/dashboard.js";
import { Apps, appSearch, InstallModal, LearnMore } from "../controllers/apps.js";
import { Users } from "../controllers/users.js";
import { Images, removeImage } from "../controllers/images.js";
@ -34,7 +34,6 @@ router.get("/logs", auth, Logs);
router.get("/modals", auth, Modals);
router.get("/stats", auth, Stats);
router.get("/chart", auth, Chart);
router.get("/installs", auth, Installs);
router.get("/sse_event", auth, SSE);
router.get("/containers", auth, Containers);
router.get("/card", auth, Card);

View file

@ -48,7 +48,7 @@
</div>
</div>
<div class="d-flex align-items-baseline">
<div class="h1 me-2" title="AppName">
<div class="h1 me-2" title="AppName" style="margin-bottom: 0;">
<a href="http://${link}:${external_port}" target="_blank">
AppShortName
</a>