@jmruthers/pace-core 0.5.11 → 0.5.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/dist/{DataTable-32L3DDeG.d.ts → DataTable-Da0D1BHX.d.ts} +1 -1
  2. package/dist/{DataTable-7LYDPZXT.js → DataTable-NNCMQSDG.js} +2 -2
  3. package/dist/{chunk-JV73V2W5.js → chunk-5E3YF7HA.js} +15 -1
  4. package/dist/chunk-5E3YF7HA.js.map +1 -0
  5. package/dist/{chunk-ROHDZOP7.js → chunk-BUWLPWDA.js} +14 -12
  6. package/dist/chunk-BUWLPWDA.js.map +1 -0
  7. package/dist/{chunk-7KDZXMES.js → chunk-PILT65PA.js} +2 -2
  8. package/dist/components.d.ts +2 -2
  9. package/dist/components.js +2 -2
  10. package/dist/hooks.d.ts +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +3 -3
  13. package/dist/rbac/index.js +1 -1
  14. package/dist/{types-CczCVCDt.d.ts → types-zOqe4P1s.d.ts} +11 -3
  15. package/dist/utils.d.ts +2 -2
  16. package/dist/utils.js +1 -1
  17. package/docs/api/classes/ErrorBoundary.md +1 -1
  18. package/docs/api/classes/InvalidScopeError.md +1 -1
  19. package/docs/api/classes/MissingUserContextError.md +1 -1
  20. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  21. package/docs/api/classes/PermissionDeniedError.md +1 -1
  22. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  23. package/docs/api/classes/RBACAuditManager.md +1 -1
  24. package/docs/api/classes/RBACCache.md +1 -1
  25. package/docs/api/classes/RBACEngine.md +1 -1
  26. package/docs/api/classes/RBACError.md +1 -1
  27. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  28. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  29. package/docs/api/interfaces/AggregateConfig.md +1 -1
  30. package/docs/api/interfaces/ButtonProps.md +1 -1
  31. package/docs/api/interfaces/CardProps.md +1 -1
  32. package/docs/api/interfaces/ColorPalette.md +1 -1
  33. package/docs/api/interfaces/ColorShade.md +1 -1
  34. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  35. package/docs/api/interfaces/DataTableAction.md +1 -1
  36. package/docs/api/interfaces/DataTableColumn.md +1 -1
  37. package/docs/api/interfaces/DataTableProps.md +1 -1
  38. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  39. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  40. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  41. package/docs/api/interfaces/EventContextType.md +1 -1
  42. package/docs/api/interfaces/EventLogoProps.md +1 -1
  43. package/docs/api/interfaces/EventProviderProps.md +1 -1
  44. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  45. package/docs/api/interfaces/FileUploadProps.md +1 -1
  46. package/docs/api/interfaces/FooterProps.md +1 -1
  47. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  48. package/docs/api/interfaces/InputProps.md +1 -1
  49. package/docs/api/interfaces/LabelProps.md +1 -1
  50. package/docs/api/interfaces/LoginFormProps.md +1 -1
  51. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  52. package/docs/api/interfaces/NavigationContextType.md +1 -1
  53. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  54. package/docs/api/interfaces/NavigationItem.md +1 -1
  55. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  56. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  57. package/docs/api/interfaces/Organisation.md +1 -1
  58. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  59. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  60. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  61. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  62. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  63. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  64. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  65. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  66. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  67. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  68. package/docs/api/interfaces/PaletteData.md +1 -1
  69. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  70. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  71. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  72. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  73. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  74. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  75. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  76. package/docs/api/interfaces/RBACConfig.md +1 -1
  77. package/docs/api/interfaces/RBACContextType.md +1 -1
  78. package/docs/api/interfaces/RBACLogger.md +1 -1
  79. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  80. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  81. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  82. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  83. package/docs/api/interfaces/RouteConfig.md +1 -1
  84. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  85. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  86. package/docs/api/interfaces/StorageConfig.md +1 -1
  87. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  88. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  89. package/docs/api/interfaces/StorageListOptions.md +1 -1
  90. package/docs/api/interfaces/StorageListResult.md +1 -1
  91. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  92. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  93. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  94. package/docs/api/interfaces/StyleImport.md +1 -1
  95. package/docs/api/interfaces/ToastActionElement.md +1 -1
  96. package/docs/api/interfaces/ToastProps.md +1 -1
  97. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  98. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  99. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  100. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  101. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  102. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  103. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  104. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  105. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  106. package/docs/api/interfaces/UserEventAccess.md +1 -1
  107. package/docs/api/interfaces/UserMenuProps.md +1 -1
  108. package/docs/api/interfaces/UserProfile.md +1 -1
  109. package/docs/api/modules.md +2 -2
  110. package/docs/implementation-guides/datatable-rbac-usage.md +31 -1
  111. package/package.json +1 -1
  112. package/src/components/DataTable/components/ActionButtons.tsx +2 -1
  113. package/src/components/DataTable/components/DataTableCore.tsx +19 -13
  114. package/src/components/DataTable/components/UnifiedTableBody.tsx +4 -2
  115. package/src/components/DataTable/types.ts +11 -3
  116. package/src/rbac/components/PagePermissionGuard.tsx +16 -0
  117. package/dist/chunk-JV73V2W5.js.map +0 -1
  118. package/dist/chunk-ROHDZOP7.js.map +0 -1
  119. /package/dist/{DataTable-7LYDPZXT.js.map → DataTable-NNCMQSDG.js.map} +0 -0
  120. /package/dist/{chunk-7KDZXMES.js.map → chunk-PILT65PA.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RBACContextType
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RBACContextType
2
2
 
3
3
  # Interface: RBACContextType
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RBACLogger
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RBACLogger
2
2
 
3
3
  # Interface: RBACLogger
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RBACProviderProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RBACProviderProps
2
2
 
3
3
  # Interface: RBACProviderProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RoleBasedRouterContextType
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RoleBasedRouterContextType
2
2
 
3
3
  # Interface: RoleBasedRouterContextType
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RoleBasedRouterProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RoleBasedRouterProps
2
2
 
3
3
  # Interface: RoleBasedRouterProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RouteAccessRecord
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RouteAccessRecord
2
2
 
3
3
  # Interface: RouteAccessRecord
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / RouteConfig
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / RouteConfig
2
2
 
3
3
  # Interface: RouteConfig
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / SecureDataContextType
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / SecureDataContextType
2
2
 
3
3
  # Interface: SecureDataContextType
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / SecureDataProviderProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / SecureDataProviderProps
2
2
 
3
3
  # Interface: SecureDataProviderProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageConfig
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageConfig
2
2
 
3
3
  # Interface: StorageConfig
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageFileInfo
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageFileInfo
2
2
 
3
3
  # Interface: StorageFileInfo
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageFileMetadata
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageFileMetadata
2
2
 
3
3
  # Interface: StorageFileMetadata
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageListOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageListOptions
2
2
 
3
3
  # Interface: StorageListOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageListResult
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageListResult
2
2
 
3
3
  # Interface: StorageListResult
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageUploadOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUploadOptions
2
2
 
3
3
  # Interface: StorageUploadOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageUploadResult
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUploadResult
2
2
 
3
3
  # Interface: StorageUploadResult
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StorageUrlOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StorageUrlOptions
2
2
 
3
3
  # Interface: StorageUrlOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / StyleImport
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / StyleImport
2
2
 
3
3
  # Interface: StyleImport
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / ToastActionElement
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / ToastActionElement
2
2
 
3
3
  # Interface: ToastActionElement
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / ToastProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / ToastProps
2
2
 
3
3
  # Interface: ToastProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UnifiedAuthContextType
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UnifiedAuthContextType
2
2
 
3
3
  # Interface: UnifiedAuthContextType
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UnifiedAuthProviderProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UnifiedAuthProviderProps
2
2
 
3
3
  # Interface: UnifiedAuthProviderProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UseInactivityTrackerOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UseInactivityTrackerOptions
2
2
 
3
3
  # Interface: UseInactivityTrackerOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UseInactivityTrackerReturn
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UseInactivityTrackerReturn
2
2
 
3
3
  # Interface: UseInactivityTrackerReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UsePublicEventLogoOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventLogoOptions
2
2
 
3
3
  # Interface: UsePublicEventLogoOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UsePublicEventLogoReturn
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventLogoReturn
2
2
 
3
3
  # Interface: UsePublicEventLogoReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UsePublicEventOptions
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventOptions
2
2
 
3
3
  # Interface: UsePublicEventOptions
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicEventReturn
2
2
 
3
3
  # Interface: UsePublicEventReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UsePublicRouteParamsReturn
2
2
 
3
3
  # Interface: UsePublicRouteParamsReturn
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UserEventAccess
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserEventAccess
2
2
 
3
3
  # Interface: UserEventAccess
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UserMenuProps
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserMenuProps
2
2
 
3
3
  # Interface: UserMenuProps
4
4
 
@@ -1,4 +1,4 @@
1
- [@jmruthers/pace-core - v0.5.11](../README.md) / [Exports](../modules.md) / UserProfile
1
+ [@jmruthers/pace-core - v0.5.13](../README.md) / [Exports](../modules.md) / UserProfile
2
2
 
3
3
  # Interface: UserProfile
4
4
 
@@ -1,6 +1,6 @@
1
- [@jmruthers/pace-core - v0.5.11](README.md) / Exports
1
+ [@jmruthers/pace-core - v0.5.13](README.md) / Exports
2
2
 
3
- # @jmruthers/pace-core - v0.5.11
3
+ # @jmruthers/pace-core - v0.5.13
4
4
 
5
5
  **`File`**
6
6
 
@@ -28,7 +28,7 @@ function DishesPage() {
28
28
  data={dishes}
29
29
  columns={columns}
30
30
  rbac={{
31
- pageId: 'dishes' // Page ID for permissions (REQUIRED)
31
+ pageName: 'dishes' // Page name for permissions (recommended)
32
32
  }}
33
33
  features={{
34
34
  search: true,
@@ -47,6 +47,36 @@ function DishesPage() {
47
47
  }
48
48
  ```
49
49
 
50
+ ### Page Identification Options
51
+
52
+ The DataTable supports two ways to identify the page for RBAC permissions:
53
+
54
+ #### Option 1: Page Name (Recommended)
55
+ ```tsx
56
+ <DataTable
57
+ data={data}
58
+ columns={columns}
59
+ rbac={{
60
+ pageName: 'dishes' // Will be resolved to page ID by RBAC engine
61
+ }}
62
+ features={features}
63
+ />
64
+ ```
65
+
66
+ #### Option 2: Page ID (Direct)
67
+ ```tsx
68
+ <DataTable
69
+ data={data}
70
+ columns={columns}
71
+ rbac={{
72
+ pageId: 'uuid-here' // Use page ID directly
73
+ }}
74
+ features={features}
75
+ />
76
+ ```
77
+
78
+ **Note:** You must provide either `pageName` or `pageId`, but not both. If both are provided, `pageId` takes precedence.
79
+
50
80
  ### Permission Mapping
51
81
 
52
82
  The DataTable now checks the following page-based permissions:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jmruthers/pace-core",
3
- "version": "0.5.11",
3
+ "version": "0.5.13",
4
4
  "description": "Clean, modern React component library with Tailwind v4 styling and native utilities",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -40,7 +40,8 @@ interface ActionButtonsProps {
40
40
  hierarchical?: boolean;
41
41
  // MANDATORY RBAC
42
42
  rbac?: {
43
- pageId: string;
43
+ pageId?: string;
44
+ pageName?: string;
44
45
  };
45
46
  permissions?: {
46
47
  canUpdate: { can: boolean; isLoading: boolean };
@@ -316,38 +316,48 @@ function DataTableInternal<TData extends DataRecord>({
316
316
 
317
317
  // MANDATORY: Check all permissions upfront - ALWAYS enforce RBAC
318
318
  // Use page-based permissions exclusively
319
- const pageId = rbac.pageId;
319
+ const pageId = rbac?.pageId;
320
+ const pageName = rbac?.pageName;
321
+
322
+ // Early validation - need either pageId or pageName
323
+ if (!pageId && !pageName) {
324
+ throw new Error('DataTable requires either rbac.pageId or rbac.pageName for permission checking');
325
+ }
326
+
327
+ // Use pageId if provided, otherwise use pageName (will be resolved by RBAC engine)
328
+ const effectivePageId = pageId || pageName;
329
+
320
330
  const permissions = {
321
331
  canRead: useCan(user?.id || '', {
322
332
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
323
333
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
324
334
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
325
- }, `read:page.${pageId}` as any, pageId),
335
+ }, `read:page.${effectivePageId}` as any, effectivePageId),
326
336
  canCreate: useCan(user?.id || '', {
327
337
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
328
338
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
329
339
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
330
- }, `create:page.${pageId}` as any, pageId),
340
+ }, `create:page.${effectivePageId}` as any, effectivePageId),
331
341
  canUpdate: useCan(user?.id || '', {
332
342
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
333
343
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
334
344
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
335
- }, `update:page.${pageId}` as any, pageId),
345
+ }, `update:page.${effectivePageId}` as any, effectivePageId),
336
346
  canDelete: useCan(user?.id || '', {
337
347
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
338
348
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
339
349
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
340
- }, `delete:page.${pageId}` as any, pageId),
350
+ }, `delete:page.${effectivePageId}` as any, effectivePageId),
341
351
  canExport: useCan(user?.id || '', {
342
352
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
343
353
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
344
354
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
345
- }, `manage:page.${pageId}` as any, pageId), // Using manage for export/import
355
+ }, `manage:page.${effectivePageId}` as any, effectivePageId), // Using manage for export/import
346
356
  canImport: useCan(user?.id || '', {
347
357
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
348
358
  eventId: user?.user_metadata?.eventId || user?.app_metadata?.eventId,
349
359
  appId: user?.user_metadata?.appId || user?.app_metadata?.appId,
350
- }, `manage:page.${pageId}` as any, pageId), // Using manage for export/import
360
+ }, `manage:page.${effectivePageId}` as any, effectivePageId), // Using manage for export/import
351
361
  };
352
362
 
353
363
  // ============================================================================
@@ -777,14 +787,10 @@ function DataTableInternal<TData extends DataRecord>({
777
787
  // RBAC VALIDATION AND EARLY RETURNS - AFTER ALL HOOKS
778
788
  // ============================================================================
779
789
 
780
- // MANDATORY: Every DataTable must have a user and RBAC config
790
+ // MANDATORY: Every DataTable must have a user
781
791
  if (!user) {
782
792
  throw new Error('DataTable requires authenticated user for RBAC');
783
793
  }
784
-
785
- if (!rbac?.pageId) {
786
- throw new Error('DataTable requires rbac.pageId for permission checking');
787
- }
788
794
 
789
795
  const scope = {
790
796
  organisationId: user?.user_metadata?.organisationId || user?.app_metadata?.organisationId,
@@ -794,7 +800,7 @@ function DataTableInternal<TData extends DataRecord>({
794
800
 
795
801
  // MANDATORY: No data access without read permission
796
802
  if (!permissions.canRead.can) {
797
- return <AccessDeniedPage resource={rbac?.pageId || 'unknown-page'} operation="read" />;
803
+ return <AccessDeniedPage resource={effectivePageId || 'unknown-page'} operation="read" />;
798
804
  }
799
805
 
800
806
  // ============================================================================
@@ -133,7 +133,8 @@ interface UnifiedTableBodyProps<TData extends Record<string, any>> {
133
133
  }>;
134
134
  // MANDATORY RBAC
135
135
  rbac?: {
136
- pageId: string;
136
+ pageId?: string;
137
+ pageName?: string;
137
138
  };
138
139
  permissions?: {
139
140
  canUpdate: { can: boolean; isLoading: boolean };
@@ -268,7 +269,8 @@ const MemoizedRow = ({
268
269
  childLabel?: string;
269
270
  }>;
270
271
  rbac?: {
271
- pageId: string;
272
+ pageId?: string;
273
+ pageName?: string;
272
274
  };
273
275
  permissions?: {
274
276
  canUpdate: { can: boolean; isLoading: boolean };
@@ -406,14 +406,22 @@ export interface DataTableFeatureConfig {
406
406
  * ```tsx
407
407
  * <DataTable
408
408
  * data={dishes}
409
- * rbac={{ pageId: 'dishes' }} // Simple and clear
409
+ * rbac={{ pageName: 'dishes' }} // Use page name (recommended)
410
+ * features={features}
411
+ * />
412
+ *
413
+ * <DataTable
414
+ * data={dishes}
415
+ * rbac={{ pageId: 'uuid-here' }} // Use page ID directly
410
416
  * features={features}
411
417
  * />
412
418
  * ```
413
419
  */
414
420
  export interface DataTableRBACConfig {
415
- /** Page ID for page-based permissions - REQUIRED for proper RBAC */
416
- pageId: string;
421
+ /** Page name for page-based permissions - will be resolved to page ID */
422
+ pageName?: string;
423
+ /** Page ID for page-based permissions - used directly if provided */
424
+ pageId?: string;
417
425
  }
418
426
 
419
427
  /**
@@ -216,6 +216,7 @@ export function PagePermissionGuard({
216
216
  };
217
217
  console.log('[PagePermissionGuard] Setting resolved scope:', resolvedScope);
218
218
  setResolvedScope(resolvedScope);
219
+ setCheckError(null); // Clear any previous errors
219
220
  return;
220
221
  }
221
222
 
@@ -250,6 +251,7 @@ export function PagePermissionGuard({
250
251
  };
251
252
  console.log('[PagePermissionGuard] Setting resolved scope (org only):', resolvedScope);
252
253
  setResolvedScope(resolvedScope);
254
+ setCheckError(null); // Clear any previous errors
253
255
  return;
254
256
  }
255
257
 
@@ -267,6 +269,7 @@ export function PagePermissionGuard({
267
269
  ...eventScope,
268
270
  appId: appId || eventScope.appId
269
271
  });
272
+ setCheckError(null); // Clear any previous errors
270
273
  } catch (error) {
271
274
  setCheckError(error as Error);
272
275
  setResolvedScope(null); // Ensure we don't proceed with incomplete scope
@@ -324,6 +327,7 @@ export function PagePermissionGuard({
324
327
  );
325
328
 
326
329
  console.log('[PagePermissionGuard] useCan returned:', { can, canIsLoading, canError });
330
+ console.log('[PagePermissionGuard] can type and value:', { type: typeof can, value: can, isBoolean: typeof can === 'boolean' });
327
331
 
328
332
  // Combine loading states - we're loading if either scope is resolving OR permission check is loading
329
333
  const isLoading = !resolvedScope || !shouldCheckPermissions || canIsLoading;
@@ -379,6 +383,18 @@ export function PagePermissionGuard({
379
383
  }
380
384
  }, [strictMode, hasChecked, isLoading, can, pageName, operation, user?.id, resolvedScope]);
381
385
 
386
+ // Debug: Log final render state
387
+ console.log('[PagePermissionGuard] Final render state:', {
388
+ isLoading,
389
+ resolvedScope: !!resolvedScope,
390
+ checkError: checkError?.message,
391
+ can,
392
+ willShowLoading: isLoading || !resolvedScope,
393
+ willShowError: !!checkError,
394
+ willShowAccessDenied: !can,
395
+ willShowContent: !isLoading && !!resolvedScope && !checkError && can
396
+ });
397
+
382
398
  // Show loading state
383
399
  if (isLoading || !resolvedScope) {
384
400
  return <>{loading}</>;