aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/TaskBox.tsx76
1 files changed, 55 insertions, 21 deletions
diff --git a/src/client/views/nodes/TaskBox.tsx b/src/client/views/nodes/TaskBox.tsx
index d29160e02..3c7a2f345 100644
--- a/src/client/views/nodes/TaskBox.tsx
+++ b/src/client/views/nodes/TaskBox.tsx
@@ -2,13 +2,16 @@ import { action, IReactionDisposer, makeObservable, observable, reaction, runInA
import { observer } from 'mobx-react';
import * as React from 'react';
import { DateField } from '../../../fields/DateField';
-import { BoolCast, DateCast, NumCast, StrCast } from '../../../fields/Types';
+import { BoolCast, DateCast, DocCast, NumCast, StrCast } from '../../../fields/Types';
import { GoogleAuthenticationManager } from '../../apis/GoogleAuthenticationManager';
import { Docs } from '../../documents/Documents';
import { DocumentType } from '../../documents/DocumentTypes';
import { ViewBoxBaseComponent } from '../DocComponent';
import { FieldView, FieldViewProps } from './FieldView';
import './TaskBox.scss';
+import { DocumentDecorations } from '../DocumentDecorations';
+import { Doc } from '../../../fields/Doc';
+import { DocumentView } from './DocumentView';
/**
* TaskBox class for adding task information + completing tasks
@@ -20,6 +23,7 @@ export class TaskBox extends ViewBoxBaseComponent<FieldViewProps>() {
_widthDisposer?: IReactionDisposer;
@observable _needsSync = false; // Whether the task needs to be synced with Google Tasks
@observable _syncing = false; // Whether the task is currently syncing with Google Tasks
+ private _isFocused = false; // Whether the task box is currently focused
// contains the last synced task information
private _lastSyncedTask: {
@@ -228,12 +232,24 @@ export class TaskBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
/**
+ * Handles the focus event for the task box (for auto-syncing)
+ */
+
+ handleFocus = () => {
+ if (!this._isFocused) {
+ this._isFocused = true;
+ this.syncWithGoogleTaskBidirectional(true); // silent sync
+ }
+ };
+
+ /**
* Handles the blur event for the task box (for auto-syncing)
* @param e - the focus event
*/
handleBlur = (e: React.FocusEvent<HTMLDivElement>) => {
// Check if focus is moving outside this component
if (!e.currentTarget.contains(e.relatedTarget)) {
+ this._isFocused = false;
this.syncWithGoogleTaskBidirectional(true);
}
};
@@ -460,29 +476,38 @@ export class TaskBox extends ViewBoxBaseComponent<FieldViewProps>() {
this._googleTaskCreateDisposer?.();
this._heightDisposer?.();
this._widthDisposer?.();
+ }
- // task deletion
- if (doc.$googleTaskId) {
- (async () => {
- try {
- const token = await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
- if (!token) return;
+ handleDeleteTask = async () => {
+ const doc = this.Document;
+ if (!doc.$googleTaskId) return;
+ if (!window.confirm('Are you sure you want to permanently delete this task from Google Tasks?')) return;
- await fetch(`/googleTasks/${doc.$googleTaskId}`, {
- method: 'DELETE',
- credentials: 'include',
- headers: {
- Authorization: `Bearer ${token}`,
- },
- });
+ try {
+ const token = await GoogleAuthenticationManager.Instance.fetchOrGenerateAccessToken();
+ if (!token) return;
- console.log(`✅ Deleted Google Task ${doc.$googleTaskId}`);
- } catch (err) {
- console.warn('❌ Failed to delete Google Task:', err);
- }
- })();
+ await fetch(`/googleTasks/${doc.$googleTaskId}`, {
+ method: 'DELETE',
+ credentials: 'include',
+ headers: {
+ Authorization: `Bearer ${token}`,
+ },
+ });
+
+ const view = DocumentView.getDocumentView(this.Document);
+ if (view) {
+ DocumentView.SelectView(view, false); // select document
+ DocumentDecorations.Instance?.onCloseClick?.(true); // simulate clicking the close button
+ }
+
+ // Remove the task from the recently closed list
+ Doc.MyRecentlyClosed && Doc.RemoveDocFromList(Doc.MyRecentlyClosed, undefined, this.Document);
+ console.log(`✅ Deleted Google Task ${doc.$googleTaskId}`);
+ } catch (err) {
+ console.warn('❌ Failed to delete Google Task:', err);
}
- }
+ };
/**
* Method to render the task box
@@ -518,7 +543,7 @@ export class TaskBox extends ViewBoxBaseComponent<FieldViewProps>() {
};
return (
- <div className="task-box-blur-wrapper" tabIndex={0} onBlur={this.handleBlur}>
+ <div className="task-box-blur-wrapper" tabIndex={0} onBlur={this.handleBlur} onFocus={this.handleFocus}>
<div className="task-manager-container">
<input className="task-manager-title" type="text" placeholder="Task Title" value={taskTitle} onChange={this.updateTitle} disabled={isCompleted} style={{ opacity: isCompleted ? 0.7 : 1 }} />
@@ -568,6 +593,15 @@ export class TaskBox extends ViewBoxBaseComponent<FieldViewProps>() {
{this._syncing ? 'Syncing...' : this.needsSync ? 'Push Updates' : 'Sync Task'}
</button>
+ <button
+ className="task-delete"
+ onClick={event => {
+ event.preventDefault();
+ this.handleDeleteTask();
+ }}>
+ Delete Task
+ </button>
+
{!allDay && (
<div className="task-manager-times" style={{ opacity: isCompleted ? 0.7 : 1 }}>
<label>