// history.js — история тестов let historyOpen=false; async function toggleHistory(){ const body=document.getElementById('history-body'); historyOpen=!historyOpen; body.style.display=historyOpen?'block':'none'; if(historyOpen) await loadHistory(); } async function loadHistory(){ const body=document.getElementById('history-body'); if(!body||body.style.display==='none') return; try{ const r=await fetch('/api/history'); const rows=await r.json(); if(!rows||!rows.length){body.innerHTML='Нет записей'; return;} let html=''; html+=''; rows.forEach((r, i)=>{ const time=r.created_at?r.created_at.replace('T',' ').substring(0,19):'?'; const cls=r.status==='OK'?'badge-success':r.status==='FAIL'?'badge' :''; const stCls=r.status==='RUNNING'?'background:#fef3c7;':r.status==='FAIL'?'background:#fef2f2;':''; html+=``; html+=``; }); html+='
ВремяОперацияИнстансСтатусДлит.
${time} ${_esc(r.op_name||'?')} ${_esc(r.display_name||r.instance_uid||'?')} ${_esc(r.status||'?')} ${r.duration_sec!=null?r.duration_sec.toFixed(1)+'s':'-'}
'; body.innerHTML=html; }catch(e){body.innerHTML='Ошибка загрузки';} } function toggleHistoryRow(i) { const el = document.getElementById('hist-stages-' + i); if (!el) return; el.style.display = el.style.display === 'none' ? 'table-row' : 'none'; } function renderStages(stages) { if (!stages || !stages.length) return 'Нет данных об этапах'; let html = '
Этапы выполнения
'; stages.forEach(s => { const done = !!s.dtFinish; const icon = done ? (s.isSuccessful ? '✅' : '❌') : '⏳'; const start = s.dtStart ? s.dtStart.replace('T',' ').substring(0,19) : '?'; const finish = s.dtFinish ? s.dtFinish.replace('T',' ').substring(0,19) : '...'; const dur = s.duration != null ? s.duration.toFixed(1) + ' сек' : '—'; html += `
`; html += `${icon} ${_esc(s.stage||'?')}`; html += `${start} → ${finish} (${dur})`; html += `
`; }); return html; }