Init Repo

This commit is contained in:
2026-02-28 03:22:04 +08:00
commit de59b57ee7
883 changed files with 156857 additions and 0 deletions
+416
View File
@@ -0,0 +1,416 @@
# Design Document
## Overview
This design outlines the refactoring of the TaskBrowser component to extract table rendering logic into a new TasksDataTable component. The refactor improves code maintainability, reusability, and provides a clearer separation of concerns between filtering/orchestration (TaskBrowser) and table rendering/selection (TasksDataTable).
The key architectural change is moving all TanStack Table logic, column definitions, row selection state, and table event handlers into the new TasksDataTable component, while TaskBrowser retains responsibility for data fetching, filtering, toolbar management, and bulk action coordination.
## Architecture
### Component Hierarchy
```
TaskBrowser (Parent)
├── TaskTableToolbar (Existing)
├── TasksDataTable (New - Extracted)
│ ├── Table (shadcn-vue)
│ │ ├── TableHeader
│ │ │ └── Checkbox (Select All)
│ │ └── TableBody
│ │ └── TableRow (Multiple)
│ └── Context Menu Trigger Logic
├── TaskDetailPanel (Existing)
└── TaskBulkActionsMenu (Existing)
```
### Responsibility Distribution
**TaskBrowser Responsibilities:**
- Fetch tasks, episodes, and project members from API
- Apply filters (status, type, episode, assignee, context, search)
- Manage filter state and toolbar interactions
- Coordinate bulk actions (status update, assignment)
- Display task detail panel (desktop and mobile)
- Show context menu and handle bulk action callbacks
- Display selection count and task count
**TasksDataTable Responsibilities:**
- Render table with TanStack Table
- Manage row selection state (single, multi, range, select-all)
- Handle row click events (single, double, context menu)
- Emit events for parent component actions
- Apply column visibility settings
- Handle sorting state
- Provide visual feedback for selection and hover states
## Components and Interfaces
### TasksDataTable Component
**Props:**
```typescript
interface TasksDataTableProps {
tasks: Task[] // Filtered tasks to display
columnVisibility: VisibilityState // Column visibility state
projectId: number // For context menu positioning
isLoading?: boolean // Loading state for operations
}
```
**Emits:**
```typescript
interface TasksDataTableEmits {
'row-click': (task: Task) => void // Single click on row
'row-double-click': (task: Task) => void // Double click on row
'context-menu': (event: MouseEvent, tasks: Task[]) => void // Right-click with selected tasks
'selection-change': (taskIds: number[]) => void // Selection state changed
'update:column-visibility': (visibility: VisibilityState) => void // Column visibility changed
}
```
**Internal State:**
```typescript
const sorting = ref<SortingState>([{ id: 'created_at', desc: true }])
const rowSelection = ref<RowSelectionState>({}) // { [taskId: string]: boolean }
const lastClickedIndex = ref<number | null>(null) // For shift-click range selection
```
### TaskBrowser Component (Updated)
**Responsibilities After Refactor:**
- Manage `filteredTasks` computed property
- Handle `@selection-change` event from TasksDataTable
- Store selected task IDs in local state
- Compute `selectedTasks` from IDs and filtered tasks
- Pass selected tasks to bulk action handlers
- Clear selection when filters change
**New State:**
```typescript
const selectedTaskIds = ref<Set<number>>(new Set()) // Selected task IDs
```
**Computed:**
```typescript
const selectedTasks = computed(() => {
return filteredTasks.value.filter(task => selectedTaskIds.value.has(task.id))
})
const selectedCount = computed(() => selectedTaskIds.value.size)
```
## Data Models
### Task Interface (Existing)
```typescript
interface Task {
id: number
name: string
description?: string
task_type: string
status: TaskStatus
shot_id?: number
shot_name?: string
asset_id?: number
asset_name?: string
episode_id?: number
episode_name?: string
assigned_user_id?: number
assigned_user_name?: string
deadline?: string
created_at: string
updated_at: string
}
```
### Selection State Model
```typescript
// TanStack Table's RowSelectionState
type RowSelectionState = Record<string, boolean>
// Example: { "123": true, "456": true, "789": true }
// Keys are task IDs as strings, values indicate selection
```
### Event Payloads
```typescript
interface ContextMenuEvent {
event: MouseEvent
tasks: Task[] // Currently selected tasks
}
interface SelectionChangeEvent {
taskIds: number[] // Array of selected task IDs
}
```
## Correctness Properties
*A property is a characteristic or behavior that should hold true across all valid executions of a system-essentially, a formal statement about what the system should do. Properties serve as the bridge between human-readable specifications and machine-verifiable correctness guarantees.*
### Property 1: Selection state consistency
*For any* set of filtered tasks and selection state, the selected task IDs should only reference tasks that exist in the current filtered task list
**Validates: Requirements 2.2**
### Property 2: Click selection exclusivity
*For any* row click without modifiers, the resulting selection should contain exactly one task ID (the clicked task)
**Validates: Requirements 3.1**
### Property 3: Shift-click range selection
*For any* two row indices A and B where A < B, shift-clicking from A to B should select all tasks with indices in the range [A, B] inclusive
**Validates: Requirements 3.3**
### Property 4: Ctrl-click toggle preservation
*For any* existing selection state and a Ctrl+click on a row, all previously selected rows (except the clicked row if it was selected) should remain selected
**Validates: Requirements 3.2**
### Property 5: Select-all completeness
*For any* filtered task list, clicking the select-all checkbox when unchecked should result in all visible task IDs being selected
**Validates: Requirements 3.4**
### Property 6: Context menu selection preservation
*For any* selected task set, right-clicking on a selected task should not modify the selection state
**Validates: Requirements 4.1**
### Property 7: Context menu selection addition
*For any* selected task set, right-clicking on an unselected task should add that task to the selection without removing existing selections
**Validates: Requirements 4.2**
### Property 8: Filter change selection clearing
*For any* filter change (status, type, episode, assignee, search), the selection state should be empty after the filter is applied
**Validates: Requirements 5.1, 5.2, 5.3, 5.4, 5.5**
### Property 9: Bulk operation selection preservation
*For any* bulk operation (status update or assignment), the selection state should remain unchanged after the operation completes successfully
**Validates: Requirements 4.3**
### Property 10: Double-click selection isolation
*For any* row double-click event, the selection state should not be modified by the double-click action itself
**Validates: Requirements 3.5**
## Error Handling
### Selection State Errors
**Invalid Task ID in Selection:**
- Detection: When computing selected tasks, filter out IDs that don't exist in filtered tasks
- Recovery: Automatically clean up invalid IDs from selection state
- User Impact: None (transparent cleanup)
**Selection State Desynchronization:**
- Detection: Watch filtered tasks and validate selection state
- Recovery: Remove selections for tasks no longer in filtered list
- User Impact: Selection may shrink when filters are applied
### Bulk Operation Errors
**Network Failure During Bulk Update:**
- Detection: Catch API errors in bulk action handlers
- Recovery: Display error toast, preserve selection for retry
- User Impact: User can retry the operation with same selection
**Partial Bulk Operation Success:**
- Detection: Check `success_count` in API response
- Recovery: Display count of successful updates, refresh task list
- User Impact: User sees which tasks were updated successfully
### Event Handling Errors
**Context Menu Outside Viewport:**
- Detection: Check event coordinates against viewport bounds
- Recovery: Adjust context menu position to stay within viewport
- User Impact: Context menu always visible and accessible
**Double-Click Race Condition:**
- Detection: Check `event.detail === 2` in click handler
- Recovery: Skip selection logic when double-click is detected
- User Impact: Double-click opens detail panel without selection changes
## Testing Strategy
### Unit Tests
**TasksDataTable Component:**
- Test row selection with single click
- Test row selection with Ctrl+click (toggle)
- Test row selection with Shift+click (range)
- Test select-all checkbox functionality
- Test context menu event emission
- Test selection-change event emission
- Test column visibility updates
- Test sorting functionality
**TaskBrowser Component:**
- Test filtered tasks computation
- Test selected tasks computation from IDs
- Test selection clearing on filter changes
- Test bulk status update handler
- Test bulk assignment handler
- Test context menu positioning
### Integration Tests
**Selection Flow:**
- Select multiple tasks → verify selection state
- Apply filter → verify selection cleared
- Select tasks → right-click → verify context menu shows
- Perform bulk action → verify tasks updated and selection preserved
**Bulk Operations Flow:**
- Select tasks → update status → verify API called with correct IDs
- Select tasks → assign user → verify API called with correct IDs
- Bulk operation fails → verify selection preserved
- Bulk operation succeeds → verify task list refreshed
### Property-Based Tests
Property-based testing will be used to verify the correctness properties defined above. We will use the `fast-check` library for TypeScript property-based testing.
**Test Configuration:**
- Minimum 100 iterations per property test
- Generate random task lists (0-100 tasks)
- Generate random selection states
- Generate random click sequences (with modifiers)
**Property Test Examples:**
1. **Selection Consistency Property:**
- Generate random filtered task list and selection state
- Verify all selected IDs exist in filtered tasks
2. **Click Selection Property:**
- Generate random task list and random row index
- Simulate single click
- Verify exactly one task selected
3. **Range Selection Property:**
- Generate random task list and two random indices
- Simulate shift-click between indices
- Verify all tasks in range are selected
4. **Filter Clearing Property:**
- Generate random task list and selection
- Apply random filter change
- Verify selection is empty
## Implementation Notes
### TanStack Table Configuration
The TasksDataTable will use TanStack Table v8 with Vue 3 composition API:
```typescript
const table = useVueTable({
get data() { return props.tasks },
get columns() { return columns },
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
enableRowSelection: true,
getRowId: (row) => String(row.id),
// ... state management
})
```
### Selection State Management
Selection will be managed using TanStack Table's built-in `rowSelection` state:
```typescript
// Internal state in TasksDataTable
const rowSelection = ref<RowSelectionState>({})
// Emit changes to parent
watch(rowSelection, (newSelection) => {
const selectedIds = Object.keys(newSelection)
.filter(key => newSelection[key])
.map(key => parseInt(key))
emit('selection-change', selectedIds)
}, { deep: true })
```
### Event Handling Pattern
All user interactions will be handled in TasksDataTable and emitted as events:
```typescript
// Click handler
const handleRowClick = (task: Task, event: MouseEvent) => {
if (event.detail === 2) return // Let double-click handler take over
// Update internal selection state based on modifiers
updateSelection(task, event)
// Emit single click event
emit('row-click', task)
}
// Double-click handler
const handleRowDoubleClick = (task: Task) => {
emit('row-double-click', task)
}
// Context menu handler
const handleContextMenu = (event: MouseEvent, rowIndex: number) => {
event.preventDefault()
// Update selection if needed
const task = props.tasks[rowIndex]
if (!isSelected(task.id)) {
addToSelection(task.id)
}
// Emit with current selected tasks
const selected = getSelectedTasks()
emit('context-menu', event, selected)
}
```
### Column Visibility Persistence
Column visibility will continue to be persisted in sessionStorage, but the logic will be split:
- **TasksDataTable**: Emits visibility changes
- **TaskBrowser**: Persists to sessionStorage and passes back to TasksDataTable
### Styling and Visual Feedback
Selection and hover states will use Tailwind classes:
```typescript
// Row classes
const rowClasses = computed(() => [
'cursor-pointer hover:bg-muted/50 select-none',
isSelected ? 'bg-muted/50' : ''
])
```
The `select-none` class prevents text selection during shift-click operations.
## Migration Strategy
### Phase 1: Create TasksDataTable Component
1. Create new file: `frontend/src/components/task/TasksDataTable.vue`
2. Copy table rendering logic from TaskBrowser
3. Set up props and emits interfaces
4. Implement internal selection state management
### Phase 2: Update TaskBrowser
1. Import TasksDataTable component
2. Replace table template with TasksDataTable component
3. Update state management to use selectedTaskIds Set
4. Wire up event handlers from TasksDataTable
5. Update bulk action handlers to use selectedTasks computed
### Phase 3: Testing and Validation
1. Test all selection scenarios (single, multi, range, select-all)
2. Test bulk operations (status update, assignment)
3. Test filter changes clear selection
4. Test context menu interactions
5. Verify no regressions in existing functionality
### Phase 4: Cleanup
1. Remove unused code from TaskBrowser
2. Update any documentation
3. Verify TypeScript types are correct
4. Run full test suite
@@ -0,0 +1,124 @@
# Requirements Document
## Introduction
This specification defines the refactoring of the TaskBrowser component to extract the data table into a separate, reusable component (TasksDataTable) and redesign the selection behavior to provide a more robust and maintainable bulk selection system for task status updates and assignments.
## Glossary
- **TaskBrowser**: The parent component that manages task filtering, toolbar, and detail panel display
- **TasksDataTable**: The new extracted component that handles table rendering, selection, and row interactions
- **Selection State**: The set of currently selected task rows, tracked by task IDs
- **Bulk Actions**: Operations performed on multiple selected tasks simultaneously (status update, assignment)
- **Context Menu**: Right-click menu that appears when user right-clicks on selected rows
- **Row Selection**: The mechanism for selecting one or more table rows using click, Shift+click, Ctrl+click, or select-all checkbox
## Requirements
### Requirement 1: Extract Data Table Component
**User Story:** As a developer, I want the data table logic separated from the TaskBrowser component, so that the code is more maintainable and the table can be reused in other contexts.
#### Acceptance Criteria
1. WHEN the TaskBrowser component is refactored THEN the system SHALL create a new TasksDataTable component that encapsulates all table rendering logic
2. WHEN the TasksDataTable component is created THEN the system SHALL move all TanStack Table configuration, column definitions, and table rendering from TaskBrowser to TasksDataTable
3. WHEN the TasksDataTable receives filtered tasks as props THEN the system SHALL render the table with all existing columns and sorting functionality
4. WHEN the TaskBrowser uses TasksDataTable THEN the system SHALL pass filtered tasks, column visibility, and event handlers as props
5. WHEN a user interacts with the table THEN the system SHALL emit events from TasksDataTable to TaskBrowser for row clicks, double-clicks, and context menu actions
### Requirement 2: Redesign Selection State Management
**User Story:** As a developer, I want selection state managed with a clearer index-based approach, so that bulk operations are more reliable and easier to debug.
#### Acceptance Criteria
1. WHEN the selection system is redesigned THEN the system SHALL maintain selection state using task IDs as the primary key
2. WHEN tasks are filtered or sorted THEN the system SHALL preserve valid selections and remove selections for tasks no longer in the filtered set
3. WHEN the TasksDataTable manages selection THEN the system SHALL expose selected task IDs through an emitted event or v-model binding
4. WHEN selection state changes THEN the system SHALL emit a selection-change event with the array of selected task IDs
5. WHEN the parent component needs selected tasks THEN the system SHALL compute the selected tasks array from the selection state and filtered tasks
### Requirement 3: Implement Robust Row Selection Behavior
**User Story:** As a user, I want intuitive row selection with keyboard modifiers, so that I can efficiently select multiple tasks for bulk operations.
#### Acceptance Criteria
1. WHEN a user clicks a row without modifiers THEN the system SHALL clear all selections and select only the clicked row
2. WHEN a user Ctrl+clicks (or Cmd+clicks on Mac) a row THEN the system SHALL toggle that row's selection state without affecting other selections
3. WHEN a user Shift+clicks a row THEN the system SHALL select all rows between the last clicked row and the current row
4. WHEN a user clicks the header checkbox THEN the system SHALL toggle selection of all visible (filtered) rows
5. WHEN a user double-clicks a row THEN the system SHALL open the task detail panel without modifying selection state
### Requirement 4: Preserve Selection During Context Menu Operations
**User Story:** As a user, I want my selection preserved when I right-click and perform bulk actions, so that I can perform multiple operations on the same set of tasks.
#### Acceptance Criteria
1. WHEN a user right-clicks a selected row THEN the system SHALL preserve the current selection and show the context menu
2. WHEN a user right-clicks an unselected row THEN the system SHALL add that row to the selection and show the context menu
3. WHEN a user performs a bulk action from the context menu THEN the system SHALL preserve the selection after the operation completes
4. WHEN a user closes the context menu without performing an action THEN the system SHALL preserve the current selection
5. WHEN a bulk operation fails THEN the system SHALL preserve the selection so the user can retry
### Requirement 5: Clear Selection on Filter Changes
**User Story:** As a user, I want selections cleared when I change filters, so that I don't accidentally perform bulk operations on tasks I can no longer see.
#### Acceptance Criteria
1. WHEN a user changes the status filter THEN the system SHALL clear all row selections
2. WHEN a user changes the type filter THEN the system SHALL clear all row selections
3. WHEN a user changes the episode filter THEN the system SHALL clear all row selections
4. WHEN a user changes the assignee filter THEN the system SHALL clear all row selections
5. WHEN a user changes the search query THEN the system SHALL clear all row selections
### Requirement 6: Maintain Visual Selection Feedback
**User Story:** As a user, I want clear visual feedback on which rows are selected, so that I know which tasks will be affected by bulk operations.
#### Acceptance Criteria
1. WHEN a row is selected THEN the system SHALL apply a distinct background color to the row
2. WHEN multiple rows are selected THEN the system SHALL apply the same background color to all selected rows
3. WHEN the user hovers over a row THEN the system SHALL show a hover state that is visually distinct from the selection state
4. WHEN the header checkbox is in an indeterminate state THEN the system SHALL display the checkbox with an indeterminate visual indicator
5. WHEN all visible rows are selected THEN the system SHALL display the header checkbox as fully checked
### Requirement 7: Support Bulk Status Updates
**User Story:** As a user, I want to update the status of multiple selected tasks at once, so that I can efficiently manage task workflows.
#### Acceptance Criteria
1. WHEN a user selects multiple tasks and chooses a status from the context menu THEN the system SHALL update all selected tasks to the chosen status
2. WHEN a bulk status update succeeds THEN the system SHALL display a success toast showing the count of updated tasks
3. WHEN a bulk status update completes THEN the system SHALL refresh the task list to show updated statuses
4. WHEN a bulk status update fails THEN the system SHALL display an error toast and preserve the selection
5. WHEN a bulk status update is in progress THEN the system SHALL show a loading indicator
### Requirement 8: Support Bulk Task Assignment
**User Story:** As a user, I want to assign multiple selected tasks to a team member at once, so that I can efficiently distribute work.
#### Acceptance Criteria
1. WHEN a user selects multiple tasks and chooses an assignee from the context menu THEN the system SHALL assign all selected tasks to the chosen user
2. WHEN a bulk assignment succeeds THEN the system SHALL display a success toast showing the count of assigned tasks
3. WHEN a bulk assignment completes THEN the system SHALL refresh the task list to show updated assignees
4. WHEN a bulk assignment fails THEN the system SHALL display an error toast and preserve the selection
5. WHEN a bulk assignment is in progress THEN the system SHALL show a loading indicator
### Requirement 9: Maintain Existing TaskBrowser Features
**User Story:** As a user, I want all existing TaskBrowser features to continue working after the refactor, so that my workflow is not disrupted.
#### Acceptance Criteria
1. WHEN the refactor is complete THEN the system SHALL maintain all existing filtering capabilities (status, type, episode, assignee, context, search)
2. WHEN the refactor is complete THEN the system SHALL maintain the task detail panel functionality for both desktop and mobile views
3. WHEN the refactor is complete THEN the system SHALL maintain column visibility controls and persistence
4. WHEN the refactor is complete THEN the system SHALL maintain sorting functionality on all sortable columns
5. WHEN the refactor is complete THEN the system SHALL maintain the task count and selection count display
+229
View File
@@ -0,0 +1,229 @@
# Implementation Plan
- [x] 1. Create TasksDataTable component with basic structure
- Create new file `frontend/src/components/task/TasksDataTable.vue`
- Define props interface (tasks, columnVisibility, projectId, isLoading)
- Define emits interface (row-click, row-double-click, context-menu, selection-change, update:column-visibility)
- Set up basic template structure with Table components
- _Requirements: 1.1, 1.2_
- [x] 2. Implement table rendering and TanStack Table integration
- Move TanStack Table configuration from TaskBrowser to TasksDataTable
- Import and use createColumns() for column definitions
- Set up table state (sorting, rowSelection, columnVisibility)
- Implement table header rendering with select-all checkbox
- Implement table body rendering with row iteration
- _Requirements: 1.2, 1.3_
- [x] 3. Implement row selection state management
- Create rowSelection ref with RowSelectionState type
- Create lastClickedIndex ref for shift-click tracking
- Implement getRowId to use task.id as row identifier
- Set up watcher to emit selection-change events when rowSelection changes
- Implement helper function to compute selected tasks from selection state
- _Requirements: 2.1, 2.3, 2.4_
- [x] 4. Implement single-click selection behavior
- Create handleRowClick function
- Implement logic for click without modifiers (clear all, select one)
- Implement logic for Ctrl/Cmd+click (toggle selection)
- Implement logic for Shift+click (range selection)
- Update lastClickedIndex on each click
- Emit row-click event after updating selection
- _Requirements: 3.1, 3.2, 3.3_
- [x] 5. Implement select-all checkbox functionality
- Update select column header to use table.getIsAllPageRowsSelected()
- Implement onUpdate:modelValue handler for select-all checkbox
- Use table.toggleAllPageRowsSelected() to toggle all rows
- Handle indeterminate state when some but not all rows selected
- _Requirements: 3.4, 6.4, 6.5_
- [x] 6. Implement double-click and context menu handlers
- Create handleRowDoubleClick function that emits row-double-click event
- Create handleContextMenu function that prevents default and emits context-menu event
- Add logic to preserve selection when right-clicking selected row
- Add logic to add unselected row to selection when right-clicked
- Pass selected tasks array in context-menu event
- _Requirements: 3.5, 4.1, 4.2_
- [x] 7. Add visual feedback for selection and hover states
- Apply conditional classes to TableRow based on selection state
- Add hover:bg-muted/50 class for hover feedback
- Add bg-muted/50 class for selected rows
- Add select-none class to prevent text selection during shift-click
- Ensure cursor-pointer class is applied to all rows
- _Requirements: 6.1, 6.2, 6.3_
- [x] 8. Update TaskBrowser to use TasksDataTable component
- Import TasksDataTable component
- Replace existing table template with TasksDataTable component tag
- Pass filteredTasks as tasks prop
- Pass columnVisibility as prop
- Pass projectId as prop
- Pass isLoading as prop
- _Requirements: 1.4_
- [x] 9. Implement event handlers in TaskBrowser
- Create selectedTaskIds ref as Set<number>
- Create handleSelectionChange function to update selectedTaskIds
- Wire up @selection-change event to handleSelectionChange
- Wire up @row-click event to existing handleRowClick logic (if needed)
- Wire up @row-double-click event to handleRowDoubleClick
- Wire up @context-menu event to handleContextMenu
- Wire up @update:column-visibility event to updateColumnVisibility
- _Requirements: 2.3, 2.4, 2.5_
- [x] 10. Update selection-related computed properties in TaskBrowser
- Update selectedTasks computed to filter filteredTasks by selectedTaskIds Set
- Update selectedCount computed to return selectedTaskIds.size
- Remove old rowSelection ref from TaskBrowser
- Remove old table configuration from TaskBrowser
- _Requirements: 2.5_
- [x] 11. Implement selection clearing on filter changes
- Update watch on filter refs to clear selectedTaskIds Set
- Ensure watch includes statusFilter, typeFilter, episodeFilter, assigneeFilter, contextFilter, searchQuery
- Test that selection clears when any filter changes
- _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5_
- [x] 12. Update bulk action handlers to preserve selection
- Remove any selection clearing logic from handleBulkStatusUpdate
- Remove any selection clearing logic from handleBulkAssignment
- Verify selection is preserved after successful bulk operations
- Verify selection is preserved after failed bulk operations
- _Requirements: 4.3, 4.4, 4.5, 7.4, 8.4_
- [x] 13. Update context menu handler in TaskBrowser
- Modify handleContextMenu to receive event and tasks array from TasksDataTable
- Remove row index parameter (no longer needed)
- Remove selection update logic (now handled in TasksDataTable)
- Keep context menu positioning and display logic
- _Requirements: 4.1, 4.2, 4.4_
- [x] 14. Clean up and remove unused code from TaskBrowser
- Remove table-related imports (FlexRender, table hooks, etc.)
- Remove columns import (now used in TasksDataTable)
- Remove sorting ref (now in TasksDataTable)
- Remove rowSelection ref (replaced by selectedTaskIds)
- Remove lastClickedIndex ref (now in TasksDataTable)
- Remove old handleRowClick implementation
- Remove table template code
- _Requirements: 1.1_
- [x] 15. Test selection behavior
- Test single-click selection (clears others, selects one)
- Test Ctrl+click toggle selection
- Test Shift+click range selection
- Test select-all checkbox (all visible rows)
- Test double-click opens detail panel without changing selection
- _Requirements: 3.1, 3.2, 3.3, 3.4, 3.5_
- [ ] 16. Test context menu and bulk operations
- Test right-click on selected row preserves selection
- Test right-click on unselected row adds to selection
- Test bulk status update with multiple selected tasks
- Test bulk assignment with multiple selected tasks
- Test selection preserved after bulk operations
- _Requirements: 4.1, 4.2, 4.3, 7.1, 7.2, 7.3, 8.1, 8.2, 8.3_
- [ ] 17. Test filter changes clear selection
- Test status filter change clears selection
- Test type filter change clears selection
- Test episode filter change clears selection
- Test assignee filter change clears selection
- Test search query change clears selection
- _Requirements: 5.1, 5.2, 5.3, 5.4, 5.5_
- [ ] 18. Test existing TaskBrowser features still work
- Test all filters work correctly
- Test task detail panel opens on double-click (desktop and mobile)
- Test column visibility controls work
- Test sorting on all columns works
- Test task count and selection count display correctly
- _Requirements: 9.1, 9.2, 9.3, 9.4, 9.5_
- [ ] 19. Verify TypeScript types and fix any type errors
- Run TypeScript compiler to check for type errors
- Fix any type mismatches in TasksDataTable
- Fix any type mismatches in TaskBrowser
- Ensure all props and emits are properly typed
- _Requirements: 1.1, 1.4_
- [ ] 20. Final validation and cleanup
- Run full application and test all task browser functionality
- Verify no console errors or warnings
- Verify performance is acceptable with large task lists
- Update any related documentation if needed
- _Requirements: 9.1, 9.2, 9.3, 9.4, 9.5_