Split style.css and app.js into modular CSS/JS files under css/ and js/ directories
Agent-Logs-Url: https://github.com/naturallaw777/staging_alpha/sessions/50712b31-5843-45c4-a8f1-3952656b636c Co-authored-by: naturallaw777 <99053422+naturallaw777@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2493777a42
commit
815b195600
120
app/sovran_systemsos_web/static/js/update.js
Normal file
120
app/sovran_systemsos_web/static/js/update.js
Normal file
@@ -0,0 +1,120 @@
|
||||
"use strict";
|
||||
|
||||
// ── Update modal ──────────────────────────────────────────────────
|
||||
|
||||
function openUpdateModal() {
|
||||
if (!$modal) return;
|
||||
_updateLog = "";
|
||||
_updateLogOffset = 0;
|
||||
_serverWasDown = false;
|
||||
_updateFinished = false;
|
||||
if ($modalLog) $modalLog.textContent = "";
|
||||
if ($modalStatus) $modalStatus.textContent = "Starting update…";
|
||||
if ($modalSpinner) $modalSpinner.classList.add("spinning");
|
||||
if ($btnReboot) $btnReboot.style.display = "none";
|
||||
if ($btnSave) $btnSave.style.display = "none";
|
||||
if ($btnCloseModal) $btnCloseModal.disabled = true;
|
||||
$modal.classList.add("open");
|
||||
startUpdate();
|
||||
}
|
||||
|
||||
function closeUpdateModal() {
|
||||
if (!$modal) return;
|
||||
$modal.classList.remove("open");
|
||||
stopUpdatePoll();
|
||||
}
|
||||
|
||||
function appendLog(text) {
|
||||
if (!text) return;
|
||||
_updateLog += text;
|
||||
if ($modalLog) { $modalLog.textContent += text; $modalLog.scrollTop = $modalLog.scrollHeight; }
|
||||
}
|
||||
|
||||
function startUpdate() {
|
||||
fetch("/api/updates/run", { method: "POST" })
|
||||
.then(function(response) {
|
||||
if (!response.ok) return response.text().then(function(t) { throw new Error(t); });
|
||||
return response.json();
|
||||
})
|
||||
.then(function(data) {
|
||||
if (data.status === "already_running") appendLog("[Update already in progress, attaching…]\n\n");
|
||||
if ($modalStatus) $modalStatus.textContent = "Updating…";
|
||||
startUpdatePoll();
|
||||
})
|
||||
.catch(function(err) {
|
||||
appendLog("[Error: failed to start update — " + err + "]\n");
|
||||
onUpdateDone(false);
|
||||
});
|
||||
}
|
||||
|
||||
function startUpdatePoll() {
|
||||
pollUpdateStatus();
|
||||
_updatePollTimer = setInterval(pollUpdateStatus, UPDATE_POLL_INTERVAL);
|
||||
}
|
||||
|
||||
function stopUpdatePoll() {
|
||||
if (_updatePollTimer) { clearInterval(_updatePollTimer); _updatePollTimer = null; }
|
||||
}
|
||||
|
||||
async function pollUpdateStatus() {
|
||||
if (_updateFinished) return;
|
||||
try {
|
||||
var data = await apiFetch("/api/updates/status?offset=" + _updateLogOffset);
|
||||
if (_serverWasDown) { _serverWasDown = false; appendLog("[Server reconnected]\n"); if ($modalStatus) $modalStatus.textContent = "Updating…"; }
|
||||
if (data.log) appendLog(data.log);
|
||||
_updateLogOffset = data.offset;
|
||||
if (data.running) return;
|
||||
_updateFinished = true;
|
||||
stopUpdatePoll();
|
||||
if (data.result === "success") onUpdateDone(true);
|
||||
else onUpdateDone(false);
|
||||
} catch (err) {
|
||||
if (!_serverWasDown) { _serverWasDown = true; appendLog("\n[Server restarting — waiting for it to come back…]\n"); if ($modalStatus) $modalStatus.textContent = "Server restarting…"; }
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdateDone(success) {
|
||||
if ($modalSpinner) $modalSpinner.classList.remove("spinning");
|
||||
if ($btnCloseModal) $btnCloseModal.disabled = false;
|
||||
if (success) {
|
||||
if ($modalStatus) $modalStatus.textContent = "✓ Update complete";
|
||||
if ($btnReboot) $btnReboot.style.display = "inline-flex";
|
||||
} else {
|
||||
if ($modalStatus) $modalStatus.textContent = "✗ Update failed";
|
||||
if ($btnSave) $btnSave.style.display = "inline-flex";
|
||||
if ($btnReboot) $btnReboot.style.display = "inline-flex";
|
||||
}
|
||||
}
|
||||
|
||||
function saveErrorReport() {
|
||||
var blob = new Blob([_updateLog], { type: "text/plain" });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = "sovran-update-error-" + new Date().toISOString().split(".")[0].replace(/:/g, "-") + ".txt";
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
// ── Reboot ────────────────────────────────────────────────────────
|
||||
|
||||
function doReboot() {
|
||||
if ($modal) $modal.classList.remove("open");
|
||||
if ($rebuildModal) $rebuildModal.classList.remove("open");
|
||||
stopUpdatePoll();
|
||||
stopRebuildPoll();
|
||||
if ($rebootOverlay) $rebootOverlay.classList.add("visible");
|
||||
fetch("/api/reboot", { method: "POST" }).catch(function() {});
|
||||
setTimeout(waitForServerReboot, REBOOT_CHECK_INTERVAL);
|
||||
}
|
||||
|
||||
function waitForServerReboot() {
|
||||
fetch("/api/config", { cache: "no-store" })
|
||||
.then(function(res) {
|
||||
if (res.ok) window.location.reload();
|
||||
else setTimeout(waitForServerReboot, REBOOT_CHECK_INTERVAL);
|
||||
})
|
||||
.catch(function() { setTimeout(waitForServerReboot, REBOOT_CHECK_INTERVAL); });
|
||||
}
|
||||
Reference in New Issue
Block a user