From b53eff9fd101047d62d0305d09f269c983b3c544 Mon Sep 17 00:00:00 2001 From: mARTin-B78 Date: Mon, 11 May 2026 12:29:01 +0200 Subject: [PATCH] feat: sort completed tasks to bottom + align Add task input - Completed tasks in someday lists now always render below all active tasks. Slot system builds from incomplete tasks only; done tasks get their own section at the bottom outside the droppable slots. - "Add task..." input right margin increased to 24px so its right edge stops before the provider icon (G) column, matching task row layout. v1.109.0 --- package.json | 2 +- src/components/WeeklyView.tsx | 53 ++++++++++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 5ceb677..7d2e1e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.108.4", + "version": "1.109.0", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/components/WeeklyView.tsx b/src/components/WeeklyView.tsx index cc66825..e48d783 100644 --- a/src/components/WeeklyView.tsx +++ b/src/components/WeeklyView.tsx @@ -8530,13 +8530,17 @@ export default function WeeklyView() { }} > {(() => { - const slotCount = getSomedaySlotCount(list.tasks); - const indexedTasks = list.tasks.filter(t => t.somedaySlotIndex !== null && t.somedaySlotIndex !== undefined && t.somedaySlotIndex < slotCount); - const unindexedTasks = list.tasks.filter(t => t.somedaySlotIndex === null || t.somedaySlotIndex === undefined || t.somedaySlotIndex >= slotCount); - + // Separate complete from active so done tasks always render at bottom + const activeTasks = list.tasks.filter(t => !t.completed); + const doneTasks = list.tasks.filter(t => t.completed); + + const slotCount = getSomedaySlotCount(activeTasks); + const indexedTasks = activeTasks.filter(t => t.somedaySlotIndex !== null && t.somedaySlotIndex !== undefined && t.somedaySlotIndex < slotCount); + const unindexedTasks = activeTasks.filter(t => t.somedaySlotIndex === null || t.somedaySlotIndex === undefined || t.somedaySlotIndex >= slotCount); + // Fill indexed slots and put unindexed tasks in empty slots starting from top const slots = Array.from({ length: slotCount }, (_, i) => ({ index: i, task: indexedTasks.find(t => t.somedaySlotIndex === i) || null })); - + let unindexedIdx = 0; const finalSlots = slots.map(slot => { if (!slot.task && unindexedIdx < unindexedTasks.length) { @@ -8545,7 +8549,7 @@ export default function WeeklyView() { return slot; }); - // Any remaining unindexed tasks that didn't fit in slots + // Any remaining unindexed active tasks that didn't fit in slots const remainingTasks = unindexedTasks.slice(unindexedIdx); return ( @@ -8718,6 +8722,41 @@ export default function WeeklyView() { /> ))} + {/* Completed tasks always rendered at bottom */} + {doneTasks.map((task) => ( +
+ toggleTask(task.id)} + onEdit={() => setEditingTaskId(task.id)} + onUpdate={(title) => updateTask(task.id, title)} + onDelete={() => deleteTask(task.id)} + onNotes={(notes) => updateTaskNotes(task.id, notes)} + onUrl={(url) => updateTaskUrl(task.id, url)} + onRollToggle={() => toggleTaskRolling(task.id)} + onRecurrence={() => setSelectedTaskForRecurrence(task)} + onDragStart={(e, t) => handleDragStart(e, t)} + onDragEnd={handleDragEnd} + variant="minimal" + isSomeday={true} + onAddSubTask={addSubTask} + onToggleSubTask={toggleSubTask} + onDeleteSubTask={deleteSubTask} + onUpdateSubTask={updateSubTask} + editingTaskId={editingTaskId} + onSetEditingTaskId={setEditingTaskId} + showTaskCheckboxes={effectiveShowTaskCheckboxes} + showProjectIcons={effectiveShowProjectIcons} + showPriorityIcons={effectiveShowPriorityIcons} + priorityStyle={effectivePriorityStyle} + projects={projects} + onProjectAssign={assignProject} + kanbanStages={kanbanStages} + /> +
+ ))} ); })()} @@ -9820,7 +9859,7 @@ function SomedayAddTask({