6.4.13: Фикс кнопки назад для диалога цели
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m5s

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
poignatov
2026-03-09 22:08:24 +03:00
parent 17e6bbf9f1
commit 3a1b836ece
5 changed files with 79 additions and 26 deletions

View File

@@ -773,9 +773,10 @@ function AppContent() {
// Проверяем, есть ли открытые модальные окна в DOM
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
const wishlistDetailModal = document.querySelector('.wishlist-detail-modal-overlay')
const conditionFormOverlay = document.querySelector('.condition-form-overlay')
// Если есть открытые модальные окна, не обрабатываем здесь - компоненты сами закроют их
if (taskDetailModal || wishlistDetailModal) {
if (taskDetailModal || wishlistDetailModal || conditionFormOverlay) {
return
}
@@ -922,7 +923,7 @@ function AppContent() {
if (isNewTabDeep) {
// Проверяем, была ли последняя запись в истории от модального окна
const currentState = window.history.state || {}
const isFromModal = currentState.modalOpen === true
const isFromModal = currentState.modalOpen === true || currentState.conditionForm === true
const isNavigatingToForm = tab === 'task-form' || tab === 'wishlist-form' || tab === 'shopping-item-form'
if (isFromModal && isNavigatingToForm) {

View File

@@ -768,11 +768,11 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
// Если был returnTo, возвращаемся на форму желания с ID новой задачи
if (returnTo === 'wishlist-form') {
console.log('[TaskForm] Navigating back to wishlist-form with newTaskId:', newTaskId)
onNavigate?.(returnTo, {
wishlistId: returnWishlistId,
newTaskId: newTaskId,
})
console.log('[TaskForm] Saving newTaskId to sessionStorage and going back:', newTaskId)
// Сохраняем newTaskId в sessionStorage, чтобы WishlistForm мог его прочитать
sessionStorage.setItem('wishlistFormNewTaskId', String(newTaskId))
// Используем history.back() чтобы не создавать лишнюю запись в стеке
window.history.back()
} else {
console.log('[TaskForm] No returnTo, going back in history')
// Возврат назад по стеку истории (на список задач, желаний и т.д.)

View File

@@ -9,8 +9,20 @@ const TASKS_API_URL = '/api/tasks'
const PROJECTS_API_URL = '/projects'
const WISHLIST_FORM_STATE_KEY = 'wishlistFormPendingState'
function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, boardId }) {
function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId: newTaskIdProp, boardId }) {
const { authFetch, user } = useAuth()
// newTaskId может прийти из props (через onNavigate) или из sessionStorage (через history.back)
const [newTaskId] = useState(() => {
if (newTaskIdProp) return newTaskIdProp
const stored = sessionStorage.getItem('wishlistFormNewTaskId')
if (stored) {
sessionStorage.removeItem('wishlistFormNewTaskId')
return parseInt(stored, 10)
}
return undefined
})
const [name, setName] = useState('')
const [price, setPrice] = useState('')
const [link, setLink] = useState('')
@@ -33,10 +45,14 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
const [toastMessage, setToastMessage] = useState(null)
const [loadingWishlist, setLoadingWishlist] = useState(false)
const [fetchingMetadata, setFetchingMetadata] = useState(false)
const [restoredFromSession, setRestoredFromSession] = useState(false) // Флаг восстановления из sessionStorage
const [restoredFromSession, setRestoredFromSession] = useState(() => {
// Инициализируем флаг сразу, чтобы loadWishlist не запустился до восстановления
return !!(newTaskId && sessionStorage.getItem(WISHLIST_FORM_STATE_KEY))
})
const [loadedWishlistData, setLoadedWishlistData] = useState(null) // Данные желания для последующего маппинга условий
const [imageUrlInput, setImageUrlInput] = useState('') // Ссылка на картинку для загрузки по URL
const [loadingImageFromUrl, setLoadingImageFromUrl] = useState(false)
const [newTaskConsumed, setNewTaskConsumed] = useState(false) // Флаг что newTaskId уже добавлен как цель
const fileInputRef = useRef(null)
// Загрузка задач, проектов и саджестов групп
@@ -139,6 +155,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
}
}, [editConditionIndex, unlockConditions])
// Обработка кнопки "назад" для диалога ConditionForm
const showConditionFormRef = useRef(false)
const conditionClosedByPopStateRef = useRef(false)
showConditionFormRef.current = showConditionForm
useEffect(() => {
const handlePopState = () => {
if (showConditionFormRef.current) {
// Закрываем диалог — popstate уже убрал запись из стека
conditionClosedByPopStateRef.current = true
setShowConditionForm(false)
setEditingConditionIndex(null)
}
}
window.addEventListener('popstate', handlePopState)
return () => window.removeEventListener('popstate', handlePopState)
}, [])
// Восстановление состояния при возврате с создания задачи
useEffect(() => {
const savedState = sessionStorage.getItem(WISHLIST_FORM_STATE_KEY)
@@ -161,6 +195,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
const restoredConditions = state.unlockConditions || []
console.log('[WishlistForm] Restored conditions:', restoredConditions)
// Устанавливаем флаг синхронно, чтобы loadWishlist не перезаписал восстановленное состояние
setRestoredFromSession(true)
// Перезагружаем задачи, чтобы новая задача была в списке
const reloadTasks = async () => {
console.log('[WishlistForm] Reloading tasks...')
@@ -171,7 +208,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
const tasksData = await tasksResponse.json()
console.log('[WishlistForm] Tasks loaded:', tasksData.length)
setTasks(Array.isArray(tasksData) ? tasksData : [])
// Автоматически добавляем цель с новой задачей
console.log('[WishlistForm] pendingConditionType:', state.pendingConditionType)
if (state.pendingConditionType === 'task_completion') {
@@ -184,11 +221,11 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
display_order: restoredConditions.length,
}
console.log('[WishlistForm] New condition to add:', newCondition)
// Если редактировали существующее условие, заменяем его
if (state.editingConditionIndex !== null && state.editingConditionIndex !== undefined) {
console.log('[WishlistForm] Replacing existing condition at index:', state.editingConditionIndex)
const updatedConditions = restoredConditions.map((cond, idx) =>
const updatedConditions = restoredConditions.map((cond, idx) =>
idx === state.editingConditionIndex ? { ...newCondition, display_order: idx } : cond
)
setUnlockConditions(updatedConditions)
@@ -199,12 +236,10 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
console.log('[WishlistForm] Adding new condition, final conditions:', finalConditions)
setUnlockConditions(finalConditions)
}
setNewTaskConsumed(true)
} else {
setUnlockConditions(restoredConditions)
}
// Устанавливаем флаг, что состояние восстановлено
setRestoredFromSession(true)
}
} catch (err) {
console.error('[WishlistForm] Error reloading tasks:', err)
@@ -543,9 +578,25 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
}
}
const openConditionForm = () => {
setShowConditionForm(true)
conditionClosedByPopStateRef.current = false
window.history.pushState({ conditionForm: true }, '', window.location.href)
}
const closeConditionForm = () => {
setShowConditionForm(false)
setEditingConditionIndex(null)
// Если закрытие через popstate — запись уже убрана, не делаем back
if (!conditionClosedByPopStateRef.current) {
window.history.back()
}
conditionClosedByPopStateRef.current = false
}
const handleAddCondition = () => {
setEditingConditionIndex(null)
setShowConditionForm(true)
openConditionForm()
}
const handleEditCondition = (index) => {
@@ -556,26 +607,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
return
}
setEditingConditionIndex(index)
setShowConditionForm(true)
openConditionForm()
}
const handleConditionSubmit = (condition) => {
if (editingConditionIndex !== null) {
// Редактирование существующего условия
setUnlockConditions(prev => prev.map((cond, idx) =>
setUnlockConditions(prev => prev.map((cond, idx) =>
idx === editingConditionIndex ? { ...condition, display_order: idx } : cond
))
} else {
// Добавление нового условия
setUnlockConditions([...unlockConditions, { ...condition, display_order: unlockConditions.length }])
}
setShowConditionForm(false)
setEditingConditionIndex(null)
closeConditionForm()
}
const handleConditionCancel = () => {
setShowConditionForm(false)
setEditingConditionIndex(null)
closeConditionForm()
}
const handleRemoveCondition = (index) => {
@@ -590,6 +639,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
// Обработчик для создания задачи из ConditionForm
const handleCreateTaskFromCondition = () => {
// Закрываем диалог цели перед переходом
setShowConditionForm(false)
// Сохранить текущее состояние формы
const stateToSave = {
name,
@@ -602,7 +654,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
}
console.log('[WishlistForm] Saving state and navigating to task-form:', stateToSave)
sessionStorage.setItem(WISHLIST_FORM_STATE_KEY, JSON.stringify(stateToSave))
// Навигация на форму создания задачи
const navParams = {
returnTo: 'wishlist-form',
@@ -987,7 +1039,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
onCancel={handleConditionCancel}
editingCondition={editingConditionIndex !== null ? unlockConditions[editingConditionIndex] : null}
onCreateTask={handleCreateTaskFromCondition}
preselectedTaskId={newTaskId}
preselectedTaskId={newTaskConsumed ? undefined : newTaskId}
authFetch={authFetch}
/>
)}