v1.6.0 #65

Merged
josh merged 25 commits from dev into main 2026-03-28 21:01:27 -04:00
Showing only changes of commit d88b79e9f0 - Show all commits

View File

@@ -298,6 +298,8 @@ async function saveInstance() {
showToast(`${name} ${editingVmid ? 'updated' : 'created'}`, 'success'); showToast(`${name} ${editingVmid ? 'updated' : 'created'}`, 'success');
closeModal(); closeModal();
if (!editingVmid) await _waitForOnCreateJobs();
if (currentVmid && document.getElementById('page-detail').classList.contains('active')) { if (currentVmid && document.getElementById('page-detail').classList.contains('active')) {
await renderDetailPage(vmid); await renderDetailPage(vmid);
} else { } else {
@@ -305,6 +307,30 @@ async function saveInstance() {
} }
} }
async function _waitForOnCreateJobs() {
const jobs = await fetch('/api/jobs').then(r => r.json());
const relevant = jobs.filter(j => {
try { return JSON.parse(j.config || '{}').run_on_create; } catch { return false; }
});
if (!relevant.length) return;
// Snapshot run IDs before jobs fire so we can detect new completions
const baseline = new Map(relevant.map(j => [j.id, j.last_run_id ?? null]));
const deadline = Date.now() + 30_000;
while (Date.now() < deadline) {
await new Promise(r => setTimeout(r, 500));
const current = await fetch('/api/jobs').then(r => r.json());
const allDone = relevant.every(j => {
const cur = current.find(c => c.id === j.id);
if (!cur) return true;
if (cur.last_run_id === baseline.get(j.id)) return false; // new run not started yet
return cur.last_status !== 'running'; // new run complete
});
if (allDone) return;
}
}
// ── Confirm Dialog ──────────────────────────────────────────────────────────── // ── Confirm Dialog ────────────────────────────────────────────────────────────
function confirmDeleteDialog(inst) { function confirmDeleteDialog(inst) {