296 lines
10 KiB
Markdown
296 lines
10 KiB
Markdown
# Task 19.3: Custom Task Types Integration with Task Template Editor
|
|
|
|
## Overview
|
|
Successfully integrated custom task types with the DefaultTaskTemplatesEditor component, enabling dynamic display and management of both standard and custom task types within the project settings interface.
|
|
|
|
## Implementation Details
|
|
|
|
### 1. DefaultTaskTemplatesEditor.vue Updates
|
|
|
|
#### New Props
|
|
- Added `projectId: number` prop to enable API calls for fetching task types
|
|
|
|
#### Dynamic Task Type Loading
|
|
- Implemented `loadTaskTypes()` method that fetches all task types from the API on component mount
|
|
- Uses `customTaskTypeService.getAllTaskTypes(projectId)` to retrieve:
|
|
- `asset_task_types`: All asset task types (standard + custom)
|
|
- `shot_task_types`: All shot task types (standard + custom)
|
|
- `standard_asset_types`: Standard asset types only
|
|
- `standard_shot_types`: Standard shot types only
|
|
- `custom_asset_types`: Custom asset types only
|
|
- `custom_shot_types`: Custom shot types only
|
|
|
|
#### Computed Properties
|
|
```typescript
|
|
const allAssetTaskTypes = computed(() => taskTypes.value?.asset_task_types || [...])
|
|
const allShotTaskTypes = computed(() => taskTypes.value?.shot_task_types || [...])
|
|
const standardAssetTypes = computed(() => taskTypes.value?.standard_asset_types || [...])
|
|
const standardShotTypes = computed(() => taskTypes.value?.standard_shot_types || [...])
|
|
const customAssetTypes = computed(() => taskTypes.value?.custom_asset_types || [])
|
|
const customShotTypes = computed(() => taskTypes.value?.custom_shot_types || [])
|
|
```
|
|
|
|
#### Dynamic Template Rendering
|
|
Replaced hardcoded task type rows with dynamic rendering:
|
|
|
|
**Asset Task Templates:**
|
|
```vue
|
|
<TableRow v-for="taskType in allAssetTaskTypes" :key="taskType">
|
|
<TableCell class="font-medium">
|
|
<div class="flex items-center gap-2">
|
|
<span class="capitalize">{{ taskType.replace('_', ' ') }}</span>
|
|
<!-- Edit/Delete icons for custom task types only -->
|
|
<div v-if="isCustomAssetType(taskType)" class="flex items-center gap-1">
|
|
<Button @click="handleEditCustomTaskType(taskType, 'asset')">
|
|
<Pencil class="h-3 w-3" />
|
|
</Button>
|
|
<Button @click="handleDeleteCustomTaskType(taskType, 'asset')">
|
|
<Trash2 class="h-3 w-3" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</TableCell>
|
|
<!-- Checkboxes for each asset category -->
|
|
</TableRow>
|
|
```
|
|
|
|
**Shot Task Templates:**
|
|
```vue
|
|
<TableRow v-for="taskType in allShotTaskTypes" :key="taskType">
|
|
<TableCell class="font-medium">
|
|
<div class="flex items-center gap-2">
|
|
<span class="capitalize">{{ taskType.replace('_', ' ') }}</span>
|
|
<!-- Edit/Delete icons for custom task types only -->
|
|
<div v-if="isCustomShotType(taskType)" class="flex items-center gap-1">
|
|
<Button @click="handleEditCustomTaskType(taskType, 'shot')">
|
|
<Pencil class="h-3 w-3" />
|
|
</Button>
|
|
<Button @click="handleDeleteCustomTaskType(taskType, 'shot')">
|
|
<Trash2 class="h-3 w-3" />
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
</TableCell>
|
|
<!-- Checkbox for enabled/disabled -->
|
|
</TableRow>
|
|
```
|
|
|
|
#### New Events
|
|
```typescript
|
|
emit('editCustomTaskType', taskType: string, category: 'asset' | 'shot')
|
|
emit('deleteCustomTaskType', taskType: string, category: 'asset' | 'shot')
|
|
```
|
|
|
|
#### Exposed Methods
|
|
```typescript
|
|
defineExpose({
|
|
refreshTaskTypes // Allows parent to refresh task types after changes
|
|
})
|
|
```
|
|
|
|
#### Helper Methods
|
|
```typescript
|
|
const isCustomAssetType = (taskType: string) => {
|
|
return customAssetTypes.value.includes(taskType)
|
|
}
|
|
|
|
const isCustomShotType = (taskType: string) => {
|
|
return customShotTypes.value.includes(taskType)
|
|
}
|
|
```
|
|
|
|
### 2. ProjectSettingsView.vue Updates
|
|
|
|
#### New Refs
|
|
```typescript
|
|
const taskTemplatesEditorRef = ref<InstanceType<typeof DefaultTaskTemplatesEditor> | null>(null)
|
|
const customTaskTypeManagerRef = ref<InstanceType<typeof CustomTaskTypeManager> | null>(null)
|
|
```
|
|
|
|
#### Updated Template
|
|
```vue
|
|
<CustomTaskTypeManager
|
|
ref="customTaskTypeManagerRef"
|
|
:project-id="projectId"
|
|
@updated="handleTaskTypesUpdated"
|
|
/>
|
|
|
|
<DefaultTaskTemplatesEditor
|
|
ref="taskTemplatesEditorRef"
|
|
:project-id="projectId"
|
|
:initial-asset-templates="projectSettings.assetTemplates"
|
|
:initial-shot-templates="projectSettings.shotTemplates"
|
|
:is-saving="isSavingSettings"
|
|
@save="handleSaveTaskTemplates"
|
|
@cancel="loadProjectSettings"
|
|
@edit-custom-task-type="handleEditCustomTaskType"
|
|
@delete-custom-task-type="handleDeleteCustomTaskType"
|
|
/>
|
|
```
|
|
|
|
#### Event Handlers
|
|
```typescript
|
|
const handleTaskTypesUpdated = async () => {
|
|
// Refresh task types in the task templates editor
|
|
if (taskTemplatesEditorRef.value) {
|
|
await taskTemplatesEditorRef.value.refreshTaskTypes()
|
|
}
|
|
// Reload project settings to refresh task templates with new custom types
|
|
await loadProjectSettings()
|
|
}
|
|
|
|
const handleEditCustomTaskType = (taskType: string, category: 'asset' | 'shot') => {
|
|
// Switch to the tasks tab if not already there
|
|
if (activeTab.value !== 'tasks') {
|
|
activeTab.value = 'tasks'
|
|
}
|
|
// Open the edit dialog in the CustomTaskTypeManager
|
|
if (customTaskTypeManagerRef.value) {
|
|
customTaskTypeManagerRef.value.openEditDialog(category, taskType)
|
|
}
|
|
}
|
|
|
|
const handleDeleteCustomTaskType = (taskType: string, category: 'asset' | 'shot') => {
|
|
// Switch to the tasks tab if not already there
|
|
if (activeTab.value !== 'tasks') {
|
|
activeTab.value = 'tasks'
|
|
}
|
|
// Open the delete dialog in the CustomTaskTypeManager
|
|
if (customTaskTypeManagerRef.value) {
|
|
customTaskTypeManagerRef.value.handleDelete(category, taskType)
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. CustomTaskTypeManager.vue Updates
|
|
|
|
#### Exposed Methods
|
|
```typescript
|
|
defineExpose({
|
|
openEditDialog, // Opens edit dialog for a specific task type
|
|
handleDelete // Opens delete confirmation for a specific task type
|
|
})
|
|
```
|
|
|
|
## User Workflow
|
|
|
|
### Adding Custom Task Types
|
|
1. Navigate to Project Settings → Tasks tab
|
|
2. Use Custom Task Type Manager to add new task types (e.g., "grooming", "lookdev")
|
|
3. New task types automatically appear in the Task Templates Editor below
|
|
4. Configure which asset categories should use the new task types
|
|
5. Save templates - new assets will include custom tasks
|
|
|
|
### Editing Custom Task Types from Template Editor
|
|
1. In Task Templates Editor, see custom task types with edit/delete icons
|
|
2. Click edit icon (pencil) next to a custom task type
|
|
3. Edit dialog opens in Custom Task Type Manager above
|
|
4. Update task type name
|
|
5. Changes reflect immediately in template editor
|
|
|
|
### Deleting Custom Task Types from Template Editor
|
|
1. In Task Templates Editor, click delete icon (trash) next to a custom task type
|
|
2. Delete confirmation dialog opens in Custom Task Type Manager
|
|
3. If task type is in use, shows error with task count
|
|
4. If not in use, confirms deletion
|
|
5. Task type removed from template editor immediately
|
|
|
|
## Features Implemented
|
|
|
|
### ✅ Dynamic Task Type Loading
|
|
Task types are fetched from API on component mount, ensuring always up-to-date list
|
|
|
|
### ✅ Visual Distinction
|
|
- Standard task types appear without icons (read-only)
|
|
- Custom task types show edit/delete icons (editable)
|
|
|
|
### ✅ Seamless Integration
|
|
Edit/delete actions in template editor trigger corresponding dialogs in task type manager
|
|
|
|
### ✅ Real-time Updates
|
|
When custom task types are added/edited/deleted, template editor refreshes automatically
|
|
|
|
### ✅ Template Persistence
|
|
Custom task types are included in template save logic, maintaining enabled/disabled state per asset category
|
|
|
|
## API Integration
|
|
|
|
### Endpoint Used
|
|
```
|
|
GET /projects/{project_id}/custom-task-types
|
|
```
|
|
|
|
### Response Structure
|
|
```typescript
|
|
{
|
|
asset_task_types: string[] // All asset types (standard + custom)
|
|
shot_task_types: string[] // All shot types (standard + custom)
|
|
standard_asset_types: string[] // Standard asset types only
|
|
standard_shot_types: string[] // Standard shot types only
|
|
custom_asset_types: string[] // Custom asset types only
|
|
custom_shot_types: string[] // Custom shot types only
|
|
}
|
|
```
|
|
|
|
## Component Communication Flow
|
|
|
|
```
|
|
CustomTaskTypeManager (Add/Edit/Delete)
|
|
↓ emits 'updated'
|
|
ProjectSettingsView
|
|
↓ calls refreshTaskTypes()
|
|
DefaultTaskTemplatesEditor (Refreshes list)
|
|
|
|
DefaultTaskTemplatesEditor (Edit/Delete icon clicked)
|
|
↓ emits 'editCustomTaskType' or 'deleteCustomTaskType'
|
|
ProjectSettingsView
|
|
↓ calls openEditDialog() or handleDelete()
|
|
CustomTaskTypeManager (Opens dialog)
|
|
```
|
|
|
|
## Requirements Coverage
|
|
|
|
- ✅ **Requirement 21.6**: Display all available task types (standard and custom) in the task template editor
|
|
- ✅ **Requirement 21.7**: Persist custom task types per project for use in asset and shot creation
|
|
- ✅ **Requirement 21.9**: Apply custom task types to the task template configuration interface
|
|
- ✅ **Requirement 21.10**: Include custom task types in the asset and shot creation workflows when enabled in templates
|
|
|
|
## Testing
|
|
|
|
### Manual Testing Steps
|
|
1. Start the application: `cd frontend && npm run dev`
|
|
2. Navigate to a project's settings page
|
|
3. Go to the Tasks tab
|
|
4. Test adding a custom task type
|
|
5. Test editing from template editor
|
|
6. Test deleting from template editor
|
|
7. Test template saving with custom types
|
|
8. Verify settings persist after page reload
|
|
|
|
### Test File
|
|
Created `frontend/test-task-template-integration.html` with comprehensive testing instructions and implementation details.
|
|
|
|
## Files Modified
|
|
|
|
1. `frontend/src/components/settings/DefaultTaskTemplatesEditor.vue`
|
|
- Added dynamic task type loading
|
|
- Replaced hardcoded rows with v-for loops
|
|
- Added edit/delete icons for custom types
|
|
- Added event emitters and exposed methods
|
|
|
|
2. `frontend/src/views/ProjectSettingsView.vue`
|
|
- Added refs for child components
|
|
- Implemented event handlers for edit/delete
|
|
- Updated handleTaskTypesUpdated to refresh editor
|
|
|
|
3. `frontend/src/components/settings/CustomTaskTypeManager.vue`
|
|
- Exposed openEditDialog and handleDelete methods
|
|
|
|
## Next Steps
|
|
|
|
Task 19.4 will integrate custom task types with asset and shot creation workflows:
|
|
- Modify asset creation logic to include custom task types from templates
|
|
- Modify shot creation logic to include custom task types from templates
|
|
- Update task generation to handle both standard and custom task types
|
|
- Ensure custom task types appear in task lists and filters
|