Правка фронта
This commit is contained in:
@@ -39,31 +39,17 @@
|
||||
|
||||
<!-- Список архивных задач -->
|
||||
<main class="main">
|
||||
<div
|
||||
class="archive-list"
|
||||
:class="{ 'drag-over': isDragOver }"
|
||||
ref="listRef"
|
||||
@dragover.prevent="handleDragOver"
|
||||
@dragenter.prevent="handleDragEnter"
|
||||
@dragleave="handleDragLeave"
|
||||
@drop="handleDrop"
|
||||
>
|
||||
<template v-for="(card, index) in filteredCards" :key="card.id">
|
||||
<!-- Индикатор перед карточкой -->
|
||||
<div v-if="isDragOver && dropIndex === index" class="drop-indicator"></div>
|
||||
<ArchiveCard
|
||||
:card="card"
|
||||
:index="index"
|
||||
:departments="departments"
|
||||
:labels="labels"
|
||||
@click="openTaskPanel(card)"
|
||||
@restore="handleRestore"
|
||||
@delete="confirmDelete"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- Индикатор в конце списка -->
|
||||
<div v-if="isDragOver && dropIndex === filteredCards.length" class="drop-indicator"></div>
|
||||
<div class="archive-list">
|
||||
<ArchiveCard
|
||||
v-for="card in filteredCards"
|
||||
:key="card.id"
|
||||
:card="card"
|
||||
:departments="departments"
|
||||
:labels="labels"
|
||||
@click="openTaskPanel(card)"
|
||||
@restore="handleRestore"
|
||||
@delete="confirmDelete"
|
||||
/>
|
||||
|
||||
<!-- Пустое состояние -->
|
||||
<div v-if="filteredCards.length === 0 && !loading" class="empty-state">
|
||||
@@ -137,93 +123,19 @@ const cards = ref([])
|
||||
const users = ref([])
|
||||
const loading = ref(true)
|
||||
|
||||
// Отфильтрованные карточки (сортируем по order)
|
||||
// Отфильтрованные карточки (сортируем по дате завершения, новые сверху)
|
||||
const filteredCards = computed(() => {
|
||||
let result = cards.value
|
||||
if (activeDepartment.value) {
|
||||
result = result.filter(card => card.departmentId === activeDepartment.value)
|
||||
}
|
||||
return result.sort((a, b) => (a.order ?? 0) - (b.order ?? 0))
|
||||
})
|
||||
|
||||
// Drag & Drop
|
||||
const listRef = ref(null)
|
||||
const isDragOver = ref(false)
|
||||
const dropIndex = ref(-1)
|
||||
let dragEnterCounter = 0
|
||||
|
||||
const handleDragEnter = () => {
|
||||
dragEnterCounter++
|
||||
isDragOver.value = true
|
||||
}
|
||||
|
||||
const calculateDropIndex = (clientY) => {
|
||||
if (!listRef.value) return filteredCards.value.length
|
||||
|
||||
const cardElements = listRef.value.querySelectorAll('.archive-card')
|
||||
let index = filteredCards.value.length
|
||||
|
||||
for (let i = 0; i < cardElements.length; i++) {
|
||||
const rect = cardElements[i].getBoundingClientRect()
|
||||
const cardMiddle = rect.top + rect.height / 2
|
||||
|
||||
if (clientY < cardMiddle) {
|
||||
index = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return index
|
||||
}
|
||||
|
||||
const handleDragOver = (e) => {
|
||||
isDragOver.value = true
|
||||
dropIndex.value = calculateDropIndex(e.clientY)
|
||||
}
|
||||
|
||||
const handleDragLeave = () => {
|
||||
dragEnterCounter--
|
||||
if (dragEnterCounter === 0) {
|
||||
isDragOver.value = false
|
||||
dropIndex.value = -1
|
||||
}
|
||||
}
|
||||
|
||||
const handleDrop = async (e) => {
|
||||
const cardId = parseInt(e.dataTransfer.getData('cardId'))
|
||||
const fromIndex = parseInt(e.dataTransfer.getData('fromIndex'))
|
||||
const toIndex = calculateDropIndex(e.clientY)
|
||||
|
||||
dragEnterCounter = 0
|
||||
isDragOver.value = false
|
||||
dropIndex.value = -1
|
||||
|
||||
// Если позиция не изменилась — ничего не делаем
|
||||
if (fromIndex === toIndex || fromIndex === toIndex - 1) return
|
||||
|
||||
// Локально перемещаем карточку
|
||||
const card = cards.value.find(c => c.id === cardId)
|
||||
if (!card) return
|
||||
|
||||
// Удаляем из старой позиции
|
||||
const cardIndex = cards.value.indexOf(card)
|
||||
cards.value.splice(cardIndex, 1)
|
||||
|
||||
// Вычисляем новую позицию
|
||||
let newIndex = toIndex
|
||||
if (cardIndex < toIndex) newIndex--
|
||||
|
||||
// Вставляем в новую позицию
|
||||
cards.value.splice(newIndex, 0, card)
|
||||
|
||||
// Пересчитываем order для всех
|
||||
cards.value.forEach((c, idx) => {
|
||||
c.order = idx
|
||||
return result.sort((a, b) => {
|
||||
// Сортировка по дате завершения (новые сверху)
|
||||
const dateA = a.dateClosed ? new Date(a.dateClosed).getTime() : 0
|
||||
const dateB = b.dateClosed ? new Date(b.dateClosed).getTime() : 0
|
||||
return dateB - dateA
|
||||
})
|
||||
|
||||
// Отправляем на сервер
|
||||
await cardsApi.updateOrder(cardId, card.columnId, newIndex)
|
||||
}
|
||||
})
|
||||
|
||||
// Загрузка данных
|
||||
const fetchData = async () => {
|
||||
@@ -462,27 +374,6 @@ onMounted(() => {
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.archive-list.drag-over {
|
||||
background: rgba(0, 212, 170, 0.03);
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
margin: -8px;
|
||||
}
|
||||
|
||||
/* Индикатор места вставки */
|
||||
.drop-indicator {
|
||||
height: 4px;
|
||||
background: var(--accent);
|
||||
border-radius: 2px;
|
||||
margin: 4px 0;
|
||||
animation: pulse 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 0.5; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
|
||||
/* Пустое состояние */
|
||||
.empty-state {
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user