146 lines
5.1 KiB
Markdown
146 lines
5.1 KiB
Markdown
# Shot Detail Panel Task Display Fix
|
|
|
|
## Issue
|
|
When double-clicking a shot in the shots table view, the Shot Detail Panel would open but would not display any task information. The panel showed "No tasks yet" even when tasks existed for the shot.
|
|
|
|
## Root Cause
|
|
The `ShotDetailPanel.vue` component had a TODO comment in the `loadTasks()` function that was simply setting tasks to an empty array instead of actually fetching tasks from the backend:
|
|
|
|
```typescript
|
|
const loadTasks = async () => {
|
|
try {
|
|
isLoadingTasks.value = true
|
|
// TODO: Implement task service to fetch tasks for shot
|
|
// For now, using empty array
|
|
tasks.value = []
|
|
} catch (err) {
|
|
console.error('Failed to load tasks:', err)
|
|
} finally {
|
|
isLoadingTasks.value = false
|
|
}
|
|
}
|
|
```
|
|
|
|
Additionally, the backend API and frontend task service did not support filtering tasks by `shot_id`.
|
|
|
|
## Solution
|
|
|
|
### 1. Backend Changes (`backend/routers/tasks.py`)
|
|
|
|
Added support for filtering tasks by `shot_id` and `asset_id`:
|
|
|
|
**Updated endpoint parameters:**
|
|
```python
|
|
@router.get("/", response_model=List[TaskListResponse])
|
|
async def get_tasks(
|
|
project_id: Optional[int] = Query(None, description="Filter by project ID"),
|
|
shot_id: Optional[int] = Query(None, description="Filter by shot ID"), # NEW
|
|
asset_id: Optional[int] = Query(None, description="Filter by asset ID"), # NEW
|
|
assigned_user_id: Optional[int] = Query(None, description="Filter by assigned user ID"),
|
|
status: Optional[str] = Query(None, description="Filter by task status"),
|
|
task_type: Optional[str] = Query(None, description="Filter by task type"),
|
|
department_role: Optional[str] = Query(None, description="Filter by department role for assignment"),
|
|
skip: int = Query(0, ge=0),
|
|
limit: int = Query(100, ge=1, le=1000),
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(get_current_user)
|
|
):
|
|
```
|
|
|
|
**Added filtering logic:**
|
|
```python
|
|
# Apply additional filters
|
|
if shot_id:
|
|
query = query.filter(Task.shot_id == shot_id)
|
|
|
|
if asset_id:
|
|
query = query.filter(Task.asset_id == asset_id)
|
|
```
|
|
|
|
### 2. Frontend Task Service Changes (`frontend/src/services/task.ts`)
|
|
|
|
**Updated TaskFilters interface:**
|
|
```typescript
|
|
export interface TaskFilters {
|
|
projectId?: number
|
|
shotId?: number // NEW
|
|
assetId?: number // NEW
|
|
assignedUserId?: number
|
|
status?: string
|
|
taskType?: string
|
|
departmentRole?: string
|
|
}
|
|
```
|
|
|
|
**Updated getTasks method:**
|
|
```typescript
|
|
async getTasks(filters?: TaskFilters): Promise<TaskListItem[]> {
|
|
const params = new URLSearchParams()
|
|
if (filters?.projectId) params.append('project_id', filters.projectId.toString())
|
|
if (filters?.shotId) params.append('shot_id', filters.shotId.toString()) // NEW
|
|
if (filters?.assetId) params.append('asset_id', filters.assetId.toString()) // NEW
|
|
if (filters?.assignedUserId) params.append('assigned_user_id', filters.assignedUserId.toString())
|
|
if (filters?.status) params.append('status', filters.status)
|
|
if (filters?.taskType) params.append('task_type', filters.taskType)
|
|
if (filters?.departmentRole) params.append('department_role', filters.departmentRole)
|
|
|
|
const response = await apiClient.get(`/tasks?${params}`)
|
|
return response.data
|
|
}
|
|
```
|
|
|
|
### 3. Shot Detail Panel Changes (`frontend/src/components/shot/ShotDetailPanel.vue`)
|
|
|
|
**Implemented loadTasks function:**
|
|
```typescript
|
|
const loadTasks = async () => {
|
|
try {
|
|
isLoadingTasks.value = true
|
|
const { taskService } = await import('@/services/task')
|
|
const taskList = await taskService.getTasks({
|
|
shotId: props.shotId
|
|
})
|
|
tasks.value = taskList as Task[]
|
|
} catch (err) {
|
|
console.error('Failed to load tasks:', err)
|
|
} finally {
|
|
isLoadingTasks.value = false
|
|
}
|
|
}
|
|
```
|
|
|
|
## Benefits
|
|
|
|
1. **Shot Detail Panel now displays tasks** - When a shot is selected, all associated tasks are loaded and displayed
|
|
2. **Task filtering by shot** - Backend and frontend now support filtering tasks by shot ID
|
|
3. **Task filtering by asset** - Also added support for filtering tasks by asset ID for future use
|
|
4. **Better user experience** - Users can now see all tasks associated with a shot in the detail panel
|
|
5. **Progress tracking** - The progress overview section now shows accurate task counts and completion percentage
|
|
|
|
## Testing
|
|
|
|
To test the fix:
|
|
|
|
1. Navigate to a project's Shots view
|
|
2. Double-click on any shot that has tasks
|
|
3. The Shot Detail Panel should open on the right side
|
|
4. Verify that:
|
|
- Tasks are displayed in the "Tasks" section
|
|
- Progress overview shows correct task counts
|
|
- Task status badges are displayed correctly
|
|
- Clicking on a task emits the 'select-task' event
|
|
|
|
## Related Components
|
|
|
|
- `ShotDetailPanel.vue` - Main component that displays shot details and tasks
|
|
- `ShotsTableView.vue` - Table view that triggers the detail panel
|
|
- `backend/routers/tasks.py` - Backend API for task filtering
|
|
- `frontend/src/services/task.ts` - Frontend service for task operations
|
|
|
|
## Future Enhancements
|
|
|
|
- Add ability to create tasks directly from the shot detail panel
|
|
- Add task assignment functionality in the detail panel
|
|
- Add task status update functionality
|
|
- Add filtering and sorting options for tasks in the detail panel
|