|
|
|
@ -2,7 +2,7 @@
|
|
|
|
|
<div class="card"> |
|
|
|
|
<ConfirmDialog></ConfirmDialog> |
|
|
|
|
<DataTable :value="computedTodos" :lazy="true" tableStyle="min-width: 50rem" removableSort |
|
|
|
|
v-model:sortField="sortField" v-model:sortOrder="sortOrder"> |
|
|
|
|
:sortMode="'multiple'" v-model:multiSortMeta="multiSortMeta"> |
|
|
|
|
<Column field="number" header="#" /> |
|
|
|
|
<Column field="id" header="ID" sortable /> |
|
|
|
|
<Column field="title" header="Title" sortable /> |
|
|
|
@ -22,6 +22,7 @@ import { useConfirm } from "primevue/useconfirm";
|
|
|
|
|
import { useToast } from "primevue/usetoast"; |
|
|
|
|
import { useTodoStore } from "@/stores/todoStore"; |
|
|
|
|
|
|
|
|
|
import type { DataTableSortMeta } from "primevue/datatable"; |
|
|
|
|
import type { Todo } from "@/schemas/todo"; |
|
|
|
|
|
|
|
|
|
const confirm = useConfirm(); |
|
|
|
@ -29,16 +30,27 @@ const store = useTodoStore();
|
|
|
|
|
const toast = useToast(); |
|
|
|
|
|
|
|
|
|
// Reactive bindings for sorting |
|
|
|
|
const sortField = ref<string>(""); |
|
|
|
|
const sortOrder = ref<number>(); |
|
|
|
|
const multiSortMeta = ref<DataTableSortMeta[]>([]); |
|
|
|
|
|
|
|
|
|
function sortTodos(): Todo[] { |
|
|
|
|
let todos: Todo[] = JSON.parse(JSON.stringify(store.todos)); // deep copy |
|
|
|
|
|
|
|
|
|
if (sortField.value) { // string or null |
|
|
|
|
todos = (sortOrder.value == 1) // 1 or -1 |
|
|
|
|
? todos.sort((a, b) => a[sortField.value as keyof Todo]?.localeCompare(b[sortField.value as keyof Todo] || "") || 0) |
|
|
|
|
: todos.sort((a, b) => b[sortField.value as keyof Todo]?.localeCompare(a[sortField.value as keyof Todo] || "") || 0); |
|
|
|
|
// Loop in reverse order to apply the sorting correctly |
|
|
|
|
for (let i = multiSortMeta.value.length - 1; i >= 0; i--) { |
|
|
|
|
|
|
|
|
|
const sort: DataTableSortMeta = multiSortMeta.value[i]; |
|
|
|
|
const value = (item: Todo): string => { |
|
|
|
|
if (typeof sort.field === "string") { |
|
|
|
|
return item[sort.field as keyof Todo] || ""; |
|
|
|
|
} |
|
|
|
|
else if (typeof sort.field === "function") { |
|
|
|
|
return sort.field(item) || ""; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return ""; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
todos.sort((a, b) => sort.order! * value(a).localeCompare(value(b))); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return todos; |
|
|
|
@ -75,7 +87,7 @@ const removeTodo = (id: String) => {
|
|
|
|
|
}; |
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
<style> |
|
|
|
|
<style scoped> |
|
|
|
|
.pointer { |
|
|
|
|
cursor: pointer; |
|
|
|
|
} |
|
|
|
|