6.19.7: Сброс скролла и загрузка при смене проекта
Some checks failed
Build and Push Docker Image / build-and-push (push) Failing after 1m16s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
poignatov
2026-03-18 16:41:55 +03:00
parent 01cd0e9003
commit b1f4fdd449
4 changed files with 40 additions and 9 deletions

View File

@@ -1 +1 @@
6.19.6 6.19.7

View File

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

View File

@@ -677,6 +677,8 @@ function AppContent() {
// Refs для отслеживания активного таба // Refs для отслеживания активного таба
const prevActiveTabRef = useRef(null) const prevActiveTabRef = useRef(null)
const lastLoadedTabRef = useRef(null) // Отслеживаем последний загруженный таб, чтобы избежать двойной загрузки const lastLoadedTabRef = useRef(null) // Отслеживаем последний загруженный таб, чтобы избежать двойной загрузки
const fullStatisticsScrollRef = useRef(null)
const lastFullProjectRef = useRef(selectedProject)
// Обновляем ref при изменении данных // Обновляем ref при изменении данных
useEffect(() => { useEffect(() => {
@@ -1102,11 +1104,15 @@ function AppContent() {
lastLoadedTabRef.current = tabKey lastLoadedTabRef.current = tabKey
const projectName = activeTab === 'full' ? selectedProject : null const projectName = activeTab === 'full' ? selectedProject : null
loadTabData(activeTab, false, projectName) loadTabData(activeTab, false, projectName)
if (activeTab === 'full') lastFullProjectRef.current = selectedProject
} else if (isReturningToTab) { } else if (isReturningToTab) {
// Возврат на таб - фоновая загрузка // Возврат на таб
lastLoadedTabRef.current = tabKey lastLoadedTabRef.current = tabKey
const projectName = activeTab === 'full' ? selectedProject : null const projectName = activeTab === 'full' ? selectedProject : null
loadTabData(activeTab, true, projectName) // Если проект изменился - загрузка с индикатором, иначе фоновая
const isBackground = activeTab === 'full' && lastFullProjectRef.current !== selectedProject ? false : true
loadTabData(activeTab, isBackground, projectName)
if (activeTab === 'full') lastFullProjectRef.current = selectedProject
} }
prevActiveTabRef.current = activeTab prevActiveTabRef.current = activeTab
@@ -1128,6 +1134,13 @@ function AppContent() {
const isAnyLoading = currentWeekLoading || fullStatisticsLoading || prioritiesLoading || isRefreshing const isAnyLoading = currentWeekLoading || fullStatisticsLoading || prioritiesLoading || isRefreshing
const hasAnyError = currentWeekError || fullStatisticsError || prioritiesError const hasAnyError = currentWeekError || fullStatisticsError || prioritiesError
// Сбрасываем скролл экрана статистики при его открытии
useEffect(() => {
if (activeTab === 'full' && fullStatisticsScrollRef.current) {
fullStatisticsScrollRef.current.scrollTop = 0
}
}, [activeTab])
// Сохраняем выбранный таб, чтобы восстановить его после перезагрузки // Сохраняем выбранный таб, чтобы восстановить его после перезагрузки
useEffect(() => { useEffect(() => {
try { try {
@@ -1238,7 +1251,7 @@ function AppContent() {
)} )}
{loadedTabs.full && ( {loadedTabs.full && (
<div className={getTabContainerClasses('full')}> <div ref={fullStatisticsScrollRef} className={getTabContainerClasses('full')}>
<div className={getInnerContainerClasses('full')}> <div className={getInnerContainerClasses('full')}>
<FullStatistics <FullStatistics
selectedProject={selectedProject} selectedProject={selectedProject}

View File

@@ -41,6 +41,8 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
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 componentJustOpenedRef = React.useRef(false)
const lastActiveProjectRef = React.useRef(selectedProject)
const [projectChanged, setProjectChanged] = React.useState(false)
// Пересчитываем текущий день и даты недели при каждом открытии экрана // Пересчитываем текущий день и даты недели при каждом открытии экрана
const [now, setNow] = useState(() => new Date()) const [now, setNow] = useState(() => new Date())
@@ -99,23 +101,39 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
// Когда компонент открывается (activeTab становится 'full'), помечаем это // Когда компонент открывается (activeTab становится 'full'), помечаем это
if (activeTab === 'full' && prevActiveTabRef.current !== 'full') { if (activeTab === 'full' && prevActiveTabRef.current !== 'full') {
componentJustOpenedRef.current = true componentJustOpenedRef.current = true
// Проверяем, изменился ли проект с прошлого открытия
if (lastActiveProjectRef.current !== selectedProject) {
setProjectChanged(true)
}
}
// Запоминаем текущий проект при закрытии экрана
if (prevActiveTabRef.current === 'full' && activeTab !== 'full') {
lastActiveProjectRef.current = selectedProject
} }
prevActiveTabRef.current = activeTab prevActiveTabRef.current = activeTab
}, [activeTab]) }, [activeTab, selectedProject])
// Загружаем данные при открытии экрана, при изменении selectedDate или selectedProject // Загружаем данные при открытии экрана, при изменении selectedDate или selectedProject
useEffect(() => { useEffect(() => {
if (activeTab === 'full' && selectedDate && fetchTodayEntries) { if (activeTab === 'full' && selectedDate && fetchTodayEntries) {
// Если компонент только что открылся - используем фоновую загрузку // Если компонент только что открылся
if (componentJustOpenedRef.current) { if (componentJustOpenedRef.current) {
componentJustOpenedRef.current = false componentJustOpenedRef.current = false
// Если проект изменился - показываем загрузку (не фоновую)
if (projectChanged) {
setProjectChanged(false)
lastActiveProjectRef.current = selectedProject
fetchTodayEntries(false, selectedProject, selectedDate)
} else {
// Тот же проект - фоновая загрузка
fetchTodayEntries(true, selectedProject, selectedDate) fetchTodayEntries(true, selectedProject, selectedDate)
}
} else { } else {
// При изменении даты или проекта - используем обычную загрузку (не фоновую) // При изменении даты или проекта - используем обычную загрузку (не фоновую)
fetchTodayEntries(false, selectedProject, selectedDate) fetchTodayEntries(false, selectedProject, selectedDate)
} }
} }
}, [activeTab, selectedDate, selectedProject, fetchTodayEntries]) }, [activeTab, selectedDate, selectedProject, fetchTodayEntries, projectChanged])
// Обработчик выбора дня // Обработчик выбора дня
const handleDaySelect = useCallback((date) => { const handleDaySelect = useCallback((date) => {