feat(client/tasks): display tasks

This commit is contained in:
Elian Doran 2025-02-18 19:58:00 +02:00
parent 1024733252
commit 7cba5a7c7d
No known key found for this signature in database
3 changed files with 67 additions and 1 deletions

View File

@ -0,0 +1,31 @@
import type { Froca } from "../services/froca-interface.js";
export interface FTaskRow {
taskId: string;
parentNoteId: string;
title: string;
dueDate?: string;
isDone?: boolean;
}
export default class FTask {
private froca: Froca;
taskId!: string;
parentNoteId!: string;
title!: string;
dueDate?: string;
isDone!: boolean;
constructor(froca: Froca, row: FTaskRow) {
this.froca = froca;
this.update(row);
}
update(row: FTaskRow) {
this.taskId = row.taskId;
this.parentNoteId = row.parentNoteId;
this.title = row.title;
this.dueDate = row.dueDate;
this.isDone = !!row.isDone;
}
}

View File

@ -6,6 +6,8 @@ import appContext from "../components/app_context.js";
import FBlob, { type FBlobRow } from "../entities/fblob.js"; import FBlob, { type FBlobRow } from "../entities/fblob.js";
import FAttachment, { type FAttachmentRow } from "../entities/fattachment.js"; import FAttachment, { type FAttachmentRow } from "../entities/fattachment.js";
import type { Froca } from "./froca-interface.js"; import type { Froca } from "./froca-interface.js";
import FTask from "../entities/ftask.js";
import type { FTaskRow } from "../entities/ftask.js";
interface SubtreeResponse { interface SubtreeResponse {
notes: FNoteRow[]; notes: FNoteRow[];
@ -37,6 +39,7 @@ class FrocaImpl implements Froca {
attributes!: Record<string, FAttribute>; attributes!: Record<string, FAttribute>;
attachments!: Record<string, FAttachment>; attachments!: Record<string, FAttachment>;
blobPromises!: Record<string, Promise<void | FBlob> | null>; blobPromises!: Record<string, Promise<void | FBlob> | null>;
tasks!: Record<string, FTask>;
constructor() { constructor() {
this.initializedPromise = this.loadInitialTree(); this.initializedPromise = this.loadInitialTree();
@ -52,6 +55,7 @@ class FrocaImpl implements Froca {
this.attributes = {}; this.attributes = {};
this.attachments = {}; this.attachments = {};
this.blobPromises = {}; this.blobPromises = {};
this.tasks = {};
this.addResp(resp); this.addResp(resp);
} }
@ -368,6 +372,20 @@ class FrocaImpl implements Froca {
}); });
} }
async getTasks() {
const taskRows = await server.get<FTaskRow[]>(`tasks`);
return this.processTaskRow(taskRows);
}
processTaskRow(taskRows: FTaskRow[]): FTask[] {
return taskRows.map((taskRow) => {
const task = new FTask(this, taskRow);
this.tasks[task.taskId] = task;
return task;
});
}
async getBlob(entityType: string, entityId: string) { async getBlob(entityType: string, entityId: string) {
// I'm not sure why we're not using blobIds directly, it would save us this composite key ... // I'm not sure why we're not using blobIds directly, it would save us this composite key ...
// perhaps one benefit is that we're always requesting the latest blob, not relying on perhaps faulty/slow // perhaps one benefit is that we're always requesting the latest blob, not relying on perhaps faulty/slow

View File

@ -1,18 +1,28 @@
import type FNote from "../../entities/fnote.js"; import type FNote from "../../entities/fnote.js";
import type FTask from "../../entities/ftask.js";
import froca from "../../services/froca.js";
import TypeWidget from "./type_widget.js"; import TypeWidget from "./type_widget.js";
const TPL = ` const TPL = `
<div class="note-detail-task-list note-detail-printable"> <div class="note-detail-task-list note-detail-printable">
Task list goes here. <div class="task-container">
</div>
</div> </div>
`; `;
function buildTask(task: FTask) {
return `<div class="task">${task.title}</div>`;
}
export default class TaskListWidget extends TypeWidget { export default class TaskListWidget extends TypeWidget {
private $taskContainer!: JQuery<HTMLElement>;
static getType() { return "taskList" } static getType() { return "taskList" }
doRender() { doRender() {
this.$widget = $(TPL); this.$widget = $(TPL);
this.$taskContainer = this.$widget.find(".task-container");
} }
async doRefresh(note: FNote) { async doRefresh(note: FNote) {
@ -21,6 +31,13 @@ export default class TaskListWidget extends TypeWidget {
if (!this.note) { if (!this.note) {
return; return;
} }
this.$taskContainer.clearQueue();
const tasks = await froca.getTasks();
for (const task of tasks) {
this.$taskContainer.append($(buildTask(task)));
}
} }
} }