import { UseMutateAsyncFunction, useMutation, UseMutationOptions, } from '@tanstack/react-query'; import useAuthProvider from './useAuthProvider'; import { HintedString } from '../types'; import { useMemo } from 'react'; /** * A hook that returns a function you can call to determine whether user has access to the given resource * * @example * import { Datagrid, List, TextField, useCanAccessCallback } from 'react-admin'; * * const UserList = () => { * const checkAccess = useCanAccessCallback(); * * const handleRowClick = (id: Identifier, resource: string, record: Record) => { * try { * const canAccess = checkAccess({ resource: 'users', action: 'edit', record }); * return canAccess ? "edit" : "show"; * } catch (error) { * console.error(error); * } * }; * * return ( * * * * * * * * ); * }; */ export const useCanAccessCallback = < RecordType extends Record = Record, ErrorType = Error, >( options: Omit< UseMutationOptions< UseCanAccessCallbackResult, ErrorType, UseCanAccessCallbackOptions >, 'mutationFn' > = {} ) => { const authProvider = useAuthProvider(); const authProviderHasCanAccess = !!authProvider?.canAccess; const { mutateAsync } = useMutation< UseCanAccessCallbackResult, ErrorType, UseCanAccessCallbackOptions >({ mutationFn: async ( params: UseCanAccessCallbackOptions ): Promise => { if (!authProvider || !authProvider.canAccess) { return true; } return authProvider.canAccess(params); }, retry: false, ...options, }); return useMemo( () => (authProviderHasCanAccess ? mutateAsync : () => true), [authProviderHasCanAccess, mutateAsync] ); }; export type UseCanAccessCallback< RecordType extends Record = Record, ErrorType = Error, > = UseMutateAsyncFunction< UseCanAccessCallbackResult, ErrorType, UseCanAccessCallbackOptions, unknown >; export type UseCanAccessCallbackOptions< RecordType extends Record = Record, > = { resource: string; action: HintedString<'list' | 'create' | 'edit' | 'show' | 'delete'>; record?: RecordType; }; export type UseCanAccessCallbackResult = boolean;