UNPKG

ra-core

Version:

Core components of react-admin, a frontend Framework for building admin applications on top of REST services, using ES6, React

124 lines 4.1 kB
import { useEffect, useMemo } from 'react'; import { useQuery, } from '@tanstack/react-query'; import useAuthProvider from "./useAuthProvider.js"; import useLogoutIfAccessDenied from "./useLogoutIfAccessDenied.js"; import { useEvent } from "../util/index.js"; const emptyParams = {}; /** * Hook for getting user permissions * * Calls the authProvider.getPermissions() method using react-query. * If the authProvider returns a rejected promise, returns empty permissions. * * The return value updates according to the request state: * * - start: { isPending: true } * - success: { permissions: [any], isPending: false } * - error: { error: [error from provider], isPending: false } * * Useful to enable features based on user permissions * * @param {Object} params Any params you want to pass to the authProvider * * @returns The current auth check state. Destructure as { permissions, error, isPending, refetch }. * * @example * import { usePermissions } from 'react-admin'; * * const PostDetail = () => { * const { isPending, permissions } = usePermissions(); * if (!isPending && permissions == 'editor') { * return <PostEdit /> * } else { * return <PostShow /> * } * }; */ const usePermissions = (params = emptyParams, queryParams = { staleTime: 5 * 60 * 1000, }) => { const authProvider = useAuthProvider(); const logoutIfAccessDenied = useLogoutIfAccessDenied(); const { onSuccess, onError, onSettled, ...queryOptions } = queryParams ?? {}; const queryResult = useQuery({ queryKey: ['auth', 'getPermissions', params], queryFn: async ({ signal }) => { if (!authProvider || !authProvider.getPermissions) { return []; } const permissions = await authProvider.getPermissions({ ...params, signal, }); return permissions ?? null; }, ...queryOptions, }); const onSuccessEvent = useEvent(onSuccess ?? noop); const onSettledEvent = useEvent(onSettled ?? noop); const onErrorEvent = useEvent(onError ?? ((error) => { if (process.env.NODE_ENV === 'development') { console.error(error); } logoutIfAccessDenied(error); })); useEffect(() => { if (queryResult.data === undefined || queryResult.isFetching) return; onSuccessEvent(queryResult.data); }, [onSuccessEvent, queryResult.data, queryResult.isFetching]); useEffect(() => { if (queryResult.error == null || queryResult.isFetching) return; onErrorEvent(queryResult.error); }, [onErrorEvent, queryResult.error, queryResult.isFetching]); useEffect(() => { if (queryResult.status === 'pending' || queryResult.isFetching) return; onSettledEvent(queryResult.data, queryResult.error); }, [ onSettledEvent, queryResult.data, queryResult.error, queryResult.status, queryResult.isFetching, ]); const result = useMemo(() => ({ ...queryResult, permissions: queryResult.data, }), [queryResult]); return !authProvider || !authProvider.getPermissions ? fakeQueryResult : result; }; export default usePermissions; const noop = () => { }; const fakeQueryResult = { permissions: undefined, data: undefined, dataUpdatedAt: 0, error: null, errorUpdatedAt: 0, errorUpdateCount: 0, failureCount: 0, failureReason: null, fetchStatus: 'idle', isError: false, isInitialLoading: false, isLoading: false, isLoadingError: false, isFetched: true, isFetchedAfterMount: true, isFetching: false, isPaused: false, isPlaceholderData: false, isPending: false, isRefetchError: false, isRefetching: false, isStale: false, isSuccess: true, status: 'success', refetch: () => Promise.resolve(fakeQueryResult), }; //# sourceMappingURL=usePermissions.js.map