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();