From b1560c38d5eba32b0b313786d3e049797c770abe Mon Sep 17 00:00:00 2001 From: Skitty1238 <157652284+Skitty1238@users.noreply.github.com> Date: Mon, 9 Jun 2025 13:43:25 -0400 Subject: implemented undoable deletion so that tasks reappear in Google Tasks upon undo in Dash --- src/client/documents/Documents.ts | 1 + src/client/views/nodes/TaskBox.tsx | 52 +++++++++++++++++++------- src/server/ApiManagers/GeneralGoogleManager.ts | 8 ++-- 3 files changed, 44 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index a29e7a9f5..683a18aee 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -530,6 +530,7 @@ export class DocumentOptions { $task_completed?: BoolInfo | boolean = new BoolInfo('whether the task is completed', /*filterable*/ false); $googleTaskId?: STRt = new StrInfo('Google Task ID for syncing'); $task_lastSyncedAt?: STRt = new StrInfo('last update time for task node'); + $task_deleted?: BoolInfo | boolean = new BoolInfo('whether task is deleted or not', /*filterable*/ false); _calendar_date?: DateInfo | DateField = new DateInfo('current selected date of a calendar', /*filterable*/ false); _calendar_dateRange?: STRt = new StrInfo('date range shown on a calendar', false); diff --git a/src/client/views/nodes/TaskBox.tsx b/src/client/views/nodes/TaskBox.tsx index 5a54e8049..f415f8b52 100644 --- a/src/client/views/nodes/TaskBox.tsx +++ b/src/client/views/nodes/TaskBox.tsx @@ -31,11 +31,13 @@ export class TaskBox extends ViewBoxBaseComponent() { text: string; due?: string; completed: boolean; + deleted?: boolean; } = { title: '', text: '', due: '', completed: false, + deleted: false, }; /** @@ -215,20 +217,28 @@ export class TaskBox extends ViewBoxBaseComponent() { * @returns - an object containing the task details */ - private buildGoogleTaskBody(): Record { + private buildGoogleTaskBody(): Record { const doc = this.Document; const title = StrCast(doc.title, 'Untitled Task'); const notes = StrCast(doc[this.fieldKey]); const due = this.computeDueDate(); const completed = !!doc.$task_completed; - return { + const body: Record = { title, notes, due, status: completed ? 'completed' : 'needsAction', completed: completed ? new Date().toISOString() : undefined, }; + + if (doc.$dashDeleted === true) { + body.deleted = true; + } else if (doc.$dashDeleted === false) { + body.deleted = false; + } + + return body; } /** @@ -307,7 +317,11 @@ export class TaskBox extends ViewBoxBaseComponent() { const dashUpdated = new Date(StrCast(doc.$task_lastSyncedAt)); const dashChanged = - StrCast(doc.title) !== this._lastSyncedTask.title || StrCast(doc[this.fieldKey]) !== this._lastSyncedTask.text || this.computeDueDate() !== this._lastSyncedTask.due || !!doc.$task_completed !== this._lastSyncedTask.completed; + StrCast(doc.title) !== this._lastSyncedTask.title || + StrCast(doc[this.fieldKey]) !== this._lastSyncedTask.text || + this.computeDueDate() !== this._lastSyncedTask.due || + !!doc.$task_completed !== this._lastSyncedTask.completed || + !!doc.$dashDeleted !== this._lastSyncedTask.deleted; if (googleUpdated > dashUpdated && !dashChanged) { // Google version is newer — update Dash @@ -328,6 +342,7 @@ export class TaskBox extends ViewBoxBaseComponent() { text: StrCast(doc[this.fieldKey]), due: this.computeDueDate(), completed: !!doc.$task_completed, + deleted: !!doc.$dashDeleted, }; this._needsSync = false; }); @@ -358,6 +373,7 @@ export class TaskBox extends ViewBoxBaseComponent() { text: StrCast(doc[this.fieldKey]), due: this.computeDueDate(), completed: !!doc.$task_completed, + deleted: !!doc.$dashDeleted, }; this._needsSync = false; console.log('Pushed newer version to Google'); @@ -446,23 +462,27 @@ export class TaskBox extends ViewBoxBaseComponent() { text: StrCast(doc[this.fieldKey]), due, completed, + deleted: !!doc.$dashDeleted, }; this._needsSync = false; }); + if (this.Document.$dashDeleted) { + runInAction(() => { + this.Document.$dashDeleted = false; + }); + } + this._googleTaskCreateDisposer = reaction( () => { const completed = BoolCast(doc.$task_completed); const due = this.computeDueDate(); + const dashDeleted = !!doc.$dashDeleted; - return { title: StrCast(doc.title), text: StrCast(doc[this.fieldKey]), completed, due }; + return { title: StrCast(doc.title), text: StrCast(doc[this.fieldKey]), completed, due, dashDeleted }; }, - ({ title, text, completed, due }) => { - this._needsSync = - title !== this._lastSyncedTask.title || // - text !== this._lastSyncedTask.text || - due !== this._lastSyncedTask.due || - completed !== this._lastSyncedTask.completed; + ({ title, text, completed, due, dashDeleted }) => { + this._needsSync = title !== this._lastSyncedTask.title || text !== this._lastSyncedTask.text || due !== this._lastSyncedTask.due || completed !== this._lastSyncedTask.completed || dashDeleted !== this._lastSyncedTask.deleted; }, { fireImmediately: true } ); @@ -478,10 +498,18 @@ export class TaskBox extends ViewBoxBaseComponent() { this._widthDisposer?.(); } + + /** + * Method to handle task deletion + * @returns - a promise that resolves when the task is deleted + */ handleDeleteTask = async () => { const doc = this.Document; if (!doc.$googleTaskId) return; - if (!window.confirm('Are you sure you want to permanently delete this task? This action is undoable.')) return; + if (!window.confirm('Are you sure you want to delete this task?')) return; + + doc.$dashDeleted = true; + this._needsSync = true; try { const token = await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken(); @@ -602,8 +630,6 @@ export class TaskBox extends ViewBoxBaseComponent() { - - Delete diff --git a/src/server/ApiManagers/GeneralGoogleManager.ts b/src/server/ApiManagers/GeneralGoogleManager.ts index b237178f4..aceead3c6 100644 --- a/src/server/ApiManagers/GeneralGoogleManager.ts +++ b/src/server/ApiManagers/GeneralGoogleManager.ts @@ -79,10 +79,10 @@ export default class GeneralGoogleManager extends ApiManager { const tasks = google.tasks({ version: 'v1', auth }); - const { title, notes, due, status, completed } = req.body; + const { title, notes, due, status, completed, deleted } = req.body; const result = await tasks.tasks.insert({ tasklist: '@default', - requestBody: { title, notes, due, status, completed }, + requestBody: { title, notes, due, status, completed, deleted }, }); res.status(200).send(result.data); @@ -109,12 +109,12 @@ export default class GeneralGoogleManager extends ApiManager { const tasks = google.tasks({ version: 'v1', auth }); const { taskId } = req.params; - const { title, notes, due, status, completed } = req.body; + const { title, notes, due, status, completed, deleted } = req.body; const result = await tasks.tasks.patch({ tasklist: '@default', task: taskId, - requestBody: { title, notes, due, status, completed }, + requestBody: { title, notes, due, status, completed, deleted}, }); res.status(200).send(result.data); -- cgit v1.2.3-70-g09d2