feat(tasks): make due date editable

This commit is contained in:
Elian Doran 2025-02-25 18:36:46 +02:00
parent 84e8559401
commit fcd7b986aa
No known key found for this signature in database
6 changed files with 72 additions and 8 deletions

View File

@ -372,6 +372,10 @@ class FrocaImpl implements Froca {
});
}
getTask(taskId: string) {
return this.tasks[taskId];
}
async getTasks(parentNoteId: string) {
const taskRows = await server.get<FTaskRow[]>(`tasks/${parentNoteId}`);
return this.processTaskRow(taskRows);

View File

@ -1,3 +1,4 @@
import type FTask from "../entities/ftask.js";
import server from "./server.js";
interface CreateNewTasksOpts {
@ -15,3 +16,15 @@ export async function createNewTask({ parentNoteId, title }: CreateNewTasksOpts)
export async function toggleTaskDone(taskId: string) {
await server.post(`tasks/${taskId}/toggle`);
}
export async function updateTask(task: FTask) {
if (!task.taskId) {
return;
}
await server.patch(`tasks/${task.taskId}/`, {
taskId: task.taskId,
dueDate: task.dueDate,
isDone: task.isDone
});
}

View File

@ -68,8 +68,8 @@ function buildTasks(tasks: FTask[]) {
let html = '';
for (const task of tasks) {
html += `<li class="task">`;
html += `<input type="checkbox" class="check" data-task-id="${task.taskId}" ${task.isDone ? "checked" : ""} />`;
html += `<li class="task" data-task-id="${task.taskId}">`;
html += `<input type="checkbox" class="check" ${task.isDone ? "checked" : ""} />`;
html += task.title;
html += `<div class="edit-container"></div>`;
html += `</li>`;
@ -79,8 +79,10 @@ function buildTasks(tasks: FTask[]) {
}
function buildEditContainer() {
const html = `Edit goes here.`;
return html;
return `\
<label>Due date:</label>
<input type="date" data-tasks-role="due-date" />
`;
}
export default class TaskListWidget extends TypeWidget {
@ -102,9 +104,9 @@ export default class TaskListWidget extends TypeWidget {
}
});
this.$taskContainer.on("change", "input", (e) => {
const target = e.target as HTMLInputElement;
const taskId = target.dataset.taskId;
this.$taskContainer.on("change", "input.check", (e) => {
const $target = $(e.target);
const taskId = $target.closest("li")[0].dataset.taskId;
if (!taskId) {
return;
@ -114,15 +116,47 @@ export default class TaskListWidget extends TypeWidget {
});
this.$taskContainer.on("click", "li", (e) => {
const $target = $(e.target);
// Don't collapse when clicking on an inside element such as the due date dropdown.
if (e.currentTarget !== e.target) {
return;
}
// Clear existing edit containers.
const $existingContainers = this.$taskContainer.find(".edit-container");
$existingContainers.html("");
// Add the new edit container.
const $target = $(e.target);
const $editContainer = $target.find(".edit-container");
$editContainer.html(buildEditContainer());
});
this.$taskContainer.on("change", "input", async (e) => {
const $target = $(e.target);
const taskId = $target.closest("li")[0].dataset.taskId;
if (!taskId) {
return;
}
const task = froca.getTask(taskId);
if (!task) {
return;
}
const role = $target.data("tasks-role");
const value = String($target.val());
switch (role) {
case "due-date":
task.dueDate = value;
break;
}
await taskService.updateTask(task);
});
}
async #createNewTask(title: string) {

View File

@ -10,6 +10,10 @@ export function createNewTask(req: Request) {
return tasksService.createNewTask(req.body);
}
export function updateTask(req: Request) {
return tasksService.updateTask(req.params.taskId, req.body);
}
export function toggleTaskDone(req: Request) {
const { taskId } = req.params;
if (!taskId) {

View File

@ -283,6 +283,7 @@ function register(app: express.Application) {
apiRoute(GET, "/api/tasks/:parentNoteId", tasksRoute.getTasks);
apiRoute(PST, "/api/tasks", tasksRoute.createNewTask);
apiRoute(PST, "/api/tasks/:taskId/toggle", tasksRoute.toggleTaskDone);
apiRoute(PATCH, "/api/tasks/:taskId", tasksRoute.updateTask);
// in case of local electron, local calls are allowed unauthenticated, for server they need auth
const clipperMiddleware = isElectron ? [] : [auth.checkEtapiToken];

View File

@ -1,5 +1,6 @@
import becca from "../becca/becca.js";
import BTask from "../becca/entities/btask.js";
import type { TaskRow } from "../becca/entities/rows.js";
export function getTasks(parentNoteId: string) {
return becca.getTasks()
@ -26,3 +27,10 @@ export function toggleTaskDone(taskId: string) {
task.isDone = !task.isDone;
task.save();
}
export function updateTask(taskId: string, content: TaskRow) {
const task = becca.tasks[taskId];
task.isDone = !!content.isDone;
task.dueDate = content.dueDate;
task.save();
}