4.20.4: Фоновая загрузка данных прогресса недель
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m8s

This commit is contained in:
poignatov
2026-02-05 12:40:44 +03:00
parent 126f9ec919
commit 0ee689151e
4 changed files with 36 additions and 15 deletions

View File

@@ -1 +1 @@
4.20.3 4.20.4

View File

@@ -1,6 +1,6 @@
{ {
"name": "play-life-web", "name": "play-life-web",
"version": "4.20.3", "version": "4.20.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -514,17 +514,32 @@ function AppContent() {
// Если нет кеша и это не первая загрузка - ничего не делаем (данные уже загружаются) // Если нет кеша и это не первая загрузка - ничего не делаем (данные уже загружаются)
} else if (tab === 'full') { } else if (tab === 'full') {
const hasCache = cacheRef.current.full !== null const hasCache = cacheRef.current.full !== null
const hasCurrentWeekCache = cacheRef.current.current !== null
const isInitialized = tabsInitializedRef.current.full const isInitialized = tabsInitializedRef.current.full
if (!isInitialized) { if (!isInitialized) {
// Первая загрузка таба - загружаем с индикатором // Первая загрузка таба
fetchFullStatisticsData(false) if (hasCache) {
// Если есть кеш - используем фоновую загрузку, показываем старые данные
fetchFullStatisticsData(true)
} else {
// Если кеша нет - загружаем с индикатором
fetchFullStatisticsData(false)
}
// Также запускаем фоновую загрузку currentWeekData, если его нет
if (!hasCurrentWeekCache) {
fetchCurrentWeekData(true)
}
// todayEntries будет загружен в FullStatistics компоненте при выборе дня // todayEntries будет загружен в FullStatistics компоненте при выборе дня
tabsInitializedRef.current.full = true tabsInitializedRef.current.full = true
setTabsInitialized(prev => ({ ...prev, full: true })) setTabsInitialized(prev => ({ ...prev, full: true }))
} else if (hasCache && isBackground) { } else if (hasCache && isBackground) {
// Возврат на таб с кешем - фоновая загрузка // Возврат на таб с кешем - фоновая загрузка
fetchFullStatisticsData(true) fetchFullStatisticsData(true)
// Также запускаем фоновую загрузку currentWeekData, если его нет
if (!hasCurrentWeekCache) {
fetchCurrentWeekData(true)
}
// todayEntries будет загружен в FullStatistics компоненте при выборе дня // todayEntries будет загружен в FullStatistics компоненте при выборе дня
} }
} else if (tab === 'priorities') { } else if (tab === 'priorities') {

View File

@@ -40,6 +40,7 @@ const dayNames = ['пн', 'вт', 'ср', 'чт', 'пт', 'сб', 'вс']
function FullStatistics({ selectedProject, onClearSelection, data, loading, error, onRetry, currentWeekData, onNavigate, todayEntries, todayEntriesLoading, todayEntriesError, onRetryTodayEntries, fetchTodayEntries, activeTab }) { function FullStatistics({ selectedProject, onClearSelection, data, loading, error, onRetry, currentWeekData, onNavigate, todayEntries, todayEntriesLoading, todayEntriesError, onRetryTodayEntries, fetchTodayEntries, activeTab }) {
const [selectedDate, setSelectedDate] = useState(null) const [selectedDate, setSelectedDate] = useState(null)
const prevActiveTabRef = React.useRef(activeTab) const prevActiveTabRef = React.useRef(activeTab)
const componentJustOpenedRef = React.useRef(false)
// Получаем даты текущей недели // Получаем даты текущей недели
const weekDates = getCurrentWeekDates() const weekDates = getCurrentWeekDates()
@@ -67,7 +68,6 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
if (prevActiveTabRef.current === 'full' && activeTab !== 'full') { if (prevActiveTabRef.current === 'full' && activeTab !== 'full') {
setSelectedDate(todayDateStr) setSelectedDate(todayDateStr)
} }
prevActiveTabRef.current = activeTab
}, [activeTab, todayDateStr]) }, [activeTab, todayDateStr])
// Инициализируем выбранную дату текущим днем при первом рендере // Инициализируем выбранную дату текущим днем при первом рендере
@@ -85,20 +85,26 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
} }
}, [selectedDate, todayDateStr, pastDays]) }, [selectedDate, todayDateStr, pastDays])
// Отслеживаем открытие компонента и загружаем данные для selectedDate // Отслеживаем открытие компонента
useEffect(() => { useEffect(() => {
// Этот эффект срабатывает при каждом рендере, но мы проверяем, нужно ли загружать данные // Когда компонент открывается (activeTab становится 'full'), помечаем это
if (selectedDate && fetchTodayEntries) { if (activeTab === 'full' && prevActiveTabRef.current !== 'full') {
// Всегда загружаем данные для selectedDate при его изменении componentJustOpenedRef.current = true
// Это гарантирует, что данные соответствуют выбранному чипсу
fetchTodayEntries(false, selectedProject, selectedDate)
} }
}, [selectedDate, selectedProject, fetchTodayEntries]) prevActiveTabRef.current = activeTab
}, [activeTab])
// Загружаем данные при изменении selectedDate или selectedProject // Загружаем данные при изменении selectedDate или selectedProject
useEffect(() => { useEffect(() => {
if (selectedDate && fetchTodayEntries) { if (selectedDate && fetchTodayEntries) {
fetchTodayEntries(false, selectedProject, selectedDate) // Если компонент только что открылся - используем фоновую загрузку
if (componentJustOpenedRef.current) {
componentJustOpenedRef.current = false
fetchTodayEntries(true, selectedProject, selectedDate)
} else {
// При изменении даты или проекта - используем обычную загрузку (не фоновую)
fetchTodayEntries(false, selectedProject, selectedDate)
}
} }
}, [selectedDate, selectedProject, fetchTodayEntries]) }, [selectedDate, selectedProject, fetchTodayEntries])
@@ -129,14 +135,14 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
</button> </button>
)} )}
{loading && (!data || data.length === 0) ? ( {loading && (!data || data.length === 0) && (!todayEntries || (Array.isArray(todayEntries) && todayEntries.length === 0)) ? (
<div className="fixed inset-0 flex justify-center items-center"> <div className="fixed inset-0 flex justify-center items-center">
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
<div className="w-12 h-12 border-4 border-indigo-200 border-t-indigo-600 rounded-full animate-spin mb-4"></div> <div className="w-12 h-12 border-4 border-indigo-200 border-t-indigo-600 rounded-full animate-spin mb-4"></div>
<div className="text-gray-600 font-medium">Загрузка...</div> <div className="text-gray-600 font-medium">Загрузка...</div>
</div> </div>
</div> </div>
) : (!data || data.length === 0) ? ( ) : (!data || data.length === 0) && !todayEntries ? (
<div className="flex justify-center items-center py-16"> <div className="flex justify-center items-center py-16">
<div className="text-gray-500 text-lg">Нет данных для отображения</div> <div className="text-gray-500 text-lg">Нет данных для отображения</div>
</div> </div>