feat: sort list
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
- [x] validate cron string
|
- [x] validate cron string
|
||||||
- [x] clone task
|
- [x] clone task
|
||||||
- [x] delete task
|
- [x] delete task
|
||||||
- [ ] list option: sort
|
- [x] list option: sort
|
||||||
- [x] list option: show last completion
|
- [x] list option: show last completion
|
||||||
- [x] list option: show next refresh
|
- [x] list option: show next refresh
|
||||||
- [x] list option: move completed below
|
- [x] list option: move completed below
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ import type { Task } from "@/types";
|
|||||||
import { getTasks, createTask, deleteTask } from "@/api/tasks";
|
import { getTasks, createTask, deleteTask } from "@/api/tasks";
|
||||||
import { CirclePlus } from "@lucide/vue";
|
import { CirclePlus } from "@lucide/vue";
|
||||||
import TaskItem from "@/components/TaskItem.vue";
|
import TaskItem from "@/components/TaskItem.vue";
|
||||||
import { taskCompleted } from "@/lib/tasks";
|
import { taskCompleted, sortTasks } from "@/lib/tasks";
|
||||||
|
import { SortType } from "@/enums";
|
||||||
|
|
||||||
const taskInput = ref<string>("");
|
const taskInput = ref<string>("");
|
||||||
const tasks = ref<Task[]>([]);
|
const tasks = ref<Task[]>([]);
|
||||||
const list = ref<string>("test");
|
const list = ref<string>("test");
|
||||||
|
const sortType = ref<SortType>(SortType.RESET_DATE);
|
||||||
|
const sortReverse = ref<boolean>(false);
|
||||||
const showLastChecked = ref<boolean>(false);
|
const showLastChecked = ref<boolean>(false);
|
||||||
const showNextReset = ref<boolean>(false);
|
const showNextReset = ref<boolean>(false);
|
||||||
const separateCompleted = ref<boolean>(false);
|
const separateCompleted = ref<boolean>(false);
|
||||||
@@ -19,10 +22,15 @@ function fetchTasks() {
|
|||||||
void getTasks(list.value)
|
void getTasks(list.value)
|
||||||
.then((data: Task[]) => {
|
.then((data: Task[]) => {
|
||||||
tasks.value = data;
|
tasks.value = data;
|
||||||
|
reSortTasks();
|
||||||
setTimeout(fetchTasks, 10000);
|
setTimeout(fetchTasks, 10000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reSortTasks() {
|
||||||
|
tasks.value = sortTasks(tasks.value, sortType.value, sortReverse.value);
|
||||||
|
}
|
||||||
|
|
||||||
function onNewTask() {
|
function onNewTask() {
|
||||||
if (taskInput.value.trim()) {
|
if (taskInput.value.trim()) {
|
||||||
void createTask(list.value, {
|
void createTask(list.value, {
|
||||||
@@ -31,6 +39,7 @@ function onNewTask() {
|
|||||||
})
|
})
|
||||||
.then((data: Task) => {
|
.then((data: Task) => {
|
||||||
tasks.value.push(data);
|
tasks.value.push(data);
|
||||||
|
reSortTasks();
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
taskInput.value = "";
|
taskInput.value = "";
|
||||||
@@ -53,6 +62,14 @@ function onDeleteTask(task: Task) {
|
|||||||
tasks.value.splice(tasks.value.indexOf(task), 1);
|
tasks.value.splice(tasks.value.indexOf(task), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onChangeSortType() {
|
||||||
|
reSortTasks();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangeSortReverse() {
|
||||||
|
reSortTasks();
|
||||||
|
}
|
||||||
|
|
||||||
onBeforeMount(fetchTasks);
|
onBeforeMount(fetchTasks);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -114,6 +131,20 @@ onBeforeMount(fetchTasks);
|
|||||||
<div class="collapse-title">Options</div>
|
<div class="collapse-title">Options</div>
|
||||||
<div class="collapse-content text-sm">
|
<div class="collapse-content text-sm">
|
||||||
<fieldset class="fieldset flex flex-col gap-2">
|
<fieldset class="fieldset flex flex-col gap-2">
|
||||||
|
<label class="label">
|
||||||
|
Sort by
|
||||||
|
<select v-model="sortType" class="select" @change="onChangeSortType">
|
||||||
|
<option :value="SortType.CREATED_AT">Creation date</option>
|
||||||
|
<option :value="SortType.UPDATED_AT">Creation or update date</option>
|
||||||
|
<option :value="SortType.CHECK_DATE">Last check date</option>
|
||||||
|
<option :value="SortType.RESET_DATE">Next reset date</option>
|
||||||
|
<option :value="SortType.NAME">Name</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label class="label">
|
||||||
|
<input v-model="sortReverse" type="checkbox" class="checkbox" @change="onChangeSortReverse" />
|
||||||
|
Reverse sort
|
||||||
|
</label>
|
||||||
<label class="label">
|
<label class="label">
|
||||||
<input v-model="showLastChecked" type="checkbox" class="checkbox" />
|
<input v-model="showLastChecked" type="checkbox" class="checkbox" />
|
||||||
Show last checked time
|
Show last checked time
|
||||||
|
|||||||
@@ -6,3 +6,11 @@ export enum CronType {
|
|||||||
EVERY_YEAR = 5,
|
EVERY_YEAR = 5,
|
||||||
SPECIFIC = 6,
|
SPECIFIC = 6,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum SortType {
|
||||||
|
CREATED_AT = 1,
|
||||||
|
UPDATED_AT = 2,
|
||||||
|
CHECK_DATE = 3,
|
||||||
|
RESET_DATE = 4,
|
||||||
|
NAME = 5,
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { SortType } from "@/enums";
|
||||||
import type { RawTask, Task } from "@/types";
|
import type { RawTask, Task } from "@/types";
|
||||||
import {CronExpressionParser} from "cron-parser";
|
import {CronExpressionParser} from "cron-parser";
|
||||||
|
|
||||||
@@ -6,6 +7,8 @@ export function parseTask(task: RawTask): Task {
|
|||||||
id: task.id,
|
id: task.id,
|
||||||
name: task.name,
|
name: task.name,
|
||||||
reset_cron: task.reset_cron,
|
reset_cron: task.reset_cron,
|
||||||
|
created_at: new Date(task.created_at),
|
||||||
|
updated_at: new Date(task.updated_at),
|
||||||
check_date: task.check_date ? new Date(task.check_date) : null,
|
check_date: task.check_date ? new Date(task.check_date) : null,
|
||||||
previous_check_date: task.previous_check_date
|
previous_check_date: task.previous_check_date
|
||||||
? new Date(task.previous_check_date)
|
? new Date(task.previous_check_date)
|
||||||
@@ -32,3 +35,20 @@ export function taskCompleted(task: Task): boolean {
|
|||||||
}
|
}
|
||||||
return nextReset.getTime() > (new Date()).getTime();
|
return nextReset.getTime() > (new Date()).getTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sortTasks(tasks: Task[], sortType: SortType, reverse: boolean): Task[] {
|
||||||
|
switch (sortType) {
|
||||||
|
case SortType.CREATED_AT:
|
||||||
|
return tasks.slice().sort((a: Task, b: Task) => (reverse ? -1 : 1) * (a.created_at.getTime() - b.created_at.getTime()));
|
||||||
|
case SortType.UPDATED_AT:
|
||||||
|
return tasks.slice().sort((a: Task, b: Task) => (reverse ? -1 : 1) * (a.updated_at.getTime() - b.updated_at.getTime()));
|
||||||
|
case SortType.CHECK_DATE:
|
||||||
|
return tasks.slice().sort((a: Task, b: Task) => (reverse ? -1 : 1) * ((a.check_date ?? a.created_at).getTime() - (b.check_date ?? b.created_at).getTime()));
|
||||||
|
case SortType.RESET_DATE:
|
||||||
|
return tasks.slice().sort((a: Task, b: Task) => (reverse ? -1 : 1) * (taskNextReset(a) ?? a.created_at).getTime() - (taskNextReset(b) ?? b.created_at).getTime());
|
||||||
|
case SortType.NAME:
|
||||||
|
return tasks.slice().sort((a: Task, b: Task) => (reverse ? -1 : 1) * a.name.localeCompare(b.name));
|
||||||
|
default:
|
||||||
|
return tasks.slice();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ export interface Task {
|
|||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
reset_cron: string | null;
|
reset_cron: string | null;
|
||||||
|
created_at: Date;
|
||||||
|
updated_at: Date;
|
||||||
check_date: Date | null;
|
check_date: Date | null;
|
||||||
previous_check_date: Date | null;
|
previous_check_date: Date | null;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user