Update Python tools

This commit is contained in:
ajp_anton
2026-08-09 01:24:06 +00:00
parent 0549ed1b0d
commit b0c707d624
8 changed files with 365 additions and 26 deletions
+85
View File
@@ -17,3 +17,88 @@ if (output) {
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);
}
});
}
+36
View File
@@ -97,6 +97,42 @@ button {
padding: .4rem .7rem;
}
button:disabled {
cursor: wait;
}
.spinner {
border: .15em solid currentColor;
border-right-color: transparent;
border-radius: 50%;
display: none;
height: .75em;
margin-left: .35em;
vertical-align: -.05em;
width: .75em;
}
.is-waiting .spinner {
animation: spin .7s linear infinite;
display: inline-block;
}
.task-result {
margin: .5rem 0 0;
}
.task-result.succeeded {
color: #167c3a;
}
.task-result.failed {
color: #b00020;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
dt {
font-weight: 700;
}