Files
DragonCoreSSH-NewWEB/admin/assets/js/11-update-status.js
T
2026-07-11 02:04:36 -03:00

120 lines
4.4 KiB
JavaScript

// ─── Git update status ───────────────────────────────────────────────────────
const DRAGON_UPDATE_COMMAND = "sudo bash /opt/sshpanel/update.sh";
function updateStatusErrorText(error) {
switch (String(error || "")) {
case "remote update check timed out":
return t("Update check timed out.");
case "could not read the remote Git branch":
return t("Could not reach the Git repository.");
case "current build commit is unavailable":
return t("Current build commit is unavailable.");
default:
return error || t("Unknown update-check error.");
}
}
function setUpdateState(label, tone = "") {
const chip = document.getElementById("updateStateChip");
if (!chip) return;
chip.className = "chip" + (tone ? ` ${tone}` : "");
chip.textContent = label;
}
function setCommitValue(elementID, shortValue, fullValue) {
const el = document.getElementById(elementID);
if (!el) return;
el.textContent = shortValue || "--";
el.title = fullValue || "";
}
function renderUpdateStatus(data) {
setCommitValue("updateCurrentCommit", data.current_commit_short, data.current_commit);
setCommitValue("updateLatestCommit", data.latest_commit_short, data.latest_commit);
const branch = document.getElementById("updateBranch");
if (branch) branch.textContent = data.branch || "main";
const checked = document.getElementById("updateCheckedAt");
if (checked) {
const date = data.checked_at ? new Date(data.checked_at) : null;
checked.textContent = date && Number.isFinite(date.getTime()) ? date.toLocaleString() : "--";
}
const repoLink = document.getElementById("updateRepoLink");
if (repoLink && data.repo_web_url) repoLink.href = data.repo_web_url;
const text = document.getElementById("updateStatusText");
const commandWrap = document.getElementById("updateCommandWrap");
commandWrap?.classList.toggle("hidden", !data.update_available);
if (data.status === "up_to_date") {
setUpdateState(t("Up to date"), "green");
if (text) text.textContent = t("The installed version matches the latest commit on {branch}.", { branch: data.branch || "main" });
return;
}
if (data.status === "update_available") {
setUpdateState(t("Update available"), "warn");
if (text) text.textContent = t("A newer commit is available on {branch}.", { branch: data.branch || "main" });
return;
}
if (data.status === "local_changes") {
setUpdateState(t("Local changes"), "warn");
if (text) text.textContent = t("This build contains local changes, so it cannot be compared safely.");
return;
}
setUpdateState(t("Unknown"), "red");
if (text) {
text.textContent = data.error
? t("Could not check for updates: {error}", { error: updateStatusErrorText(data.error) })
: t("The update status could not be determined.");
}
}
async function loadUpdateStatus(force = false) {
if (currentRole !== "superadmin") return;
const button = document.getElementById("checkUpdateBtn");
const text = document.getElementById("updateStatusText");
if (button) button.disabled = true;
setUpdateState(t("Checking…"));
if (text) text.textContent = t("Checking repository…");
try {
const path = "/api/system/update-status" + (force ? "?refresh=1" : "");
const res = await api(path);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
renderUpdateStatus(await res.json());
} catch (error) {
setUpdateState(t("Unknown"), "red");
if (text) text.textContent = t("Could not check for updates: {error}", { error: error.message || t("Network error.") });
} finally {
if (button) button.disabled = false;
}
}
document.getElementById("checkUpdateBtn")?.addEventListener("click", () => loadUpdateStatus(true));
document.getElementById("copyUpdateCommandBtn")?.addEventListener("click", async () => {
try {
await navigator.clipboard.writeText(DRAGON_UPDATE_COMMAND);
} catch {
const input = document.createElement("textarea");
input.value = DRAGON_UPDATE_COMMAND;
input.style.position = "fixed";
input.style.opacity = "0";
document.body.appendChild(input);
input.select();
document.execCommand("copy");
input.remove();
}
const button = document.getElementById("copyUpdateCommandBtn");
if (button) {
const oldText = button.textContent;
button.textContent = t("Copied");
setTimeout(() => { button.textContent = oldText; }, 1400);
}
});