Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion backend/controllers/add_task.go
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the function call to accept this new parameter.

Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func AddTaskHandler(w http.ResponseWriter, r *http.Request) {
priority := requestBody.Priority
dueDate := requestBody.DueDate
start := requestBody.Start
waitDate := requestBody.WaitDate
end := requestBody.End
recur := requestBody.Recur
tags := requestBody.Tags
Expand All @@ -66,7 +67,7 @@ func AddTaskHandler(w http.ResponseWriter, r *http.Request) {
Name: "Add Task",
Execute: func() error {
logStore.AddLog("INFO", fmt.Sprintf("Adding task: %s", description), uuid, "Add Task")
err := tw.AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, priority, dueDateStr, start, end, recur, tags, annotations)
err := tw.AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, priority, dueDateStr, start, waitDate, end, recur, tags, annotations)
if err != nil {
logStore.AddLog("ERROR", fmt.Sprintf("Failed to add task: %v", err), uuid, "Add Task")
return err
Expand Down
1 change: 1 addition & 0 deletions backend/models/request_body.go
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added wait field to this struct to accept it from frontend

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type AddTaskRequestBody struct {
Priority string `json:"priority"`
DueDate *string `json:"due"`
Start string `json:"start"`
WaitDate string `json:"wait"`
End string `json:"end"`
Recur string `json:"recur"`
Tags []string `json:"tags"`
Expand Down
5 changes: 4 additions & 1 deletion backend/utils/tw/add_task.go
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update the function to accept new parameter and only append the wait field is non-empty which ensures it remains optional.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
)

// add task to the user's tw client
func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, priority, dueDate, start, end, recur string, tags []string, annotations []models.Annotation) error {
func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, priority, dueDate, start, waitDate string, end, recur string, tags []string, annotations []models.Annotation) error {
if err := utils.ExecCommand("rm", "-rf", "/root/.task"); err != nil {
return fmt.Errorf("error deleting Taskwarrior data: %v", err)
}
Expand Down Expand Up @@ -43,6 +43,9 @@ func AddTaskToTaskwarrior(email, encryptionSecret, uuid, description, project, p
if start != "" {
cmdArgs = append(cmdArgs, "start:"+start)
}
if waitDate != "" {
cmdArgs = append(cmdArgs, "wait:"+waitDate)
}
if end != "" {
cmdArgs = append(cmdArgs, "end:"+end)
}
Expand Down
22 changes: 20 additions & 2 deletions backend/utils/tw/taskwarrior_test.go
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated existing tests to include new waitDate parameter and added two new tests to check that it works correctly.

Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,23 @@ func TestExportTasks(t *testing.T) {
}

func TestAddTaskToTaskwarrior(t *testing.T) {
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "", "H", "2025-03-03", "2025-03-01", "2025-03-03", "daily", nil, []models.Annotation{{Description: "note"}})
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "", "H", "2025-03-03", "2025-03-01", "2025-03-01", "2025-03-03", "daily", nil, []models.Annotation{{Description: "note"}})
if err != nil {
t.Errorf("AddTaskToTaskwarrior failed: %v", err)
} else {
fmt.Println("Add task passed")
}
}

func TestAddTaskToTaskwarriorWithWaitDate(t *testing.T) {
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "project", "H", "2025-03-03", "2025-03-04", "2025-03-04", "2025-03-04", "", nil, nil)
if err != nil {
t.Errorf("AddTaskToTaskwarrior with wait date failed: %v", err)
} else {
fmt.Println("Add task with wait date passed")
}
}

func TestCompleteTaskInTaskwarrior(t *testing.T) {
err := CompleteTaskInTaskwarrior("email", "encryptionSecret", "client_id", "taskuuid")
if err != nil {
Expand All @@ -60,14 +69,23 @@ func TestCompleteTaskInTaskwarrior(t *testing.T) {
}

func TestAddTaskWithTags(t *testing.T) {
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "", "H", "2025-03-03", "2025-03-01", "2025-03-03", "daily", []string{"work", "important"}, []models.Annotation{{Description: "note"}})
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "", "H", "2025-03-03", "2025-03-01", "2025-03-01", "2025-03-03", "daily", []string{"work", "important"}, []models.Annotation{{Description: "note"}})
if err != nil {
t.Errorf("AddTaskToTaskwarrior with tags failed: %v", err)
} else {
fmt.Println("Add task with tags passed")
}
}

func TestAddTaskToTaskwarriorWithWaitDateWithTags(t *testing.T) {
err := AddTaskToTaskwarrior("email", "encryption_secret", "clientId", "description", "project", "H", "2025-03-03", "2025-03-04", "2025-03-04", "2025-03-04", "", []string{"work", "important"}, nil)
if err != nil {
t.Errorf("AddTaskToTaskwarrior with wait date failed: %v", err)
} else {
fmt.Println("Add task with wait date and tags passed")
}
}

