feat(workflow) : bulk status désactivé sur sélection multi-projets, scoped au workflow du projet

This commit is contained in:
2026-05-19 20:12:01 +02:00
parent 52b78d6bbc
commit 6a37349cf7
2 changed files with 47 additions and 10 deletions

View File

@@ -14,8 +14,9 @@
</span>
<div v-if="selectedCount > 0" class="ml-2 flex items-center gap-1">
<!-- Bulk status -->
<!-- Bulk status (scoped to single project's workflow) -->
<MalioSelect
v-if="!isMultiProject"
:model-value="null"
:options="statusOptions"
label="Status"
@@ -25,6 +26,13 @@
text-value="text-xs"
@update:model-value="(v: number | null) => v && emit('bulk-update', 'status', v)"
/>
<span
v-else
class="rounded border border-neutral-200 px-2 py-1 text-xs text-neutral-400"
title="Sélection multi-projets le statut dépend du workflow de chaque projet"
>
Status —
</span>
<!-- Bulk user -->
<MalioSelect
:model-value="null"
@@ -85,13 +93,15 @@
</template>
<script setup lang="ts">
import type { Task } from '~/services/dto/task'
import type { TaskStatus } from '~/services/dto/task-status'
import type { TaskEffort } from '~/services/dto/task-effort'
import type { TaskPriority } from '~/services/dto/task-priority'
import type { TaskGroup } from '~/services/dto/task-group'
import type { UserData } from '~/services/dto/user-data'
import type { Project } from '~/services/dto/project'
const props = defineProps<{
const props = withDefaults(defineProps<{
selectedCount: number
totalCount: number
allSelected: boolean
@@ -101,7 +111,12 @@ const props = defineProps<{
priorities: TaskPriority[]
efforts: TaskEffort[]
groups: TaskGroup[]
}>()
selectedTasks?: Task[]
projects?: Project[]
}>(), {
selectedTasks: () => [],
projects: () => [],
})
const emit = defineEmits<{
(e: 'toggle-all'): void
@@ -110,23 +125,42 @@ const emit = defineEmits<{
(e: 'bulk-delete'): void
}>()
const statusOptions = computed(() =>
props.statuses.map(s => ({ label: s.label, value: s.id }))
)
const distinctProjectIds = computed(() => {
const ids = new Set<number>()
for (const t of props.selectedTasks) {
if (t.project) ids.add(t.project.id)
}
return ids
})
const isMultiProject = computed(() => distinctProjectIds.value.size > 1)
const statusOptions = computed<{ label: string, value: number }[]>(() => {
// Si on connait les projets et qu'on est sur un seul, on scope au workflow de ce projet
if (distinctProjectIds.value.size === 1 && props.projects.length > 0) {
const projectId = [...distinctProjectIds.value][0]
const project = props.projects.find(p => p.id === projectId)
if (project?.workflow?.statuses) {
return project.workflow.statuses.map(s => ({ label: s.label, value: s.id }))
}
}
// Fallback : statuts globaux fournis en props (ex. depuis projects/[id])
return props.statuses.map(s => ({ label: s.label, value: s.id }))
})
const userOptions = computed(() =>
props.users.map(u => ({ label: u.username, value: u.id }))
props.users.map(u => ({ label: u.username, value: u.id })),
)
const priorityOptions = computed(() =>
props.priorities.map(p => ({ label: p.label, value: p.id }))
props.priorities.map(p => ({ label: p.label, value: p.id })),
)
const effortOptions = computed(() =>
props.efforts.map(e => ({ label: e.label, value: e.id }))
props.efforts.map(e => ({ label: e.label, value: e.id })),
)
const groupOptions = computed(() =>
props.groups.filter(g => !g.archived).map(g => ({ label: g.title, value: g.id }))
props.groups.filter(g => !g.archived).map(g => ({ label: g.title, value: g.id })),
)
</script>

View File

@@ -62,6 +62,7 @@ const viewMode = ref<'kanban' | 'list'>('kanban')
// Bulk selection
const selectedTaskIds = reactive(new Set<number>())
const selectedTasksArray = computed(() => tasks.value.filter(t => selectedTaskIds.has(t.id)))
// Modal
const taskModalOpen = ref(false)
@@ -456,6 +457,8 @@ onMounted(async () => {
:priorities="priorities"
:efforts="efforts"
:groups="groups"
:selected-tasks="selectedTasksArray"
:projects="projects"
@toggle-all="toggleSelectAll(tasks)"
@bulk-update="onBulkUpdate"
@bulk-archive="onBulkArchive"