LinkDesk/frontend/docs/task-19.3-implementation.md

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: 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

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

  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

{
  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