v1.6.0 #65
16
js/ui.js
16
js/ui.js
@@ -289,6 +289,10 @@ async function saveInstance() {
|
||||
hardware_acceleration: +document.getElementById('f-hardware-accel').checked,
|
||||
};
|
||||
|
||||
// Snapshot job state before creation — jobs fire immediately after the 201
|
||||
// so the baseline must be captured before the POST, not after.
|
||||
const jobBaseline = !editingVmid ? await _snapshotJobBaseline() : null;
|
||||
|
||||
const result = editingVmid
|
||||
? await updateInstance(editingVmid, data)
|
||||
: await createInstance(data);
|
||||
@@ -298,7 +302,7 @@ async function saveInstance() {
|
||||
showToast(`${name} ${editingVmid ? 'updated' : 'created'}`, 'success');
|
||||
closeModal();
|
||||
|
||||
if (!editingVmid) await _waitForOnCreateJobs();
|
||||
if (jobBaseline) await _waitForOnCreateJobs(jobBaseline);
|
||||
|
||||
if (currentVmid && document.getElementById('page-detail').classList.contains('active')) {
|
||||
await renderDetailPage(vmid);
|
||||
@@ -307,16 +311,18 @@ async function saveInstance() {
|
||||
}
|
||||
}
|
||||
|
||||
async function _waitForOnCreateJobs() {
|
||||
async function _snapshotJobBaseline() {
|
||||
const jobs = await fetch('/api/jobs').then(r => r.json());
|
||||
return new Map(jobs.map(j => [j.id, j.last_run_id ?? null]));
|
||||
}
|
||||
|
||||
async function _waitForOnCreateJobs(baseline) {
|
||||
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));
|
||||
|
||||
Reference in New Issue
Block a user