Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@
<string name="task_list_menu_sort_by">Trier par</string>
<string name="task_list_menu_sort_manual">Manuel</string>
<string name="task_list_menu_sort_due_date">Date d'échéance</string>
<string name="task_list_menu_sort_title">Titre</string>
<string name="task_list_menu_rename">Renommer</string>
<string name="task_list_menu_clear_all_completed_tasks">Effacer toutes les tâches terminées</string>
<string name="task_list_menu_delete">Supprimer la liste</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
<string name="task_list_menu_sort_by">Sort by</string>
<string name="task_list_menu_sort_manual">Manual</string>
<string name="task_list_menu_sort_due_date">Due date</string>
<string name="task_list_menu_sort_title">Title</string>
<string name="task_list_menu_rename">Rename</string>
<string name="task_list_menu_clear_all_completed_tasks">Clear all completed tasks</string>
<string name="task_list_menu_delete">Delete list</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ private fun TaskListDataModel.asTaskListUIModel(): TaskListUIModel {
else -> task.dateRange
}
}
TaskListSorting.Title -> mapOf(null to remainingTasks)
}

return TaskListUIModel(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ import net.opatry.tasks.resources.task_list_menu_rename
import net.opatry.tasks.resources.task_list_menu_sort_by
import net.opatry.tasks.resources.task_list_menu_sort_due_date
import net.opatry.tasks.resources.task_list_menu_sort_manual
import net.opatry.tasks.resources.task_list_menu_sort_title
import org.jetbrains.compose.resources.stringResource

enum class TaskListMenuAction {
Dismiss,
SortManual,
SortDate,
SortTitle,
Rename,
ClearCompletedTasks,
Delete,
Expand Down Expand Up @@ -106,6 +108,18 @@ fun TaskListMenu(
onClick = { onAction(TaskListMenuAction.SortDate) }
)

val isTitleSorting = taskList.sorting == TaskListSorting.Title
DropdownMenuItem(
text = {
RowWithIcon(
stringResource(Res.string.task_list_menu_sort_title),
LucideIcons.Check.takeIf { isTitleSorting }
)
},
enabled = !isTitleSorting,
onClick = { onAction(TaskListMenuAction.SortTitle) }
)

HorizontalDivider()

DropdownMenuItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ fun TaskListDetail(
TaskListMenuAction.Dismiss -> Unit
TaskListMenuAction.SortManual -> viewModel.sortBy(taskList.id, TaskListSorting.Manual)
TaskListMenuAction.SortDate -> viewModel.sortBy(taskList.id, TaskListSorting.DueDate)
TaskListMenuAction.SortTitle -> viewModel.sortBy(taskList.id, TaskListSorting.Title)
TaskListMenuAction.Rename -> showRenameTaskListDialog = true
TaskListMenuAction.ClearCompletedTasks -> showClearTaskListCompletedTasksDialog = true
TaskListMenuAction.Delete -> showDeleteTaskListDialog = true
Expand Down Expand Up @@ -690,7 +691,13 @@ fun TasksColumn(
RemainingTaskRow(
taskLists,
task,
showDate = taskList.sorting == TaskListSorting.Manual || dateRange is DateRange.Overdue
// TODO could come from the UI mapper/UI state
showDate = when {
taskList.sorting == TaskListSorting.Manual -> true
taskList.sorting == TaskListSorting.Title -> true
dateRange is DateRange.Overdue -> true
else -> false
}
) { action ->
when (action) {
TaskAction.ToggleCompletion -> onToggleCompletionState(task)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,35 @@ class TaskRepositoryCRUDTest {
assertEquals(task2.id, updatedTask.id)
assertEquals("00000000000000000000", updatedTask.position, "task should be moved at first position")
}

@Test
fun `sorting tasks by title should honor title (ignore case) and ignore parent task link`() =
runTaskRepositoryTest { repository ->
val (taskList, task1) = repository.createAndGetTask("list", "t1")
val task2 = repository.createAndGetTask(taskList.id, "T1")
val task3 = repository.createAndGetTask(taskList.id, "t100")
val task4 = repository.createAndGetTask(taskList.id, "t2")
repository.indentTask(task3.id)
// list
// - t2 [0000]
// - t100 [0000]
// - T1 [0001]
// - t1 [0002]

repository.sortTasksBy(taskList.id, TaskListSorting.Title)

// list
// - t1 (lowercase comes first)
// - T1 (uppercase come second)
// - t100 (no collator, 100 comes before 2)
// - t2
val updatedTaskList = repository.findTaskListById(taskList.id)
assertNotNull(updatedTaskList)
val tasks = updatedTaskList.tasks
assertEquals(4, tasks.size, "should have 4 tasks in list")
assertEquals(task1.id, tasks[0].id, "first task should be t1")
assertEquals(task2.id, tasks[1].id, "second task should be T1")
assertEquals(task3.id, tasks[2].id, "third task should be t100")
assertEquals(task4.id, tasks[3].id, "fourth task should be t2")
}
}
Loading