Make task reorder work better with moving checked to the bottom

This commit is contained in:
Adrian Gruntkowski 2025-11-11 00:01:34 +01:00
parent 8d12c66141
commit a91903598d
2 changed files with 59 additions and 10 deletions

View file

@ -275,7 +275,12 @@ class TaskListItem extends HTMLElement {
}); });
this.checkboxElement.addEventListener("change", () => this.checkboxElement.addEventListener("change", () =>
this.dispatchEvent(new Event("contentChange", { bubbles: true })), this.dispatchEvent(
new CustomEvent("contentChange", {
bubbles: true,
detail: { operation: "toggle_task" },
}),
),
); );
// drag and drop events // drag and drop events
@ -299,7 +304,12 @@ class TaskListItem extends HTMLElement {
this.parentNode.addEventListener("dragend", () => { this.parentNode.addEventListener("dragend", () => {
this.parentNode.setAttribute("draggable", "false"); this.parentNode.setAttribute("draggable", "false");
this.parentNode.classList.remove("dragging"); this.parentNode.classList.remove("dragging");
this.dispatchEvent(new Event("contentChange", { bubbles: true })); this.dispatchEvent(
new CustomEvent("contentChange", {
bubbles: true,
detail: { operation: "reorder_task" },
}),
);
}); });
this.parentNode.addEventListener("touchstart", (e) => { this.parentNode.addEventListener("touchstart", (e) => {
@ -361,6 +371,12 @@ class TaskListItem extends HTMLElement {
} }
this.taskList.dragActiveElement = null; this.taskList.dragActiveElement = null;
this.taskList.dragPlaceholder = null; this.taskList.dragPlaceholder = null;
this.dispatchEvent(
new CustomEvent("contentChange", {
bubbles: true,
detail: { operation: "reorder_task" },
}),
);
} }
}); });
@ -385,12 +401,14 @@ class TaskListItem extends HTMLElement {
get value() { get value() {
return { return {
order: parseInt(this.dataset.order),
content: this.contentElement.value, content: this.contentElement.value,
checked: !!this.checkboxElement.checked, checked: !!this.checkboxElement.checked,
}; };
} }
set value(item) { set value(item) {
this.dataset.order = item.order;
this.checkboxElement.checked = item.checked; this.checkboxElement.checked = item.checked;
this.contentElement.value = item.content; this.contentElement.value = item.content;
} }
@ -424,6 +442,8 @@ class TaskList extends HTMLElement {
} }
connectedCallback() { connectedCallback() {
const that = this;
this.listElement = this.querySelector("ul"); this.listElement = this.querySelector("ul");
this.addEventListener("removeTaskWithButton", (e) => { this.addEventListener("removeTaskWithButton", (e) => {
@ -490,6 +510,18 @@ class TaskList extends HTMLElement {
} }
}); });
this.addEventListener("contentChange", (e) => {
const operation = e.detail?.operation;
if (operation === "toggle_task") {
that.value = that.value;
} else if (operation === "reorder_task") {
const tasks = this.#valueNoOrder().map((task, idx) => {
return { ...task, order: idx };
});
that.value = tasks;
}
});
// drag and drop // drag and drop
this.listElement.addEventListener("dragover", (e) => { this.listElement.addEventListener("dragover", (e) => {
e.preventDefault(); e.preventDefault();
@ -506,15 +538,30 @@ class TaskList extends HTMLElement {
} }
get value() { get value() {
return Array.from(this.querySelectorAll("task-list-item")).map( const tasks = this.#valueNoOrder().sort((a, b) => a.order - b.order);
(item) => item.value,
); return tasks;
} }
set value(tasks) { set value(tasks) {
const sortedTasks = [...tasks]
.map((task, idx) => {
return { ...task, order: idx };
})
.sort((a, b) => {
const maxOrder = Math.max(a.order, b.order) + 1;
return (
(a.checked ? maxOrder : 0) +
a.order -
b.order -
(b.checked ? maxOrder : 0)
);
});
this.listElement.replaceChildren(); this.listElement.replaceChildren();
tasks.forEach((task) => { sortedTasks.forEach((task) => {
const item = html` const item = html`
<li><task-list-item></task-list-itm></li> <li><task-list-item></task-list-itm></li>
`; `;
@ -524,6 +571,12 @@ class TaskList extends HTMLElement {
this.dispatchEvent(new Event("contentChange", { bubbles: true })); this.dispatchEvent(new Event("contentChange", { bubbles: true }));
} }
#valueNoOrder() {
return Array.from(this.querySelectorAll("task-list-item")).map(
(item) => item.value,
);
}
} }
function getDragAfterElement(container, y) { function getDragAfterElement(container, y) {

View file

@ -172,10 +172,6 @@ task-list ul {
padding: 4px 0; padding: 4px 0;
} }
task-list li:has(.checkbox input:checked) {
order: 1;
}
task-list-item .remove { task-list-item .remove {
width: 3em; width: 3em;
} }