260 lines
9.3 KiB
JavaScript
260 lines
9.3 KiB
JavaScript
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
|
||
}
|
||
})
|