Files
cmroubao/backend-api/internal/transport/webui/static/admin.js
T

123 lines
4.2 KiB
JavaScript
Raw Normal View History

(() => {
"use strict";
const focusError = document.querySelector("[data-error-field]");
if (focusError) {
focusError.focus();
} else {
const summary = document.querySelector("[data-error-summary]");
if (summary) summary.focus();
}
const passwordToggle = document.querySelector("[data-password-toggle]");
if (passwordToggle) {
const password = document.getElementById(
passwordToggle.getAttribute("aria-controls"),
);
passwordToggle.addEventListener("click", () => {
const showing = password.type === "text";
password.type = showing ? "password" : "text";
passwordToggle.textContent = showing ? "显示" : "隐藏";
passwordToggle.setAttribute("aria-pressed", String(!showing));
});
}
document.querySelectorAll("[data-loading-form]").forEach((form) => {
form.addEventListener("submit", () => {
form.setAttribute("aria-busy", "true");
const button = form.querySelector("button[type='submit']");
if (!button) return;
button.disabled = true;
button.textContent = button.dataset.loadingLabel || "正在加载…";
});
});
document.querySelectorAll("[data-submit-form]").forEach((form) => {
form.addEventListener("submit", () => {
form.dataset.submitting = "true";
const button = form.querySelector("[data-submit-button]");
if (!button) return;
button.disabled = true;
button.textContent = button.dataset.loadingLabel || "正在提交…";
});
});
const fileInput = document.querySelector("input[type='file'][name='image']");
const image = document.querySelector("[data-image-preview]");
const placeholder = document.querySelector("[data-image-placeholder]");
const imageName = document.querySelector("[data-image-name]");
let previewURL = "";
if (fileInput && image && placeholder && imageName) {
fileInput.addEventListener("change", () => {
if (previewURL) URL.revokeObjectURL(previewURL);
const file = fileInput.files && fileInput.files[0];
if (!file) {
image.hidden = true;
placeholder.hidden = false;
imageName.textContent = "选择后在本地预览";
return;
}
previewURL = URL.createObjectURL(file);
image.src = previewURL;
image.hidden = false;
placeholder.hidden = true;
imageName.textContent = `${file.name} · ${(file.size / 1024).toFixed(1)} KB`;
});
window.addEventListener("pagehide", () => {
if (previewURL) URL.revokeObjectURL(previewURL);
});
}
const dirtyForm = document.querySelector("[data-dirty-form]");
const leaveDialog = document.querySelector("[data-leave-dialog]");
let dirty = false;
let destination = "";
if (dirtyForm && leaveDialog) {
dirtyForm.addEventListener("input", () => {
dirty = true;
});
dirtyForm.addEventListener("change", () => {
dirty = true;
});
dirtyForm.addEventListener("submit", () => {
dirty = false;
});
document.querySelectorAll("a[href]").forEach((link) => {
link.addEventListener("click", (event) => {
if (!dirty || link.hasAttribute("data-discard")) return;
const target = new URL(link.href, window.location.href);
if (target.origin !== window.location.origin) return;
event.preventDefault();
destination = target.href;
leaveDialog.showModal();
leaveDialog.querySelector("[data-stay]").focus();
});
});
leaveDialog.querySelector("[data-stay]").addEventListener("click", () => {
leaveDialog.close();
});
leaveDialog.querySelector("[data-discard]").addEventListener("click", (event) => {
event.preventDefault();
dirty = false;
window.location.assign(destination || "/tasks");
});
}
const openCancel = document.querySelector("[data-open-cancel]");
const cancelDialog = document.querySelector("[data-cancel-dialog]");
if (openCancel && cancelDialog) {
openCancel.addEventListener("click", () => {
cancelDialog.showModal();
cancelDialog.querySelector("[data-keep-task]").focus();
});
cancelDialog.querySelector("[data-keep-task]").addEventListener("click", () => {
cancelDialog.close();
openCancel.focus();
});
}
})();