aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/TaskManagerTask.tsx
diff options
context:
space:
mode:
authoraaravkumar <aarav.kumar1510@gmail.com>2025-04-28 23:48:41 -0400
committeraaravkumar <aarav.kumar1510@gmail.com>2025-04-28 23:48:41 -0400
commitc53ab98d37e68653057f12ff02e00fbe131ae930 (patch)
treecdeebeebe96555d03c00f4543d4b6f87a4e702ea /src/client/views/nodes/TaskManagerTask.tsx
parente59643a3346db0429dd2936ad8d7430401e658be (diff)
added task nodes calendar intergation, and ability to complete tasks directly via calendar view
Diffstat (limited to 'src/client/views/nodes/TaskManagerTask.tsx')
-rw-r--r--src/client/views/nodes/TaskManagerTask.tsx138
1 files changed, 121 insertions, 17 deletions
diff --git a/src/client/views/nodes/TaskManagerTask.tsx b/src/client/views/nodes/TaskManagerTask.tsx
index 1a9205ada..2d2444275 100644
--- a/src/client/views/nodes/TaskManagerTask.tsx
+++ b/src/client/views/nodes/TaskManagerTask.tsx
@@ -37,24 +37,87 @@ export class TaskManagerTask extends React.Component<TaskManagerProps> {
delete this.props.Document.startTime;
delete this.props.Document.endTime;
}
+
+ this.setTaskDateRange();
};
@action
updateStart = (e: React.ChangeEvent<HTMLInputElement>) => {
- this.props.Document.startTime = new DateField(new Date(e.target.value));
+ const newStart = new Date(e.target.value);
+
+ this.props.Document.startTime = new DateField(newStart);
+
+ const endDate = this.props.Document.endTime instanceof DateField ? this.props.Document.endTime.date : undefined;
+ if (endDate && newStart > endDate) {
+ // Alert user
+ alert('Start time cannot be after end time. End time has been adjusted.');
+
+ // Fix end time
+ const adjustedEnd = new Date(newStart.getTime() + 60 * 60 * 1000);
+ this.props.Document.endTime = new DateField(adjustedEnd);
+ }
+
+ this.setTaskDateRange();
};
+
+
@action
updateEnd = (e: React.ChangeEvent<HTMLInputElement>) => {
- this.props.Document.endTime = new DateField(new Date(e.target.value));
+ const newEnd = new Date(e.target.value);
+
+ this.props.Document.endTime = new DateField(newEnd);
+
+ const startDate = this.props.Document.startTime instanceof DateField ? this.props.Document.startTime.date : undefined;
+ if (startDate && newEnd < startDate) {
+ // Alert user
+ alert('End time cannot be before start time. Start time has been adjusted.');
+
+ // Fix start time
+ const adjustedStart = new Date(newEnd.getTime() - 60 * 60 * 1000);
+ this.props.Document.startTime = new DateField(adjustedStart);
+ }
+
+ this.setTaskDateRange();
};
- @observable
- completed = false;
+
+
+
+ @action
+ setTaskDateRange() {
+ const doc = this.props.Document;
+
+ if (doc.allDay) {
+ // All-day task → use date only
+ if (!doc.title) return;
+
+ const parsedDate = new Date(doc.title as string);
+ if (!isNaN(parsedDate.getTime())) {
+ const localStart = new Date(parsedDate.getFullYear(), parsedDate.getMonth(), parsedDate.getDate());
+ const localEnd = new Date(localStart);
+ doc.date_range = `${localStart.toISOString()}|${localEnd.toISOString()}`;
+ doc.allDay = true;
+ }
+ } else {
+ // Timed task → use full startTime and endTime
+ const startField = doc.startTime;
+ const endField = doc.endTime;
+ const startDate = startField instanceof DateField ? startField.date : null;
+ const endDate = endField instanceof DateField ? endField.date : null;
+
+ if (startDate && endDate && !isNaN(startDate.getTime()) && !isNaN(endDate.getTime())) {
+ doc.date_range = `${startDate.toISOString()}|${endDate.toISOString()}`;
+ doc.allDay = false;
+ } else {
+ console.warn('startTime or endTime is invalid');
+ }
+ }
+ }
@action
toggleComplete = (e: React.ChangeEvent<HTMLInputElement>) => {
- this.completed = e.target.checked;
+ this.props.Document.completed = e.target.checked;
};
constructor(props: TaskManagerProps) {
@@ -62,15 +125,44 @@ export class TaskManagerTask extends React.Component<TaskManagerProps> {
makeObservable(this);
}
+ componentDidMount() {
+ this.setTaskDateRange();
+ }
+
+
render() {
+
+ function toLocalDateTimeString(date: Date): string {
+ const pad = (n: number) => n.toString().padStart(2, '0');
+ return (
+ date.getFullYear() +
+ '-' +
+ pad(date.getMonth() + 1) +
+ '-' +
+ pad(date.getDate()) +
+ 'T' +
+ pad(date.getHours()) +
+ ':' +
+ pad(date.getMinutes())
+ );
+ }
+
const doc = this.props.Document;
const taskDesc = typeof doc.text === 'string' ? doc.text : '';
const taskTitle = typeof doc.title === 'string' ? doc.title : '';
const allDay = !!doc.allDay;
+ const isCompleted = !!this.props.Document.completed;
+
+ const startTime = doc.startTime instanceof DateField && doc.startTime.date instanceof Date
+ ? toLocalDateTimeString(doc.startTime.date)
+ : '';
+
+ const endTime = doc.endTime instanceof DateField && doc.endTime.date instanceof Date
+ ? toLocalDateTimeString(doc.endTime.date)
+ : '';
+
- const startTime = doc.startTime instanceof DateField ? doc.startTime.date.toISOString().slice(0, 16) : '';
- const endTime = doc.endTime instanceof DateField ? doc.endTime.date.toISOString().slice(0, 16) : '';
return (
<div className="task-manager-container">
@@ -80,8 +172,8 @@ export class TaskManagerTask extends React.Component<TaskManagerProps> {
placeholder="Task Title"
value={taskTitle}
onChange={this.updateTitle}
- disabled={this.completed}
- style={{opacity: this.completed ? 0.7 : 1,}}
+ disabled={isCompleted}
+ style={{opacity: isCompleted ? 0.7 : 1,}}
/>
<textarea
@@ -89,42 +181,54 @@ export class TaskManagerTask extends React.Component<TaskManagerProps> {
placeholder="What’s your task?"
value={taskDesc}
onChange={this.updateText}
- disabled={this.completed}
- style={{opacity: this.completed ? 0.7 : 1,}}
+ disabled={isCompleted}
+ style={{opacity: isCompleted ? 0.7 : 1,}}
/>
<div className="task-manager-checkboxes">
- <label className="task-manager-allday" style={{opacity: this.completed ? 0.7 : 1,}}>
+ <label className="task-manager-allday" style={{opacity: isCompleted ? 0.7 : 1,}}>
<input
type="checkbox"
checked={allDay}
onChange={this.updateAllDay}
- disabled={this.completed}
+ disabled={isCompleted}
/>
All day
</label>
<label className="task-manager-complete">
- <input type="checkbox" checked={this.completed} onChange={this.toggleComplete} />
+ <input type="checkbox" checked={isCompleted} onChange={this.toggleComplete} />
Complete
</label>
</div>
+ {!allDay && (
<div
className="task-manager-times"
- style={{ visibility: allDay ? 'hidden' : 'visible', opacity: this.completed ? 0.7 : 1}}
+ style={{ opacity: isCompleted ? 0.7 : 1 }}
>
<label>
Start:
- <input type="datetime-local" value={startTime} onChange={this.updateStart} disabled={this.completed}/>
+ <input
+ type="datetime-local"
+ value={startTime}
+ onChange={this.updateStart}
+ disabled={isCompleted}
+ />
</label>
<label>
End:
- <input type="datetime-local" value={endTime} onChange={this.updateEnd} disabled={this.completed} />
+ <input
+ type="datetime-local"
+ value={endTime}
+ onChange={this.updateEnd}
+ disabled={isCompleted}
+ />
</label>
</div>
+ )}
</div>
);
}