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)
|
||||
notify('Edited item successfully.')
|
||||
return () => navigate(`/time-unit/${tu_name}`)
|
||||
return () => {
|
||||
unsavedChanges?.allowNextNavigation?.()
|
||||
navigate(`/time-unit/${tu_name}`)
|
||||
}
|
||||
} catch (e) {
|
||||
if (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 { UnsavedChangesDialog } from './UnsavedChangesDialog'
|
||||
@@ -20,12 +20,13 @@ const unblockedState = {
|
||||
}
|
||||
|
||||
type BlockerState = typeof unblockedState | ReturnType<typeof useBlocker>
|
||||
type BlockerPredicate = Parameters<typeof useBlocker>[0]
|
||||
|
||||
const BlockerBridge = ({
|
||||
shouldBlock,
|
||||
onChange,
|
||||
}: {
|
||||
shouldBlock: boolean
|
||||
shouldBlock: BlockerPredicate
|
||||
onChange: (blocker: ReturnType<typeof useBlocker>) => void
|
||||
}) => {
|
||||
const blocker = useBlocker(shouldBlock)
|
||||
@@ -45,6 +46,7 @@ export const UnsavedChangesProvider = ({
|
||||
const [isDirty, setDirty] = useState(false)
|
||||
const [message, setMessage] = useState(defaultMessage)
|
||||
const [blocker, setBlocker] = useState<BlockerState>(unblockedState)
|
||||
const allowNextNavigationRef = useRef(false)
|
||||
const dataRouterContext = useContext(UNSAFE_DataRouterContext)
|
||||
|
||||
const isSamePathNavigation = blocker.state === 'blocked' && blocker.location?.pathname === window.location.pathname
|
||||
@@ -54,6 +56,20 @@ export const UnsavedChangesProvider = ({
|
||||
setMessage(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(() => {
|
||||
if (blocker.state === 'blocked') {
|
||||
setDirty(false)
|
||||
@@ -87,13 +103,14 @@ export const UnsavedChangesProvider = ({
|
||||
setDirty,
|
||||
setMessage,
|
||||
resetMessage,
|
||||
allowNextNavigation,
|
||||
}),
|
||||
[isDirty, message, resetMessage]
|
||||
[allowNextNavigation, isDirty, message, resetMessage]
|
||||
)
|
||||
|
||||
return (
|
||||
<UnsavedChangesContext.Provider value={value}>
|
||||
{dataRouterContext ? <BlockerBridge shouldBlock={isDirty} onChange={setBlocker} /> : null}
|
||||
{dataRouterContext ? <BlockerBridge shouldBlock={shouldBlockNavigation} onChange={setBlocker} /> : null}
|
||||
{children}
|
||||
<UnsavedChangesDialog
|
||||
open={showDialog}
|
||||
|
||||
@@ -6,6 +6,7 @@ export type UnsavedChangesContextValue = {
|
||||
setDirty: (dirty: boolean) => void
|
||||
setMessage: (message: string) => void
|
||||
resetMessage: () => void
|
||||
allowNextNavigation?: () => void
|
||||
}
|
||||
|
||||
export const UnsavedChangesContext = createContext<UnsavedChangesContextValue | null>(null)
|
||||
|
||||
Reference in New Issue
Block a user