46 lines
3.9 KiB
JavaScript
46 lines
3.9 KiB
JavaScript
(() => {
|
|
'use strict';
|
|
const $=id=>document.getElementById(id);
|
|
let csrf='',selected=null,latest=null, busy=false;
|
|
const message=(txt,ok=false,id='dvMessage')=>{let e=$(id);e.textContent=txt;e.classList.toggle('ok',ok);};
|
|
async function fetchJson(url,options={}){
|
|
const r=await fetch(url,{credentials:'same-origin',cache:'no-store',...options});
|
|
const d=await r.json().catch(()=>({}));
|
|
if(!r.ok)throw Error(d.error || 'Erreur HTTP '+r.status);
|
|
return d;
|
|
}
|
|
async function auth(){
|
|
const d=await fetchJson('/api/control/auth');csrf=d.csrf||'';
|
|
$('dvLoginBox').hidden=!!d.authenticated;$('dvApp').hidden=!d.authenticated;
|
|
if(d.authenticated)await refresh();
|
|
}
|
|
async function getName(){try{const r=await fetchJson('/api/alfred/identity/name');let n=r.name||'Assistant';$('dvName').textContent=n;$('dvInitial').textContent=Array.from(n)[0]?.toLocaleUpperCase('fr-FR')||'A';document.title='Maintenance · '+n;}catch(_){}}
|
|
function renderTasks(tasks){$('dvCount').textContent=tasks.length+' propositions';const host=$('dvTasks');host.replaceChildren();
|
|
if(!tasks.length){let p=document.createElement('p');p.className='dv-muted';p.textContent='Aucune proposition pour le moment.';host.append(p);return;}
|
|
for(const t of tasks){let btn=document.createElement('button');btn.type='button';btn.className='dv-task'+(selected===t.id?' selected':'');
|
|
let strong=document.createElement('strong');strong.textContent=t.title;let small=document.createElement('small');small.textContent=t.id+' · '+t.status+' · '+t.changed.length+' fichier(s)';btn.append(strong,small);btn.addEventListener('click',()=>select(t.id));host.append(btn);}
|
|
}
|
|
async function refresh(){const r=await fetchJson('/api/control/developer/tasks');renderTasks(r.tasks);if(selected)await select(selected,false);}
|
|
async function select(id,again=true){selected=id;const d=await fetchJson('/api/control/developer/tasks/'+id);latest=d.task;
|
|
$('dvEmpty').hidden=true;$('dvSelected').hidden=false;$('dvTitle').textContent=latest.title;
|
|
$('dvState').textContent=latest.status;$('dvMeta').textContent='Proposition '+id+' · '+latest.changed.length+' fichier(s) · '+latest.created_at;
|
|
$('dvDiff').textContent=latest.diff||'Aucun changement détecté.';
|
|
const c=$('dvChecks');c.replaceChildren();for(const t of latest.checks||[]){let div=document.createElement('div');div.className='dv-check'+(t.ok?'':' fail');div.textContent=(t.ok?'✓ ':'✗ ')+t.file+' — '+t.detail;c.append(div);}
|
|
if(!c.childNodes.length)c.textContent='Contrôles pas encore réalisés.';
|
|
$('dvActions').hidden=latest.status!=='pending';$('dvNext').hidden=latest.status!=='approved';
|
|
$('dvCommand').textContent='sudo python3 /opt/alfred/app/tools/alfred_deploy.py deploy '+id+' --apply';
|
|
if(again)await refresh();
|
|
}
|
|
async function decide(decision){if(!latest||busy)return;const desc=decision==='approve'?'approuver':'refuser';
|
|
if(!confirm('Confirmer : '+desc+' la proposition '+latest.id+' ?'))return;
|
|
busy=true;try{const id=latest.id;const d=await fetchJson('/api/control/developer/tasks/'+id+'/decision',{
|
|
method:'POST',headers:{'Content-Type':'application/json','X-Alfred-CSRF':csrf},body:JSON.stringify({decision,diff_sha256:latest.diff_sha256})
|
|
});message('Décision enregistrée : '+d.result.status,true);await select(id);}catch(e){message(e.message);}finally{busy=false;}
|
|
}
|
|
$('dvLogin').addEventListener('submit',async e=>{e.preventDefault();try{await fetchJson('/api/control/login',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({password:$('dvPassword').value})});$('dvPassword').value='';await auth();}catch(err){message(err.message,false,'dvLoginInfo');}});
|
|
$('dvRefresh').addEventListener('click',()=>refresh().catch(err=>message(err.message)));
|
|
$('dvApprove').addEventListener('click',()=>decide('approve'));
|
|
$('dvReject').addEventListener('click',()=>decide('reject'));
|
|
getName();auth().catch(e=>{$('dvLoginBox').hidden=false;message(e.message,false,'dvLoginInfo');});
|
|
})();
|