From 676c80984f616091c39afb94f9068a0e15ce9636 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 24 Jun 2026 01:19:40 +1000 Subject: [PATCH] control: show instance identity (who/version/activation) + delete button Renders applicant label/email, activation state and lease expiry per instance (was id-only), and a Delete button (DELETE /admin/licenses/:id) to clear dead test instances. Co-Authored-By: Claude Opus 4.8 --- public/views/control.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/public/views/control.js b/public/views/control.js index ca76a8d..92c01cc 100644 --- a/public/views/control.js +++ b/public/views/control.js @@ -200,14 +200,31 @@ async function renderInstances(panel) { const n = parseInt(d, 10); if (Number.isFinite(n) && n !== 0) patch({ extend_days: n }, `extended +${n}d`); })); + // Hard delete — clears a dead/test instance + its record (vs Revoke, which keeps it). + actions.appendChild(btn('Delete', async () => { + const who = l.label || l.email || `#${l.id}`; + if (!confirm(`Permanently delete "${who}" and its record? This cannot be undone.`)) return; + try { await api.del(`${A}/licenses/${l.id}`); renderInstances(panel); } + catch (e) { notify(msg, e.message || 'delete failed', false); } + }, 'ghost')); + + // Status cell: pill + activation state + lease expiry (more than just "active"). + const statusCell = [ + statusPill(l.status), + el('div', { class: 'muted', style: { fontSize: '0.68rem', marginTop: '0.15rem' } }, + l.claimed ? 'activated' : 'awaiting activation'), + ]; + if (l.expires_at) statusCell.push( + el('div', { class: 'muted', style: { fontSize: '0.68rem' } }, `lease ends ${fmtTime(l.expires_at)}`)); return el('tr', {}, - td(el('strong', {}, l.label || l.email || `#${l.id}`), el('div', { class: 'muted', style: { fontSize: '0.72rem' } }, l.email || '')), + td(el('strong', {}, l.label || l.email || `#${l.id}`), + el('div', { class: 'muted', style: { fontSize: '0.72rem' } }, l.email && l.label ? l.email : `instance #${l.id}`)), td(groupSel), - td(statusPill(l.status)), + td(...statusCell), td(tierSel), td(String(l.lease_days ?? '—')), - td(l.version || '—'), + td(l.version || el('span', { class: 'muted' }, 'unknown')), td(el('span', { class: 'muted', style: { fontSize: '0.72rem' } }, fmtTime(l.last_seen || l.last_seen_at))), td(actions, msg)); });