// delete confirmation dialog and attachment to elements const fireConfirmModal = (event) => { Swal.fire({ title: 'Wirklich löschen?', showCancelButton: true, cancelButtonText: 'Abbrechen', icon: 'warning', confirmButtonText: "Löschen", showCloseButton: true }) .then((result) => { if (result.isConfirmed) { htmx.trigger(event.target, 'confirmed'); } }); } document.querySelectorAll("button[hx-trigger='confirmed']").forEach((value) => value.addEventListener("click", fireConfirmModal)); document.addEventListener("htmx:afterSwap", () => { document.querySelectorAll("button[hx-trigger='confirmed']").forEach((value) => value.addEventListener("click", fireConfirmModal)); }); // dropdown activation / deactivation const toggleDropdown = (event) => { const classList = event.target.closest('.dropdown').classList if (!classList.contains('is-active')) { Array.from(document.querySelectorAll('.dropdown')).forEach((d) => d.classList.remove('is-active')); } classList.toggle('is-active'); }; const closeDropdownsIfClickedOutside = (event) => { const dropdowns = Array.from(document.querySelectorAll('.dropdown')); if (dropdowns.every((v) => !v.contains(event.target))) { dropdowns.forEach((d) => d.classList.remove('is-active')) } } document.querySelectorAll(".dropdown-trigger .button").forEach((value) => value.addEventListener("click", toggleDropdown)); document.addEventListener("click", closeDropdownsIfClickedOutside); document.addEventListener("htmx:afterSwap", () => { document.querySelectorAll(".dropdown-trigger .button").forEach((value) => value.addEventListener("click", toggleDropdown)); document.addEventListener("click", closeDropdownsIfClickedOutside); }); // light / dark mode interpretation for first load and switch behaviour respecting localStorage and CSS prefers-color-scheme const getCurrentTheme = () => { let current = localStorage.getItem("theme"); if (current === null) { if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) { current = "dark"; } else { current = "light"; } } return current; } const setThemeSwitcherIconTo = (name) => document.querySelector("#theme-switcher use")?.setAttribute("href", `/static/feather-sprite.svg#${name}`) const switchTheme = () => { const currentTheme = getCurrentTheme(); const newTheme = currentTheme === "light" ? "dark" : "light"; const newIcon = currentTheme === "light" ? "sun" : "moon"; document.documentElement.setAttribute("data-theme", newTheme); setThemeSwitcherIconTo(newIcon); localStorage.setItem("theme", newTheme); } const observer = new MutationObserver((mutationList) => { const foundNavbar = mutationList.flatMap((record) => Array.from(record.addedNodes)) .some((node) => node.className?.includes("navbar")); if (foundNavbar) { document.getElementById("theme-switcher")?.addEventListener("click", switchTheme); setThemeSwitcherIconTo(getCurrentTheme() === "light" ? "moon" : "sun"); } }); observer.observe(document, { childList: true, subtree: true }); const isCurrentlyLight = getCurrentTheme() === "light"; document.documentElement.setAttribute("data-theme", isCurrentlyLight ? "light" : "dark"); document.getElementById("theme-switcher")?.addEventListener("click", switchTheme); setThemeSwitcherIconTo(isCurrentlyLight ? "moon" : "sun"); // toast htmx.on("showToast", (e) => { const toast = document.getElementById("toast"); const toastProgress = document.getElementById("toast-progress"); document.getElementById("toast-message").innerText = e.detail.message; toast.classList.add(`is-${e.detail.type}`); toastProgress.classList.add(`has-background-${e.detail.type}-90`) toast.classList.remove("is-hidden"); setTimeout(() => { toast.classList.add("is-hidden"); toast.classList.remove(`is-${e.detail.type}`); toastProgress.classList.remove(`has-background-${e.detail.type}-90`) }, 3000); }) const convertBool = (val) => { if (val === "true" || val === true) return true; if (val === "false" || val === false) return false; return null; } _hyperscript.config.conversions["bool"] = convertBool; _hyperscript.config.conversions["inverseBool"] = function(val) { return !convertBool(val); };