Исправления фронта
Множество оптимизаций по фронту
This commit is contained in:
@@ -5,13 +5,10 @@
|
||||
v-for="column in filteredColumns"
|
||||
:key="column.id"
|
||||
:column="column"
|
||||
:departments="departments"
|
||||
:labels="labels"
|
||||
:done-column-id="doneColumnId"
|
||||
@drop-card="handleDropCard"
|
||||
@open-task="(card) => emit('open-task', { card, columnId: column.id })"
|
||||
@create-task="emit('create-task', column.id)"
|
||||
@archive-task="archiveTask"
|
||||
@archive-task="confirmArchive"
|
||||
@move-request="handleMoveRequest"
|
||||
/>
|
||||
</div>
|
||||
@@ -41,6 +38,15 @@
|
||||
@close="closeMovePanel"
|
||||
@move="handleDropCard"
|
||||
/>
|
||||
|
||||
<!-- Диалог подтверждения архивации -->
|
||||
<ConfirmDialog
|
||||
:show="archiveDialogOpen"
|
||||
type="archive"
|
||||
:action="handleConfirmArchive"
|
||||
@confirm="archiveDialogOpen = false"
|
||||
@cancel="archiveDialogOpen = false"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -48,10 +54,13 @@
|
||||
import { ref, computed, onMounted, onUpdated, watch } from 'vue'
|
||||
import Column from './Column.vue'
|
||||
import MoveCardPanel from './ui/MoveCardPanel.vue'
|
||||
import ConfirmDialog from './ConfirmDialog.vue'
|
||||
import { cardsApi } from '../api'
|
||||
import { useMobile } from '../composables/useMobile'
|
||||
import { useProjectsStore } from '../stores/projects'
|
||||
|
||||
const { isMobile } = useMobile()
|
||||
const store = useProjectsStore()
|
||||
|
||||
// Состояние для мобильной панели перемещения
|
||||
const movePanel = ref({
|
||||
@@ -76,7 +85,7 @@ const closeMovePanel = () => {
|
||||
|
||||
// Колонки для панели перемещения (только id, title, color)
|
||||
const movePanelColumns = computed(() => {
|
||||
return props.columns.map(col => ({
|
||||
return store.columns.map(col => ({
|
||||
id: col.id,
|
||||
title: col.name_columns,
|
||||
color: col.color
|
||||
@@ -111,19 +120,6 @@ const currentColumnTitle = computed(() => {
|
||||
|
||||
const props = defineProps({
|
||||
activeDepartment: Number,
|
||||
doneColumnId: Number,
|
||||
departments: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
labels: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
cards: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
@@ -155,7 +151,7 @@ watch(() => props.cards, (newCards) => {
|
||||
|
||||
// Собираем колонки с карточками (используем localCards, сортируем по order)
|
||||
const columnsWithCards = computed(() => {
|
||||
return props.columns.map(col => ({
|
||||
return store.columns.map(col => ({
|
||||
id: col.id,
|
||||
title: col.name_columns,
|
||||
color: col.color,
|
||||
@@ -205,8 +201,8 @@ const inProgressTasks = computed(() => {
|
||||
})
|
||||
|
||||
const completedTasks = computed(() => {
|
||||
if (!props.doneColumnId) return 0
|
||||
const col = filteredColumns.value.find(c => c.id === props.doneColumnId)
|
||||
if (!store.doneColumnId) return 0
|
||||
const col = filteredColumns.value.find(c => c.id === store.doneColumnId)
|
||||
return col ? col.cards.length : 0
|
||||
})
|
||||
|
||||
@@ -227,9 +223,9 @@ const handleDropCard = async ({ cardId, fromColumnId, toColumnId, toIndex }) =>
|
||||
card.column_id = toColumnId
|
||||
|
||||
// Обновляем date_closed при перемещении в/из колонки "Готово"
|
||||
if (props.doneColumnId && toColumnId === props.doneColumnId && fromColumnId !== props.doneColumnId) {
|
||||
if (store.doneColumnId && toColumnId === store.doneColumnId && fromColumnId !== store.doneColumnId) {
|
||||
card.date_closed = new Date().toISOString()
|
||||
} else if (props.doneColumnId && fromColumnId === props.doneColumnId && toColumnId !== props.doneColumnId) {
|
||||
} else if (store.doneColumnId && fromColumnId === store.doneColumnId && toColumnId !== store.doneColumnId) {
|
||||
card.date_closed = null
|
||||
}
|
||||
|
||||
@@ -337,12 +333,38 @@ const deleteTask = async (cardId, columnId) => {
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== АРХИВАЦИЯ С ПОДТВЕРЖДЕНИЕМ ====================
|
||||
const archiveDialogOpen = ref(false)
|
||||
const cardToArchive = ref(null)
|
||||
|
||||
const confirmArchive = (cardId) => {
|
||||
cardToArchive.value = cardId
|
||||
archiveDialogOpen.value = true
|
||||
}
|
||||
|
||||
const handleConfirmArchive = async () => {
|
||||
if (!cardToArchive.value) {
|
||||
throw new Error('Задача не выбрана')
|
||||
}
|
||||
|
||||
const result = await cardsApi.setArchive(cardToArchive.value, 1)
|
||||
if (!result.success) {
|
||||
throw new Error('Ошибка архивации задачи')
|
||||
}
|
||||
|
||||
// Удаляем из локального списка
|
||||
const index = localCards.value.findIndex(c => c.id === cardToArchive.value)
|
||||
if (index !== -1) {
|
||||
localCards.value.splice(index, 1)
|
||||
}
|
||||
cardToArchive.value = null
|
||||
}
|
||||
|
||||
// Публичный метод для архивации из TaskPanel (без диалога — там свой)
|
||||
const archiveTask = async (cardId) => {
|
||||
// Архивируем на сервере
|
||||
const result = await cardsApi.setArchive(cardId, 1)
|
||||
|
||||
if (result.success) {
|
||||
// Удаляем из локального списка (задача уходит в архив)
|
||||
const index = localCards.value.findIndex(c => c.id === cardId)
|
||||
if (index !== -1) {
|
||||
localCards.value.splice(index, 1)
|
||||
|
||||
Reference in New Issue
Block a user