Обновление бека+фронт
MVP версия - которая уже готова к работе
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUpdated, watch } from 'vue'
|
||||
import Column from './Column.vue'
|
||||
import { cardsApi } from '../api'
|
||||
|
||||
const props = defineProps({
|
||||
activeDepartment: Number,
|
||||
@@ -68,18 +69,19 @@ watch(() => props.cards, (newCards) => {
|
||||
const columnsWithCards = computed(() => {
|
||||
return props.columns.map(col => ({
|
||||
id: col.id,
|
||||
title: col.name,
|
||||
title: col.name_columns,
|
||||
color: col.color,
|
||||
cards: localCards.value
|
||||
.filter(card => card.column_id === col.id)
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map(card => ({
|
||||
id: card.id_card,
|
||||
id: card.id,
|
||||
title: card.title,
|
||||
description: card.descript,
|
||||
details: card.descript_full,
|
||||
departmentId: card.id_department,
|
||||
labelId: card.id_label,
|
||||
accountId: card.id_account,
|
||||
assignee: card.avatar_img,
|
||||
dueDate: card.date,
|
||||
dateCreate: card.date_create,
|
||||
@@ -126,35 +128,36 @@ watch([filteredTotalTasks, inProgressTasks, completedTasks], () => {
|
||||
})
|
||||
}, { immediate: true })
|
||||
|
||||
const handleDropCard = ({ cardId, fromColumnId, toColumnId, toIndex }) => {
|
||||
const card = localCards.value.find(c => c.id_card === cardId)
|
||||
const handleDropCard = async ({ cardId, fromColumnId, toColumnId, toIndex }) => {
|
||||
const card = localCards.value.find(c => c.id === cardId)
|
||||
if (!card) return
|
||||
|
||||
// Меняем колонку
|
||||
// Локально обновляем для мгновенного отклика
|
||||
card.column_id = toColumnId
|
||||
|
||||
// Получаем карточки целевой колонки (без перемещаемой)
|
||||
const columnCards = localCards.value
|
||||
.filter(c => c.column_id === toColumnId && c.id_card !== cardId)
|
||||
.filter(c => c.column_id === toColumnId && c.id !== cardId)
|
||||
.sort((a, b) => a.order - b.order)
|
||||
|
||||
// Вставляем карточку в нужную позицию и пересчитываем order
|
||||
// Вставляем карточку в нужную позицию и пересчитываем order локально
|
||||
columnCards.splice(toIndex, 0, card)
|
||||
columnCards.forEach((c, idx) => {
|
||||
c.order = idx
|
||||
})
|
||||
|
||||
// TODO: отправить изменение на сервер
|
||||
// Отправляем на сервер (сервер сам пересчитает order для всех)
|
||||
await cardsApi.updateOrder(cardId, toColumnId, toIndex)
|
||||
}
|
||||
|
||||
// Генератор id для новых карточек
|
||||
let nextCardId = 100
|
||||
|
||||
// Методы для модалки
|
||||
const saveTask = (taskData, columnId) => {
|
||||
const saveTask = async (taskData, columnId) => {
|
||||
if (taskData.id) {
|
||||
// Редактирование существующей карточки
|
||||
const card = localCards.value.find(c => c.id_card === taskData.id)
|
||||
const card = localCards.value.find(c => c.id === taskData.id)
|
||||
if (card) {
|
||||
card.title = taskData.title
|
||||
card.descript = taskData.description
|
||||
@@ -162,8 +165,23 @@ const saveTask = (taskData, columnId) => {
|
||||
card.id_department = taskData.departmentId
|
||||
card.id_label = taskData.labelId
|
||||
card.date = taskData.dueDate
|
||||
card.id_account = taskData.accountId
|
||||
card.avatar_img = taskData.assignee
|
||||
card.files = taskData.files || []
|
||||
|
||||
// Отправляем на сервер
|
||||
await cardsApi.update({
|
||||
id: taskData.id,
|
||||
id_department: taskData.departmentId,
|
||||
id_label: taskData.labelId,
|
||||
id_account: taskData.accountId,
|
||||
column_id: card.column_id,
|
||||
order: card.order,
|
||||
date: taskData.dueDate,
|
||||
title: taskData.title,
|
||||
descript: taskData.description,
|
||||
descript_full: taskData.details
|
||||
})
|
||||
}
|
||||
} else {
|
||||
// Создание новой карточки (в конец колонки)
|
||||
@@ -172,32 +190,52 @@ const saveTask = (taskData, columnId) => {
|
||||
? Math.max(...columnCards.map(c => c.order)) + 1
|
||||
: 0
|
||||
|
||||
localCards.value.push({
|
||||
id_card: nextCardId++,
|
||||
// Отправляем на сервер
|
||||
const result = await cardsApi.create({
|
||||
id_department: taskData.departmentId,
|
||||
id_label: taskData.labelId,
|
||||
id_account: taskData.accountId,
|
||||
column_id: columnId,
|
||||
order: maxOrder,
|
||||
date: taskData.dueDate,
|
||||
title: taskData.title,
|
||||
descript: taskData.description,
|
||||
descript_full: taskData.details,
|
||||
avatar_img: taskData.assignee,
|
||||
column_id: columnId,
|
||||
date: taskData.dueDate,
|
||||
date_create: new Date().toISOString().split('T')[0],
|
||||
order: maxOrder,
|
||||
files: taskData.files || []
|
||||
})
|
||||
|
||||
if (result.success) {
|
||||
// Добавляем локально с ID от сервера
|
||||
localCards.value.push({
|
||||
id: parseInt(result.id),
|
||||
id_department: taskData.departmentId,
|
||||
id_label: taskData.labelId,
|
||||
id_account: taskData.accountId,
|
||||
title: taskData.title,
|
||||
descript: taskData.description,
|
||||
descript_full: taskData.details,
|
||||
avatar_img: taskData.assignee,
|
||||
column_id: columnId,
|
||||
date: taskData.dueDate,
|
||||
date_create: new Date().toISOString().split('T')[0],
|
||||
order: maxOrder,
|
||||
files: result.files || []
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: отправить на сервер
|
||||
}
|
||||
|
||||
const deleteTask = (cardId, columnId) => {
|
||||
const index = localCards.value.findIndex(c => c.id_card === cardId)
|
||||
if (index !== -1) {
|
||||
localCards.value.splice(index, 1)
|
||||
}
|
||||
const deleteTask = async (cardId, columnId) => {
|
||||
// Удаляем на сервере
|
||||
const result = await cardsApi.delete(cardId)
|
||||
|
||||
// TODO: отправить на сервер
|
||||
if (result.success) {
|
||||
// Удаляем локально
|
||||
const index = localCards.value.findIndex(c => c.id === cardId)
|
||||
if (index !== -1) {
|
||||
localCards.value.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({ saveTask, deleteTask })
|
||||
|
||||
Reference in New Issue
Block a user