home: add Containers + Cluster cards, fix Editor link, extend loadStats
This commit is contained in:
parent
0c761d553c
commit
879c547e08
1 changed files with 85 additions and 3 deletions
|
|
@ -234,6 +234,14 @@
|
|||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="6" cy="10" r="3.5"/><path d="M8.7 7.3L13 3M11.5 3.5l1.5 1.5M13.5 2.5l1 1"/></svg>
|
||||
Tokens
|
||||
</a>
|
||||
<a href="containers.html" class="nav-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1" y="5" width="14" height="4" rx="1"/><rect x="1" y="10" width="14" height="4" rx="1"/><path d="M4 7h1M4 12h1"/></svg>
|
||||
Containers
|
||||
</a>
|
||||
<a href="cluster.html" class="nav-item">
|
||||
<svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="8" cy="8" r="2"/><circle cx="2" cy="3" r="1.5"/><circle cx="14" cy="3" r="1.5"/><circle cx="2" cy="13" r="1.5"/><circle cx="14" cy="13" r="1.5"/><path d="M3.1 4.1L6.5 6.5M12.9 4.1L9.5 6.5M3.1 11.9L6.5 9.5M12.9 11.9L9.5 9.5"/></svg>
|
||||
Cluster
|
||||
</a>
|
||||
</nav>
|
||||
<div class="sidebar-footer">
|
||||
<div class="sidebar-user">
|
||||
|
|
@ -366,7 +374,7 @@
|
|||
<div class="home-card-desc">DeckLink SDI capture with manual scene control and per-device routing.</div>
|
||||
</a>
|
||||
|
||||
<a href="edit.html" class="home-card">
|
||||
<a href="editor.html" class="home-card">
|
||||
<div class="home-card-title">Editor</div>
|
||||
<div class="home-card-preview">
|
||||
<svg class="preview-art" viewBox="0 0 200 125" xmlns="http://www.w3.org/2000/svg">
|
||||
|
|
@ -410,6 +418,66 @@
|
|||
<div class="home-card-desc">Track proxy generation, thumbnails, and AMPP folder sync as they run.</div>
|
||||
</a>
|
||||
|
||||
<a href="containers.html" class="home-card">
|
||||
<div class="home-card-title">Containers</div>
|
||||
<div class="home-card-preview">
|
||||
<svg class="preview-art" viewBox="0 0 200 125" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="200" height="125" fill="oklch(13% 0.02 250)"/>
|
||||
<!-- stacked container boxes -->
|
||||
<g fill="oklch(20% 0.04 260)" stroke="oklch(45% 0.10 266 / 0.45)" stroke-width="0.6">
|
||||
<rect x="20" y="18" width="160" height="22" rx="3"/>
|
||||
<rect x="20" y="46" width="160" height="22" rx="3"/>
|
||||
<rect x="20" y="74" width="160" height="22" rx="3"/>
|
||||
<rect x="20" y="102" width="160" height="16" rx="3"/>
|
||||
</g>
|
||||
<!-- status dots -->
|
||||
<circle cx="34" cy="29" r="3.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="34" cy="57" r="3.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="34" cy="85" r="3.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="34" cy="110" r="3.5" fill="oklch(62% 0.22 25)"/>
|
||||
<!-- label bars -->
|
||||
<rect x="46" y="25" width="60" height="5" rx="2" fill="oklch(50% 0.12 266 / 0.7)"/>
|
||||
<rect x="46" y="53" width="80" height="5" rx="2" fill="oklch(50% 0.12 266 / 0.7)"/>
|
||||
<rect x="46" y="81" width="50" height="5" rx="2" fill="oklch(50% 0.12 266 / 0.7)"/>
|
||||
<rect x="46" y="107" width="70" height="4" rx="2" fill="oklch(40% 0.10 266 / 0.5)"/>
|
||||
</svg>
|
||||
<span class="home-card-stats"><span class="home-card-stats-dot"></span><b id="containerCount">--</b> running</span>
|
||||
</div>
|
||||
<div class="home-card-desc">Manage Docker Compose services — start, stop, and restart containers.</div>
|
||||
</a>
|
||||
|
||||
<a href="cluster.html" class="home-card">
|
||||
<div class="home-card-title">Cluster</div>
|
||||
<div class="home-card-preview">
|
||||
<svg class="preview-art" viewBox="0 0 200 125" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="0" y="0" width="200" height="125" fill="oklch(13% 0.02 250)"/>
|
||||
<!-- hub -->
|
||||
<circle cx="100" cy="62" r="10" fill="oklch(20% 0.04 260)" stroke="oklch(55% 0.20 266 / 0.7)" stroke-width="1"/>
|
||||
<circle cx="100" cy="62" r="4" fill="oklch(70% 0.18 266)"/>
|
||||
<!-- spokes -->
|
||||
<line x1="100" y1="62" x2="36" y2="22" stroke="oklch(45% 0.12 266 / 0.4)" stroke-width="1"/>
|
||||
<line x1="100" y1="62" x2="164" y2="22" stroke="oklch(45% 0.12 266 / 0.4)" stroke-width="1"/>
|
||||
<line x1="100" y1="62" x2="24" y2="80" stroke="oklch(45% 0.12 266 / 0.4)" stroke-width="1"/>
|
||||
<line x1="100" y1="62" x2="176" y2="80" stroke="oklch(45% 0.12 266 / 0.4)" stroke-width="1"/>
|
||||
<line x1="100" y1="62" x2="100" y2="108" stroke="oklch(45% 0.12 266 / 0.4)" stroke-width="1"/>
|
||||
<!-- satellite nodes -->
|
||||
<circle cx="36" cy="22" r="7" fill="oklch(18% 0.03 260)" stroke="oklch(45% 0.10 266 / 0.5)" stroke-width="0.6"/>
|
||||
<circle cx="164" cy="22" r="7" fill="oklch(18% 0.03 260)" stroke="oklch(45% 0.10 266 / 0.5)" stroke-width="0.6"/>
|
||||
<circle cx="24" cy="80" r="7" fill="oklch(18% 0.03 260)" stroke="oklch(45% 0.10 266 / 0.5)" stroke-width="0.6"/>
|
||||
<circle cx="176" cy="80" r="7" fill="oklch(18% 0.03 260)" stroke="oklch(45% 0.10 266 / 0.5)" stroke-width="0.6"/>
|
||||
<circle cx="100" cy="108" r="7" fill="oklch(18% 0.03 260)" stroke="oklch(45% 0.10 266 / 0.5)" stroke-width="0.6"/>
|
||||
<!-- online dots -->
|
||||
<circle cx="36" cy="22" r="2.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="164" cy="22" r="2.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="24" cy="80" r="2.5" fill="oklch(62% 0.22 145)"/>
|
||||
<circle cx="176" cy="80" r="2.5" fill="oklch(55% 0.18 80)"/>
|
||||
<circle cx="100" cy="108" r="2.5" fill="oklch(45% 0.10 266 / 0.4)"/>
|
||||
</svg>
|
||||
<span class="home-card-stats"><span class="home-card-stats-dot"></span><b id="nodeCount">--</b> nodes</span>
|
||||
</div>
|
||||
<div class="home-card-desc">Multi-server cluster registry. Monitor, federate, and scale Z-AMPP nodes.</div>
|
||||
</a>
|
||||
|
||||
<a href="tokens.html" class="home-card" title="Just kidding">
|
||||
<div class="home-card-title">Tokens</div>
|
||||
<div class="home-card-preview">
|
||||
|
|
@ -441,11 +509,13 @@
|
|||
async function loadStats() {
|
||||
const setText = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val; };
|
||||
try {
|
||||
const [aRes, pRes, rRes, jRes] = await Promise.allSettled([
|
||||
const [aRes, pRes, rRes, jRes, cRes, nRes] = await Promise.allSettled([
|
||||
fetch('/api/v1/assets?limit=1', { credentials: 'include' }),
|
||||
fetch('/api/v1/projects', { credentials: 'include' }),
|
||||
fetch('/api/v1/recorders', { credentials: 'include' }),
|
||||
fetch('/api/v1/jobs?status=active', { credentials: 'include' }),
|
||||
fetch('/api/v1/system/containers', { credentials: 'include' }),
|
||||
fetch('/api/v1/cluster', { credentials: 'include' }),
|
||||
]);
|
||||
|
||||
if (aRes.status === 'fulfilled' && aRes.value.ok) {
|
||||
|
|
@ -469,7 +539,19 @@
|
|||
setText('jobCount', arr.length);
|
||||
setText('ingestCount', arr.filter(x => (x.type || '').toLowerCase().includes('proxy')).length || arr.length);
|
||||
}
|
||||
const tb = document.getElementById('tokenBurn'); if (tb) { tb.textContent = (14000 + Math.round(Math.random() * 8000)).toLocaleString(); }
|
||||
if (cRes.status === 'fulfilled' && cRes.value.ok) {
|
||||
const j = await cRes.value.json();
|
||||
const arr = Array.isArray(j) ? j : (j.containers ?? []);
|
||||
const running = arr.filter(c => c.state === 'running').length;
|
||||
setText('containerCount', running);
|
||||
}
|
||||
if (nRes.status === 'fulfilled' && nRes.value.ok) {
|
||||
const j = await nRes.value.json();
|
||||
const arr = Array.isArray(j) ? j : (j.nodes ?? []);
|
||||
const online = arr.filter(n => n.online).length;
|
||||
setText('nodeCount', arr.length > 0 ? online + '/' + arr.length : '--');
|
||||
}
|
||||
const tb = document.getElementById('tokenBurn'); if (tb) { tb.textContent = (14000 + Math.round(Math.random() * 8000)).toLocaleString(); }
|
||||
} catch (_) { /* leave dashes */ }
|
||||
}
|
||||
loadStats();
|
||||
|
|
|
|||
Loading…
Reference in a new issue