@@ -3,6 +3,14 @@ import { getSiteConfig } from '../config';
33import type { PermissionValidationQuery , PermissionValidationAnswer } from './types' ;
44import { validatePermissions } from './api' ;
55
6+ /**
7+ * TanStack Query cache key factory for permission queries.
8+ * Use `validate` to scope cache reads and invalidations to a specific
9+ * query + backend combination.
10+ *
11+ * @example
12+ * queryClient.invalidateQueries({ queryKey: permissionsQueryKeys.validate(myQuery) });
13+ */
614export const permissionsQueryKeys = {
715 all : [ 'authz' ] as const ,
816 validate : ( query : PermissionValidationQuery , apiBaseUrl : string = getSiteConfig ( ) . lmsBaseUrl ) =>
@@ -22,14 +30,20 @@ export interface UsePermissionsOptions {
2230
2331/**
2432 * Intersection return type: metadata fields plus every permission key spread at the top level.
25- * Consumers destructure permission keys directly, no nested from `permissions.* ` object.
33+ * Consumers destructure permission keys directly — no nested `.permissions ` object.
2634 *
2735 * @example
28- * const { isLoading, canViewGradingSettings, canEditGradingSettings } =
29- * usePermissions(query, featureEnabled);
36+ * const { enableAuthz } = useWaffleFlags(courseId);
37+ * const { isLoading, isError, canViewGrading, canEditGrading } = usePermissions(
38+ * { canViewGrading: { action: 'courses.view_grading_settings', scope: courseId },
39+ * canEditGrading: { action: 'courses.edit_grading_settings', scope: courseId } },
40+ * enableAuthz ?? false,
41+ * { apiBaseUrl: getConfig().LMS_BASE_URL },
42+ * );
3043 */
3144export type UsePermissionsResult < Query extends PermissionValidationQuery > = {
3245 isLoading : boolean ,
46+ isError : boolean ,
3347 isAuthzEnabled : boolean ,
3448} & PermissionValidationAnswer < Query > ;
3549
@@ -41,7 +55,7 @@ export type UsePermissionsResult<Query extends PermissionValidationQuery> = {
4155 * When featureEnabled is true: hits the authz API; returns actual server values.
4256 *
4357 * The caller is responsible for reading its own waffle flag and passing the result
44- * as featureEnabled — waffle flag differ per MFE
58+ * as featureEnabled — waffle flag names differ per MFE
4559 *
4660 * @param query - Key/value map of permission check descriptors.
4761 * @param featureEnabled - Pass the result of your waffle flag check here.
@@ -63,7 +77,7 @@ export const usePermissions = <Query extends PermissionValidationQuery>(
6377) : UsePermissionsResult < Query > => {
6478 const { retry = false , apiBaseUrl = getSiteConfig ( ) . lmsBaseUrl } = options ;
6579
66- const { isLoading, data } = useQuery < PermissionValidationAnswer < Query > , Error > ( {
80+ const { isLoading, isError , data } = useQuery < PermissionValidationAnswer < Query > , Error > ( {
6781 queryKey : permissionsQueryKeys . validate ( query , apiBaseUrl ) ,
6882 queryFn : featureEnabled ? ( ) => validatePermissions ( apiBaseUrl , query ) : skipToken ,
6983 retry,
@@ -81,6 +95,7 @@ export const usePermissions = <Query extends PermissionValidationQuery>(
8195
8296 return {
8397 isLoading : featureEnabled ? isLoading : false ,
98+ isError : featureEnabled ? isError : false ,
8499 isAuthzEnabled : featureEnabled ,
85100 ...permissionResults ,
86101 } as UsePermissionsResult < Query > ;
0 commit comments