# Shift+Click Selection Visual Feedback Fix

**Date:** 2025-11-26  
**Issue:** When using Shift+click for range selection and select-all checkbox, selected rows were not showing the visual highlight (background color change)

## Problem

The TasksDataTable component's selection state was not properly synchronized with TanStack Table's internal state, causing `row.getIsSelected()` to return incorrect values and preventing the visual feedback (`bg-muted/50` class) from being applied.

## Root Cause

The issue was with how TanStack Table's state management works. The table needs to read selection state from a reactive source. The configuration uses a getter:

```typescript
state: {
  get rowSelection() {
    return rowSelection.value
  }
}
```

This getter ensures that whenever `rowSelection.value` changes, the table's internal state updates and `row.getIsSelected()` returns the correct value. The key is that we must update `rowSelection.value` directly, not try to use non-existent table methods.

## Solution

The correct approach is to update `rowSelection.value` directly. The table configuration's `state.rowSelection` getter ensures the table reads from our reactive ref:

### 1. Shift+Click Range Selection
```typescript
// CORRECT - Update ref directly
const newSelection: Record<string, boolean> = {}
for (let i = start; i <= end; i++) {
  const id = String(props.tasks[i].id)
  newSelection[id] = true
}
rowSelection.value = newSelection
```

### 2. Ctrl+Click Toggle
```typescript
// CORRECT - Update ref directly
const newSelection = { ...rowSelection.value }
if (newSelection[taskId]) {
  delete newSelection[taskId]
} else {
  newSelection[taskId] = true
}
rowSelection.value = newSelection
```

### 3. Single Click
```typescript
// CORRECT - Update ref directly
rowSelection.value = { [taskId]: true }
```

### 4. Context Menu
```typescript
// CORRECT - Update ref directly
if (!rowSelection.value[taskId]) {
  const newSelection = { ...rowSelection.value }
  newSelection[taskId] = true
  rowSelection.value = newSelection
}
```

## Changes Made

**File:** `frontend/src/components/task/TasksDataTable.vue`

1. **handleRowClick function:**
   - All selection updates now directly modify `rowSelection.value`
   - Shift+click: Creates new selection object and assigns to `rowSelection.value`
   - Ctrl+click: Creates new selection object with toggle logic and assigns to `rowSelection.value`
   - Single click: Assigns new object with single selection to `rowSelection.value`

2. **handleContextMenu function:**
   - Checks `rowSelection.value[taskId]` directly instead of using table methods
   - Updates `rowSelection.value` directly when adding unselected task

## How It Works

The table configuration includes a reactive getter:

```typescript
state: {
  get rowSelection() {
    return rowSelection.value
  }
}
```

This means:
1. When we update `rowSelection.value`, Vue's reactivity triggers
2. The table's state getter reads the new value
3. The table's internal state updates
4. `row.getIsSelected()` returns the correct value
5. The template re-renders with correct CSS classes

## Benefits

1. **Proper State Synchronization:** Table state automatically syncs with our ref through the getter
2. **Visual Feedback Works:** The `row.getIsSelected()` method correctly reflects selection state
3. **Simple and Direct:** No need for complex table methods, just update the ref
4. **Vue Reactivity:** Leverages Vue's reactivity system properly

## Testing

To verify the fix:

1. Navigate to a project's Tasks view
2. Click on Task 1
3. Hold Shift and click on Task 5
4. **Expected:** All tasks from 1-5 should show the selected background color (`bg-muted/50`)
5. **Expected:** Selection count should show "5 tasks selected"

### Additional Test Cases

- **Backward range:** Click Task 5, Shift+click Task 1 → Tasks 1-5 selected with visual feedback
- **Ctrl+click after range:** Select range, then Ctrl+click to toggle individual tasks → Visual feedback updates correctly
- **Context menu:** Right-click unselected task → Task gets added to selection with visual feedback

## Related Requirements

- **Requirement 3.3:** Shift+click range selection
- **Requirement 6.1:** Selected rows have distinct background color
- **Requirement 6.2:** Hover state is distinct from selection

## Status

✅ **Fixed** - Shift+click range selection now properly updates visual feedback
