-
Notifications
You must be signed in to change notification settings - Fork 991
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(router): Implement routing with Suspense (#8392)
Co-authored-by: Kris Coulson <kriscoulson@gmail.com>
- Loading branch information
Showing
24 changed files
with
1,450 additions
and
879 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
import React, { useCallback } from 'react' | ||
|
||
import { Redirect } from './links' | ||
import { routes } from './router' | ||
import { useRouterState } from './router-context' | ||
|
||
export function AuthenticatedRoute(props: any) { | ||
const { | ||
private: privateSet, | ||
unauthenticated, | ||
roles, | ||
whileLoadingAuth, | ||
children, | ||
} = props | ||
const routerState = useRouterState() | ||
const { | ||
loading: authLoading, | ||
isAuthenticated, | ||
hasRole, | ||
} = routerState.useAuth() | ||
|
||
const unauthorized = useCallback(() => { | ||
return !(isAuthenticated && (!roles || hasRole(roles))) | ||
}, [isAuthenticated, roles, hasRole]) | ||
|
||
// Make sure `wrappers` is always an array with at least one wrapper component | ||
if (privateSet && unauthorized()) { | ||
if (!unauthenticated) { | ||
throw new Error( | ||
'Private Sets need to specify what route to redirect unauthorized ' + | ||
'users to by setting the `unauthenticated` prop' | ||
) | ||
} | ||
|
||
if (authLoading) { | ||
return whileLoadingAuth?.() || null | ||
} else { | ||
const currentLocation = | ||
globalThis.location.pathname + | ||
encodeURIComponent(globalThis.location.search) | ||
|
||
if (!routes[unauthenticated]) { | ||
throw new Error(`We could not find a route named ${unauthenticated}`) | ||
} | ||
|
||
let unauthenticatedPath | ||
|
||
try { | ||
unauthenticatedPath = routes[unauthenticated]() | ||
} catch (e) { | ||
if ( | ||
e instanceof Error && | ||
/Missing parameter .* for route/.test(e.message) | ||
) { | ||
throw new Error( | ||
`Redirecting to route "${unauthenticated}" would require route ` + | ||
'parameters, which currently is not supported. Please choose ' + | ||
'a different route' | ||
) | ||
} | ||
|
||
throw new Error( | ||
`Could not redirect to the route named ${unauthenticated}` | ||
) | ||
} | ||
|
||
return ( | ||
<Redirect to={`${unauthenticatedPath}?redirectTo=${currentLocation}`} /> | ||
) | ||
} | ||
} | ||
|
||
return <>{children}</> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.