From 7c0b43db85f7f2f16a35ba85703aca44d40e8cb4 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 19 Feb 2025 19:22:38 +0200 Subject: [PATCH] feat(tasks): mark tasks as completed --- src/becca/entities/btask.ts | 1 + src/public/app/services/tasks.ts | 4 ++++ .../app/widgets/type_widgets/task_list.ts | 20 ++++++++++++++++++- src/routes/api/tasks.ts | 9 +++++++++ src/routes/routes.ts | 1 + src/services/tasks.ts | 6 ++++++ 6 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/becca/entities/btask.ts b/src/becca/entities/btask.ts index e04f9b8ab..6271384b3 100644 --- a/src/becca/entities/btask.ts +++ b/src/becca/entities/btask.ts @@ -75,6 +75,7 @@ export default class BTask extends AbstractBeccaEntity { parentNoteId: this.parentNoteId, title: this.title, dueDate: this.dueDate, + isDone: this.isDone, isDeleted: this.isDeleted, utcDateModified: this.utcDateModified }; diff --git a/src/public/app/services/tasks.ts b/src/public/app/services/tasks.ts index a5a6a9ceb..400e94712 100644 --- a/src/public/app/services/tasks.ts +++ b/src/public/app/services/tasks.ts @@ -5,3 +5,7 @@ export async function createNewTask(title: string) { title }); } + +export async function toggleTaskDone(taskId: string) { + await server.post(`tasks/${taskId}/toggle`); +} diff --git a/src/public/app/widgets/type_widgets/task_list.ts b/src/public/app/widgets/type_widgets/task_list.ts index 573e7de63..0f71092e9 100644 --- a/src/public/app/widgets/type_widgets/task_list.ts +++ b/src/public/app/widgets/type_widgets/task_list.ts @@ -48,12 +48,19 @@ const TPL = ` border-bottom: 1px solid var(--main-background-color); padding: 0.5em 1em; } + + .note-detail-task-list .task-container li .check { + margin-right: 0.5em; + } `; function buildTask(task: FTask) { - return `
  • ${task.title}
  • `; + return `\ +
  • + ${task.title} +
  • `; } export default class TaskListWidget extends TypeWidget { @@ -73,6 +80,17 @@ export default class TaskListWidget extends TypeWidget { this.#createNewTask(String(this.$addNewTask.val())); } }); + + this.$taskContainer.on("change", "input", (e) => { + const target = e.target as HTMLInputElement; + const taskId = target.dataset.taskId; + + if (!taskId) { + return; + } + + taskService.toggleTaskDone(taskId); + }); } async #createNewTask(title: string) { diff --git a/src/routes/api/tasks.ts b/src/routes/api/tasks.ts index 33516ef28..a9942ffa6 100644 --- a/src/routes/api/tasks.ts +++ b/src/routes/api/tasks.ts @@ -8,3 +8,12 @@ export function getTasks() { export function createNewTask(req: Request) { return tasksService.createNewTask(req.body); } + +export function toggleTaskDone(req: Request) { + const { taskId } = req.params; + if (!taskId) { + return; + } + + return tasksService.toggleTaskDone(taskId); +} diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 6cff1e033..563cd21d1 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -282,6 +282,7 @@ function register(app: express.Application) { apiRoute(GET, "/api/tasks", tasksRoute.getTasks); apiRoute(PST, "/api/tasks", tasksRoute.createNewTask); + apiRoute(PST, "/api/tasks/:taskId/toggle", tasksRoute.toggleTaskDone); // in case of local electron, local calls are allowed unauthenticated, for server they need auth const clipperMiddleware = isElectron ? [] : [auth.checkEtapiToken]; diff --git a/src/services/tasks.ts b/src/services/tasks.ts index 6a2f93710..dda9fc4b7 100644 --- a/src/services/tasks.ts +++ b/src/services/tasks.ts @@ -19,3 +19,9 @@ export function createNewTask(params: CreateTaskParams) { task } } + +export function toggleTaskDone(taskId: string) { + const task = becca.tasks[taskId]; + task.isDone = !task.isDone; + task.save(); +}