From 2d9440b05c0f4756c41bb1af8160e63a4f720633 Mon Sep 17 00:00:00 2001 From: medic-bot Date: Sun, 8 Mar 2026 11:04:32 -0400 Subject: [PATCH] Sort completed main tasks to the bottom of the list Add asc(tasks.completed) as the primary sort key in getOrderClauses() so completed tasks always appear after active ones regardless of the chosen sort mode (position, priority, dueDate, title, createdAt). Also apply the same completed-first ordering to: - getSubtasks() in tasks.ts - noDateTasks query in widgetSync.ts - subtasks query in widgetSync.ts Ref: simpl-liste#15 Co-Authored-By: Claude Opus 4.6 --- src/db/repository/tasks.ts | 13 +++++++------ src/services/widgetSync.ts | 4 ++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/db/repository/tasks.ts b/src/db/repository/tasks.ts index 0d5d376..d2668c4 100644 --- a/src/db/repository/tasks.ts +++ b/src/db/repository/tasks.ts @@ -85,18 +85,19 @@ export async function getTasksByList(listId: string, filters?: TaskFilters) { function getOrderClauses(sortBy: SortBy, sortOrder: SortOrder) { const dir = sortOrder === 'asc' ? asc : desc; + // Always sort completed tasks to the bottom, then apply the requested sort switch (sortBy) { case 'priority': - return [dir(tasks.priority), asc(tasks.position)]; + return [asc(tasks.completed), dir(tasks.priority), asc(tasks.position)]; case 'dueDate': - return [dir(tasks.dueDate), asc(tasks.position)]; + return [asc(tasks.completed), dir(tasks.dueDate), asc(tasks.position)]; case 'title': - return [dir(tasks.title)]; + return [asc(tasks.completed), dir(tasks.title)]; case 'createdAt': - return [dir(tasks.createdAt)]; + return [asc(tasks.completed), dir(tasks.createdAt)]; case 'position': default: - return [asc(tasks.position), desc(tasks.createdAt)]; + return [asc(tasks.completed), asc(tasks.position), desc(tasks.createdAt)]; } } @@ -105,7 +106,7 @@ export async function getSubtasks(parentId: string) { .select() .from(tasks) .where(eq(tasks.parentId, parentId)) - .orderBy(asc(tasks.position)); + .orderBy(asc(tasks.completed), asc(tasks.position)); } export async function getTaskById(id: string) { diff --git a/src/services/widgetSync.ts b/src/services/widgetSync.ts index c78805a..e60c623 100644 --- a/src/services/widgetSync.ts +++ b/src/services/widgetSync.ts @@ -89,7 +89,7 @@ export async function syncWidgetData(): Promise { isNull(tasks.dueDate) ) ) - .orderBy(asc(tasks.position)); + .orderBy(asc(tasks.completed), asc(tasks.position)); const toWidgetTask = (t: typeof upcomingTasks[number]): WidgetTask => ({ id: t.id, @@ -117,7 +117,7 @@ export async function syncWidgetData(): Promise { .select({ id: tasks.id, title: tasks.title, completed: tasks.completed }) .from(tasks) .where(eq(tasks.parentId, task.id)) - .orderBy(asc(tasks.position)); + .orderBy(asc(tasks.completed), asc(tasks.position)); task.subtasks = subs; } }