Files
jiggablend/web/static/admin.js
Justin Harms 2deb47e5ad Refactor web build process and update documentation
- Removed Node.js build artifacts from .gitignore and adjusted Makefile to reflect changes in web UI build process, now using server-rendered Go templates instead of React.
- Updated README to clarify the new web UI architecture and output formats, emphasizing the removal of the Node.js build step.
- Added a command to set the number of frames per render task in manager configuration, enhancing user control over rendering settings.
- Improved Gitea workflow by removing unnecessary npm install step, streamlining the CI process.
2026-03-12 19:44:40 -05:00

96 lines
3.3 KiB
JavaScript

(function () {
const msgEl = document.getElementById("admin-message");
const errEl = document.getElementById("admin-error");
const saveRegBtn = document.getElementById("save-registration");
const regCheckbox = document.getElementById("registration-enabled");
const createKeyBtn = document.getElementById("create-api-key");
function showMessage(msg) {
msgEl.textContent = msg || "";
msgEl.classList.toggle("hidden", !msg);
}
function showError(msg) {
errEl.textContent = msg || "";
errEl.classList.toggle("hidden", !msg);
}
async function request(url, method, payload) {
const res = await fetch(url, {
method,
credentials: "include",
headers: { "Content-Type": "application/json" },
body: payload ? JSON.stringify(payload) : undefined,
});
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data.error || "Request failed");
return data;
}
function refreshAll() {
if (!window.htmx) return window.location.reload();
htmx.ajax("GET", "/ui/fragments/admin/runners", "#admin-runners");
htmx.ajax("GET", "/ui/fragments/admin/users", "#admin-users");
htmx.ajax("GET", "/ui/fragments/admin/apikeys", "#admin-apikeys");
}
if (saveRegBtn && regCheckbox) {
saveRegBtn.addEventListener("click", async () => {
showError("");
try {
await request("/api/admin/settings/registration", "POST", { enabled: regCheckbox.checked });
showMessage("Registration setting saved.");
} catch (err) {
showError(err.message);
}
});
}
if (createKeyBtn) {
createKeyBtn.addEventListener("click", async () => {
const name = prompt("API key name:");
if (!name) return;
showError("");
try {
const data = await request("/api/admin/runners/api-keys", "POST", { name, scope: "manager" });
showMessage(`New API key created: ${data.key}`);
refreshAll();
} catch (err) {
showError(err.message);
}
});
}
document.body.addEventListener("click", async (e) => {
const deleteRunner = e.target.closest("[data-delete-runner]");
const setAdmin = e.target.closest("[data-set-admin]");
const revokeKey = e.target.closest("[data-revoke-apikey]");
const deleteKey = e.target.closest("[data-delete-apikey]");
if (!deleteRunner && !setAdmin && !revokeKey && !deleteKey) return;
showError("");
try {
if (deleteRunner) {
const id = deleteRunner.getAttribute("data-delete-runner");
if (!confirm("Delete this runner?")) return;
await request(`/api/admin/runners/${id}`, "DELETE");
}
if (setAdmin) {
const id = setAdmin.getAttribute("data-set-admin");
const value = setAdmin.getAttribute("data-admin-value") === "true";
await request(`/api/admin/users/${id}/admin`, "POST", { is_admin: value });
}
if (revokeKey) {
const id = revokeKey.getAttribute("data-revoke-apikey");
await request(`/api/admin/runners/api-keys/${id}/revoke`, "PATCH");
}
if (deleteKey) {
const id = deleteKey.getAttribute("data-delete-apikey");
await request(`/api/admin/runners/api-keys/${id}`, "DELETE");
}
refreshAll();
} catch (err) {
showError(err.message);
}
});
})();