fix(web): harden workspace route guards against flash

- move guard redirects to useEffect to keep render side-effect free\n- keep null short-circuit for unauthorized routes before child mount\n- add app loading fallback in RoleRouteGuard while workspace is loading
This commit is contained in:
yyh
2026-02-13 15:30:14 +08:00
parent de62812134
commit 4a58b098e6
2 changed files with 23 additions and 8 deletions

View File

@ -1,6 +1,7 @@
'use client'
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'
import Loading from '@/app/components/base/loading'
import { useAppContext } from '@/context/app-context'
import { ExternalApiPanelProvider } from '@/context/external-api-panel-context'
@ -9,12 +10,19 @@ import { ExternalKnowledgeApiProvider } from '@/context/external-knowledge-api-c
export default function DatasetsLayout({ children }: { children: React.ReactNode }) {
const { isCurrentWorkspaceEditor, isCurrentWorkspaceDatasetOperator, currentWorkspace, isLoadingCurrentWorkspace } = useAppContext()
const router = useRouter()
const shouldRedirect = !isLoadingCurrentWorkspace
&& currentWorkspace.id
&& !(isCurrentWorkspaceEditor || isCurrentWorkspaceDatasetOperator)
useEffect(() => {
if (shouldRedirect)
router.replace('/apps')
}, [shouldRedirect, router])
if (isLoadingCurrentWorkspace || !currentWorkspace.id)
return <Loading type="app" />
if (!(isCurrentWorkspaceEditor || isCurrentWorkspaceDatasetOperator)) {
router.replace('/apps')
if (shouldRedirect) {
return null
}

View File

@ -2,22 +2,29 @@
import type { ReactNode } from 'react'
import { usePathname, useRouter } from 'next/navigation'
import { useEffect } from 'react'
import Loading from '@/app/components/base/loading'
import { useAppContext } from '@/context/app-context'
export default function RoleRouteGuard({ children }: { children: ReactNode }) {
const { isCurrentWorkspaceDatasetOperator, isLoadingCurrentWorkspace, currentWorkspace } = useAppContext()
const pathname = usePathname()
const router = useRouter()
if (
!isLoadingCurrentWorkspace
const shouldRedirect = !isLoadingCurrentWorkspace
&& currentWorkspace.id
&& isCurrentWorkspaceDatasetOperator
&& !pathname.startsWith('/datasets')
) {
router.replace('/datasets')
useEffect(() => {
if (shouldRedirect)
router.replace('/datasets')
}, [shouldRedirect, router])
if (isLoadingCurrentWorkspace)
return <Loading type="app" />
if (shouldRedirect)
return null
}
return <>{children}</>
}