hyperdex-trainer / web /templates /models.html
GGUFGuy's picture
Duplicate from GGUFGuy/hyperdex-trainer
2a49d9a
Raw History Blame Contribute Delete
2.76 kB
{% extends "base.html" %}
{% set nav = 'models' %}
{% block title %}Models — NanoDex{% endblock %}
{% block body %}
<div class="sect-h" style="margin-bottom:22px">
<div>
<span class="eyebrow">Your models</span>
<h1 style="font-size:28px;margin-top:5px">Everything you've trained</h1>
</div>
<a class="btn primary" href="/train">+ New run</a>
</div>
<div style="display:flex;gap:7px;flex-wrap:wrap;margin-bottom:22px" id="filters">
<button class="btn sm on" data-f="all">All</button>
<button class="btn sm" data-f="running">Training</button>
<button class="btn sm" data-f="queued">Queued</button>
<button class="btn sm" data-f="done">Completed</button>
<button class="btn sm" data-f="other">Failed / cancelled</button>
</div>
<section id="sec-running" style="margin-bottom:32px"></section>
<section id="sec-queued" style="margin-bottom:32px"></section>
<section id="sec-done" style="margin-bottom:32px"></section>
<section id="sec-other"></section>
<div id="none"></div>
{% endblock %}
{% block scripts %}
<script>
let filter = 'all';
document.querySelectorAll('#filters .btn').forEach(b =>
b.addEventListener('click', () => {
document.querySelectorAll('#filters .btn').forEach(x =>
x.classList.remove('primary'));
b.classList.add('primary');
filter = b.dataset.f;
render(last);
}));
document.querySelector('#filters .btn').classList.add('primary');
let last = [];
function section(id, title, note, jobs){
const el = document.getElementById(id);
if(!jobs.length){ el.innerHTML = ''; return 0; }
el.innerHTML = `<div class="sect-h">
<div><h2>${title} <span class="muted" style="font-weight:400">
(${jobs.length})</span></h2>
${note ? `<p class="sub" style="margin-top:3px">${note}</p>` : ''}</div>
</div>
<div class="runs">${jobs.map(NX.runRow).join('')}</div>`;
return jobs.length;
}
function render(jobs){
last = jobs;
const pick = s => (filter==='all' || filter===s) ? jobs.filter(j =>
s==='other' ? (j.status==='failed'||j.status==='cancelled') : j.status===s) : [];
let n = 0;
n += section('sec-running','Training now','Live on a worker right now.', pick('running'));
n += section('sec-queued','In the queue','Waiting for a free worker — oldest first.', pick('queued'));
n += section('sec-done','Completed','Finished. Open one to publish it or generate text.', pick('done'));
n += section('sec-other','Failed or cancelled','', pick('other'));
document.getElementById('none').innerHTML = n ? '' :
`<div class="empty">Nothing here yet.
<a href="/train" style="color:var(--accent)">Train your first model →</a></div>`;
}
NX.poll(async () => render((await NX.get('/api/jobs')).jobs), 4000);
</script>
{% endblock %}