feat(projects) : archivage en masse des tickets sur statut final
Auto Tag Develop / tag (push) Successful in 9s
Auto Tag Develop / tag (push) Successful in 9s
- TaskBulkActions : prop canArchive + bouton archive conditionnel - pages/projects/[id] : computed canArchiveSelection (true quand le filtre statut courant pointe vers un statut isFinal) - purge la sélection des ids hors filtre courant pour garder le compteur cohérent en vue liste
This commit is contained in:
@@ -79,6 +79,17 @@
|
|||||||
@update:model-value="(v: number | null) => v && emit('bulk-update', 'group', v)"
|
@update:model-value="(v: number | null) => v && emit('bulk-update', 'group', v)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- Archive (only when current filter targets a final status) -->
|
||||||
|
<MalioButtonIcon
|
||||||
|
v-if="canArchive"
|
||||||
|
icon="mdi:archive-outline"
|
||||||
|
aria-label="Archiver"
|
||||||
|
variant="ghost"
|
||||||
|
icon-size="22"
|
||||||
|
button-class="self-end text-neutral-500 hover:bg-primary-50 hover:text-primary-500"
|
||||||
|
@click="emit('bulk-archive')"
|
||||||
|
/>
|
||||||
|
|
||||||
<!-- Delete -->
|
<!-- Delete -->
|
||||||
<MalioButtonIcon
|
<MalioButtonIcon
|
||||||
icon="mdi:delete-outline"
|
icon="mdi:delete-outline"
|
||||||
@@ -113,9 +124,11 @@ const props = withDefaults(defineProps<{
|
|||||||
groups: TaskGroup[]
|
groups: TaskGroup[]
|
||||||
selectedTasks?: Task[]
|
selectedTasks?: Task[]
|
||||||
projects?: Project[]
|
projects?: Project[]
|
||||||
|
canArchive?: boolean
|
||||||
}>(), {
|
}>(), {
|
||||||
selectedTasks: () => [],
|
selectedTasks: () => [],
|
||||||
projects: () => [],
|
projects: () => [],
|
||||||
|
canArchive: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
|
|||||||
@@ -161,6 +161,7 @@
|
|||||||
:priorities="priorities"
|
:priorities="priorities"
|
||||||
:efforts="efforts"
|
:efforts="efforts"
|
||||||
:groups="groups"
|
:groups="groups"
|
||||||
|
:can-archive="canArchiveSelection"
|
||||||
@toggle-all="toggleSelectAll(filteredTasks)"
|
@toggle-all="toggleSelectAll(filteredTasks)"
|
||||||
@bulk-update="onBulkUpdate"
|
@bulk-update="onBulkUpdate"
|
||||||
@bulk-archive="onBulkArchive"
|
@bulk-archive="onBulkArchive"
|
||||||
@@ -297,6 +298,12 @@ const effortFilterOptions = computed(() =>
|
|||||||
efforts.value.map(e => ({ label: e.label, value: e.id }))
|
efforts.value.map(e => ({ label: e.label, value: e.id }))
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const canArchiveSelection = computed(() => {
|
||||||
|
if (selectedStatusId.value === null) return false
|
||||||
|
const status = statuses.value.find(s => s.id === selectedStatusId.value)
|
||||||
|
return status?.isFinal === true
|
||||||
|
})
|
||||||
|
|
||||||
const filteredTasks = computed(() => {
|
const filteredTasks = computed(() => {
|
||||||
let result = tasks.value.filter(t => !t.archived)
|
let result = tasks.value.filter(t => !t.archived)
|
||||||
if (selectedGroupId.value) {
|
if (selectedGroupId.value) {
|
||||||
@@ -323,6 +330,14 @@ const filteredTasks = computed(() => {
|
|||||||
return result
|
return result
|
||||||
})
|
})
|
||||||
|
|
||||||
|
watch(filteredTasks, (list) => {
|
||||||
|
if (selectedTaskIds.size === 0) return
|
||||||
|
const visibleIds = new Set(list.map(t => t.id))
|
||||||
|
for (const id of selectedTaskIds) {
|
||||||
|
if (!visibleIds.has(id)) selectedTaskIds.delete(id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function tasksByStatus(statusId: number): Task[] {
|
function tasksByStatus(statusId: number): Task[] {
|
||||||
return filteredTasks.value.filter(t => t.status?.id === statusId)
|
return filteredTasks.value.filter(t => t.status?.id === statusId)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user