diff --git a/static/js/admin.js b/static/js/admin.js index cbc3871..ff992eb 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -170,53 +170,45 @@ export async function startAdminWatches() { safe(r.name), safe(r.node), badge(safe(r.status), /running|online|started/i.test(r.status) ? 'ok' : 'dark'), - `
- - - - + `
+ + + +
`, - ``, - `` + ``, + `` ])); setRows(tbody, htmlRows); // wire per-row - Array.from(tbody.querySelectorAll('tr[data-sid]')).forEach(function(tr){ - const nodeCell = tr.children[3]; - const targetSel = qSel(tr, '.target-node'); - const currentNode = text(nodeCell).trim(); - rebuildTargetSelect(targetSel, currentNode, availableNodes); - updateMigrateButton(tr, /running|online|started/i.test(tr.children[4].innerText)); + // (replaced by delegated handler below) + // delegated events for reliability + tbody.addEventListener('click', async function(ev){ + const t = ev.target; + const tr = t && t.closest ? t.closest('tr[data-sid]') : null; + if (!tr) return; const sid = tr.getAttribute('data-sid'); const nameCell = tr.children[2]; - + const targetSel = tr.querySelector('.target-node'); async function doAction(kind, needsTarget) { try { - const targetNode = needsTarget ? val(targetSel) : undefined; + const targetNode = needsTarget ? (targetSel ? targetSel.value : undefined) : undefined; activeSids.add(sid); setBadgeCell(tr.children[4], 'working'); updateMigrateButton(tr, false); const res = await api.vmAction(sid, kind, targetNode); - if (res && res.ok) { - showToast(`Task ${kind} started for ${safe(text(nameCell))}`); - } else { - showToast(`Task ${kind} failed for ${safe(text(nameCell))}`, 'danger'); - } - } catch (e) { - showToast(`Error: ${e && e.message ? e.message : e}`, 'danger'); - } + if (res && res.ok) { showToast(`Task ${kind} started for ${safe(nameCell.textContent)}`); } + else { showToast(`Task ${kind} failed for ${safe(nameCell.textContent)}`, 'danger'); } + } catch(e) { showToast(`Error: ${e && e.message ? e.message : e}`, 'danger'); } } - - const bStart = qSel(tr, '.act-start'); if (bStart) bStart.addEventListener('click', function(){ doAction('start'); }); - const bStop = qSel(tr, '.act-stop'); if (bStop) bStop.addEventListener('click', function(){ doAction('stop'); }); - const bShut = qSel(tr, '.act-shutdown'); if (bShut) bShut.addEventListener('click', function(){ doAction('shutdown'); }); - const bUnl = qSel(tr, '.act-unlock'); if (bUnl) bUnl.addEventListener('click', function(){ doAction('unlock'); }); - const bMig = qSel(tr, '.act-migrate'); if (bMig) bMig.addEventListener('click', function(){ doAction('migrate', true); }); - - ensureWatchOn(); + if (t.matches && t.matches('.act-start')) return doAction('start'); + if (t.matches && t.matches('.act-stop')) return doAction('stop'); + if (t.matches && t.matches('.act-shutdown')) return doAction('shutdown'); + if (t.matches && t.matches('.act-unlock')) return doAction('unlock'); + if (t.matches && t.matches('.act-migrate')) return doAction('migrate', true); }); window.__nodesCache = availableNodes.slice();