mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
Allow saved time unit redirect past blocker
This commit is contained in:
@@ -65,7 +65,10 @@ export const TimeUnitDetails = ({
|
|||||||
})
|
})
|
||||||
unsavedChanges?.setDirty(false)
|
unsavedChanges?.setDirty(false)
|
||||||
notify('Edited item successfully.')
|
notify('Edited item successfully.')
|
||||||
return () => navigate(`/time-unit/${tu_name}`)
|
return () => {
|
||||||
|
unsavedChanges?.allowNextNavigation?.()
|
||||||
|
navigate(`/time-unit/${tu_name}`)
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (data) {
|
if (data) {
|
||||||
setEditData(makeEditData(data))
|
setEditData(makeEditData(data))
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useContext, useEffect, useMemo, useState, type ReactNode } from 'react'
|
import { useCallback, useContext, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'
|
||||||
import { UNSAFE_DataRouterContext, useBlocker } from 'react-router-dom'
|
import { UNSAFE_DataRouterContext, useBlocker } from 'react-router-dom'
|
||||||
|
|
||||||
import { UnsavedChangesDialog } from './UnsavedChangesDialog'
|
import { UnsavedChangesDialog } from './UnsavedChangesDialog'
|
||||||
@@ -20,12 +20,13 @@ const unblockedState = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BlockerState = typeof unblockedState | ReturnType<typeof useBlocker>
|
type BlockerState = typeof unblockedState | ReturnType<typeof useBlocker>
|
||||||
|
type BlockerPredicate = Parameters<typeof useBlocker>[0]
|
||||||
|
|
||||||
const BlockerBridge = ({
|
const BlockerBridge = ({
|
||||||
shouldBlock,
|
shouldBlock,
|
||||||
onChange,
|
onChange,
|
||||||
}: {
|
}: {
|
||||||
shouldBlock: boolean
|
shouldBlock: BlockerPredicate
|
||||||
onChange: (blocker: ReturnType<typeof useBlocker>) => void
|
onChange: (blocker: ReturnType<typeof useBlocker>) => void
|
||||||
}) => {
|
}) => {
|
||||||
const blocker = useBlocker(shouldBlock)
|
const blocker = useBlocker(shouldBlock)
|
||||||
@@ -45,6 +46,7 @@ export const UnsavedChangesProvider = ({
|
|||||||
const [isDirty, setDirty] = useState(false)
|
const [isDirty, setDirty] = useState(false)
|
||||||
const [message, setMessage] = useState(defaultMessage)
|
const [message, setMessage] = useState(defaultMessage)
|
||||||
const [blocker, setBlocker] = useState<BlockerState>(unblockedState)
|
const [blocker, setBlocker] = useState<BlockerState>(unblockedState)
|
||||||
|
const allowNextNavigationRef = useRef(false)
|
||||||
const dataRouterContext = useContext(UNSAFE_DataRouterContext)
|
const dataRouterContext = useContext(UNSAFE_DataRouterContext)
|
||||||
|
|
||||||
const isSamePathNavigation = blocker.state === 'blocked' && blocker.location?.pathname === window.location.pathname
|
const isSamePathNavigation = blocker.state === 'blocked' && blocker.location?.pathname === window.location.pathname
|
||||||
@@ -54,6 +56,20 @@ export const UnsavedChangesProvider = ({
|
|||||||
setMessage(defaultMessage)
|
setMessage(defaultMessage)
|
||||||
}, [defaultMessage])
|
}, [defaultMessage])
|
||||||
|
|
||||||
|
const allowNextNavigation = useCallback(() => {
|
||||||
|
allowNextNavigationRef.current = true
|
||||||
|
setDirty(false)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const shouldBlockNavigation = useCallback(() => {
|
||||||
|
if (!isDirty) return false
|
||||||
|
if (allowNextNavigationRef.current) {
|
||||||
|
allowNextNavigationRef.current = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}, [isDirty])
|
||||||
|
|
||||||
const handleConfirm = useCallback(() => {
|
const handleConfirm = useCallback(() => {
|
||||||
if (blocker.state === 'blocked') {
|
if (blocker.state === 'blocked') {
|
||||||
setDirty(false)
|
setDirty(false)
|
||||||
@@ -87,13 +103,14 @@ export const UnsavedChangesProvider = ({
|
|||||||
setDirty,
|
setDirty,
|
||||||
setMessage,
|
setMessage,
|
||||||
resetMessage,
|
resetMessage,
|
||||||
|
allowNextNavigation,
|
||||||
}),
|
}),
|
||||||
[isDirty, message, resetMessage]
|
[allowNextNavigation, isDirty, message, resetMessage]
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<UnsavedChangesContext.Provider value={value}>
|
<UnsavedChangesContext.Provider value={value}>
|
||||||
{dataRouterContext ? <BlockerBridge shouldBlock={isDirty} onChange={setBlocker} /> : null}
|
{dataRouterContext ? <BlockerBridge shouldBlock={shouldBlockNavigation} onChange={setBlocker} /> : null}
|
||||||
{children}
|
{children}
|
||||||
<UnsavedChangesDialog
|
<UnsavedChangesDialog
|
||||||
open={showDialog}
|
open={showDialog}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export type UnsavedChangesContextValue = {
|
|||||||
setDirty: (dirty: boolean) => void
|
setDirty: (dirty: boolean) => void
|
||||||
setMessage: (message: string) => void
|
setMessage: (message: string) => void
|
||||||
resetMessage: () => void
|
resetMessage: () => void
|
||||||
|
allowNextNavigation?: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const UnsavedChangesContext = createContext<UnsavedChangesContextValue | null>(null)
|
export const UnsavedChangesContext = createContext<UnsavedChangesContextValue | null>(null)
|
||||||
|
|||||||
Reference in New Issue
Block a user