Check Update
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
// ─── 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);
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user