feat: add shared task assignments and quick win sorting

This commit is contained in:
2026-04-15 13:18:50 +02:00
parent f8f3641811
commit 4233175067
18 changed files with 414 additions and 55 deletions

View File

@@ -3,6 +3,7 @@
const dialogForm = document.getElementById("completeDialogForm");
const dialogChoice = document.getElementById("completeDialogChoice");
const dialogText = document.getElementById("completeDialogText");
const dialogChoices = document.getElementById("completeDialogChoices");
const closeButton = document.getElementById("completeDialogClose");
const quickTaskDialog = document.getElementById("quickTaskDialog");
const quickTaskOpen = document.getElementById("quickTaskOpen");
@@ -13,23 +14,55 @@
const quickWinCustomFields = document.getElementById("quickWinCustomFields");
const quickWinTitle = document.getElementById("quick-title");
const quickWinEffort = document.getElementById("quick-effort");
const currentUserId = document.body.dataset.currentUserId;
const currentUserName = document.body.dataset.currentUserName;
const quickWinSortList = document.querySelector("[data-quick-win-sort-list]");
const quickWinSortToken = document.getElementById("quickWinSortToken");
let draggedQuickWin = null;
function buildCompletionOptions(button) {
const options = [];
const assignedPairs = [
[button.dataset.assignedPrimaryId, button.dataset.assignedPrimaryName],
[button.dataset.assignedSecondaryId, button.dataset.assignedSecondaryName],
];
assignedPairs.forEach(([id, label]) => {
if (id && label && !options.some((option) => option.value === id)) {
options.push({ value: id, label });
}
});
if (currentUserId && currentUserName && !options.some((option) => option.value === currentUserId)) {
options.push({ value: currentUserId, label: "Ich" });
}
return options;
}
document.querySelectorAll("[data-complete-action]").forEach((button) => {
button.addEventListener("click", () => {
if (!dialog || !dialogForm || !dialogChoice || !dialogText) {
if (!dialog || !dialogForm || !dialogChoice || !dialogText || !dialogChoices) {
return;
}
dialogForm.action = button.dataset.completeAction;
dialogText.textContent = `Die Aufgabe "${button.dataset.completeTitle}" war ${button.dataset.completeAssigned} zugewiesen. Wer hat sie erledigt?`;
dialog.showModal();
});
});
dialogChoices.innerHTML = "";
document.querySelectorAll("[data-complete-choice]").forEach((button) => {
button.addEventListener("click", () => {
dialogChoice.value = button.dataset.completeChoice || "me";
dialog.close();
dialogForm.submit();
buildCompletionOptions(button).forEach((option, index) => {
const choiceButton = document.createElement("button");
choiceButton.type = "button";
choiceButton.className = index === 0 ? "button button--secondary" : "button";
choiceButton.dataset.completeChoice = option.value;
choiceButton.textContent = option.label;
choiceButton.addEventListener("click", () => {
dialogChoice.value = option.value;
dialog.close();
dialogForm.submit();
});
dialogChoices.appendChild(choiceButton);
});
dialog.showModal();
});
});
@@ -87,6 +120,64 @@
});
}
async function persistQuickWinSort() {
if (!quickWinSortList || !quickWinSortToken) {
return;
}
const ids = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")]
.map((item) => item.dataset.quickWinSortItem)
.filter(Boolean);
await fetch("/settings/quick-wins/reorder", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRFToken": quickWinSortToken.value,
},
body: JSON.stringify({ ids }),
});
}
if (quickWinSortList) {
quickWinSortList.querySelectorAll("[data-quick-win-sort-item]").forEach((item) => {
item.addEventListener("dragstart", () => {
draggedQuickWin = item;
item.classList.add("is-dragging");
});
item.addEventListener("dragend", () => {
item.classList.remove("is-dragging");
draggedQuickWin = null;
});
item.addEventListener("dragover", (event) => {
event.preventDefault();
});
item.addEventListener("drop", async (event) => {
event.preventDefault();
if (!draggedQuickWin || draggedQuickWin === item) {
return;
}
const items = [...quickWinSortList.querySelectorAll("[data-quick-win-sort-item]")];
const draggedIndex = items.indexOf(draggedQuickWin);
const targetIndex = items.indexOf(item);
if (draggedIndex < targetIndex) {
item.after(draggedQuickWin);
} else {
item.before(draggedQuickWin);
}
try {
await persistQuickWinSort();
} catch (error) {
console.error("Quick-Win-Sortierung konnte nicht gespeichert werden", error);
}
});
});
}
const pushButton = document.getElementById("pushToggle");
const pushHint = document.getElementById("pushHint");
const vapidKey = document.body.dataset.pushKey;