LinkDesk/frontend/docs/bulk-assignment-implementat...

5.4 KiB

Bulk Assignment Implementation

Overview

Implemented bulk assignment functionality for the TaskBrowser component, allowing users to assign multiple selected tasks to a user through the context menu.

Implementation Details

Frontend Changes

TaskBrowser.vue

Added handleBulkAssignment method that:

  1. Extracts selected task IDs from the selection state
  2. Calls taskService.bulkAssignTasks with task IDs and user ID
  3. Shows loading state during the operation
  4. Displays success toast with count of assigned tasks
  5. Handles errors and displays error toast
  6. Refreshes task list after successful update
  7. Closes context menu and clears selection after completion
const handleBulkAssignment = async (userId: number) => {
  try {
    const taskIds = selectedTasks.value.map(task => task.id)
    
    if (taskIds.length === 0) {
      return
    }

    isLoading.value = true
    const result = await taskService.bulkAssignTasks(taskIds, userId)

    toast({
      title: 'Success',
      description: `${result.success_count} ${result.success_count === 1 ? 'task' : 'tasks'} assigned`,
    })

    await fetchTasks()
    closeContextMenu()
    rowSelection.value = {}
  } catch (error) {
    console.error('Failed to assign tasks:', error)
    toast({
      title: 'Error',
      description: 'Failed to assign tasks. Please try again.',
      variant: 'destructive',
    })
  } finally {
    isLoading.value = false
  }
}

Connected the method to the TaskBulkActionsMenu component:

<TaskBulkActionsMenu
  v-model:open="showContextMenu"
  :position="contextMenuPosition"
  :selected-count="selectedCount"
  :project-members="projectMembers"
  @status-selected="handleBulkStatusUpdate"
  @assignee-selected="handleBulkAssignment"
/>

Backend

The backend endpoint was already implemented in task 1:

  • Endpoint: PUT /tasks/bulk/assign
  • Handles atomic assignment (all or nothing)
  • Validates user exists and is a project member
  • Returns success/failure counts

Service Layer

The bulkAssignTasks method was already implemented in frontend/src/services/task.ts:

async bulkAssignTasks(taskIds: number[], assignedUserId: number): Promise<BulkActionResult> {
  const response = await apiClient.put('/tasks/bulk/assign', {
    task_ids: taskIds,
    assigned_user_id: assignedUserId
  })
  return response.data
}

Requirements Validated

Requirement 5.3

When a user selects an assignee from the submenu, the system updates all selected tasks to be assigned to that user

Requirement 5.4

When the bulk assignment completes successfully, the system displays a success notification indicating the number of tasks assigned

Requirement 5.5

When the bulk assignment fails, the system displays an error notification and maintains the original assignments (backend handles atomicity)

Requirement 5.6

When the assignment update completes, the system refreshes the task list to reflect the changes

Requirement 6.1

When a user completes a bulk action from the context menu, the system closes the context menu automatically

Requirement 6.3

When a bulk action completes, the system clears the task selections

User Flow

  1. User selects multiple tasks using checkboxes
  2. User right-clicks on a selected task
  3. Context menu appears with "Assign To" option
  4. User hovers over "Assign To" to see submenu with project members
  5. User clicks on a project member
  6. System shows loading state
  7. System calls backend API to assign all selected tasks
  8. On success:
    • Success toast appears showing count of assigned tasks
    • Task list refreshes to show updated assignments
    • Context menu closes
    • Selection is cleared
  9. On error:
    • Error toast appears with user-friendly message
    • Original assignments are maintained (backend atomicity)
    • Context menu remains open for retry

Error Handling

The implementation includes comprehensive error handling:

  • Try-catch block wraps the entire operation
  • Loading state is properly managed in finally block
  • Error toast displays user-friendly message
  • Console logs detailed error for debugging
  • Backend ensures atomicity (all tasks assigned or none)
  • Backend validates user exists and is a project member

Testing

Manual testing steps:

  1. Open TaskBrowser in the application
  2. Select multiple tasks using checkboxes
  3. Right-click on a selected task
  4. Click "Assign To" in the context menu
  5. Select a user from the submenu
  6. Verify success toast appears
  7. Verify task list refreshes
  8. Verify context menu closes
  9. Verify selection is cleared
  10. Verify tasks show the assigned user

See frontend/test-bulk-assignment.html for detailed test documentation.

Files Modified

  • frontend/src/components/task/TaskBrowser.vue - Added handleBulkAssignment method and connected to context menu

Files Created

  • frontend/test-bulk-assignment.html - Test documentation
  • frontend/docs/bulk-assignment-implementation.md - This file
  • Task 1: Set up backend bulk action endpoints (completed)
  • Task 2: Update task service with bulk action methods (completed)
  • Task 7: Create TaskBulkActionsMenu component (completed)
  • Task 8: Implement context menu trigger in TaskBrowser (completed)
  • Task 9: Implement bulk status update action (completed)
  • Task 10: Implement bulk assignment action (completed)

Next Steps

The next task in the implementation plan is:

  • Task 11: Implement keyboard shortcuts for selection operations