10 KiB
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: numberprop 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 onlystandard_shot_types: Standard shot types onlycustom_asset_types: Custom asset types onlycustom_shot_types: Custom shot types only
Computed Properties
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:
<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:
<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
emit('editCustomTaskType', taskType: string, category: 'asset' | 'shot')
emit('deleteCustomTaskType', taskType: string, category: 'asset' | 'shot')
Exposed Methods
defineExpose({
refreshTaskTypes // Allows parent to refresh task types after changes
})
Helper Methods
const isCustomAssetType = (taskType: string) => {
return customAssetTypes.value.includes(taskType)
}
const isCustomShotType = (taskType: string) => {
return customShotTypes.value.includes(taskType)
}
2. ProjectSettingsView.vue Updates
New Refs
const taskTemplatesEditorRef = ref<InstanceType<typeof DefaultTaskTemplatesEditor> | null>(null)
const customTaskTypeManagerRef = ref<InstanceType<typeof CustomTaskTypeManager> | null>(null)
Updated Template
<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
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
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
- Navigate to Project Settings → Tasks tab
- Use Custom Task Type Manager to add new task types (e.g., "grooming", "lookdev")
- New task types automatically appear in the Task Templates Editor below
- Configure which asset categories should use the new task types
- Save templates - new assets will include custom tasks
Editing Custom Task Types from Template Editor
- In Task Templates Editor, see custom task types with edit/delete icons
- Click edit icon (pencil) next to a custom task type
- Edit dialog opens in Custom Task Type Manager above
- Update task type name
- Changes reflect immediately in template editor
Deleting Custom Task Types from Template Editor
- In Task Templates Editor, click delete icon (trash) next to a custom task type
- Delete confirmation dialog opens in Custom Task Type Manager
- If task type is in use, shows error with task count
- If not in use, confirms deletion
- 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
{
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
- Start the application:
cd frontend && npm run dev - Navigate to a project's settings page
- Go to the Tasks tab
- Test adding a custom task type
- Test editing from template editor
- Test deleting from template editor
- Test template saving with custom types
- Verify settings persist after page reload
Test File
Created frontend/test-task-template-integration.html with comprehensive testing instructions and implementation details.
Files Modified
-
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
-
frontend/src/views/ProjectSettingsView.vue- Added refs for child components
- Implemented event handlers for edit/delete
- Updated handleTaskTypesUpdated to refresh editor
-
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