refactor: use hyperscript instead of javascript

This commit is contained in:
Max Hohlfeld 2025-07-16 08:47:11 +02:00
parent 653dbb4233
commit 1d493b85b1
4 changed files with 29 additions and 41 deletions

View File

@ -30,7 +30,12 @@ snapshot_kind: text
</td>
<td>
<div class="dropdown">
<div class="dropdown-trigger">
<div class="dropdown-trigger"
_="on click[.dropdown does not contain target] from elsewhere
or keyup[key is 'Escape'] from elsewhere
or click[parentElement of me does not match .is-active]
remove .is-active from .dropdown end
on click toggle .is-active on the parentElement of me">
<button class="button" aria-haspopup="true" aria-controls="dropdown-menu">
<span>als Posten geplant</span>
@ -44,7 +49,7 @@ snapshot_kind: text
<div class="dropdown-content" hx-target="closest table" hx-swap="outerHTML">
<a class="dropdown-item"
hx-post="/assignments/new?event=1&availability=1&function=1" disabled>
hx-post="/assignments/new?event=1&availability=1&function=1" disabled>
als Posten planen</a>
@ -52,8 +57,8 @@ snapshot_kind: text
<hr class="dropdown-divider" />
<a class="dropdown-item"
hx-delete="/assignments/delete?event=1&availability=1"
class="button is-small">entplanen</a>
hx-delete="/assignments/delete?event=1&availability=1"
class="button is-small">entplanen</a>
</div>
</div>

View File

@ -1,6 +1,7 @@
use askama::Template;
use crate::filters;
use crate::utils::DateTimeFormat::{DayMonthYearHourMinute, HourMinute};
use brass_db::models::{Availability, AvailabilityAssignmentState, Event};
pub mod delete;

View File

@ -11,30 +11,6 @@ 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");

View File

@ -27,14 +27,20 @@
{{ u.function|show_tree|safe }}
</td>
<td>
{{ availability.start.format("%R") }} bis {{ availability.end.format("%d.%m.%Y %R") }}
{{ availability.start|fmt_datetime(HourMinute) }} bis {{ availability.end|fmt_datetime(DayMonthYearHourMinute)
}}
</td>
<td>
{{ availability.comment.as_deref().unwrap_or("") }}
{{ availability.comment.as_deref().unwrap_or_default() }}
</td>
<td>
<div class="dropdown">
<div class="dropdown-trigger">
<div class="dropdown-trigger"
_="on click[.dropdown does not contain target] from elsewhere
or keyup[key is 'Escape'] from elsewhere
or click[parentElement of me does not match .is-active]
remove .is-active from .dropdown end
on click toggle .is-active on the parentElement of me">
<button class="button" aria-haspopup="true" aria-controls="dropdown-menu">
{% match status %}
{% when AvailabilityAssignmentState::AssignedPosten(_) %}
@ -64,28 +70,28 @@
<div class="dropdown-content" hx-target="closest table" hx-swap="outerHTML">
{% if u.function.is_posten() %}
<a class="dropdown-item"
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=1" {% if
!further_posten_required || status !=AvailabilityAssignmentState::Unassigned|ref %}disabled{% endif %}>
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=1" {% if
!further_posten_required || status !=AvailabilityAssignmentState::Unassigned|ref %}disabled{% endif %}>
als Posten planen</a>
{% endif %}
{% if u.function.is_fuehrungsassistent() %}
<a class="dropdown-item"
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=5" {% if
!further_fuehrungsassistent_required || status !=AvailabilityAssignmentState::Unassigned|ref
%}disabled{% endif %}>als Führungsassistent planen</a>
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=5" {% if
!further_fuehrungsassistent_required || status !=AvailabilityAssignmentState::Unassigned|ref
%}disabled{% endif %}>als Führungsassistent planen</a>
{% endif %}
{% if u.function.is_wachhabender() %}
<a class="dropdown-item"
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=10" {% if
!further_wachhabender_required || status !=AvailabilityAssignmentState::Unassigned|ref %}disabled{%
endif %}>als Wachhabender planen</a>
hx-post="/assignments/new?event={{ event.id }}&availability={{ availability.id }}&function=10" {% if
!further_wachhabender_required || status !=AvailabilityAssignmentState::Unassigned|ref %}disabled{%
endif %}>als Wachhabender planen</a>
{% endif %}
{% if status != AvailabilityAssignmentState::Unassigned|ref && status !=
AvailabilityAssignmentState::Conflicting|ref %}
<hr class="dropdown-divider" />
<a class="dropdown-item"
hx-delete="/assignments/delete?event={{ event.id }}&availability={{ availability.id }}"
class="button is-small">entplanen</a>
hx-delete="/assignments/delete?event={{ event.id }}&availability={{ availability.id }}"
class="button is-small">entplanen</a>
{% endif %}
</div>
</div>