generated from mathias/template-go-web
feat(atlas): Phase C — recent-runs timeline
A strip of the last 12 runs (aggregate pass/fail/running per run) below the substrate ribbon, coloured, newest-first, run # on hover. Parsed from the same Gitea /actions/tasks fetch (RecentRuns, test-first; State refactored to share the aggregate). No new RBAC. Hidden when no live data. Verified: build/vet/lint(0)/test green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,13 @@
|
||||
.host .k{color:var(--dim);font-size:11px}
|
||||
.host.mesh{border-style:dashed;color:var(--dim)}
|
||||
|
||||
.tl{display:none;gap:5px;align-items:center;flex-wrap:wrap;
|
||||
padding:8px 22px;border-bottom:1px solid var(--line);background:var(--panel)}
|
||||
.tl .lbl{color:var(--dim);font-size:11px;letter-spacing:1.5px;margin-right:4px}
|
||||
.rundot{width:22px;height:16px;border-radius:4px;border:1px solid rgba(0,0,0,.35);
|
||||
display:inline-flex;align-items:center;justify-content:center;
|
||||
font-size:9px;color:#08121f;font-weight:600}
|
||||
|
||||
.scroll{overflow-x:auto;padding:24px 22px 20px}
|
||||
.track{position:relative;display:flex;align-items:flex-start;min-width:max-content}
|
||||
svg.spine{position:absolute;left:0;top:0;z-index:0;pointer-events:none;overflow:visible}
|
||||
@@ -122,6 +129,7 @@
|
||||
</header>
|
||||
|
||||
<div class="substrate" id="substrate"><span class="lbl mono">SUBSTRATE</span></div>
|
||||
<div class="tl mono" id="timeline"></div>
|
||||
|
||||
<div class="scroll">
|
||||
<div class="track" id="track">
|
||||
@@ -154,7 +162,7 @@
|
||||
// stage from the live cd.yml + substrate from the live cluster). These start
|
||||
// empty and are filled by init()'s fetch; on failure the page shows an error
|
||||
// banner rather than stale inline data.
|
||||
let SUBSTRATE=[], NS="", STAGES=[];
|
||||
let SUBSTRATE=[], NS="", STAGES=[], TIMELINE=[];
|
||||
|
||||
const track=document.getElementById('track');
|
||||
let stageEls=[];
|
||||
@@ -181,6 +189,20 @@ function renderAtlas(){
|
||||
});
|
||||
}
|
||||
|
||||
function renderTimeline(){
|
||||
const tl=document.getElementById('timeline');
|
||||
if(!TIMELINE.length){tl.style.display='none';return;}
|
||||
tl.innerHTML='<span class="lbl">RECENT RUNS</span>';
|
||||
TIMELINE.forEach(d=>{
|
||||
const c=d.state==='success'?'var(--green)':(d.state==='failure'?'var(--coral)':'var(--amber)');
|
||||
const el=document.createElement('span');
|
||||
el.className='rundot';el.style.background=c;
|
||||
el.title='run #'+d.number+' · '+d.state;el.textContent=d.number;
|
||||
tl.appendChild(el);
|
||||
});
|
||||
tl.style.display='flex';
|
||||
}
|
||||
|
||||
/* ---- geometry ---- */
|
||||
const spine=document.getElementById('spine'), spinePath=document.getElementById('spinePath'),
|
||||
loopPath=document.getElementById('loopPath'), loopLbl=document.getElementById('loopLbl'),
|
||||
@@ -233,6 +255,7 @@ async function init(){
|
||||
if(Array.isArray(data.substrate)) SUBSTRATE=data.substrate;
|
||||
if(typeof data.ns==='string') NS=data.ns;
|
||||
if(Array.isArray(data.stages)) STAGES=data.stages;
|
||||
if(Array.isArray(data.timeline)) TIMELINE=data.timeline;
|
||||
if(data.version) document.getElementById('ver').textContent=data.version;
|
||||
}catch(e){
|
||||
console.error('atlas: failed to load /api/atlas.json —',e);
|
||||
@@ -243,6 +266,7 @@ async function init(){
|
||||
return;
|
||||
}
|
||||
renderAtlas();
|
||||
renderTimeline();
|
||||
replay();
|
||||
}
|
||||
window.addEventListener('load',init);
|
||||
|
||||
Reference in New Issue
Block a user