func TestEditTaskWithTagAddition(t *testing.T) {
err := EditTaskInTaskwarrior("uuid", "description", "email", "encryptionSecret", "taskuuid", []string{"+urgent", "+important"}, "project", "2025-11-29T18:30:00.000Z", "2025-11-29T18:30:00.000Z", "2025-11-29T18:30:00.000Z", "2025-11-30T18:30:00.000Z", nil, "2025-12-01T18:30:00.000Z", "daily")
if err != nil {
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/components/HomeComponents/Tasks/AddTaskDialog.tsx
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added wait-date picker ui

Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,23 @@ export const AddTaskdialog = ({
/>
</div>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="wait" className="text-right">
Wait
</Label>
<div className="col-span-3">
<DatePicker
date={newTask.wait ? new Date(newTask.wait) : undefined}
onDateChange={(date) => {
setNewTask({
...newTask,
wait: date ? format(date, 'yyyy-MM-dd') : '',
});
}}
placeholder="Select a wait date"
/>
</div>
</div>
<div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="recur" className="text-right">
Recur
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/components/HomeComponents/Tasks/Tasks.tsx
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added new wait field to newTask state intialization and passed it to addTaskToBackend when submitting, and after submission, reset it.

Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export const Tasks = (
project: '',
due: '',
start: '',
wait: '',
end: '',
recur: '',
tags: [],
Expand Down Expand Up @@ -310,6 +311,7 @@ export const Tasks = (
priority: task.priority,
due: task.due || undefined,
start: task.start || '',
wait: task.wait,
end: task.end || '',
recur: task.recur || '',
tags: task.tags,
Expand All @@ -324,6 +326,7 @@ export const Tasks = (
project: '',
due: '',
start: '',
wait: '',
end: '',
recur: '',
tags: [],
Expand Down
Copy link
Copy Markdown
Contributor Author

@ShivaGupta-14 ShivaGupta-14 Dec 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added new test cases for new wait field

Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ describe('AddTaskDialog Component', () => {
project: '',
due: '',
start: '',
wait: '',
end: '',
recur: '',
tags: [],
Expand Down Expand Up @@ -223,6 +224,7 @@ describe('AddTaskDialog Component', () => {
project: 'Work',
due: '2024-12-25',
start: '',
wait: '2025-12-20',
end: '',
recur: '',
tags: ['urgent'],
Expand Down Expand Up @@ -293,4 +295,51 @@ describe('AddTaskDialog Component', () => {
project: 'New Project',
});
});

test('renders wait date picker with correct placeholder', () => {
mockProps.isOpen = true;
render(<AddTaskdialog {...mockProps} />);

const waitDatePicker = screen.getByPlaceholderText(/select a wait date/i);
expect(waitDatePicker).toBeInTheDocument();
});

test('updates wait when user selects a date', () => {
mockProps.isOpen = true;
render(<AddTaskdialog {...mockProps} />);

const waitDatePicker = screen.getByPlaceholderText(/select a wait date/i);
fireEvent.change(waitDatePicker, { target: { value: '2025-12-20' } });

expect(mockProps.setNewTask).toHaveBeenCalledWith({
...mockProps.newTask,
wait: '2024-12-25', // Mocked format() always returns this value regardless of input
});
});

test('submits task with wait date when provided', () => {
mockProps.isOpen = true;
mockProps.newTask.wait = '2025-12-20';
render(<AddTaskdialog {...mockProps} />);

const submitButton = screen.getByRole('button', {
name: /add task/i,
});
fireEvent.click(submitButton);

expect(mockProps.onSubmit).toHaveBeenCalledWith(mockProps.newTask);
});

test('allows empty wait date (optional field)', () => {
mockProps.isOpen = true;
mockProps.newTask.wait = '';
render(<AddTaskdialog {...mockProps} />);

const submitButton = screen.getByRole('button', {
name: /add task/i,
});
fireEvent.click(submitButton);

expect(mockProps.onSubmit).toHaveBeenCalledWith(mockProps.newTask);
});
});
3 changes: 3 additions & 0 deletions frontend/src/components/HomeComponents/Tasks/hooks.ts
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added wait field to the addTaskToBackend function that will be sent to the backend's /add-task endpoint.

Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export const addTaskToBackend = async ({
priority,
due,
start,
wait,
end,
recur,
tags,
Expand All @@ -57,6 +58,7 @@ export const addTaskToBackend = async ({
priority: string;
due?: string;
start: string;
wait: string;
end?: string;
recur: string;
tags: string[];
Expand All @@ -70,6 +72,7 @@ export const addTaskToBackend = async ({
description,
project,
priority,
wait,
tags,
};

Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ export interface TaskFormData {
project: string;
due: string;
start: string;
wait: string;
end: string;
recur: string;
tags: string[];
Expand Down
Loading