aktueller stand

This commit is contained in:
2025-12-15 16:49:37 +01:00
parent b71d99b048
commit 1555dc02e9
3 changed files with 47 additions and 8 deletions

View File

@@ -1,10 +1,11 @@
FROM node:18-alpine
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
RUN apk add --no-cache python3 make g++ \
&& npm install --production
COPY . .
@@ -12,4 +13,4 @@ RUN mkdir -p /app/data
EXPOSE 3000
CMD ["node", "server.js"]
CMD ["node", "server.js"]

View File

@@ -5,6 +5,7 @@ const { v4: uuidv4 } = require('uuid');
const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const os = require('os');
const app = express();
const PORT = process.env.PORT || 3000;
@@ -6000,6 +6001,22 @@ app.get('/health', (req, res) => {
startAutomationWorker();
function logRuntimeInfo() {
let osPretty = '';
try {
const raw = fs.readFileSync('/etc/os-release', 'utf8');
const match = raw.match(/^PRETTY_NAME="?(.*?)"?$/m);
if (match && match[1]) {
osPretty = match[1];
}
} catch (error) {
// ignore
}
const osInfo = osPretty || `${os.platform()} ${os.release()}`;
console.log(`Runtime: Node ${process.version}, OS ${osInfo}`);
}
app.listen(PORT, '0.0.0.0', () => {
logRuntimeInfo();
console.log(`Server running on port ${PORT}`);
});

View File

@@ -86,6 +86,7 @@
let sortState = { key: 'next', dir: 'asc' };
let listInstance = null;
let sse = null;
let relativeTimer = null;
function toDateTimeLocal(value) {
if (!value) return '';
@@ -509,6 +510,20 @@
`;
}
function updateRelativeTimes() {
renderHero();
if (!requestTableBody || !state.requests.length) return;
const byId = new Map(state.requests.map((req) => [String(req.id), req]));
requestTableBody.querySelectorAll('tr[data-id]').forEach((row) => {
const req = byId.get(row.dataset.id);
if (!req) return;
const nextEl = row.querySelector('.next');
if (nextEl) nextEl.textContent = formatRelative(req.next_run_at);
const lastEl = row.querySelector('.last');
if (lastEl) lastEl.textContent = formatRelative(req.last_run_at);
});
}
function renderRequests() {
if (!requestTableBody) return;
requestTableBody.innerHTML = '';
@@ -946,10 +961,7 @@
function initListInstance() {
const container = document.getElementById('automationTable');
if (!container) return;
if (listInstance) {
listInstance.remove();
listInstance = null;
}
listInstance = null;
const options = {
listClass: 'list',
valueNames: [
@@ -968,7 +980,6 @@
applyFilters();
listInstance.sort(sortState.key, { order: sortState.dir === 'desc' ? 'desc' : 'asc' });
updateSortIndicators();
listInstance.on('updated', updateSortIndicators);
}
function applyFilters() {
@@ -996,6 +1007,7 @@
return matchName && matchNext && matchLast && matchStatus && matchRuns;
});
updateSortIndicators();
}
function getSelectedRequest() {
@@ -1135,6 +1147,15 @@
applyPresetDisabling();
resetForm();
loadRequests();
if (!relativeTimer) {
updateRelativeTimes();
relativeTimer = setInterval(updateRelativeTimes, 60000);
document.addEventListener('visibilitychange', () => {
if (!document.hidden) {
updateRelativeTimes();
}
});
}
form.addEventListener('submit', handleSubmit);
intervalPreset.addEventListener('change', applyPresetDisabling);