1
0

Обновление бека+фронт

MVP версия - которая уже готова к работе
This commit is contained in:
2026-01-12 01:11:32 +07:00
parent a9c146b192
commit 456876f837
16 changed files with 894 additions and 75 deletions

View File

@@ -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 })