118 lines
4.5 KiB
Markdown
118 lines
4.5 KiB
Markdown
# Custom Task Type Delete Fix
|
|
|
|
## Problem
|
|
When attempting to delete a custom task type (asset or shot) from the frontend, a "Method Not Allowed" (405) error was returned.
|
|
|
|
## Root Cause
|
|
The issue had three parts:
|
|
|
|
1. **Missing Query Parameter Declaration (Backend)**: The `category` parameter in the delete endpoint wasn't explicitly declared as a query parameter using FastAPI's `Query()` annotation.
|
|
|
|
2. **Incorrect Response Format (Backend)**: All three custom task type endpoints (add, update, delete) were returning simple dictionaries instead of the `AllTaskTypesResponse` format that the frontend expected.
|
|
|
|
3. **Dialog Event Handler Bug (Frontend)**: The `@update:open="closeDeleteDialog"` handler was clearing `taskTypeToDelete` when the dialog state changed for ANY reason, including when clicking the Delete button. This meant the task type value was cleared BEFORE the delete API call could use it, resulting in an empty URL path.
|
|
|
|
## Solution
|
|
|
|
### Backend Changes (backend/routers/projects.py)
|
|
|
|
1. **Added Query import**:
|
|
```python
|
|
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
|
```
|
|
|
|
2. **Created helper function** to build consistent responses:
|
|
```python
|
|
def _build_all_task_types_response(db_project: Project):
|
|
"""Helper function to build AllTaskTypesResponse"""
|
|
from schemas.custom_task_type import AllTaskTypesResponse
|
|
|
|
custom_asset_types = db_project.custom_asset_task_types or []
|
|
custom_shot_types = db_project.custom_shot_task_types or []
|
|
|
|
all_asset_types = STANDARD_ASSET_TASK_TYPES + custom_asset_types
|
|
all_shot_types = STANDARD_SHOT_TASK_TYPES + custom_shot_types
|
|
|
|
return AllTaskTypesResponse(
|
|
asset_task_types=all_asset_types,
|
|
shot_task_types=all_shot_types,
|
|
standard_asset_types=STANDARD_ASSET_TASK_TYPES,
|
|
standard_shot_types=STANDARD_SHOT_TASK_TYPES,
|
|
custom_asset_types=custom_asset_types,
|
|
custom_shot_types=custom_shot_types
|
|
)
|
|
```
|
|
|
|
3. **Updated delete endpoint signature**:
|
|
```python
|
|
@router.delete("/{project_id}/custom-task-types/{task_type}")
|
|
async def delete_custom_task_type(
|
|
project_id: int,
|
|
task_type: str,
|
|
category: str = Query(..., description="Category: 'asset' or 'shot'"), # ← Explicit query param
|
|
db: Session = Depends(get_db),
|
|
current_user: User = Depends(require_coordinator_or_admin)
|
|
):
|
|
```
|
|
|
|
4. **Updated all three endpoints** to return `AllTaskTypesResponse`:
|
|
- `add_custom_task_type()` - now returns `_build_all_task_types_response(db_project)`
|
|
- `update_custom_task_type()` - now returns `_build_all_task_types_response(db_project)`
|
|
- `delete_custom_task_type()` - now returns `_build_all_task_types_response(db_project)`
|
|
|
|
### Frontend (No Changes Required)
|
|
The frontend service (`frontend/src/services/customTaskType.ts`) was already correctly sending the category as a query parameter:
|
|
|
|
```typescript
|
|
async deleteCustomTaskType(projectId: number, taskType: string, category: 'asset' | 'shot'): Promise<AllTaskTypesResponse> {
|
|
const encodedTaskType = encodeURIComponent(taskType)
|
|
const response = await apiClient.delete(`/projects/${projectId}/custom-task-types/${encodedTaskType}`, {
|
|
params: { category } // ← Correctly sends as query param
|
|
})
|
|
return response.data
|
|
}
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Restart Backend Server
|
|
**IMPORTANT**: The backend server must be restarted for changes to take effect:
|
|
|
|
```bash
|
|
cd backend
|
|
uvicorn main:app --reload --host 0.0.0.0 --port 8000
|
|
```
|
|
|
|
### Test Methods
|
|
|
|
1. **Via Frontend UI**:
|
|
- Navigate to Project Settings → Custom Task Types
|
|
- Add a custom task type
|
|
- Click the delete button
|
|
- Should now work without "Method Not Allowed" error
|
|
|
|
2. **Via Test HTML Page**:
|
|
- Open `frontend/test-delete-custom-task.html` in browser
|
|
- Follow the 4-step test process
|
|
- Verify delete works correctly
|
|
|
|
3. **Via Python Test Script**:
|
|
```bash
|
|
cd backend
|
|
python test_delete_fix.py
|
|
```
|
|
|
|
## Expected Behavior
|
|
|
|
After the fix:
|
|
- ✅ Delete button works for custom task types
|
|
- ✅ Returns updated list of all task types
|
|
- ✅ Frontend automatically refreshes the UI with updated list
|
|
- ✅ Consistent response format across all custom task type operations
|
|
|
|
## Files Modified
|
|
- `backend/routers/projects.py` - Fixed delete endpoint and response formats
|
|
- `backend/test_delete_fix.py` - Created test script
|
|
- `frontend/test-delete-custom-task.html` - Created browser test page
|
|
- `frontend/docs/custom-task-delete-fix.md` - This documentation
|