mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-07-30 19:52:28 +08:00
feat(tasks): make due date editable
This commit is contained in:
parent
84e8559401
commit
fcd7b986aa
@ -372,6 +372,10 @@ class FrocaImpl implements Froca {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTask(taskId: string) {
|
||||||
|
return this.tasks[taskId];
|
||||||
|
}
|
||||||
|
|
||||||
async getTasks(parentNoteId: string) {
|
async getTasks(parentNoteId: string) {
|
||||||
const taskRows = await server.get<FTaskRow[]>(`tasks/${parentNoteId}`);
|
const taskRows = await server.get<FTaskRow[]>(`tasks/${parentNoteId}`);
|
||||||
return this.processTaskRow(taskRows);
|
return this.processTaskRow(taskRows);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import type FTask from "../entities/ftask.js";
|
||||||
import server from "./server.js";
|
import server from "./server.js";
|
||||||
|
|
||||||
interface CreateNewTasksOpts {
|
interface CreateNewTasksOpts {
|
||||||
@ -15,3 +16,15 @@ export async function createNewTask({ parentNoteId, title }: CreateNewTasksOpts)
|
|||||||
export async function toggleTaskDone(taskId: string) {
|
export async function toggleTaskDone(taskId: string) {
|
||||||
await server.post(`tasks/${taskId}/toggle`);
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -68,8 +68,8 @@ function buildTasks(tasks: FTask[]) {
|
|||||||
let html = '';
|
let html = '';
|
||||||
|
|
||||||
for (const task of tasks) {
|
for (const task of tasks) {
|
||||||
html += `<li class="task">`;
|
html += `<li class="task" data-task-id="${task.taskId}">`;
|
||||||
html += `<input type="checkbox" class="check" data-task-id="${task.taskId}" ${task.isDone ? "checked" : ""} />`;
|
html += `<input type="checkbox" class="check" ${task.isDone ? "checked" : ""} />`;
|
||||||
html += task.title;
|
html += task.title;
|
||||||
html += `<div class="edit-container"></div>`;
|
html += `<div class="edit-container"></div>`;
|
||||||
html += `</li>`;
|
html += `</li>`;
|
||||||
@ -79,8 +79,10 @@ function buildTasks(tasks: FTask[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildEditContainer() {
|
function buildEditContainer() {
|
||||||
const html = `Edit goes here.`;
|
return `\
|
||||||
return html;
|
<label>Due date:</label>
|
||||||
|
<input type="date" data-tasks-role="due-date" />
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class TaskListWidget extends TypeWidget {
|
export default class TaskListWidget extends TypeWidget {
|
||||||
@ -102,9 +104,9 @@ export default class TaskListWidget extends TypeWidget {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$taskContainer.on("change", "input", (e) => {
|
this.$taskContainer.on("change", "input.check", (e) => {
|
||||||
const target = e.target as HTMLInputElement;
|
const $target = $(e.target);
|
||||||
const taskId = target.dataset.taskId;
|
const taskId = $target.closest("li")[0].dataset.taskId;
|
||||||
|
|
||||||
if (!taskId) {
|
if (!taskId) {
|
||||||
return;
|
return;
|
||||||
@ -114,15 +116,47 @@ export default class TaskListWidget extends TypeWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.$taskContainer.on("click", "li", (e) => {
|
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.
|
// Clear existing edit containers.
|
||||||
const $existingContainers = this.$taskContainer.find(".edit-container");
|
const $existingContainers = this.$taskContainer.find(".edit-container");
|
||||||
|
|
||||||
$existingContainers.html("");
|
$existingContainers.html("");
|
||||||
|
|
||||||
// Add the new edit container.
|
// Add the new edit container.
|
||||||
const $target = $(e.target);
|
|
||||||
const $editContainer = $target.find(".edit-container");
|
const $editContainer = $target.find(".edit-container");
|
||||||
$editContainer.html(buildEditContainer());
|
$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) {
|
async #createNewTask(title: string) {
|
||||||
|
@ -10,6 +10,10 @@ export function createNewTask(req: Request) {
|
|||||||
return tasksService.createNewTask(req.body);
|
return tasksService.createNewTask(req.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateTask(req: Request) {
|
||||||
|
return tasksService.updateTask(req.params.taskId, req.body);
|
||||||
|
}
|
||||||
|
|
||||||
export function toggleTaskDone(req: Request) {
|
export function toggleTaskDone(req: Request) {
|
||||||
const { taskId } = req.params;
|
const { taskId } = req.params;
|
||||||
if (!taskId) {
|
if (!taskId) {
|
||||||
|
@ -283,6 +283,7 @@ function register(app: express.Application) {
|
|||||||
apiRoute(GET, "/api/tasks/:parentNoteId", tasksRoute.getTasks);
|
apiRoute(GET, "/api/tasks/:parentNoteId", tasksRoute.getTasks);
|
||||||
apiRoute(PST, "/api/tasks", tasksRoute.createNewTask);
|
apiRoute(PST, "/api/tasks", tasksRoute.createNewTask);
|
||||||
apiRoute(PST, "/api/tasks/:taskId/toggle", tasksRoute.toggleTaskDone);
|
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
|
// in case of local electron, local calls are allowed unauthenticated, for server they need auth
|
||||||
const clipperMiddleware = isElectron ? [] : [auth.checkEtapiToken];
|
const clipperMiddleware = isElectron ? [] : [auth.checkEtapiToken];
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import becca from "../becca/becca.js";
|
import becca from "../becca/becca.js";
|
||||||
import BTask from "../becca/entities/btask.js";
|
import BTask from "../becca/entities/btask.js";
|
||||||
|
import type { TaskRow } from "../becca/entities/rows.js";
|
||||||
|
|
||||||
export function getTasks(parentNoteId: string) {
|
export function getTasks(parentNoteId: string) {
|
||||||
return becca.getTasks()
|
return becca.getTasks()
|
||||||
@ -26,3 +27,10 @@ export function toggleTaskDone(taskId: string) {
|
|||||||
task.isDone = !task.isDone;
|
task.isDone = !task.isDone;
|
||||||
task.save();
|
task.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function updateTask(taskId: string, content: TaskRow) {
|
||||||
|
const task = becca.tasks[taskId];
|
||||||
|
task.isDone = !!content.isDone;
|
||||||
|
task.dueDate = content.dueDate;
|
||||||
|
task.save();
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user