diff options
author | aaravkumar <aarav.kumar1510@gmail.com> | 2025-04-28 23:48:41 -0400 |
---|---|---|
committer | aaravkumar <aarav.kumar1510@gmail.com> | 2025-04-28 23:48:41 -0400 |
commit | c53ab98d37e68653057f12ff02e00fbe131ae930 (patch) | |
tree | cdeebeebe96555d03c00f4543d4b6f87a4e702ea /src/client/views/nodes/TaskManagerTask.tsx | |
parent | e59643a3346db0429dd2936ad8d7430401e658be (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.tsx | 138 |
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> ); } |