Files
docker-images/python-tools/static/app.js
T
2026-08-09 01:24:06 +00:00

105 lines
3.1 KiB
JavaScript

const output = document.querySelector("#run-output");
if (output) {
const refresh = async () => {
const response = await fetch(output.dataset.outputUrl, { cache: "no-store" });
if (response.ok) {
output.textContent = (await response.json()).output;
}
const status = document.querySelector("#run-status");
if (status) {
const stateResponse = await fetch(status.dataset.stateUrl, { cache: "no-store" });
if (stateResponse.ok) {
status.textContent = (await stateResponse.json()).status;
}
}
};
refresh();
window.setInterval(refresh, 2000);
}
for (const form of document.querySelectorAll("form[data-wait-for-result]")) {
const result = form.querySelector(".task-result");
const controls = [...form.querySelectorAll("input, select, button")];
let waiting = false;
const warnBeforeLeaving = (event) => {
event.preventDefault();
event.returnValue = "";
};
const setWaiting = (value) => {
waiting = value;
form.classList.toggle("is-waiting", value);
controls.forEach((control) => {
control.disabled = value;
});
if (value) {
window.addEventListener("beforeunload", warnBeforeLeaving);
} else {
window.removeEventListener("beforeunload", warnBeforeLeaving);
}
};
const showResult = (message, kind, detailUrl) => {
result.replaceChildren();
result.className = `task-result ${kind}`;
result.append(message);
if (detailUrl) {
const link = document.createElement("a");
link.href = detailUrl;
link.textContent = "View details";
result.append(" ", link);
}
};
const waitForRun = async (run) => {
while (true) {
const response = await fetch(run.state_url, { cache: "no-store" });
if (!response.ok) {
throw new Error("Could not read task status.");
}
const state = await response.json();
if (state.status !== "queued" && state.status !== "running") {
if (state.status === "succeeded") {
showResult("Completed successfully.", "succeeded", run.detail_url);
} else {
showResult(`Finished with status: ${state.status}.`, "failed", run.detail_url);
}
return;
}
await new Promise((resolve) => window.setTimeout(resolve, 500));
}
};
form.addEventListener("submit", async (event) => {
if (waiting) {
event.preventDefault();
return;
}
if (!form.reportValidity()) {
return;
}
event.preventDefault();
setWaiting(true);
showResult("Running...", "running");
try {
const response = await fetch(form.action, {
method: "POST",
body: new FormData(form),
headers: { Accept: "application/json" },
});
const data = await response.json();
if (!response.ok) {
const messages = data.errors ? Object.values(data.errors).join(" ") : "Could not start task.";
throw new Error(messages);
}
await waitForRun(data);
} catch (error) {
showResult(error instanceof Error ? error.message : "Could not run task.", "failed");
} finally {
setWaiting(false);
}
});
}