diff --git a/frontend/src/components/asset/AssetDetailPanel.vue b/frontend/src/components/asset/AssetDetailPanel.vue index 46b006b..725ffa2 100644 --- a/frontend/src/components/asset/AssetDetailPanel.vue +++ b/frontend/src/components/asset/AssetDetailPanel.vue @@ -293,6 +293,7 @@ import { assetService, AssetStatus, type Asset, type TaskStatusInfo } from '@/se import { taskService, type ProductionNote, type Submission } from '@/services/task' import { useAuthStore } from '@/stores/auth' import { useUserStore } from '@/stores/user' +import { useDepartmentsStore } from '@/stores/departments' interface Task { id: number @@ -321,6 +322,7 @@ const emit = defineEmits() const authStore = useAuthStore() const userStore = useUserStore() +const departmentsStore = useDepartmentsStore() // Reactive state const asset = ref(null) @@ -363,9 +365,15 @@ const progressPercentage = computed(() => { return Math.round((completedTasksCount.value / tasks.value.length) * 100) }) +// Task types offered in "Add Task" include the flat asset task type list +// plus every task type owned by an asset department (e.g. Modeling's own +// task types), deduped against types the asset already has a task for. const availableTaskTypes = computed(() => { const existingTypes = new Set(tasks.value.map(task => task.task_type)) - return props.allTaskTypes.filter(type => !existingTypes.has(type)) + const departmentTaskTypes = departmentsStore.getDepartmentsByType(props.projectId, 'asset') + .flatMap(d => d.task_types) + const merged = Array.from(new Set([...props.allTaskTypes, ...departmentTaskTypes])) + return merged.filter(type => !existingTypes.has(type)) }) const taskStatusCounts = computed(() => { @@ -394,7 +402,8 @@ const loadAssetDetails = async () => { isLoading.value = true error.value = null asset.value = await assetService.getAsset(props.assetId) - + departmentsStore.fetchProjectDepartments(props.projectId) + // Load users if not already loaded (for user name resolution) if (userStore.users.length === 0) { try { diff --git a/frontend/src/components/shot/ShotDetailPanel.vue b/frontend/src/components/shot/ShotDetailPanel.vue index 25f986e..c37a8ab 100644 --- a/frontend/src/components/shot/ShotDetailPanel.vue +++ b/frontend/src/components/shot/ShotDetailPanel.vue @@ -341,6 +341,7 @@ import { shotService, type Shot, type TaskStatusInfo } from '@/services/shot' import { taskService, type ProductionNote, type Submission } from '@/services/task' import { projectService, type ProjectMember } from '@/services/project' import { useTaskStatusesStore } from '@/stores/taskStatuses' +import { useDepartmentsStore } from '@/stores/departments' import { useAvatarUrl } from '@/composables/useAvatarUrl' import { usePermission } from '@/composables/usePermission' @@ -375,6 +376,7 @@ const props = defineProps() const emit = defineEmits() const taskStatusesStore = useTaskStatusesStore() +const departmentsStore = useDepartmentsStore() const { getAvatarUrl } = useAvatarUrl() const { isAdmin, isCoordinatorOrAdmin } = usePermission() @@ -435,9 +437,15 @@ const canUploadReferences = computed(() => { const canEditDesign = computed(() => isCoordinatorOrAdmin.value) +// Task types offered in "Add Task" include the flat shot task type list +// plus every task type owned by a shot department (e.g. Animation's own +// task types), deduped against types the shot already has a task for. const availableTaskTypes = computed(() => { const existingTypes = new Set(tasks.value.map(task => task.task_type)) - return props.allTaskTypes.filter(type => !existingTypes.has(type)) + const departmentTaskTypes = departmentsStore.getDepartmentsByType(props.projectId, 'shot') + .flatMap(d => d.task_types) + const merged = Array.from(new Set([...props.allTaskTypes, ...departmentTaskTypes])) + return merged.filter(type => !existingTypes.has(type)) }) // Methods @@ -446,6 +454,7 @@ const loadShotDetails = async () => { isLoading.value = true error.value = null shot.value = props.initialShot ?? await shotService.getShot(props.shotId) + departmentsStore.fetchProjectDepartments(props.projectId) await Promise.all([ taskStatusesStore.fetchProjectStatuses(props.projectId), loadProjectMembers()