4.15.0: Добавлена принадлежность желаний к проектам
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m33s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m33s
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import React, { useState, useEffect, useRef } from 'react'
|
||||
import React, { useState, useEffect, useRef, useMemo } from 'react'
|
||||
import { useAuth } from './auth/AuthContext'
|
||||
import BoardSelector from './BoardSelector'
|
||||
import LoadingError from './LoadingError'
|
||||
import WishlistDetail from './WishlistDetail'
|
||||
import { sortProjectsLikeCurrentWeek } from '../utils/projectUtils'
|
||||
import './Wishlist.css'
|
||||
|
||||
const API_URL = '/api/wishlist'
|
||||
@@ -45,6 +46,7 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
const [completedLoading, setCompletedLoading] = useState(false)
|
||||
const [selectedItem, setSelectedItem] = useState(null)
|
||||
const [selectedWishlistForDetail, setSelectedWishlistForDetail] = useState(null)
|
||||
const [currentWeekData, setCurrentWeekData] = useState(null)
|
||||
const fetchingRef = useRef(false)
|
||||
const fetchingCompletedRef = useRef(false)
|
||||
const initialFetchDoneRef = useRef(false)
|
||||
@@ -234,6 +236,24 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
}
|
||||
}
|
||||
|
||||
// Загрузка данных текущей недели для сортировки проектов
|
||||
const fetchCurrentWeek = async () => {
|
||||
try {
|
||||
const response = await authFetch('/api/current-week')
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
// Обрабатываем ответ: приходит массив с одним объектом [{total: ..., projects: [...]}]
|
||||
if (Array.isArray(data) && data.length > 0) {
|
||||
setCurrentWeekData(data[0])
|
||||
} else if (data && typeof data === 'object') {
|
||||
setCurrentWeekData(data)
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error loading current week data:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// Первая инициализация
|
||||
useEffect(() => {
|
||||
if (!initialFetchDoneRef.current) {
|
||||
@@ -247,6 +267,9 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
|
||||
// Загружаем доски с сервера
|
||||
fetchBoards()
|
||||
|
||||
// Загружаем данные текущей недели для сортировки проектов
|
||||
fetchCurrentWeek()
|
||||
}
|
||||
}, [])
|
||||
|
||||
@@ -557,6 +580,60 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
)
|
||||
}
|
||||
|
||||
// Группируем желания по проектам
|
||||
const groupedItems = useMemo(() => {
|
||||
const groups = {}
|
||||
const noProjectItems = []
|
||||
|
||||
items.forEach(item => {
|
||||
if (item.project_id && item.project_name) {
|
||||
const projectId = item.project_id
|
||||
if (!groups[projectId]) {
|
||||
groups[projectId] = {
|
||||
projectId: projectId,
|
||||
projectName: item.project_name,
|
||||
items: []
|
||||
}
|
||||
}
|
||||
groups[projectId].items.push(item)
|
||||
} else {
|
||||
noProjectItems.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
// Сортируем группы проектов
|
||||
const projectIds = Object.keys(groups)
|
||||
if (currentWeekData && projectIds.length > 0) {
|
||||
const projectNames = projectIds.map(id => groups[id].projectName)
|
||||
const sortedProjectNames = sortProjectsLikeCurrentWeek(projectNames, currentWeekData)
|
||||
|
||||
// Создаем отсортированный массив групп
|
||||
const sortedGroups = []
|
||||
sortedProjectNames.forEach(projectName => {
|
||||
const group = Object.values(groups).find(g => g.projectName === projectName)
|
||||
if (group) {
|
||||
sortedGroups.push(group)
|
||||
}
|
||||
})
|
||||
|
||||
// Добавляем группы, которых нет в currentWeekData (если есть)
|
||||
Object.values(groups).forEach(group => {
|
||||
if (!sortedProjectNames.includes(group.projectName)) {
|
||||
sortedGroups.push(group)
|
||||
}
|
||||
})
|
||||
|
||||
return { groups: sortedGroups, noProjectItems }
|
||||
}
|
||||
|
||||
// Если нет данных текущей недели, сортируем по алфавиту
|
||||
const sortedGroups = Object.values(groups).sort((a, b) =>
|
||||
a.projectName.localeCompare(b.projectName)
|
||||
)
|
||||
|
||||
return { groups: sortedGroups, noProjectItems }
|
||||
}, [items, currentWeekData])
|
||||
|
||||
const renderItem = (item) => {
|
||||
const isFaded = (!item.unlocked && !item.completed) || item.completed
|
||||
|
||||
@@ -646,9 +723,24 @@ function Wishlist({ onNavigate, refreshTrigger = 0, isActive = false, initialBoa
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<div className="wishlist-grid">
|
||||
{items.map(renderItem)}
|
||||
</div>
|
||||
{/* Группы проектов */}
|
||||
{groupedItems.groups.map(group => (
|
||||
<div key={group.projectId} className="wishlist-project-group">
|
||||
<div className="wishlist-project-group-title">{group.projectName}</div>
|
||||
<div className="wishlist-project-group-items">
|
||||
{group.items.map(renderItem)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
|
||||
{/* Желания без проекта */}
|
||||
{groupedItems.noProjectItems.length > 0 && (
|
||||
<div className="wishlist-no-project">
|
||||
<div className="wishlist-grid">
|
||||
{groupedItems.noProjectItems.map(renderItem)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Завершённые */}
|
||||
{completedCount > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user