import { defineStore } from 'pinia' import { ref, computed } from 'vue' import { projectsApi, usersApi, cardsApi } from '../api' import { getCachedUser } from '../router' export const useProjectsStore = defineStore('projects', () => { // ==================== СОСТОЯНИЕ ==================== const projects = ref([]) const departments = ref([]) const labels = ref([]) const columns = ref([]) const users = ref([]) const cards = ref([]) // Активные карточки текущего проекта const archivedCards = ref([]) // Архивные карточки текущего проекта const cardsLoading = ref(false) // Загрузка карточек const loading = ref(false) const initialized = ref(false) const currentUser = ref(null) // Текущий авторизованный пользователь // Текущий проект (из localStorage) const savedProjectId = localStorage.getItem('currentProjectId') const savedProjectName = localStorage.getItem('currentProjectName') const currentProjectId = ref(savedProjectId ? parseInt(savedProjectId) : null) // ==================== ГЕТТЕРЫ ==================== // Текущий проект (объект) const currentProject = computed(() => projects.value.find(p => p.id === currentProjectId.value) || (savedProjectName && currentProjectId.value ? { id: currentProjectId.value, name: savedProjectName } : null) ) // ID колонки "Готово" текущего проекта const doneColumnId = computed(() => { const project = projects.value.find(p => p.id === currentProjectId.value) return project ? Number(project.id_ready) : null }) // ID текущего пользователя const currentUserId = computed(() => currentUser.value?.id || null) // Имя текущего пользователя const currentUserName = computed(() => currentUser.value?.name || '') // Аватар текущего пользователя const currentUserAvatar = computed(() => currentUser.value?.avatar_url || '') // Является ли текущий пользователь админом проекта // Сервер возвращает id_admin: true только если текущий пользователь — админ const isProjectAdmin = computed(() => { const project = projects.value.find(p => p.id === currentProjectId.value) return project?.id_admin === true }) // ==================== ДЕЙСТВИЯ ==================== // Инициализация (загрузка проектов + данных активного) const init = async () => { // Если уже инициализировано И есть данные — пропускаем if (initialized.value && projects.value.length > 0) return loading.value = true try { // Загружаем проекты и данные активного одним запросом const result = await projectsApi.getAll(currentProjectId.value || undefined) if (result.success) { if (result.data.projects) { projects.value = result.data.projects // Применяем данные активного проекта if (result.data.active) { columns.value = result.data.active.columns departments.value = result.data.active.departments labels.value = result.data.active.labels } } else { projects.value = result.data } // Если нет выбранного проекта — выбираем первый if (!currentProjectId.value || !projects.value.find(p => p.id === currentProjectId.value)) { if (projects.value.length > 0) { await selectProject(projects.value[0].id, true) // Загружаем данные проекта } } else if (!columns.value.length) { // Есть проект но нет данных — загружаем await fetchProjectData() } else { // Обновляем название в localStorage const project = projects.value.find(p => p.id === currentProjectId.value) if (project) localStorage.setItem('currentProjectName', project.name) } } // Загружаем пользователей const usersData = await usersApi.getAll() if (usersData.success) users.value = usersData.data // Получаем текущего пользователя из кэша роутера (без повторного запроса) if (!currentUser.value) { const cachedUser = getCachedUser() if (cachedUser) { // Находим полные данные пользователя (с id) из списка users const fullUser = users.value.find(u => u.username === cachedUser.username) currentUser.value = fullUser || cachedUser } } initialized.value = true } catch (error) { console.error('Ошибка инициализации:', error) } finally { loading.value = false } } // Выбор проекта const selectProject = async (projectId, fetchData = true) => { currentProjectId.value = projectId localStorage.setItem('currentProjectId', projectId.toString()) // Сохраняем название const project = projects.value.find(p => p.id === projectId) if (project) localStorage.setItem('currentProjectName', project.name) // Загружаем данные проекта if (fetchData) { await fetchProjectData() } } // Загрузка данных текущего проекта const fetchProjectData = async () => { if (!currentProjectId.value) return try { const projectData = await projectsApi.getData(currentProjectId.value) if (projectData.success) { columns.value = projectData.data.columns departments.value = projectData.data.departments labels.value = projectData.data.labels // Обновляем id_admin в списке проектов (сервер возвращает true если текущий пользователь админ) const project = projects.value.find(p => p.id === currentProjectId.value) if (project && projectData.data.project?.id_admin === true) { project.id_admin = true } } } catch (error) { console.error('Ошибка загрузки данных проекта:', error) } } // ==================== КАРТОЧКИ ==================== // Загрузка активных карточек (silent = тихое обновление без loading) const fetchCards = async (silent = false) => { if (!currentProjectId.value) { cardsLoading.value = false return } if (!silent) cardsLoading.value = true try { const result = await cardsApi.getAll(currentProjectId.value) if (result.success) cards.value = result.data } finally { if (!silent) cardsLoading.value = false } } // Загрузка архивных карточек const fetchArchivedCards = async () => { if (!currentProjectId.value) return cardsLoading.value = true try { const result = await cardsApi.getAll(currentProjectId.value, 1) // archive = 1 if (result.success) { archivedCards.value = result.data.map(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, dateClosed: card.date_closed, columnId: card.column_id, order: card.order ?? 0, comments_count: card.comments_count || 0, files: card.files || (card.file_img || []).map(f => ({ name: f.name, url: f.url, size: f.size, preview: f.url })) })) } } finally { cardsLoading.value = false } } // Очистка карточек при смене проекта const clearCards = () => { cards.value = [] archivedCards.value = [] } // Сброс при выходе const reset = () => { projects.value = [] departments.value = [] labels.value = [] columns.value = [] users.value = [] cards.value = [] archivedCards.value = [] currentProjectId.value = null currentUser.value = null initialized.value = false localStorage.removeItem('currentProjectId') localStorage.removeItem('currentProjectName') } return { // Состояние projects, departments, labels, columns, users, cards, archivedCards, cardsLoading, loading, initialized, currentProjectId, currentUser, // Геттеры currentProject, doneColumnId, currentUserId, currentUserName, currentUserAvatar, isProjectAdmin, // Действия init, selectProject, fetchProjectData, fetchCards, fetchArchivedCards, clearCards, reset } })