6.4.13: Фикс кнопки назад для диалога цели
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m5s
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:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "play-life-web",
|
"name": "play-life-web",
|
||||||
"version": "6.4.12",
|
"version": "6.4.13",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -773,9 +773,10 @@ function AppContent() {
|
|||||||
// Проверяем, есть ли открытые модальные окна в DOM
|
// Проверяем, есть ли открытые модальные окна в DOM
|
||||||
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
|
const taskDetailModal = document.querySelector('.task-detail-modal-overlay')
|
||||||
const wishlistDetailModal = document.querySelector('.wishlist-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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +923,7 @@ function AppContent() {
|
|||||||
if (isNewTabDeep) {
|
if (isNewTabDeep) {
|
||||||
// Проверяем, была ли последняя запись в истории от модального окна
|
// Проверяем, была ли последняя запись в истории от модального окна
|
||||||
const currentState = window.history.state || {}
|
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'
|
const isNavigatingToForm = tab === 'task-form' || tab === 'wishlist-form' || tab === 'shopping-item-form'
|
||||||
|
|
||||||
if (isFromModal && isNavigatingToForm) {
|
if (isFromModal && isNavigatingToForm) {
|
||||||
|
|||||||
@@ -768,11 +768,11 @@ function TaskForm({ onNavigate, taskId, wishlistId, isTest: isTestFromProps = fa
|
|||||||
|
|
||||||
// Если был returnTo, возвращаемся на форму желания с ID новой задачи
|
// Если был returnTo, возвращаемся на форму желания с ID новой задачи
|
||||||
if (returnTo === 'wishlist-form') {
|
if (returnTo === 'wishlist-form') {
|
||||||
console.log('[TaskForm] Navigating back to wishlist-form with newTaskId:', newTaskId)
|
console.log('[TaskForm] Saving newTaskId to sessionStorage and going back:', newTaskId)
|
||||||
onNavigate?.(returnTo, {
|
// Сохраняем newTaskId в sessionStorage, чтобы WishlistForm мог его прочитать
|
||||||
wishlistId: returnWishlistId,
|
sessionStorage.setItem('wishlistFormNewTaskId', String(newTaskId))
|
||||||
newTaskId: newTaskId,
|
// Используем history.back() чтобы не создавать лишнюю запись в стеке
|
||||||
})
|
window.history.back()
|
||||||
} else {
|
} else {
|
||||||
console.log('[TaskForm] No returnTo, going back in history')
|
console.log('[TaskForm] No returnTo, going back in history')
|
||||||
// Возврат назад по стеку истории (на список задач, желаний и т.д.)
|
// Возврат назад по стеку истории (на список задач, желаний и т.д.)
|
||||||
|
|||||||
@@ -9,8 +9,20 @@ const TASKS_API_URL = '/api/tasks'
|
|||||||
const PROJECTS_API_URL = '/projects'
|
const PROJECTS_API_URL = '/projects'
|
||||||
const WISHLIST_FORM_STATE_KEY = 'wishlistFormPendingState'
|
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()
|
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 [name, setName] = useState('')
|
||||||
const [price, setPrice] = useState('')
|
const [price, setPrice] = useState('')
|
||||||
const [link, setLink] = useState('')
|
const [link, setLink] = useState('')
|
||||||
@@ -33,10 +45,14 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
const [toastMessage, setToastMessage] = useState(null)
|
const [toastMessage, setToastMessage] = useState(null)
|
||||||
const [loadingWishlist, setLoadingWishlist] = useState(false)
|
const [loadingWishlist, setLoadingWishlist] = useState(false)
|
||||||
const [fetchingMetadata, setFetchingMetadata] = 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 [loadedWishlistData, setLoadedWishlistData] = useState(null) // Данные желания для последующего маппинга условий
|
||||||
const [imageUrlInput, setImageUrlInput] = useState('') // Ссылка на картинку для загрузки по URL
|
const [imageUrlInput, setImageUrlInput] = useState('') // Ссылка на картинку для загрузки по URL
|
||||||
const [loadingImageFromUrl, setLoadingImageFromUrl] = useState(false)
|
const [loadingImageFromUrl, setLoadingImageFromUrl] = useState(false)
|
||||||
|
const [newTaskConsumed, setNewTaskConsumed] = useState(false) // Флаг что newTaskId уже добавлен как цель
|
||||||
const fileInputRef = useRef(null)
|
const fileInputRef = useRef(null)
|
||||||
|
|
||||||
// Загрузка задач, проектов и саджестов групп
|
// Загрузка задач, проектов и саджестов групп
|
||||||
@@ -139,6 +155,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
}
|
}
|
||||||
}, [editConditionIndex, unlockConditions])
|
}, [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(() => {
|
useEffect(() => {
|
||||||
const savedState = sessionStorage.getItem(WISHLIST_FORM_STATE_KEY)
|
const savedState = sessionStorage.getItem(WISHLIST_FORM_STATE_KEY)
|
||||||
@@ -161,6 +195,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
const restoredConditions = state.unlockConditions || []
|
const restoredConditions = state.unlockConditions || []
|
||||||
console.log('[WishlistForm] Restored conditions:', restoredConditions)
|
console.log('[WishlistForm] Restored conditions:', restoredConditions)
|
||||||
|
|
||||||
|
// Устанавливаем флаг синхронно, чтобы loadWishlist не перезаписал восстановленное состояние
|
||||||
|
setRestoredFromSession(true)
|
||||||
|
|
||||||
// Перезагружаем задачи, чтобы новая задача была в списке
|
// Перезагружаем задачи, чтобы новая задача была в списке
|
||||||
const reloadTasks = async () => {
|
const reloadTasks = async () => {
|
||||||
console.log('[WishlistForm] Reloading tasks...')
|
console.log('[WishlistForm] Reloading tasks...')
|
||||||
@@ -171,7 +208,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
const tasksData = await tasksResponse.json()
|
const tasksData = await tasksResponse.json()
|
||||||
console.log('[WishlistForm] Tasks loaded:', tasksData.length)
|
console.log('[WishlistForm] Tasks loaded:', tasksData.length)
|
||||||
setTasks(Array.isArray(tasksData) ? tasksData : [])
|
setTasks(Array.isArray(tasksData) ? tasksData : [])
|
||||||
|
|
||||||
// Автоматически добавляем цель с новой задачей
|
// Автоматически добавляем цель с новой задачей
|
||||||
console.log('[WishlistForm] pendingConditionType:', state.pendingConditionType)
|
console.log('[WishlistForm] pendingConditionType:', state.pendingConditionType)
|
||||||
if (state.pendingConditionType === 'task_completion') {
|
if (state.pendingConditionType === 'task_completion') {
|
||||||
@@ -184,11 +221,11 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
display_order: restoredConditions.length,
|
display_order: restoredConditions.length,
|
||||||
}
|
}
|
||||||
console.log('[WishlistForm] New condition to add:', newCondition)
|
console.log('[WishlistForm] New condition to add:', newCondition)
|
||||||
|
|
||||||
// Если редактировали существующее условие, заменяем его
|
// Если редактировали существующее условие, заменяем его
|
||||||
if (state.editingConditionIndex !== null && state.editingConditionIndex !== undefined) {
|
if (state.editingConditionIndex !== null && state.editingConditionIndex !== undefined) {
|
||||||
console.log('[WishlistForm] Replacing existing condition at index:', state.editingConditionIndex)
|
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
|
idx === state.editingConditionIndex ? { ...newCondition, display_order: idx } : cond
|
||||||
)
|
)
|
||||||
setUnlockConditions(updatedConditions)
|
setUnlockConditions(updatedConditions)
|
||||||
@@ -199,12 +236,10 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
console.log('[WishlistForm] Adding new condition, final conditions:', finalConditions)
|
console.log('[WishlistForm] Adding new condition, final conditions:', finalConditions)
|
||||||
setUnlockConditions(finalConditions)
|
setUnlockConditions(finalConditions)
|
||||||
}
|
}
|
||||||
|
setNewTaskConsumed(true)
|
||||||
} else {
|
} else {
|
||||||
setUnlockConditions(restoredConditions)
|
setUnlockConditions(restoredConditions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Устанавливаем флаг, что состояние восстановлено
|
|
||||||
setRestoredFromSession(true)
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('[WishlistForm] Error reloading tasks:', 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 = () => {
|
const handleAddCondition = () => {
|
||||||
setEditingConditionIndex(null)
|
setEditingConditionIndex(null)
|
||||||
setShowConditionForm(true)
|
openConditionForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleEditCondition = (index) => {
|
const handleEditCondition = (index) => {
|
||||||
@@ -556,26 +607,24 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
setEditingConditionIndex(index)
|
setEditingConditionIndex(index)
|
||||||
setShowConditionForm(true)
|
openConditionForm()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConditionSubmit = (condition) => {
|
const handleConditionSubmit = (condition) => {
|
||||||
if (editingConditionIndex !== null) {
|
if (editingConditionIndex !== null) {
|
||||||
// Редактирование существующего условия
|
// Редактирование существующего условия
|
||||||
setUnlockConditions(prev => prev.map((cond, idx) =>
|
setUnlockConditions(prev => prev.map((cond, idx) =>
|
||||||
idx === editingConditionIndex ? { ...condition, display_order: idx } : cond
|
idx === editingConditionIndex ? { ...condition, display_order: idx } : cond
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
// Добавление нового условия
|
// Добавление нового условия
|
||||||
setUnlockConditions([...unlockConditions, { ...condition, display_order: unlockConditions.length }])
|
setUnlockConditions([...unlockConditions, { ...condition, display_order: unlockConditions.length }])
|
||||||
}
|
}
|
||||||
setShowConditionForm(false)
|
closeConditionForm()
|
||||||
setEditingConditionIndex(null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConditionCancel = () => {
|
const handleConditionCancel = () => {
|
||||||
setShowConditionForm(false)
|
closeConditionForm()
|
||||||
setEditingConditionIndex(null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleRemoveCondition = (index) => {
|
const handleRemoveCondition = (index) => {
|
||||||
@@ -590,6 +639,9 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
|
|
||||||
// Обработчик для создания задачи из ConditionForm
|
// Обработчик для создания задачи из ConditionForm
|
||||||
const handleCreateTaskFromCondition = () => {
|
const handleCreateTaskFromCondition = () => {
|
||||||
|
// Закрываем диалог цели перед переходом
|
||||||
|
setShowConditionForm(false)
|
||||||
|
|
||||||
// Сохранить текущее состояние формы
|
// Сохранить текущее состояние формы
|
||||||
const stateToSave = {
|
const stateToSave = {
|
||||||
name,
|
name,
|
||||||
@@ -602,7 +654,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
}
|
}
|
||||||
console.log('[WishlistForm] Saving state and navigating to task-form:', stateToSave)
|
console.log('[WishlistForm] Saving state and navigating to task-form:', stateToSave)
|
||||||
sessionStorage.setItem(WISHLIST_FORM_STATE_KEY, JSON.stringify(stateToSave))
|
sessionStorage.setItem(WISHLIST_FORM_STATE_KEY, JSON.stringify(stateToSave))
|
||||||
|
|
||||||
// Навигация на форму создания задачи
|
// Навигация на форму создания задачи
|
||||||
const navParams = {
|
const navParams = {
|
||||||
returnTo: 'wishlist-form',
|
returnTo: 'wishlist-form',
|
||||||
@@ -987,7 +1039,7 @@ function WishlistForm({ onNavigate, wishlistId, editConditionIndex, newTaskId, b
|
|||||||
onCancel={handleConditionCancel}
|
onCancel={handleConditionCancel}
|
||||||
editingCondition={editingConditionIndex !== null ? unlockConditions[editingConditionIndex] : null}
|
editingCondition={editingConditionIndex !== null ? unlockConditions[editingConditionIndex] : null}
|
||||||
onCreateTask={handleCreateTaskFromCondition}
|
onCreateTask={handleCreateTaskFromCondition}
|
||||||
preselectedTaskId={newTaskId}
|
preselectedTaskId={newTaskConsumed ? undefined : newTaskId}
|
||||||
authFetch={authFetch}
|
authFetch={authFetch}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
Reference in New Issue
Block a user