Skip to content

Conversation

@dkhalife
Copy link
Owner

  • Nav issue only when signing in successfully rather than auto-logged
  • Finish implementing Completed tasks (context menu and request logic)
  • Completed tasks should preload during boot if the toggle was on

Copilot AI review requested due to automatic review settings December 23, 2025 20:50
@dkhalife dkhalife merged commit 3d6fb13 into main Dec 23, 2025
12 checks passed
@dkhalife dkhalife deleted the fix-bugs branch December 23, 2025 20:53
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements three key improvements: fixes a navigation initialization issue that occurred after successful login (rather than auto-login), completes the implementation of "completed tasks" functionality including UI interactions and state management, and ensures completed tasks are preloaded on boot when the toggle is enabled.

  • Added authentication initialization logic that triggers after pathname changes to handle post-login scenarios
  • Implemented full uncomplete task flow including API calls, Redux actions, WebSocket handlers, and UI controls
  • Added preloading of completed tasks in TasksOverview and MyTasks components when the feature toggle is enabled

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 16 comments.

Show a summary per file
File Description
frontend/src/App.tsx Refactored authentication initialization to support post-login scenarios by tracking pathname changes and adding componentDidUpdate lifecycle method
frontend/src/views/Navigation/NavBar.tsx Updated to receive pathname as prop instead of calling getPathName() directly
frontend/src/views/Tasks/TasksOverview.tsx Added logic to fetch completed tasks on mount when showCompleted toggle is enabled
frontend/src/views/Tasks/MyTasks.tsx Implemented uncomplete task functionality including context menu option, handler, and state management
frontend/src/views/Tasks/TaskCard.tsx Added uncomplete button/handler and updated to support isCompleted prop for conditional rendering
frontend/src/store/tasksSlice.ts Added uncompleteTask async thunk, new reducers for managing completed task state, and updated WebSocket event handlers
frontend/src/api/tasks.ts Added UncompleteTask API function for HTTP and WebSocket transports
frontend/src/models/task.ts Extended TASK_UPDATE_EVENT type to include 'uncompleted' event
frontend/src/utils/websocket.ts Removed unnecessary eslint-disable comment

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

break
case 'uncompleted':
message = 'Task uncompleted'
break
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: This line uses tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Copilot uses AI. Check for mistakes.
Comment on lines +489 to +491
isCompleted={true}
onTaskUpdate={this.onEvent}
onContextMenu={this.showContextMenu}
onContextMenu={this.showContextMenu}
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: These lines use tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

See below for a potential fix:

                  isCompleted={true}
                  onTaskUpdate={this.onEvent}
                  onContextMenu={this.showContextMenu}

Copilot uses AI. Check for mistakes.
fetchCompletedTasks: () => dispatch(fetchCompletedTasks()),

