fix(diarization-ui): make job runtime counter tick every second (fallback + live list)
This commit is contained in:
24
app.py
24
app.py
@@ -801,7 +801,7 @@ def jobs_page(queued: Optional[int] = None):
|
|||||||
items = _jobs_payload(200)
|
items = _jobs_payload(200)
|
||||||
pre = "".join([
|
pre = "".join([
|
||||||
(
|
(
|
||||||
f"<div class='card'><b>Job #{it['id']}</b> [{it['kind']}] · <b>{it['status']}</b> · läuft: {_fmt_elapsed(it.get('started_at') or it.get('created_at'), it.get('finished_at'))}<br>"
|
f"<div class='card'><b>Job #{it['id']}</b> [{it['kind']}] · <b>{it['status']}</b> · läuft: <span class='elapsed' data-start='{(it.get('started_at') or it.get('created_at') or '')}' data-end='{(it.get('finished_at') or '')}'>{_fmt_elapsed(it.get('started_at') or it.get('created_at'), it.get('finished_at'))}</span><br>"
|
||||||
f"<small>{it['created_at']}</small><br>"
|
f"<small>{it['created_at']}</small><br>"
|
||||||
f"<div class='row' style='margin-top:8px'>"
|
f"<div class='row' style='margin-top:8px'>"
|
||||||
+ (
|
+ (
|
||||||
@@ -834,13 +834,21 @@ def jobs_page(queued: Optional[int] = None):
|
|||||||
<div id='jobs-status' class='hint'>Live-Update aktiv …</div>
|
<div id='jobs-status' class='hint'>Live-Update aktiv …</div>
|
||||||
<div id='jobs-root'>{pre}</div>
|
<div id='jobs-root'>{pre}</div>
|
||||||
<script>
|
<script>
|
||||||
function since(ts) {{
|
function since(ts, endTs=null) {{
|
||||||
if(!ts) return '-';
|
if(!ts) return '-';
|
||||||
const s = Math.floor((Date.now()-Date.parse(ts))/1000);
|
const end = endTs ? Date.parse(endTs) : Date.now();
|
||||||
|
const s = Math.max(0, Math.floor((end-Date.parse(ts))/1000));
|
||||||
if (s<60) return s+'s';
|
if (s<60) return s+'s';
|
||||||
const m = Math.floor(s/60); if (m<60) return m+'m '+(s%60)+'s';
|
const m = Math.floor(s/60); if (m<60) return m+'m '+(s%60)+'s';
|
||||||
const h = Math.floor(m/60); return h+'h '+(m%60)+'m';
|
const h = Math.floor(m/60); return h+'h '+(m%60)+'m';
|
||||||
}}
|
}}
|
||||||
|
function tickElapsed() {{
|
||||||
|
document.querySelectorAll('.elapsed').forEach(el => {{
|
||||||
|
const start = el.getAttribute('data-start') || '';
|
||||||
|
const end = el.getAttribute('data-end') || '';
|
||||||
|
el.textContent = since(start, end || null);
|
||||||
|
}});
|
||||||
|
}}
|
||||||
async function post(url) {{
|
async function post(url) {{
|
||||||
const r = await fetch(url, {{method:'POST'}});
|
const r = await fetch(url, {{method:'POST'}});
|
||||||
if(!r.ok) alert('Fehler '+r.status);
|
if(!r.ok) alert('Fehler '+r.status);
|
||||||
@@ -859,13 +867,16 @@ async function renderJobs() {{
|
|||||||
actions.push("<a href='#' class='iconbtn' onclick=\"deleteJob("+it.id+");return false;\">🗑️</a>");
|
actions.push("<a href='#' class='iconbtn' onclick=\"deleteJob("+it.id+");return false;\">🗑️</a>");
|
||||||
const result = it.result_document_id ? ("<a href='/document/"+it.result_document_id+"'>Ergebnis öffnen</a>") : '';
|
const result = it.result_document_id ? ("<a href='/document/"+it.result_document_id+"'>Ergebnis öffnen</a>") : '';
|
||||||
const err = it.error ? ("<pre>"+String(it.error).replaceAll('<','<')+"</pre>") : '';
|
const err = it.error ? ("<pre>"+String(it.error).replaceAll('<','<')+"</pre>") : '';
|
||||||
d.innerHTML = "<b>Job #"+it.id+"</b> ["+it.kind+"] · <b>"+it.status+"</b> · läuft: "+since(it.started_at || it.created_at)+"<br><small>"+it.created_at+"</small><br>"
|
const startTs = (it.started_at || it.created_at || '');
|
||||||
|
const endTs = (it.finished_at || '');
|
||||||
|
d.innerHTML = "<b>Job #"+it.id+"</b> ["+it.kind+"] · <b>"+it.status+"</b> · läuft: <span class='elapsed' data-start='"+startTs+"' data-end='"+endTs+"'>"+since(startTs, endTs || null)+"</span><br><small>"+it.created_at+"</small><br>"
|
||||||
+(it.project_name?('Projekt: '+it.project_name+'<br>'):'')
|
+(it.project_name?('Projekt: '+it.project_name+'<br>'):'')
|
||||||
+(it.document_title?('Dokument: '+it.document_title+'<br>'):'')
|
+(it.document_title?('Dokument: '+it.document_title+'<br>'):'')
|
||||||
+(it.prompt_name?('Prompt: '+it.prompt_name+'<br>'):'')
|
+(it.prompt_name?('Prompt: '+it.prompt_name+'<br>'):'')
|
||||||
+"<div class='row' style='margin-top:8px'>"+actions.join(' ')+" "+result+"</div>"+err;
|
+"<div class='row' style='margin-top:8px'>"+actions.join(' ')+" "+result+"</div>"+err;
|
||||||
root.appendChild(d);
|
root.appendChild(d);
|
||||||
}}
|
}}
|
||||||
|
tickElapsed();
|
||||||
document.getElementById('jobs-status').textContent = 'Live-Update aktiv';
|
document.getElementById('jobs-status').textContent = 'Live-Update aktiv';
|
||||||
}} catch(e) {{
|
}} catch(e) {{
|
||||||
document.getElementById('jobs-status').textContent = 'Live-Update Fehler: '+e;
|
document.getElementById('jobs-status').textContent = 'Live-Update Fehler: '+e;
|
||||||
@@ -873,7 +884,10 @@ async function renderJobs() {{
|
|||||||
}}
|
}}
|
||||||
async function cancelJob(id) {{ if(!confirm('Job abbrechen?')) return; await post('/jobs/'+id+'/cancel'); renderJobs(); }}
|
async function cancelJob(id) {{ if(!confirm('Job abbrechen?')) return; await post('/jobs/'+id+'/cancel'); renderJobs(); }}
|
||||||
async function deleteJob(id) {{ if(!confirm('Job löschen?')) return; await post('/jobs/'+id+'/delete'); renderJobs(); }}
|
async function deleteJob(id) {{ if(!confirm('Job löschen?')) return; await post('/jobs/'+id+'/delete'); renderJobs(); }}
|
||||||
renderJobs(); setInterval(renderJobs, 5000);
|
renderJobs();
|
||||||
|
tickElapsed();
|
||||||
|
setInterval(tickElapsed, 1000);
|
||||||
|
setInterval(renderJobs, 5000);
|
||||||
</script>
|
</script>
|
||||||
"""
|
"""
|
||||||
return layout("Jobs", body)
|
return layout("Jobs", body)
|
||||||
|
|||||||
Reference in New Issue
Block a user