Add per-project Department management
Departments are now a customizable per-project list (standard + custom), matching the existing custom task type/status pattern, instead of a fixed 7-value enum. They're usable directly on tasks (new field, independent of assignee) and continue to drive team member department roles.
This commit is contained in:
@@ -123,7 +123,22 @@
|
||||
<Badge variant="outline">{{ formatTaskType(task.task_type) }}</Badge>
|
||||
</p>
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<Label class="text-muted-foreground">Department</Label>
|
||||
<div class="mt-1">
|
||||
<Select :model-value="localDepartment || 'none'" @update:model-value="(value) => handleDepartmentChange(value === 'none' ? '' : (value as string))">
|
||||
<SelectTrigger class="h-8">
|
||||
<SelectValue placeholder="None" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="none">None</SelectItem>
|
||||
<SelectItem v-for="department in departmentOptions" :key="department" :value="department">
|
||||
{{ formatDepartment(department) }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label class="text-muted-foreground">Start Date</Label>
|
||||
<div class="mt-1">
|
||||
@@ -341,6 +356,7 @@ import TaskAttachments from './TaskAttachments.vue'
|
||||
import TaskSubmissions from './TaskSubmissions.vue'
|
||||
import { taskService, type Task, type ProductionNote, type TaskAttachment, type Submission } from '@/services/task'
|
||||
import { projectService, type ProjectMember } from '@/services/project'
|
||||
import { useDepartmentsStore } from '@/stores/departments'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { useToast } from '@/components/ui/toast/use-toast'
|
||||
|
||||
@@ -358,6 +374,7 @@ const emit = defineEmits<{
|
||||
const { toast } = useToast()
|
||||
const authStore = useAuthStore()
|
||||
const { isCoordinatorOrAdmin } = usePermission()
|
||||
const departmentsStore = useDepartmentsStore()
|
||||
|
||||
const task = ref<Task | null>(null)
|
||||
const loading = ref(false)
|
||||
@@ -365,6 +382,7 @@ const error = ref<string | null>(null)
|
||||
const localStatus = ref('')
|
||||
const localStartDate = ref('')
|
||||
const localDeadline = ref('')
|
||||
const localDepartment = ref('')
|
||||
const notes = ref<ProductionNote[]>([])
|
||||
const attachments = ref<TaskAttachment[]>([])
|
||||
const submissions = ref<Submission[]>([])
|
||||
@@ -392,6 +410,15 @@ const canSubmitWork = computed(() => {
|
||||
|
||||
const canReassign = computed(() => isCoordinatorOrAdmin.value)
|
||||
|
||||
const departmentOptions = computed(() => {
|
||||
if (!task.value) return []
|
||||
return departmentsStore.getAllDepartmentOptions(task.value.project_id)
|
||||
})
|
||||
|
||||
function formatDepartment(department: string): string {
|
||||
return department.replace(/_/g, ' ').replace(/^\w/, c => c.toUpperCase())
|
||||
}
|
||||
|
||||
async function loadTask() {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
@@ -400,6 +427,8 @@ async function loadTask() {
|
||||
localStatus.value = task.value.status
|
||||
localStartDate.value = task.value.start_date || ''
|
||||
localDeadline.value = task.value.deadline || ''
|
||||
localDepartment.value = task.value.department || ''
|
||||
departmentsStore.fetchProjectDepartments(task.value.project_id)
|
||||
} catch (err: any) {
|
||||
console.error('Error loading task:', err)
|
||||
error.value = err.response?.data?.detail || 'Failed to load task'
|
||||
@@ -483,6 +512,30 @@ async function handleDateChange(field: 'start_date' | 'deadline', value: string)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDepartmentChange(value: string) {
|
||||
if (!task.value) return
|
||||
|
||||
const previous = task.value.department
|
||||
try {
|
||||
const updated = await taskService.updateTask(props.taskId, { department: value || null } as any)
|
||||
task.value.department = updated.department
|
||||
localDepartment.value = updated.department || ''
|
||||
emit('taskUpdated')
|
||||
toast({
|
||||
title: 'Success',
|
||||
description: 'Task department updated successfully'
|
||||
})
|
||||
} catch (error: any) {
|
||||
console.error('Error updating department:', error)
|
||||
localDepartment.value = previous || ''
|
||||
toast({
|
||||
title: 'Error',
|
||||
description: error.response?.data?.detail || 'Failed to update task department',
|
||||
variant: 'destructive'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async function handleQuickAction(action: 'start' | 'submit') {
|
||||
if (!task.value) return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user