Working install cards and fixes for dashboard.js
This commit is contained in:
parent
8b8e30772f
commit
5c6e2a9eaa
6 changed files with 64 additions and 19 deletions
|
@ -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.
|
||||
|
|
|
@ -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') {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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('/');
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Reference in a new issue