Files
appfactory-portal/app/static/portal.js
T
2026-06-03 10:38:23 +02:00

202 lines
5.4 KiB
JavaScript

function writeClipboard(value) {
if (navigator.clipboard && window.isSecureContext) {
return navigator.clipboard.writeText(value);
}
const textarea = document.createElement("textarea");
textarea.value = value;
textarea.setAttribute("readonly", "");
textarea.style.position = "fixed";
textarea.style.top = "-1000px";
document.body.appendChild(textarea);
textarea.select();
document.execCommand("copy");
document.body.removeChild(textarea);
return Promise.resolve();
}
function nearestCopyValue(button) {
if (button.dataset.copyValue) {
return button.dataset.copyValue;
}
const scopes = [
button.closest(".copy-row"),
button.closest(".cmd-row"),
button.closest("td"),
button.parentElement,
];
for (const scope of scopes) {
if (!scope) {
continue;
}
const target = scope.querySelector("input, textarea, pre, code");
if (target) {
return "value" in target ? target.value : target.textContent;
}
}
return "";
}
function showCopied(button, ok) {
const label = button.textContent;
button.textContent = ok ? "Zkopírováno" : "Nelze kopírovat";
window.setTimeout(() => {
button.textContent = label;
}, 1200);
}
function copyValue(idOrButton) {
const target = typeof idOrButton === "string" ? document.getElementById(idOrButton) : idOrButton;
if (!target) {
return false;
}
const value = "value" in target ? target.value : nearestCopyValue(target);
if ("select" in target) {
target.select();
target.setSelectionRange(0, target.value.length);
}
writeClipboard(value)
.then(() => {
if (!("value" in target)) {
showCopied(target, true);
}
})
.catch(() => {
if (!("value" in target)) {
showCopied(target, false);
}
});
return false;
}
function copyText(button) {
const value = nearestCopyValue(button);
writeClipboard(value)
.then(() => showCopied(button, true))
.catch(() => showCopied(button, false));
return false;
}
function openResourceModal(id) {
const modal = document.getElementById(id);
if (!modal) {
return false;
}
if (typeof modal.showModal === "function") {
modal.showModal();
} else {
modal.setAttribute("open", "");
}
return false;
}
function closeResourceModal(id) {
const modal = document.getElementById(id);
if (!modal) {
return false;
}
if (typeof modal.close === "function") {
modal.close();
} else {
modal.removeAttribute("open");
}
return false;
}
document.addEventListener("click", (event) => {
const modal = event.target;
if (typeof HTMLDialogElement !== "undefined" && modal instanceof HTMLDialogElement && modal.classList.contains("resource-modal")) {
modal.close();
}
});
function setFormDisabled(form, disabled) {
for (const field of form.querySelectorAll("input, select, textarea, button")) {
field.disabled = disabled;
}
}
function extractMainHtml(responseText) {
const parser = new DOMParser();
const doc = parser.parseFromString(responseText, "text/html");
const main = doc.querySelector("main");
return main ? main.innerHTML : "";
}
document.addEventListener("DOMContentLoaded", () => {
const form = document.querySelector('[data-ajax-form="new-app"]');
if (!form) {
return;
}
const loader = document.getElementById("new-app-loader");
const status = document.getElementById("new-app-status");
const result = document.getElementById("new-app-result");
form.addEventListener("submit", async (event) => {
event.preventDefault();
const formData = new FormData(form);
if (status) {
status.className = "async-status";
status.textContent = "Vytv\u00e1\u0159\u00edm slu\u017ebu, neobnovujte str\u00e1nku.";
}
if (result) {
result.innerHTML = "";
}
if (loader) {
loader.hidden = false;
}
setFormDisabled(form, true);
try {
const response = await fetch(form.action, {
method: "POST",
body: formData,
headers: {
"X-Requested-With": "fetch",
},
});
const responseText = await response.text();
const mainHtml = extractMainHtml(responseText);
if (mainHtml) {
const main = document.querySelector("main");
if (main) {
main.innerHTML = mainHtml;
}
return;
}
if (!response.ok) {
throw new Error(responseText || "Vytvo\u0159en\u00ed slu\u017eby selhalo.");
}
if (result) {
result.innerHTML = responseText;
}
if (status) {
status.textContent = "";
}
} catch (error) {
if (status) {
status.className = "async-status async-status-error";
status.textContent = error.message || "Vytvo\u0159en\u00ed slu\u017eby selhalo.";
}
setFormDisabled(form, false);
} finally {
if (loader) {
loader.hidden = true;
}
}
});
});