From c2a664d89128e4fb326fbb3d55828fd5b05ebba3 Mon Sep 17 00:00:00 2001 From: Kristian Wind Date: Mon, 17 Aug 2026 10:40:05 +0200 Subject: [PATCH] feat(web): drag to reorder in the list view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The board has had it since it was written; the list has not, and POST /tasks/{id}/move was already tested and working. Where the board shows the target column, a list has to show the target gap — the whole decision is "above this one or below it" — so a line is drawn where the row would land, chosen by which half of the row the pointer is in rather than by counting rows, which is what keeps it where the eye expects it when rows have different heights. The move sends both neighbours. The API's after_id is the task above, which reads as the opposite of "after" in a vertical list, so the locals here are named for where they end up on screen. Co-Authored-By: Claude Opus 5 --- web/src/lib/components/TaskList.svelte | 167 +++++++++++++++++++++++ web/src/routes/projekt/[id]/+page.svelte | 10 +- 2 files changed, 170 insertions(+), 7 deletions(-) create mode 100644 web/src/lib/components/TaskList.svelte diff --git a/web/src/lib/components/TaskList.svelte b/web/src/lib/components/TaskList.svelte new file mode 100644 index 0000000..22a36d1 --- /dev/null +++ b/web/src/lib/components/TaskList.svelte @@ -0,0 +1,167 @@ + + +{#each ordered as task (task.id)} + +
onDragStart(e, task)} + ondragend={() => { + draggingId = null; + overId = null; + }} + ondragover={(e) => onDragOver(e, task)} + ondragleave={clearOver} + ondrop={(e) => onDrop(e, task)} + > + +
+{/each} + + diff --git a/web/src/routes/projekt/[id]/+page.svelte b/web/src/routes/projekt/[id]/+page.svelte index 29511a8..6daaaf2 100644 --- a/web/src/routes/projekt/[id]/+page.svelte +++ b/web/src/routes/projekt/[id]/+page.svelte @@ -3,7 +3,7 @@ import { page } from '$app/stores'; import { api, humanMessage } from '$lib/api.js'; import { app } from '$lib/stores.svelte.js'; - import TaskRow from '$lib/components/TaskRow.svelte'; + import TaskList from '$lib/components/TaskList.svelte'; import QuickAdd from '$lib/components/QuickAdd.svelte'; import BoardView from '$lib/components/BoardView.svelte'; import CalendarView from '$lib/components/CalendarView.svelte'; @@ -168,18 +168,14 @@ {:else}
- {#each unsectioned as task (task.id)} - - {/each} +
{#each sections as section (section.id)} {@const tasks = open.filter((t) => t.section_id === section.id)}

{section.name}

- {#each tasks as task (task.id)} - - {/each} + {#if !tasks.length}

Tom

{/if}