mirror of
https://github.com/Theodor-Springmann-Stiftung/musenalm.git
synced 2026-02-04 10:35:30 +00:00
+density on list
This commit is contained in:
@@ -132,26 +132,45 @@
|
||||
<span data-role="contents-htmx-label">Eintrag wird geladen</span>
|
||||
</div>
|
||||
<input type="hidden" name="csrf_token" value="{{ $model.csrf_token }}" data-role="csrf-token" />
|
||||
<div class="flex items-center justify-end gap-2 px-4">
|
||||
<button type="button" class="resetbutton w-auto px-3 py-2 flex items-center gap-2" data-role="contents-collapse-all" data-state="expanded">
|
||||
<i class="ri-arrow-up-s-line" data-role="contents-collapse-all-icon"></i>
|
||||
<span data-role="contents-collapse-all-label">Alle Eintraege einklappen</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="resetbutton w-auto px-3 py-2 flex items-center gap-2"
|
||||
data-role="contents-create"
|
||||
data-loading-label="Eintrag wird geladen"
|
||||
hx-post="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/insert"
|
||||
hx-target="[data-role='contents-list']"
|
||||
hx-swap="beforeend"
|
||||
hx-include="[data-role='csrf-token']"
|
||||
hx-vals='{"position":"after","content_id":""}'>
|
||||
<i class="ri-add-line"></i>
|
||||
<span>Eintrag anlegen</span>
|
||||
</button>
|
||||
<div class="flex items-center gap-3 px-4">
|
||||
<form
|
||||
method="POST"
|
||||
action="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit/extent"
|
||||
class="extent-inline flex-1 grid grid-cols-[max-content_minmax(12rem,1fr)_max-content] items-center gap-2">
|
||||
<input type="hidden" name="csrf_token" value="{{ $model.csrf_token }}" />
|
||||
<label for="contents-extent" class="text-sm font-bold text-gray-700">Struktur</label>
|
||||
<input
|
||||
id="contents-extent"
|
||||
name="extent"
|
||||
type="text"
|
||||
class="min-w-[10rem] w-full max-w-none flex-1 border border-slate-300 rounded-xs bg-white px-2 py-1 text-sm leading-5 text-gray-800 focus:outline-none focus:ring-2 focus:ring-slate-400/30"
|
||||
placeholder="z. B. 12 Bl., 3 Taf."
|
||||
value="{{- $model.result.Entry.Extent -}}" />
|
||||
<button type="submit" class="rounded-xs border border-slate-300 bg-stone-100 px-3 py-1 text-sm font-semibold text-gray-700 hover:bg-stone-200">
|
||||
Speichern
|
||||
</button>
|
||||
</form>
|
||||
<div class="flex items-center gap-2">
|
||||
<button type="button" class="resetbutton w-auto px-3 py-2 flex items-center gap-2" data-role="contents-collapse-all" data-state="expanded">
|
||||
<i class="ri-arrow-up-s-line" data-role="contents-collapse-all-icon"></i>
|
||||
<span data-role="contents-collapse-all-label">Alle Eintraege einklappen</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="resetbutton w-auto px-3 py-2 flex items-center gap-2"
|
||||
data-role="contents-create"
|
||||
data-loading-label="Eintrag wird geladen"
|
||||
hx-post="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/insert"
|
||||
hx-target="[data-role='contents-list']"
|
||||
hx-swap="beforeend"
|
||||
hx-include="[data-role='csrf-token']"
|
||||
hx-vals='{"position":"after","content_id":""}'>
|
||||
<i class="ri-add-line"></i>
|
||||
<span>Eintrag anlegen</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1"
|
||||
<div class="flex flex-col gap-0.5"
|
||||
data-role="contents-list"
|
||||
data-insert-endpoint="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/insert"
|
||||
data-edit-endpoint="/almanach/{{ $model.result.Entry.MusenalmID }}/contents/edit/form"
|
||||
@@ -263,7 +282,7 @@
|
||||
}
|
||||
};
|
||||
const setEditSpacing = (active) => {
|
||||
list.style.rowGap = active ? "0.75rem" : "";
|
||||
list.style.rowGap = active ? "0.5rem" : "";
|
||||
list.style.paddingTop = active ? "0.25rem" : "";
|
||||
list.style.paddingBottom = active ? "0.25rem" : "";
|
||||
};
|
||||
@@ -317,6 +336,51 @@
|
||||
}
|
||||
};
|
||||
|
||||
const deleteContent = (item, dialog) => {
|
||||
if (!item) {
|
||||
return;
|
||||
}
|
||||
if (item.dataset.contentTemp === "true") {
|
||||
dialog?.close();
|
||||
removeItem(item);
|
||||
return;
|
||||
}
|
||||
const contentId = item.dataset.contentId || "";
|
||||
if (!contentId || !csrfToken) {
|
||||
return;
|
||||
}
|
||||
if (window.htmx?.ajax) {
|
||||
window.htmx.ajax("POST", deleteEndpoint, {
|
||||
target: item,
|
||||
swap: "outerHTML",
|
||||
values: {
|
||||
csrf_token: csrfToken,
|
||||
content_id: contentId,
|
||||
},
|
||||
});
|
||||
dialog?.close();
|
||||
return;
|
||||
}
|
||||
const payload = new URLSearchParams();
|
||||
payload.set("csrf_token", csrfToken);
|
||||
payload.set("content_id", contentId);
|
||||
fetch(deleteEndpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
"HX-Request": "true",
|
||||
},
|
||||
body: payload.toString(),
|
||||
})
|
||||
.then(() => {
|
||||
removeItem(item);
|
||||
})
|
||||
.catch(() => null)
|
||||
.finally(() => {
|
||||
dialog?.close();
|
||||
});
|
||||
};
|
||||
|
||||
const performOrderSync = () => {
|
||||
if (!list || !orderEndpoint || !csrfToken || isOrderSyncing) {
|
||||
pendingOrderSync = true;
|
||||
@@ -442,10 +506,16 @@
|
||||
item.dataset.init = "true";
|
||||
|
||||
const editButton = item.querySelector("[data-role='content-edit-button']");
|
||||
const deleteButtonView = item.querySelector("[data-role='content-delete-view']");
|
||||
const deleteDialogView = item.querySelector("[data-role='content-delete-dialog-view']");
|
||||
const deleteConfirmView = item.querySelector("[data-role='content-delete-confirm-view']");
|
||||
const deleteCancelView = item.querySelector("[data-role='content-delete-cancel-view']");
|
||||
const view = item.querySelector("[data-role='content-view']");
|
||||
const collapseButton = item.querySelector("[data-role='content-collapse-toggle']");
|
||||
const collapseIcon = item.querySelector("[data-role='content-collapse-icon']");
|
||||
const collapseTooltip = item.querySelector("[data-role='content-collapse-tooltip']");
|
||||
const collapsedSummary = item.querySelector("[data-role='content-collapsed-summary']");
|
||||
const headerTitle = item.querySelector("[data-role='content-header-title']");
|
||||
const viewBody = item.querySelector("[data-role='content-view-body']");
|
||||
const header = item.querySelector("[data-content-header='true']");
|
||||
|
||||
@@ -457,6 +527,9 @@
|
||||
item.classList.toggle("data-collapsed", collapsed);
|
||||
viewBody.classList.toggle("hidden", collapsed);
|
||||
collapsedSummary.classList.toggle("hidden", !collapsed);
|
||||
if (headerTitle) {
|
||||
headerTitle.classList.toggle("hidden", collapsed);
|
||||
}
|
||||
if (header) {
|
||||
header.classList.toggle("bg-stone-100", collapsed);
|
||||
header.classList.toggle("bg-stone-200", !collapsed);
|
||||
@@ -465,6 +538,9 @@
|
||||
collapseButton.setAttribute("aria-expanded", (!collapsed).toString());
|
||||
collapseButton.setAttribute("aria-label", collapsed ? "Beitrag ausklappen" : "Beitrag einklappen");
|
||||
}
|
||||
if (collapseTooltip) {
|
||||
collapseTooltip.textContent = collapsed ? "Ausklappen" : "Einklappen";
|
||||
}
|
||||
if (collapseIcon) {
|
||||
collapseIcon.classList.toggle("ri-arrow-up-s-line", !collapsed);
|
||||
collapseIcon.classList.toggle("ri-arrow-down-s-line", collapsed);
|
||||
@@ -512,6 +588,32 @@
|
||||
});
|
||||
}
|
||||
|
||||
if (deleteButtonView && deleteDialogView) {
|
||||
deleteButtonView.addEventListener("click", () => {
|
||||
if (deleteDialogView.showModal) {
|
||||
deleteDialogView.showModal();
|
||||
} else {
|
||||
deleteDialogView.setAttribute("open", "true");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (deleteCancelView && deleteDialogView) {
|
||||
deleteCancelView.addEventListener("click", () => {
|
||||
deleteDialogView.close();
|
||||
});
|
||||
deleteDialogView.addEventListener("cancel", (event) => {
|
||||
event.preventDefault();
|
||||
deleteDialogView.close();
|
||||
});
|
||||
}
|
||||
|
||||
if (deleteConfirmView) {
|
||||
deleteConfirmView.addEventListener("click", () => {
|
||||
deleteContent(item, deleteDialogView);
|
||||
});
|
||||
}
|
||||
|
||||
const pendingEdit = item.dataset.pendingEdit === "true";
|
||||
if (pendingEdit && item.querySelector("[data-role='content-edit']")) {
|
||||
item.dataset.pendingEdit = "";
|
||||
@@ -580,29 +682,7 @@
|
||||
|
||||
if (deleteConfirm) {
|
||||
deleteConfirm.addEventListener("click", () => {
|
||||
if (item.dataset.contentTemp === "true") {
|
||||
deleteDialog?.close();
|
||||
removeItem(item);
|
||||
return;
|
||||
}
|
||||
const payload = new URLSearchParams();
|
||||
payload.set("csrf_token", csrfToken);
|
||||
payload.set("content_id", item.dataset.contentId || "");
|
||||
fetch(deleteEndpoint, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
},
|
||||
body: payload.toString(),
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.redirected) {
|
||||
window.location.assign(response.url);
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
})
|
||||
.catch(() => null);
|
||||
deleteContent(item, deleteDialog);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -646,8 +726,10 @@
|
||||
}
|
||||
const viewBody = item.querySelector("[data-role='content-view-body']");
|
||||
const collapsedSummary = item.querySelector("[data-role='content-collapsed-summary']");
|
||||
const headerTitle = item.querySelector("[data-role='content-header-title']");
|
||||
const collapseButton = item.querySelector("[data-role='content-collapse-toggle']");
|
||||
const collapseIcon = item.querySelector("[data-role='content-collapse-icon']");
|
||||
const collapseTooltip = item.querySelector("[data-role='content-collapse-tooltip']");
|
||||
const header = item.querySelector("[data-content-header='true']");
|
||||
if (!viewBody || !collapsedSummary) {
|
||||
return;
|
||||
@@ -656,6 +738,9 @@
|
||||
item.classList.toggle("data-collapsed", collapsed);
|
||||
viewBody.classList.toggle("hidden", collapsed);
|
||||
collapsedSummary.classList.toggle("hidden", !collapsed);
|
||||
if (headerTitle) {
|
||||
headerTitle.classList.toggle("hidden", collapsed);
|
||||
}
|
||||
if (header) {
|
||||
header.classList.toggle("bg-stone-100", collapsed);
|
||||
header.classList.toggle("bg-stone-200", !collapsed);
|
||||
@@ -664,6 +749,9 @@
|
||||
collapseButton.setAttribute("aria-expanded", (!collapsed).toString());
|
||||
collapseButton.setAttribute("aria-label", collapsed ? "Beitrag ausklappen" : "Beitrag einklappen");
|
||||
}
|
||||
if (collapseTooltip) {
|
||||
collapseTooltip.textContent = collapsed ? "Ausklappen" : "Einklappen";
|
||||
}
|
||||
if (collapseIcon) {
|
||||
collapseIcon.classList.toggle("ri-arrow-up-s-line", !collapsed);
|
||||
collapseIcon.classList.toggle("ri-arrow-down-s-line", collapsed);
|
||||
@@ -765,7 +853,7 @@
|
||||
draggedItem = item;
|
||||
item.dataset.dragging = "true";
|
||||
draggedItem.classList.add("opacity-60");
|
||||
list.style.rowGap = "0.75rem";
|
||||
list.style.rowGap = "0.5rem";
|
||||
list.style.paddingTop = "0.25rem";
|
||||
list.style.paddingBottom = "0.25rem";
|
||||
removeGaps();
|
||||
|
||||
Reference in New Issue
Block a user