aboutsummaryrefslogtreecommitdiff
path: root/src/zenserver/frontend/html/compute/compute.html
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-03-09 17:43:08 +0100
committerGitHub Enterprise <[email protected]>2026-03-09 17:43:08 +0100
commitb37b34ea6ad906f54e8104526e77ba66aed997da (patch)
treee80ce17d666aff6d2f0d73d4977128ffb4055476 /src/zenserver/frontend/html/compute/compute.html
parentadd fallback for zencache multirange (#816) (diff)
downloadzen-b37b34ea6ad906f54e8104526e77ba66aed997da.tar.xz
zen-b37b34ea6ad906f54e8104526e77ba66aed997da.zip
Dashboard overhaul, compute integration (#814)
- **Frontend dashboard overhaul**: Unified compute/main dashboards into a single shared UI. Added new pages for cache, projects, metrics, sessions, info (build/runtime config, system stats). Added live-update via WebSockets with pause control, sortable detail tables, themed styling. Refactored compute/hub/orchestrator pages into modular JS. - **HTTP server fixes and stats**: Fixed http.sys local-only fallback when default port is in use, implemented root endpoint redirect for http.sys, fixed Linux/Mac port reuse. Added /stats endpoint exposing HTTP server metrics (bytes transferred, request rates). Added WebSocket stats tracking. - **OTEL/diagnostics hardening**: Improved OTLP HTTP exporter with better error handling and resilience. Extended diagnostics services configuration. - **Session management**: Added new sessions service with HTTP endpoints for registering, updating, querying, and removing sessions. Includes session log file support. This is still WIP. - **CLI subcommand support**: Added support for commands with subcommands in the zen CLI tool, with improved command dispatch. - **Misc**: Exposed CPU usage/hostname to frontend, fixed JS compact binary float32/float64 decoding, limited projects displayed on front page to 25 sorted by last access, added vscode:// link support. Also contains some fixes from TSAN analysis.
Diffstat (limited to 'src/zenserver/frontend/html/compute/compute.html')
-rw-r--r--src/zenserver/frontend/html/compute/compute.html327
1 files changed, 92 insertions, 235 deletions
diff --git a/src/zenserver/frontend/html/compute/compute.html b/src/zenserver/frontend/html/compute/compute.html
index 1e101d839..66c20175f 100644
--- a/src/zenserver/frontend/html/compute/compute.html
+++ b/src/zenserver/frontend/html/compute/compute.html
@@ -5,101 +5,13 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Zen Compute Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
- <script src="banner.js" defer></script>
- <script src="nav.js" defer></script>
+ <link rel="stylesheet" type="text/css" href="../zen.css" />
+ <script src="../theme.js"></script>
+ <script src="../banner.js" defer></script>
+ <script src="../nav.js" defer></script>
<style>
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
-
- body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
- background: #0d1117;
- color: #c9d1d9;
- padding: 20px;
- }
-
- .container {
- max-width: 1400px;
- margin: 0 auto;
- }
-
- h1 {
- font-size: 32px;
- font-weight: 600;
- margin-bottom: 10px;
- color: #f0f6fc;
- }
-
- .header {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 30px;
- }
-
- .health-indicator {
- display: flex;
- align-items: center;
- gap: 8px;
- font-size: 14px;
- padding: 8px 16px;
- border-radius: 6px;
- background: #161b22;
- border: 1px solid #30363d;
- }
-
- .health-indicator .status-dot {
- width: 10px;
- height: 10px;
- border-radius: 50%;
- background: #6e7681;
- }
-
- .health-indicator.healthy .status-dot {
- background: #3fb950;
- }
-
- .health-indicator.unhealthy .status-dot {
- background: #f85149;
- }
-
.grid {
- display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
- gap: 20px;
- margin-bottom: 30px;
- }
-
- .card {
- background: #161b22;
- border: 1px solid #30363d;
- border-radius: 6px;
- padding: 20px;
- }
-
- .card-title {
- font-size: 14px;
- font-weight: 600;
- color: #8b949e;
- margin-bottom: 12px;
- text-transform: uppercase;
- letter-spacing: 0.5px;
- }
-
- .metric-value {
- font-size: 36px;
- font-weight: 600;
- color: #f0f6fc;
- line-height: 1;
- }
-
- .metric-label {
- font-size: 12px;
- color: #8b949e;
- margin-top: 4px;
}
.chart-container {
@@ -113,7 +25,7 @@
justify-content: space-between;
margin-bottom: 12px;
padding: 8px 0;
- border-bottom: 1px solid #21262d;
+ border-bottom: 1px solid var(--theme_border_subtle);
}
.stats-row:last-child {
@@ -122,12 +34,12 @@
}
.stats-label {
- color: #8b949e;
+ color: var(--theme_g1);
font-size: 13px;
}
.stats-value {
- color: #f0f6fc;
+ color: var(--theme_bright);
font-weight: 600;
font-size: 13px;
}
@@ -146,77 +58,39 @@
.rate-value {
font-size: 20px;
font-weight: 600;
- color: #58a6ff;
+ color: var(--theme_p0);
}
.rate-label {
font-size: 11px;
- color: #8b949e;
+ color: var(--theme_g1);
margin-top: 4px;
text-transform: uppercase;
}
- .progress-bar {
- width: 100%;
- height: 8px;
- background: #21262d;
- border-radius: 4px;
- overflow: hidden;
- margin-top: 8px;
- }
-
- .progress-fill {
- height: 100%;
- background: #58a6ff;
- transition: width 0.3s ease;
- }
-
- .timestamp {
- font-size: 12px;
- color: #6e7681;
- text-align: right;
- margin-top: 30px;
- }
-
- .error {
- color: #f85149;
- padding: 12px;
- background: #1c1c1c;
- border-radius: 6px;
- margin: 20px 0;
- font-size: 13px;
- }
-
- .section-title {
- font-size: 20px;
- font-weight: 600;
- margin-bottom: 20px;
- color: #f0f6fc;
- }
-
.worker-row {
cursor: pointer;
transition: background 0.15s;
}
.worker-row:hover {
- background: #1c2128;
+ background: var(--theme_p4);
}
.worker-row.selected {
- background: #1f2d3d;
+ background: var(--theme_p3);
}
.worker-detail {
margin-top: 20px;
- border-top: 1px solid #30363d;
+ border-top: 1px solid var(--theme_g2);
padding-top: 16px;
}
.worker-detail-title {
font-size: 15px;
font-weight: 600;
- color: #f0f6fc;
+ color: var(--theme_bright);
margin-bottom: 12px;
}
@@ -227,7 +101,7 @@
.detail-section-label {
font-size: 11px;
font-weight: 600;
- color: #8b949e;
+ color: var(--theme_g1);
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 6px;
@@ -241,13 +115,13 @@
.detail-table td {
padding: 4px 8px;
- color: #c9d1d9;
- border-bottom: 1px solid #21262d;
+ color: var(--theme_g0);
+ border-bottom: 1px solid var(--theme_border_subtle);
vertical-align: top;
}
.detail-table td:first-child {
- color: #8b949e;
+ color: var(--theme_g1);
width: 40%;
font-family: monospace;
}
@@ -259,42 +133,25 @@
.detail-mono {
font-family: monospace;
font-size: 11px;
- color: #8b949e;
+ color: var(--theme_g1);
}
.detail-tag {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
- background: #21262d;
- color: #c9d1d9;
+ background: var(--theme_border_subtle);
+ color: var(--theme_g0);
font-size: 11px;
margin: 2px 4px 2px 0;
}
-
- .status-badge {
- display: inline-block;
- padding: 2px 8px;
- border-radius: 4px;
- font-size: 11px;
- font-weight: 600;
- }
-
- .status-badge.success {
- background: rgba(63, 185, 80, 0.15);
- color: #3fb950;
- }
-
- .status-badge.failure {
- background: rgba(248, 81, 73, 0.15);
- color: #f85149;
- }
</style>
</head>
<body>
- <div class="container">
- <zen-banner cluster-status="nominal" load="0" tagline="Node Overview"></zen-banner>
+ <div class="container" style="max-width: 1400px; margin: 0 auto;">
+ <zen-banner cluster-status="nominal" load="0" tagline="Node Overview" logo-src="../favicon.ico"></zen-banner>
<zen-nav>
+ <a href="/dashboard/">Home</a>
<a href="compute.html">Node</a>
<a href="orchestrator.html">Orchestrator</a>
</zen-nav>
@@ -369,15 +226,15 @@
<span class="stats-value" id="worker-count">-</span>
</div>
<div id="worker-table-container" style="margin-top: 16px; display: none;">
- <table id="worker-table" style="width: 100%; border-collapse: collapse; font-size: 13px;">
+ <table id="worker-table">
<thead>
<tr>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Name</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Platform</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Cores</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Timeout</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Functions</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Worker ID</th>
+ <th>Name</th>
+ <th>Platform</th>
+ <th style="text-align: right;">Cores</th>
+ <th style="text-align: right;">Timeout</th>
+ <th style="text-align: right;">Functions</th>
+ <th>Worker ID</th>
</tr>
</thead>
<tbody id="worker-table-body"></tbody>
@@ -390,19 +247,19 @@
<div class="section-title">Queues</div>
<div class="card" style="margin-bottom: 30px;">
<div class="card-title">Queue Status</div>
- <div id="queue-list-empty" style="color: #6e7681; font-size: 13px;">No queues.</div>
+ <div id="queue-list-empty" class="empty-state" style="text-align: left;">No queues.</div>
<div id="queue-list-container" style="display: none;">
- <table id="queue-list-table" style="width: 100%; border-collapse: collapse; font-size: 13px;">
+ <table id="queue-list-table">
<thead>
<tr>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 60px;">ID</th>
- <th style="text-align: center; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 80px;">Status</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Active</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Completed</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Failed</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Abandoned</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Cancelled</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Token</th>
+ <th style="text-align: right; width: 60px;">ID</th>
+ <th style="text-align: center; width: 80px;">Status</th>
+ <th style="text-align: right;">Active</th>
+ <th style="text-align: right;">Completed</th>
+ <th style="text-align: right;">Failed</th>
+ <th style="text-align: right;">Abandoned</th>
+ <th style="text-align: right;">Cancelled</th>
+ <th>Token</th>
</tr>
</thead>
<tbody id="queue-list-body"></tbody>
@@ -414,20 +271,20 @@
<div class="section-title">Recent Actions</div>
<div class="card" style="margin-bottom: 30px;">
<div class="card-title">Action History</div>
- <div id="action-history-empty" style="color: #6e7681; font-size: 13px;">No actions recorded yet.</div>
+ <div id="action-history-empty" class="empty-state" style="text-align: left;">No actions recorded yet.</div>
<div id="action-history-container" style="display: none;">
- <table id="action-history-table" style="width: 100%; border-collapse: collapse; font-size: 13px;">
+ <table id="action-history-table">
<thead>
<tr>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 60px;">LSN</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 60px;">Queue</th>
- <th style="text-align: center; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 70px;">Status</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Function</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 80px;">Started</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 80px;">Finished</th>
- <th style="text-align: right; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px; width: 80px;">Duration</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Worker ID</th>
- <th style="text-align: left; color: #8b949e; padding: 6px 8px; border-bottom: 1px solid #30363d; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; font-size: 11px;">Action ID</th>
+ <th style="text-align: right; width: 60px;">LSN</th>
+ <th style="text-align: right; width: 60px;">Queue</th>
+ <th style="text-align: center; width: 70px;">Status</th>
+ <th>Function</th>
+ <th style="text-align: right; width: 80px;">Started</th>
+ <th style="text-align: right; width: 80px;">Finished</th>
+ <th style="text-align: right; width: 80px;">Duration</th>
+ <th>Worker ID</th>
+ <th>Action ID</th>
</tr>
</thead>
<tbody id="action-history-body"></tbody>
@@ -766,7 +623,7 @@
// Functions
const functions = desc.functions || [];
- const functionsHtml = functions.length === 0 ? '<span style="color:#6e7681;font-size:12px;">none</span>' :
+ const functionsHtml = functions.length === 0 ? '<span style="color:var(--theme_faint);font-size:12px;">none</span>' :
`<table class="detail-table">${functions.map(f =>
`<tr><td>${escapeHtml(f.name || '-')}</td><td class="detail-mono">${escapeHtml(f.version || '-')}</td></tr>`
).join('')}</table>`;
@@ -774,12 +631,12 @@
// Executables
const executables = desc.executables || [];
const totalExecSize = executables.reduce((sum, e) => sum + (e.size || 0), 0);
- const execHtml = executables.length === 0 ? '<span style="color:#6e7681;font-size:12px;">none</span>' :
+ const execHtml = executables.length === 0 ? '<span style="color:var(--theme_faint);font-size:12px;">none</span>' :
`<table class="detail-table">
<tr style="font-size:11px;">
- <td style="color:#6e7681;padding-bottom:4px;">Path</td>
- <td style="color:#6e7681;padding-bottom:4px;">Hash</td>
- <td style="color:#6e7681;padding-bottom:4px;text-align:right;">Size</td>
+ <td style="color:var(--theme_faint);padding-bottom:4px;">Path</td>
+ <td style="color:var(--theme_faint);padding-bottom:4px;">Hash</td>
+ <td style="color:var(--theme_faint);padding-bottom:4px;text-align:right;">Size</td>
</tr>
${executables.map(e =>
`<tr>
@@ -788,28 +645,28 @@
<td style="text-align:right;white-space:nowrap;">${e.size != null ? formatBytes(e.size) : '-'}</td>
</tr>`
).join('')}
- <tr style="border-top:1px solid #30363d;">
- <td style="color:#8b949e;padding-top:6px;">Total</td>
+ <tr style="border-top:1px solid var(--theme_g2);">
+ <td style="color:var(--theme_g1);padding-top:6px;">Total</td>
<td></td>
- <td style="text-align:right;white-space:nowrap;padding-top:6px;color:#f0f6fc;font-weight:600;">${formatBytes(totalExecSize)}</td>
+ <td style="text-align:right;white-space:nowrap;padding-top:6px;color:var(--theme_bright);font-weight:600;">${formatBytes(totalExecSize)}</td>
</tr>
</table>`;
// Files
const files = desc.files || [];
- const filesHtml = files.length === 0 ? '<span style="color:#6e7681;font-size:12px;">none</span>' :
+ const filesHtml = files.length === 0 ? '<span style="color:var(--theme_faint);font-size:12px;">none</span>' :
`<table class="detail-table">${files.map(f =>
`<tr><td>${escapeHtml(f.name || f)}</td><td class="detail-mono">${escapeHtml(f.hash || '')}</td></tr>`
).join('')}</table>`;
// Dirs
const dirs = desc.dirs || [];
- const dirsHtml = dirs.length === 0 ? '<span style="color:#6e7681;font-size:12px;">none</span>' :
+ const dirsHtml = dirs.length === 0 ? '<span style="color:var(--theme_faint);font-size:12px;">none</span>' :
dirs.map(d => `<span class="detail-tag">${escapeHtml(d)}</span>`).join('');
// Environment
const env = desc.environment || [];
- const envHtml = env.length === 0 ? '<span style="color:#6e7681;font-size:12px;">none</span>' :
+ const envHtml = env.length === 0 ? '<span style="color:var(--theme_faint);font-size:12px;">none</span>' :
env.map(e => `<span class="detail-tag">${escapeHtml(e)}</span>`).join('');
panel.innerHTML = `
@@ -880,16 +737,16 @@
const timeout = desc ? (desc.timeout != null ? desc.timeout + 's' : '-') : '-';
const functions = desc ? (desc.functions ? desc.functions.length : 0) : '-';
- const tr = document.createElement('tr');
+ const tr = document.createElement('tr');
tr.className = 'worker-row' + (id === selectedWorkerId ? ' selected' : '');
tr.dataset.workerId = id;
tr.innerHTML = `
- <td style="padding: 6px 8px; color: #f0f6fc; border-bottom: 1px solid #21262d;">${escapeHtml(name)}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d;">${escapeHtml(host)}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d; text-align: right;">${escapeHtml(String(cores))}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d; text-align: right;">${escapeHtml(String(timeout))}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d; text-align: right;">${escapeHtml(String(functions))}</td>
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; font-family: monospace; font-size: 11px;">${escapeHtml(id)}</td>
+ <td style="color: var(--theme_bright);">${escapeHtml(name)}</td>
+ <td>${escapeHtml(host)}</td>
+ <td style="text-align: right;">${escapeHtml(String(cores))}</td>
+ <td style="text-align: right;">${escapeHtml(String(timeout))}</td>
+ <td style="text-align: right;">${escapeHtml(String(functions))}</td>
+ <td style="color: var(--theme_g1); font-family: monospace; font-size: 11px;">${escapeHtml(id)}</td>
`;
tr.addEventListener('click', () => {
document.querySelectorAll('.worker-row').forEach(r => r.classList.remove('selected'));
@@ -963,24 +820,24 @@
const badge = q.state === 'cancelled'
? '<span class="status-badge failure">cancelled</span>'
: q.state === 'draining'
- ? '<span class="status-badge" style="background:rgba(210,153,34,0.15);color:#d29922;">draining</span>'
+ ? '<span class="status-badge" style="background:color-mix(in srgb, var(--theme_warn) 15%, transparent);color:var(--theme_warn);">draining</span>'
: q.is_complete
? '<span class="status-badge success">complete</span>'
- : '<span class="status-badge" style="background:rgba(88,166,255,0.15);color:#58a6ff;">active</span>';
+ : '<span class="status-badge" style="background:color-mix(in srgb, var(--theme_p0) 15%, transparent);color:var(--theme_p0);">active</span>';
const token = q.queue_token
? `<span class="detail-mono">${escapeHtml(q.queue_token)}</span>`
- : '<span style="color:#6e7681;">-</span>';
+ : '<span style="color:var(--theme_faint);">-</span>';
const tr = document.createElement('tr');
tr.innerHTML = `
- <td style="padding: 6px 8px; color: #f0f6fc; border-bottom: 1px solid #21262d; text-align: right; font-family: monospace;">${escapeHtml(String(id))}</td>
- <td style="padding: 6px 8px; border-bottom: 1px solid #21262d; text-align: center;">${badge}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d; text-align: right;">${q.active_count ?? 0}</td>
- <td style="padding: 6px 8px; color: #3fb950; border-bottom: 1px solid #21262d; text-align: right;">${q.completed_count ?? 0}</td>
- <td style="padding: 6px 8px; color: #f85149; border-bottom: 1px solid #21262d; text-align: right;">${q.failed_count ?? 0}</td>
- <td style="padding: 6px 8px; color: #d29922; border-bottom: 1px solid #21262d; text-align: right;">${q.abandoned_count ?? 0}</td>
- <td style="padding: 6px 8px; color: #f0883e; border-bottom: 1px solid #21262d; text-align: right;">${q.cancelled_count ?? 0}</td>
- <td style="padding: 6px 8px; border-bottom: 1px solid #21262d;">${token}</td>
+ <td style="text-align: right; font-family: monospace; color: var(--theme_bright);">${escapeHtml(String(id))}</td>
+ <td style="text-align: center;">${badge}</td>
+ <td style="text-align: right;">${q.active_count ?? 0}</td>
+ <td style="text-align: right; color: var(--theme_ok);">${q.completed_count ?? 0}</td>
+ <td style="text-align: right; color: var(--theme_fail);">${q.failed_count ?? 0}</td>
+ <td style="text-align: right; color: var(--theme_warn);">${q.abandoned_count ?? 0}</td>
+ <td style="text-align: right; color: var(--theme_warn);">${q.cancelled_count ?? 0}</td>
+ <td>${token}</td>
`;
tbody.appendChild(tr);
}
@@ -1010,7 +867,7 @@
const lsn = entry.lsn ?? '-';
const succeeded = entry.succeeded;
const badge = succeeded == null
- ? '<span class="status-badge" style="background:#21262d;color:#8b949e;">unknown</span>'
+ ? '<span class="status-badge" style="background:var(--theme_border_subtle);color:var(--theme_g1);">unknown</span>'
: succeeded
? '<span class="status-badge success">ok</span>'
: '<span class="status-badge failure">failed</span>';
@@ -1024,20 +881,20 @@
const queueId = entry.queueId || 0;
const queueCell = queueId
- ? `<a href="/compute/queues/${queueId}" style="color: #58a6ff; text-decoration: none; font-family: monospace;">${escapeHtml(String(queueId))}</a>`
- : '<span style="color: #6e7681;">-</span>';
+ ? `<a href="/compute/queues/${queueId}" style="color: var(--theme_ln); text-decoration: none; font-family: monospace;">${escapeHtml(String(queueId))}</a>`
+ : '<span style="color: var(--theme_faint);">-</span>';
const tr = document.createElement('tr');
tr.innerHTML = `
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; text-align: right; font-family: monospace;">${escapeHtml(String(lsn))}</td>
- <td style="padding: 6px 8px; border-bottom: 1px solid #21262d; text-align: right;">${queueCell}</td>
- <td style="padding: 6px 8px; border-bottom: 1px solid #21262d; text-align: center;">${badge}</td>
- <td style="padding: 6px 8px; color: #f0f6fc; border-bottom: 1px solid #21262d;">${escapeHtml(fn)}</td>
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; text-align: right; font-size: 12px; white-space: nowrap;">${formatTime(startDate)}</td>
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; text-align: right; font-size: 12px; white-space: nowrap;">${formatTime(endDate)}</td>
- <td style="padding: 6px 8px; color: #c9d1d9; border-bottom: 1px solid #21262d; text-align: right; font-size: 12px; white-space: nowrap;">${formatDuration(startDate, endDate)}</td>
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; font-family: monospace; font-size: 11px;">${escapeHtml(workerId)}</td>
- <td style="padding: 6px 8px; color: #8b949e; border-bottom: 1px solid #21262d; font-family: monospace; font-size: 11px;">${escapeHtml(actionId)}</td>
+ <td style="text-align: right; font-family: monospace; color: var(--theme_g1);">${escapeHtml(String(lsn))}</td>
+ <td style="text-align: right;">${queueCell}</td>
+ <td style="text-align: center;">${badge}</td>
+ <td style="color: var(--theme_bright);">${escapeHtml(fn)}</td>
+ <td style="text-align: right; font-size: 12px; white-space: nowrap; color: var(--theme_g1);">${formatTime(startDate)}</td>
+ <td style="text-align: right; font-size: 12px; white-space: nowrap; color: var(--theme_g1);">${formatTime(endDate)}</td>
+ <td style="text-align: right; font-size: 12px; white-space: nowrap;">${formatDuration(startDate, endDate)}</td>
+ <td style="font-family: monospace; font-size: 11px; color: var(--theme_g1);">${escapeHtml(workerId)}</td>
+ <td style="font-family: monospace; font-size: 11px; color: var(--theme_g1);">${escapeHtml(actionId)}</td>
`;
tbody.appendChild(tr);
}