completeTask: (taskId: number, endRecurrence: boolean) => dispatch(completeTask({ taskId, endRecurrence })),
uncompleteTask: (taskId: number) => dispatch(uncompleteTask(taskId)),
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: This line uses tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Copilot uses AI. Check for mistakes.
Comment on lines +469 to +490
state.status = 'loading'
state.error = null
})
.addCase(uncompleteTask.fulfilled, (state, action) => {
const updatedTask = action.payload

// Task is active again; remove from completed list and upsert into active lists.
tasksSlice.caseReducers.completedTaskRemoved(state, {
payload: updatedTask.id,
type: 'tasks/completedTaskRemoved',
})
tasksSlice.caseReducers.taskUpserted(state, {
payload: updatedTask,
type: 'tasks/taskUpserted',
})

state.status = 'succeeded'
state.error = null
})
.addCase(uncompleteTask.rejected, (state, action) => {
state.status = 'failed'
state.error = action.error.message ?? null
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: The callback functions in these addCase blocks are not indented correctly. They should have an additional 2 spaces of indentation to match the pattern used in other addCase blocks (see lines 451-465 above). The state assignments inside should be indented accordingly.

Suggested change
state.status = 'loading'
state.error = null
})
.addCase(uncompleteTask.fulfilled, (state, action) => {
const updatedTask = action.payload
// Task is active again; remove from completed list and upsert into active lists.
tasksSlice.caseReducers.completedTaskRemoved(state, {
payload: updatedTask.id,
type: 'tasks/completedTaskRemoved',
})
tasksSlice.caseReducers.taskUpserted(state, {
payload: updatedTask,
type: 'tasks/taskUpserted',
})
state.status = 'succeeded'
state.error = null
})
.addCase(uncompleteTask.rejected, (state, action) => {
state.status = 'failed'
state.error = action.error.message ?? null
state.status = 'loading'
state.error = null
})
.addCase(uncompleteTask.fulfilled, (state, action) => {
const updatedTask = action.payload
// Task is active again; remove from completed list and upsert into active lists.
tasksSlice.caseReducers.completedTaskRemoved(state, {
payload: updatedTask.id,
type: 'tasks/completedTaskRemoved',
})
tasksSlice.caseReducers.taskUpserted(state, {
payload: updatedTask,
type: 'tasks/taskUpserted',
})
state.status = 'succeeded'
state.error = null
})
.addCase(uncompleteTask.rejected, (state, action) => {
state.status = 'failed'
state.error = action.error.message ?? null

Copilot uses AI. Check for mistakes.

type TaskCardProps = WithNavigate & {
task: TaskUI
isCompleted?: boolean
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: This line uses tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Copilot uses AI. Check for mistakes.
Comment on lines +517 to +518
store.dispatch(tasksSlice.actions.taskRemovedFromActive(data.id))
store.dispatch(tasksSlice.actions.completedTaskUpserted(data))
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: These lines use tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Suggested change
store.dispatch(tasksSlice.actions.taskRemovedFromActive(data.id))
store.dispatch(tasksSlice.actions.completedTaskUpserted(data))
store.dispatch(tasksSlice.actions.taskRemovedFromActive(data.id))
store.dispatch(tasksSlice.actions.completedTaskUpserted(data))

Copilot uses AI. Check for mistakes.
Comment on lines +253 to +256
completedTaskRemoved: (state, action: PayloadAction<number>) => {
const taskId = action.payload
state.completedItems = state.completedItems.filter(t => t.id !== taskId)
},
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: These lines use tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Suggested change
completedTaskRemoved: (state, action: PayloadAction<number>) => {
const taskId = action.payload
state.completedItems = state.completedItems.filter(t => t.id !== taskId)
},
completedTaskRemoved: (state, action: PayloadAction<number>) => {
const taskId = action.payload
state.completedItems = state.completedItems.filter(t => t.id !== taskId)
},

Copilot uses AI. Check for mistakes.
Comment on lines +391 to +399
// Task is now completed/inactive; remove from active lists and add to completed list.
tasksSlice.caseReducers.taskRemovedFromActive(state, {
payload: newTask.id,
type: 'tasks/taskRemovedFromActive',
})
tasksSlice.caseReducers.completedTaskUpserted(state, {
payload: newTask,
type: 'tasks/completedTaskUpserted',
})
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: These lines use tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Suggested change
// Task is now completed/inactive; remove from active lists and add to completed list.
tasksSlice.caseReducers.taskRemovedFromActive(state, {
payload: newTask.id,
type: 'tasks/taskRemovedFromActive',
})
tasksSlice.caseReducers.completedTaskUpserted(state, {
payload: newTask,
type: 'tasks/completedTaskUpserted',
})
// Task is now completed/inactive; remove from active lists and add to completed list.
tasksSlice.caseReducers.taskRemovedFromActive(state, {
payload: newTask.id,
type: 'tasks/taskRemovedFromActive',
})
tasksSlice.caseReducers.completedTaskUpserted(state, {
payload: newTask,
type: 'tasks/completedTaskUpserted',
})

Copilot uses AI. Check for mistakes.
uncompleteTask: (taskId: number) => Promise<any>
onTaskUpdate: (event: TASK_UPDATE_EVENT) => void
onContextMenu: (event: React.MouseEvent<HTMLDivElement>, task: TaskUI) => void
onContextMenu: (event: React.MouseEvent<HTMLDivElement>, task: TaskUI, isCompleted: boolean) => void
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: This line uses tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Copilot uses AI. Check for mistakes.
interface MyTasksState {
isMoreMenuOpen: boolean
contextMenuTask: TaskUI | null
contextMenuIsCompleted: boolean
Copy link

Copilot AI Dec 23, 2025

Choose a reason for hiding this comment

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

Inconsistent indentation: This line uses tabs instead of spaces. The rest of the codebase consistently uses spaces (2 spaces per indentation level). Please replace tabs with spaces to maintain consistency.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants