feat(backend): implement task creation and admin web
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
(() => {
|
||||
"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();
|
||||
}
|
||||
|
||||
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();
|
||||
});
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user