4.21.0: Исправление навигации и истории
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m15s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m15s
This commit is contained in:
@@ -750,8 +750,33 @@ function AppContent() {
|
||||
setTabParams(params)
|
||||
// Обновляем URL только для глубоких табов
|
||||
if (isNewTabDeep) {
|
||||
// Сохраняем текущий таб как предыдущий при переходе на глубокий таб
|
||||
updateUrl(tab, params, activeTab)
|
||||
// Проверяем, была ли последняя запись в истории от модального окна
|
||||
const currentState = window.history.state || {}
|
||||
const isFromModal = currentState.modalOpen === true
|
||||
const isNavigatingToForm = tab === 'task-form' || tab === 'wishlist-form'
|
||||
|
||||
if (isFromModal && isNavigatingToForm) {
|
||||
// Заменяем запись модального окна на запись формы редактирования
|
||||
// Используем replaceState вместо pushState, сохраняя activeTab как previousTab
|
||||
const url = new URL(window.location)
|
||||
url.searchParams.set('tab', tab)
|
||||
// Удаляем старые параметры
|
||||
const keysToRemove = []
|
||||
url.searchParams.forEach((value, key) => {
|
||||
if (key !== 'tab') keysToRemove.push(key)
|
||||
})
|
||||
keysToRemove.forEach(key => url.searchParams.delete(key))
|
||||
// Добавляем новые параметры
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
url.searchParams.set(key, typeof value === 'object' ? JSON.stringify(value) : value)
|
||||
}
|
||||
})
|
||||
window.history.replaceState({ tab, params, previousTab: activeTab }, '', url)
|
||||
} else {
|
||||
// Сохраняем текущий таб как предыдущий при переходе на глубокий таб
|
||||
updateUrl(tab, params, activeTab)
|
||||
}
|
||||
} else if (isNewTabMain && isCurrentTabDeep) {
|
||||
// При переходе с глубокого таба на основной - очищаем URL и сохраняем таб в state
|
||||
clearUrl(tab)
|
||||
|
||||
@@ -139,7 +139,7 @@ function AddWords({ onNavigate, dictionaryId, dictionaryName }) {
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
onNavigate?.('words', dictionaryId !== undefined && dictionaryId !== null ? { dictionaryId } : {})
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
// Show loading state while fetching dictionary name
|
||||
|
||||
@@ -156,7 +156,7 @@ function BoardForm({ boardId, onNavigate, onSaved }) {
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
onNavigate('wishlist')
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
if (loadingBoard) {
|
||||
|
||||
@@ -94,7 +94,7 @@ function DictionaryList({ onNavigate, refreshTrigger = 0 }) {
|
||||
{/* Кнопка закрытия */}
|
||||
<button
|
||||
className="dictionary-close-button"
|
||||
onClick={() => onNavigate?.('profile')}
|
||||
onClick={() => window.history.back()}
|
||||
title="Закрыть"
|
||||
>
|
||||
✕
|
||||
|
||||
@@ -127,7 +127,7 @@ function FullStatistics({ selectedProject, onClearSelection, data, loading, erro
|
||||
onClick={() => {
|
||||
// Сбрасываем выбор дня перед выходом с экрана
|
||||
setSelectedDate(todayDateStr)
|
||||
onNavigate('current')
|
||||
window.history.back()
|
||||
}}
|
||||
className="close-x-button"
|
||||
title="Закрыть"
|
||||
|
||||
@@ -921,7 +921,7 @@ function ProjectPriorityManager({ allProjectsData, currentWeekData, shouldLoad,
|
||||
<div className="max-w-2xl mx-auto flex flex-col h-full">
|
||||
{onNavigate && (
|
||||
<button
|
||||
onClick={() => onNavigate('current')}
|
||||
onClick={() => window.history.back()}
|
||||
className="close-x-button"
|
||||
title="Закрыть"
|
||||
>
|
||||
|
||||
@@ -735,7 +735,9 @@ function TaskDetail({ taskId, onClose, onRefresh, onTaskCompleted, onNavigate })
|
||||
<h2
|
||||
className="task-detail-title"
|
||||
onClick={taskDetail ? () => {
|
||||
onClose?.()
|
||||
// Закрываем модальное окно БЕЗ history.back() (skipHistoryBack = true)
|
||||
// handleTabChange заменит запись модального окна через replaceState
|
||||
onClose?.(true)
|
||||
onNavigate?.('task-form', { taskId: taskId })
|
||||
} : undefined}
|
||||
style={{ cursor: taskDetail ? 'pointer' : 'default' }}
|
||||
|
||||
@@ -774,7 +774,7 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
|
||||
|
||||
const handleCancel = () => {
|
||||
resetForm()
|
||||
onNavigate?.('tasks')
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
const handleDelete = async () => {
|
||||
|
||||
@@ -71,8 +71,15 @@ function TaskList({ onNavigate, data, loading, backgroundLoading, error, onRetry
|
||||
setSelectedTaskForDetail(task.id)
|
||||
}
|
||||
|
||||
const handleCloseDetail = () => {
|
||||
setSelectedTaskForDetail(null)
|
||||
const handleCloseDetail = (skipHistoryBack = false) => {
|
||||
// Если skipHistoryBack = true (например, при навигации на форму редактирования),
|
||||
// просто закрываем модальное окно без history.back()
|
||||
if (!skipHistoryBack && historyPushedForDetailRef.current) {
|
||||
window.history.back()
|
||||
} else {
|
||||
historyPushedForDetailRef.current = false
|
||||
setSelectedTaskForDetail(null)
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем запись в историю при открытии модальных окон и обрабатываем "назад"
|
||||
|
||||
@@ -557,7 +557,7 @@ function TestWords({ onNavigate, wordCount: initialWordCount, configId: initialC
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
onNavigate?.('tasks')
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
const handleStartTest = () => {
|
||||
|
||||
@@ -52,6 +52,9 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
}, [wishlistId, fetchWishlistDetail])
|
||||
|
||||
const handleEdit = () => {
|
||||
// Сбрасываем флаг, чтобы handleClose не вызвал history.back()
|
||||
// handleTabChange заменит запись модального окна через replaceState
|
||||
historyPushedForWishlistRef.current = false
|
||||
onClose?.()
|
||||
onNavigate?.('wishlist-form', { wishlistId: wishlistId, boardId: boardId })
|
||||
}
|
||||
@@ -192,8 +195,15 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
}
|
||||
}
|
||||
|
||||
const handleCloseDetail = () => {
|
||||
setSelectedTaskForDetail(null)
|
||||
const handleCloseDetail = (skipHistoryBack = false) => {
|
||||
// Если skipHistoryBack = true (например, при навигации на форму редактирования),
|
||||
// просто закрываем модальное окно без history.back()
|
||||
if (!skipHistoryBack && historyPushedForTaskRef.current) {
|
||||
window.history.back()
|
||||
} else {
|
||||
historyPushedForTaskRef.current = false
|
||||
setSelectedTaskForDetail(null)
|
||||
}
|
||||
}
|
||||
|
||||
// Добавляем запись в историю при открытии модальных окон и обрабатываем "назад"
|
||||
@@ -278,8 +288,11 @@ function WishlistDetail({ wishlistId, onNavigate, onRefresh, boardId, onClose, p
|
||||
}, [wishlistId, selectedTaskForDetail, onClose, onNavigate, previousTab, boardId])
|
||||
|
||||
const handleClose = () => {
|
||||
// Используем onClose если передан, иначе возвращаемся на wishlist
|
||||
if (onClose) {
|
||||
// Если была добавлена запись в историю, удаляем её через history.back()
|
||||
// Обработчик popstate закроет модальное окно
|
||||
if (historyPushedForWishlistRef.current) {
|
||||
window.history.back()
|
||||
} else if (onClose) {
|
||||
onClose()
|
||||
} else {
|
||||
// Возвращаемся на предыдущий таб, если он был сохранен, иначе на wishlist
|
||||
|
||||
@@ -666,12 +666,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
||||
|
||||
const handleCancel = () => {
|
||||
resetForm()
|
||||
// Возвращаемся на доску, если она была указана
|
||||
if (boardId) {
|
||||
onNavigate?.('wishlist', { boardId })
|
||||
} else {
|
||||
onNavigate?.('wishlist')
|
||||
}
|
||||
window.history.back()
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -176,7 +176,7 @@ function WordList({ onNavigate, dictionaryId, isNewDictionary, refreshTrigger =
|
||||
return (
|
||||
<div className="word-list">
|
||||
<button
|
||||
onClick={() => onNavigate?.('dictionaries')}
|
||||
onClick={() => window.history.back()}
|
||||
className="close-x-button"
|
||||
title="Закрыть"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user