import * as React from 'react'; import { useCanAccess, UseCanAccessOptions } from './useCanAccess'; import { RaRecord } from '../types'; import { useBasename, Navigate } from '../routing'; /** * A component that only displays its children after checking whether users are authorized to access the provided resource and action. * @param options * @param options.action The action to check. One of 'list', 'create', 'edit', 'show', 'delete', or a custom action. * @param options.resource The resource to check. e.g. 'posts', 'comments', 'users' * @param options.children The component to render if users are authorized. * @param options.loading An optional element to render while the authorization is being checked. Defaults to null. * @param options.accessDenied An optional element to render if users are denied access. Defaults to null. * @param options.error An optional element to render if an error occur while checking users access rights. Redirect users to `/authentication-error` by default. */ export const CanAccess = < RecordType extends RaRecord | Omit = RaRecord, ErrorType extends Error = Error, >({ children, loading = null, accessDenied = null, error: errorElement = DEFAULT_ERROR, ...props }: CanAccessProps) => { const { canAccess, error, isPending } = useCanAccess(props); if (isPending) { return loading; } if (error) { return errorElement; } if (canAccess === false) { return accessDenied; } return children; }; export interface CanAccessProps< RecordType extends RaRecord | Omit = RaRecord, ErrorType extends Error = Error, > extends UseCanAccessOptions { children: React.ReactNode; loading?: React.ReactNode; accessDenied?: React.ReactNode; error?: React.ReactNode; } const CanAccessDefaultError = () => { const basename = useBasename(); return ; }; const DEFAULT_ERROR = ;