1
0

Фиксы

Доп правки
This commit is contained in:
2026-01-18 21:02:23 +07:00
parent e8a4480747
commit 6928687982
3 changed files with 86 additions and 19 deletions

View File

@@ -377,6 +377,11 @@ class Project extends BaseEntity {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
// Валидация имени
if (!$name || trim($name) === '') {
return ['success' => false, 'errors' => ['name' => 'Укажите название отдела']];
}
// Получаем максимальный order_id для проекта
$maxOrder = (int)(Database::max('departments', 'order_id', ['id_project' => $project_id]) ?? 0);
$newOrderId = $maxOrder + 1;
@@ -413,6 +418,11 @@ class Project extends BaseEntity {
return ['success' => false, 'errors' => ['access' => 'Нет прав на управление отделами']];
}
// Валидация имени (если передано)
if ($name !== null && trim($name) === '') {
return ['success' => false, 'errors' => ['name' => 'Укажите название отдела']];
}
$updateData = [];
if ($name !== null) $updateData['name_departments'] = $name;
if ($color !== null) $updateData['color'] = $color;

View File

@@ -307,6 +307,9 @@ const deleteColumnMessage = ref('')
const departmentToDelete = ref(null)
const deleteDepartmentMessage = ref('')
// Отделы к удалению (ID существующих отделов для удаления при сохранении)
const departmentsToDelete = ref([])
// Drag state for columns
const dragIndex = ref(null)
const dragOverIndex = ref(null)
@@ -495,16 +498,20 @@ const addDepartment = () => {
const confirmDeleteDepartment = async (index) => {
const department = form.value.departments[index]
// Для новых отделов (ещё не на сервере) — удаляем сразу без диалога
if (department.tempId && !department.id) {
form.value.departments.splice(index, 1)
nextTick(refreshIcons)
return
}
// Для существующих отделов — показываем диалог с предупреждением
departmentToDelete.value = index
// Для существующих отделов проверяем количество задач
if (department.id) {
const count = await store.getDepartmentTasksCount(department.id)
if (count > 0) {
deleteDepartmentMessage.value = `В отделе ${count} задач.<br>Задачи не удалятся, но потеряют привязку к отделу.`
} else {
deleteDepartmentMessage.value = 'Отдел будет удалён.'
}
const count = await store.getDepartmentTasksCount(department.id)
if (count > 0) {
deleteDepartmentMessage.value = `В отделе ${count} задач.<br>Задачи не удалятся, но потеряют привязку к отделу.`
} else {
deleteDepartmentMessage.value = 'Отдел будет удалён.'
}
@@ -516,15 +523,12 @@ const confirmDeleteDepartmentAction = async () => {
const index = departmentToDelete.value
const department = form.value.departments[index]
// Если отдел уже существует на сервере — удаляем через API
// Если отдел существует на сервере — добавляем в список для удаления при сохранении
if (department.id) {
const result = await store.deleteDepartment(department.id)
if (!result.success) {
throw new Error(result.errors?.department || 'Ошибка удаления')
}
departmentsToDelete.value.push(department.id)
}
// Удаляем из формы
// Удаляем из формы (локально)
form.value.departments.splice(index, 1)
departmentToDelete.value = null
@@ -768,15 +772,35 @@ const handleSave = async () => {
try {
if (isNew.value) {
// Проверяем что у всех отделов есть имена (для нового проекта тоже)
const emptyDeptNew = form.value.departments.find(d => !d.name_departments?.trim())
if (emptyDeptNew) {
toast.error('Укажите название для всех отделов')
return
}
// Создание проекта
const result = await store.createProject(form.value.name)
if (result.success) {
// Обновляем колонки если есть изменения
// Дефолтные колонки уже созданы сервером
// Здесь можно добавить логику для кастомизации колонок при создании
const newProjectId = result.id
// Создаём отделы для нового проекта
for (const department of form.value.departments) {
if (department.tempId) {
const deptResult = await store.addDepartmentToProject(
newProjectId,
department.name_departments,
department.color
)
if (!deptResult.success) {
toast.error(deptResult.errors?.name || 'Ошибка создания отдела')
}
}
}
toast.success('Проект создан')
emit('saved', result.id)
emit('saved', newProjectId)
emit('close')
} else {
toast.error('Ошибка создания проекта')
@@ -816,6 +840,23 @@ const handleSave = async () => {
await store.reorderColumns(ids)
}
// Удаляем отделы, помеченные на удаление
for (const deptId of departmentsToDelete.value) {
const result = await store.deleteDepartment(deptId)
if (!result.success) {
toast.error(result.errors?.department || result.errors?.access || 'Ошибка удаления отдела')
return
}
}
departmentsToDelete.value = []
// Проверяем что у всех отделов есть имена
const emptyDepartment = form.value.departments.find(d => !d.name_departments?.trim())
if (emptyDepartment) {
toast.error('Укажите название для всех отделов')
return
}
// Обрабатываем отделы
for (const department of form.value.departments) {
if (department.tempId && !department.id) {
@@ -824,6 +865,9 @@ const handleSave = async () => {
if (result.success) {
department.id = result.id
delete department.tempId
} else {
toast.error(result.errors?.name || result.errors?.access || 'Ошибка создания отдела')
return
}
} else if (department.id) {
// Проверяем изменения в существующем отделе
@@ -832,7 +876,11 @@ const handleSave = async () => {
const nameChanged = department.name_departments !== original.name_departments
const colorChanged = department.color !== original.color
if (nameChanged || colorChanged) {
await store.updateDepartment(department.id, department.name_departments, department.color)
const result = await store.updateDepartment(department.id, department.name_departments, department.color)
if (!result.success) {
toast.error(result.errors?.name || result.errors?.access || 'Ошибка обновления отдела')
return
}
}
}
}
@@ -903,6 +951,7 @@ watch(() => props.show, async (newVal) => {
if (newVal) {
isSaving.value = false
tempIdCounter = 0
departmentsToDelete.value = []
if (props.project) {
// Редактирование — загружаем данные

View File

@@ -661,6 +661,13 @@ export const useProjectsStore = defineStore('projects', () => {
await projectsApi.updateDepartmentsOrder(currentProjectId.value, ids)
}
// Добавление отдела в конкретный проект (для создания нового проекта)
const addDepartmentToProject = async (projectId, name, color = '#6366f1') => {
const result = await projectsApi.addDepartment(projectId, name, color)
// Не добавляем в локальный state — при переключении на проект данные загрузятся
return result
}
return {
// Состояние
projects,
@@ -714,6 +721,7 @@ export const useProjectsStore = defineStore('projects', () => {
setReadyColumn,
// CRUD отделов
addDepartment,
addDepartmentToProject,
updateDepartment,
getDepartmentTasksCount,
deleteDepartment,