Update button — popup progress modal, polls for version confirmation, live cell update

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 01:45:52 +00:00
parent 0469b31829
commit 7dc457562b
+72
View File
@@ -2172,10 +2172,82 @@ function wToast(msg,err=false) {
setTimeout(()=>{t.style.opacity='0';},3000); setTimeout(()=>{t.style.opacity='0';},3000);
} }
async function workerAction(type,id,action) { async function workerAction(type,id,action) {
if (type === 'agent' && action === 'update') {
await agentUpdateFlow(id);
return;
}
const res=await api('worker_action',{worker_type:type,worker_id:id,action}); const res=await api('worker_action',{worker_type:type,worker_id:id,action});
if(res&&res.ok){wToast(res.msg||'Done');setTimeout(loadWorkers,2500);} if(res&&res.ok){wToast(res.msg||'Done');setTimeout(loadWorkers,2500);}
else wToast((res&&res.error)||'Action failed',true); else wToast((res&&res.error)||'Action failed',true);
} }
async function agentUpdateFlow(agentId) {
// Find the current version for this agent from the table
const row = [...document.querySelectorAll('#workers-agents tr')]
.find(r => r.innerHTML.includes(agentId));
const curVerEl = row ? row.querySelector('td:nth-child(5) span') : null;
const curVer = curVerEl ? curVerEl.textContent.replace(/[^0-9.]/g,'').trim() : '?';
// Show modal with live status
openModal(`⬆ UPDATE AGENT — ${agentId}`,
`<div id="upd-status" style="font-size:0.7rem;line-height:2;font-family:var(--mono)">
<div>Dispatching update command...</div>
</div>`, null, null);
document.getElementById('modalSave').style.display = 'none';
const log = (msg, col) => {
const el = document.getElementById('upd-status');
if (el) el.innerHTML += `<div style="color:${col||'var(--text)'}">${msg}</div>`;
};
// Dispatch command
const res = await api('worker_action', {worker_type:'agent', worker_id:agentId, action:'update'});
if (!res || !res.ok) {
log('✗ Failed to dispatch: ' + (res?.error||'unknown'), 'var(--red)');
document.getElementById('modalSave').style.display = '';
document.getElementById('modalSave').textContent = 'CLOSE';
document.getElementById('modalSave').onclick = closeModal;
return;
}
log('✓ Command dispatched — waiting for agent to pick up...', 'var(--cyan)');
// Poll agent_commands for the result (max 90s)
const cmdRes = await api('worker_action', {worker_type:'agent', worker_id:agentId, action:'update_status'}).catch(()=>null);
// Actually poll via workers_list for version change
const deadline = Date.now() + 90000;
let done = false;
while (Date.now() < deadline) {
await new Promise(r => setTimeout(r, 4000));
const wData = await api('workers_list').catch(()=>null);
if (!wData || !wData.agents) break;
const ag = wData.agents.find(a => a.agent_id === agentId);
if (!ag) break;
const newVer = ag.version || null;
const latest = (wData.latest_versions||{})[ag.agent_type] || null;
if (latest && newVer === latest) {
log(`✓ Agent confirmed v${newVer} — up to date!`, 'var(--green)');
// Update the version cell in the table live
if (curVerEl) {
curVerEl.textContent = `v${newVer} ✓`;
curVerEl.style.color = 'var(--green)';
const tdVer = curVerEl.closest('td');
if (tdVer) tdVer.innerHTML = `<span style="color:var(--green);font-size:0.62rem;font-family:var(--mono)">v${newVer} ✓</span>`;
}
done = true;
break;
} else if (newVer && newVer !== curVer) {
log(`↻ Version changed: ${curVer} → ${newVer} (checking if latest...)`, 'var(--yellow)');
} else {
log('· Waiting...', 'var(--text-dim)');
}
}
if (!done) {
log('⚠ Timed out — agent may update in background (self-update runs periodically)', 'var(--yellow)');
}
document.getElementById('modalSave').style.display = '';
document.getElementById('modalSave').textContent = 'CLOSE';
document.getElementById('modalSave').onclick = () => { closeModal(); loadWorkers(); };
}
async function loadWorkers() { async function loadWorkers() {
const d=await api('workers_list'); const d=await api('workers_list');
if(!d||d.error) return; if(!d||d.error) return;