@jmruthers/pace-core 0.5.189 → 0.5.191

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 (438) hide show
  1. package/core-usage-manifest.json +0 -4
  2. package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
  3. package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
  4. package/dist/{DataTable-GUFUNZ3N.js → DataTable-WKRZD47S.js} +8 -8
  5. package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-ULXC_u6U.d.ts} +84 -25
  6. package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
  7. package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-FTSG5XH7.js} +4 -2
  8. package/dist/{api-YP7XD5L6.js → api-IHKALJZD.js} +4 -2
  9. package/dist/{chunk-VGZZXKBR.js → chunk-6LTQQAT6.js} +351 -157
  10. package/dist/chunk-6LTQQAT6.js.map +1 -0
  11. package/dist/{chunk-MX64ZF6I.js → chunk-6TQDD426.js} +15 -15
  12. package/dist/chunk-6TQDD426.js.map +1 -0
  13. package/dist/{chunk-YHCN776L.js → chunk-G37KK66H.js} +2 -75
  14. package/dist/chunk-G37KK66H.js.map +1 -0
  15. package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
  16. package/dist/chunk-HW3OVDUF.js.map +1 -0
  17. package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
  18. package/dist/chunk-I7PSE6JW.js.map +1 -0
  19. package/dist/{chunk-IM4QE42D.js → chunk-LOMZXPSN.js} +141 -326
  20. package/dist/chunk-LOMZXPSN.js.map +1 -0
  21. package/dist/chunk-OETXORNB.js +614 -0
  22. package/dist/chunk-OETXORNB.js.map +1 -0
  23. package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
  24. package/dist/{chunk-HEHYGYOX.js → chunk-ROXMHMY2.js} +403 -46
  25. package/dist/chunk-ROXMHMY2.js.map +1 -0
  26. package/dist/{chunk-2UUZZJFT.js → chunk-ULHIJK66.js} +228 -177
  27. package/dist/{chunk-2UUZZJFT.js.map → chunk-ULHIJK66.js.map} +1 -1
  28. package/dist/{chunk-YGPFYGA6.js → chunk-VKB2CO4Z.js} +838 -503
  29. package/dist/chunk-VKB2CO4Z.js.map +1 -0
  30. package/dist/{chunk-3GOZZZYH.js → chunk-VRGWKHDB.js} +238 -301
  31. package/dist/chunk-VRGWKHDB.js.map +1 -0
  32. package/dist/{chunk-UCQSRW7Z.js → chunk-XNYQOL3Z.js} +431 -384
  33. package/dist/chunk-XNYQOL3Z.js.map +1 -0
  34. package/dist/{chunk-DDM4CCYT.js → chunk-XYXSXPUK.js} +79 -59
  35. package/dist/chunk-XYXSXPUK.js.map +1 -0
  36. package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
  37. package/dist/chunk-ZSAAAMVR.js.map +1 -0
  38. package/dist/components.d.ts +5 -6
  39. package/dist/components.js +19 -19
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
  42. package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
  43. package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
  44. package/dist/hooks.d.ts +20 -15
  45. package/dist/hooks.js +14 -8
  46. package/dist/hooks.js.map +1 -1
  47. package/dist/index.d.ts +17 -15
  48. package/dist/index.js +86 -81
  49. package/dist/index.js.map +1 -1
  50. package/dist/providers.d.ts +3 -3
  51. package/dist/providers.js +3 -1
  52. package/dist/rbac/index.d.ts +77 -13
  53. package/dist/rbac/index.js +12 -9
  54. package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
  55. package/dist/types.d.ts +3 -3
  56. package/dist/types.js +1 -1
  57. package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +17 -10
  58. package/dist/utils.d.ts +8 -8
  59. package/dist/utils.js +16 -16
  60. package/docs/README.md +2 -2
  61. package/docs/api/classes/ColumnFactory.md +1 -1
  62. package/docs/api/classes/ErrorBoundary.md +1 -1
  63. package/docs/api/classes/InvalidScopeError.md +2 -2
  64. package/docs/api/classes/Logger.md +1 -1
  65. package/docs/api/classes/MissingUserContextError.md +2 -2
  66. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  67. package/docs/api/classes/PermissionDeniedError.md +1 -1
  68. package/docs/api/classes/RBACAuditManager.md +2 -2
  69. package/docs/api/classes/RBACCache.md +1 -1
  70. package/docs/api/classes/RBACEngine.md +5 -5
  71. package/docs/api/classes/RBACError.md +1 -1
  72. package/docs/api/classes/RBACNotInitializedError.md +2 -2
  73. package/docs/api/classes/SecureSupabaseClient.md +25 -20
  74. package/docs/api/classes/StorageUtils.md +7 -4
  75. package/docs/api/enums/FileCategory.md +1 -1
  76. package/docs/api/enums/LogLevel.md +1 -1
  77. package/docs/api/enums/RBACErrorCode.md +1 -1
  78. package/docs/api/enums/RPCFunction.md +1 -1
  79. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  80. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +1 -1
  82. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  83. package/docs/api/interfaces/AvatarProps.md +1 -1
  84. package/docs/api/interfaces/BadgeProps.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CalendarProps.md +20 -6
  87. package/docs/api/interfaces/CardProps.md +1 -1
  88. package/docs/api/interfaces/ColorPalette.md +1 -1
  89. package/docs/api/interfaces/ColorShade.md +1 -1
  90. package/docs/api/interfaces/ComplianceResult.md +1 -1
  91. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  92. package/docs/api/interfaces/DataRecord.md +1 -1
  93. package/docs/api/interfaces/DataTableAction.md +1 -1
  94. package/docs/api/interfaces/DataTableColumn.md +1 -1
  95. package/docs/api/interfaces/DataTableProps.md +1 -1
  96. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  97. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  98. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  99. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  100. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  101. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  102. package/docs/api/interfaces/ExportColumn.md +1 -1
  103. package/docs/api/interfaces/ExportOptions.md +1 -1
  104. package/docs/api/interfaces/FileDisplayProps.md +62 -16
  105. package/docs/api/interfaces/FileMetadata.md +1 -1
  106. package/docs/api/interfaces/FileReference.md +2 -2
  107. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  108. package/docs/api/interfaces/FileUploadOptions.md +26 -12
  109. package/docs/api/interfaces/FileUploadProps.md +30 -19
  110. package/docs/api/interfaces/FooterProps.md +1 -1
  111. package/docs/api/interfaces/FormFieldProps.md +1 -1
  112. package/docs/api/interfaces/FormProps.md +1 -1
  113. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  114. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  115. package/docs/api/interfaces/InputProps.md +1 -1
  116. package/docs/api/interfaces/LabelProps.md +1 -1
  117. package/docs/api/interfaces/LoggerConfig.md +1 -1
  118. package/docs/api/interfaces/LoginFormProps.md +1 -1
  119. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  120. package/docs/api/interfaces/NavigationContextType.md +9 -9
  121. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  122. package/docs/api/interfaces/NavigationItem.md +1 -1
  123. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  124. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  125. package/docs/api/interfaces/Organisation.md +1 -1
  126. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  127. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  128. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  129. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  130. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  131. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  132. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  133. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  134. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  135. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  136. package/docs/api/interfaces/PaletteData.md +1 -1
  137. package/docs/api/interfaces/ParsedAddress.md +2 -2
  138. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  139. package/docs/api/interfaces/ProgressProps.md +3 -11
  140. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  141. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  142. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  143. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  144. package/docs/api/interfaces/QuickFix.md +1 -1
  145. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  146. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  147. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  148. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  149. package/docs/api/interfaces/RBACConfig.md +2 -2
  150. package/docs/api/interfaces/RBACContext.md +1 -1
  151. package/docs/api/interfaces/RBACLogger.md +1 -1
  152. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  153. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  154. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  155. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  156. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  157. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  158. package/docs/api/interfaces/RBACResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  160. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  161. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  162. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  163. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  164. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  165. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  166. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  167. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  168. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  169. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  170. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  171. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  172. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  173. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  174. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  175. package/docs/api/interfaces/RouteConfig.md +10 -10
  176. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  177. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  178. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  179. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  180. package/docs/api/interfaces/SetupIssue.md +1 -1
  181. package/docs/api/interfaces/StorageConfig.md +4 -4
  182. package/docs/api/interfaces/StorageFileInfo.md +7 -7
  183. package/docs/api/interfaces/StorageFileMetadata.md +25 -14
  184. package/docs/api/interfaces/StorageListOptions.md +22 -9
  185. package/docs/api/interfaces/StorageListResult.md +4 -4
  186. package/docs/api/interfaces/StorageUploadOptions.md +21 -8
  187. package/docs/api/interfaces/StorageUploadResult.md +6 -6
  188. package/docs/api/interfaces/StorageUrlOptions.md +19 -6
  189. package/docs/api/interfaces/StyleImport.md +1 -1
  190. package/docs/api/interfaces/SwitchProps.md +1 -1
  191. package/docs/api/interfaces/TabsContentProps.md +1 -1
  192. package/docs/api/interfaces/TabsListProps.md +1 -1
  193. package/docs/api/interfaces/TabsProps.md +1 -1
  194. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  195. package/docs/api/interfaces/TextareaProps.md +1 -1
  196. package/docs/api/interfaces/ToastActionElement.md +1 -1
  197. package/docs/api/interfaces/ToastProps.md +1 -1
  198. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  199. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  200. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  201. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  202. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  203. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  205. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  207. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  208. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  209. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  210. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  211. package/docs/api/interfaces/UseResolvedScopeOptions.md +5 -5
  212. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  213. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  214. package/docs/api/interfaces/UserEventAccess.md +11 -11
  215. package/docs/api/interfaces/UserMenuProps.md +1 -1
  216. package/docs/api/interfaces/UserProfile.md +1 -1
  217. package/docs/api/modules.md +165 -106
  218. package/docs/api-reference/components.md +15 -7
  219. package/docs/api-reference/providers.md +2 -2
  220. package/docs/api-reference/rpc-functions.md +1 -0
  221. package/docs/best-practices/README.md +1 -1
  222. package/docs/best-practices/deployment.md +8 -8
  223. package/docs/getting-started/examples/README.md +2 -2
  224. package/docs/getting-started/installation-guide.md +4 -4
  225. package/docs/getting-started/quick-start.md +3 -3
  226. package/docs/migration/MIGRATION_GUIDE.md +3 -3
  227. package/docs/migration/README.md +18 -0
  228. package/docs/migration/database-changes-december-2025.md +767 -0
  229. package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
  230. package/docs/rbac/compliance/compliance-guide.md +2 -2
  231. package/docs/rbac/event-based-apps.md +2 -2
  232. package/docs/rbac/getting-started.md +2 -2
  233. package/docs/rbac/quick-start.md +2 -2
  234. package/docs/security/README.md +4 -4
  235. package/docs/standards/07-rbac-and-rls-standard.md +430 -7
  236. package/docs/troubleshooting/README.md +2 -2
  237. package/docs/troubleshooting/migration.md +3 -3
  238. package/package.json +1 -3
  239. package/scripts/check-pace-core-compliance.cjs +1 -1
  240. package/scripts/check-pace-core-compliance.js +1 -1
  241. package/src/__tests__/fixtures/supabase.ts +301 -0
  242. package/src/__tests__/public-recipe-view.test.ts +19 -19
  243. package/src/__tests__/rls-policies.test.ts +210 -74
  244. package/src/components/AddressField/AddressField.test.tsx +42 -0
  245. package/src/components/AddressField/AddressField.tsx +71 -60
  246. package/src/components/AddressField/README.md +7 -6
  247. package/src/components/Alert/Alert.test.tsx +50 -10
  248. package/src/components/Alert/Alert.tsx +5 -3
  249. package/src/components/Avatar/Avatar.test.tsx +95 -43
  250. package/src/components/Avatar/Avatar.tsx +16 -16
  251. package/src/components/Button/Button.test.tsx +2 -1
  252. package/src/components/Button/Button.tsx +3 -3
  253. package/src/components/Calendar/Calendar.test.tsx +53 -37
  254. package/src/components/Calendar/Calendar.tsx +409 -82
  255. package/src/components/Card/Card.test.tsx +7 -4
  256. package/src/components/Card/Card.tsx +3 -6
  257. package/src/components/Checkbox/Checkbox.tsx +2 -2
  258. package/src/components/DataTable/components/ActionButtons.tsx +5 -5
  259. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  260. package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
  261. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
  262. package/src/components/DataTable/components/DataTableBody.tsx +12 -12
  263. package/src/components/DataTable/components/DataTableCore.tsx +3 -3
  264. package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
  265. package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
  266. package/src/components/DataTable/components/EditableRow.tsx +2 -2
  267. package/src/components/DataTable/components/EmptyState.tsx +3 -3
  268. package/src/components/DataTable/components/GroupHeader.tsx +2 -2
  269. package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
  270. package/src/components/DataTable/components/ImportModal.tsx +4 -4
  271. package/src/components/DataTable/components/LoadingState.tsx +1 -1
  272. package/src/components/DataTable/components/PaginationControls.tsx +11 -11
  273. package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
  274. package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
  275. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
  276. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
  277. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
  278. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
  279. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
  280. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
  281. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
  282. package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
  283. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
  284. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
  285. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
  286. package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
  287. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
  288. package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
  289. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
  290. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
  291. package/src/components/Dialog/Dialog.tsx +2 -2
  292. package/src/components/EventSelector/EventSelector.tsx +7 -7
  293. package/src/components/FileDisplay/FileDisplay.tsx +291 -179
  294. package/src/components/FileUpload/FileUpload.tsx +7 -4
  295. package/src/components/Header/Header.test.tsx +28 -0
  296. package/src/components/Header/Header.tsx +22 -9
  297. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
  298. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
  299. package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
  301. package/src/components/OrganisationSelector/OrganisationSelector.tsx +42 -22
  302. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
  303. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
  304. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
  305. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
  306. package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
  307. package/src/components/PaceAppLayout/test-setup.tsx +1 -0
  308. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
  309. package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
  310. package/src/components/Progress/Progress.test.tsx +18 -19
  311. package/src/components/Progress/Progress.tsx +31 -32
  312. package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
  313. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
  314. package/src/components/Select/Select.test.tsx +4 -1
  315. package/src/components/Select/Select.tsx +65 -20
  316. package/src/components/Switch/Switch.test.tsx +2 -1
  317. package/src/components/Switch/Switch.tsx +1 -1
  318. package/src/components/Toast/Toast.tsx +1 -1
  319. package/src/components/Tooltip/Tooltip.test.tsx +8 -2
  320. package/src/components/UserMenu/UserMenu.tsx +3 -3
  321. package/src/eslint-rules/pace-core-compliance.cjs +0 -2
  322. package/src/eslint-rules/pace-core-compliance.js +0 -2
  323. package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
  324. package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
  325. package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
  326. package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
  327. package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
  328. package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
  329. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -1
  330. package/src/hooks/__tests__/usePublicEvent.test.ts +608 -0
  331. package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
  332. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +67 -24
  333. package/src/hooks/index.ts +1 -1
  334. package/src/hooks/public/usePublicEvent.ts +10 -10
  335. package/src/hooks/public/usePublicFileDisplay.ts +173 -87
  336. package/src/hooks/useAppConfig.ts +24 -5
  337. package/src/hooks/useFileDisplay.ts +298 -36
  338. package/src/hooks/useFileReference.ts +56 -11
  339. package/src/hooks/useFileUrl.ts +1 -1
  340. package/src/hooks/useInactivityTracker.ts +16 -7
  341. package/src/hooks/usePermissionCache.test.ts +85 -8
  342. package/src/hooks/useQueryCache.ts +27 -6
  343. package/src/hooks/useSecureDataAccess.test.ts +87 -42
  344. package/src/hooks/useSecureDataAccess.ts +95 -48
  345. package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
  346. package/src/providers/services/EventServiceProvider.tsx +37 -17
  347. package/src/providers/services/InactivityServiceProvider.tsx +4 -4
  348. package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
  349. package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
  350. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
  351. package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
  352. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
  353. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
  354. package/src/rbac/api.ts +240 -36
  355. package/src/rbac/cache-invalidation.ts +21 -7
  356. package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
  357. package/src/rbac/components/NavigationGuard.tsx +23 -63
  358. package/src/rbac/components/NavigationProvider.test.tsx +52 -23
  359. package/src/rbac/components/NavigationProvider.tsx +13 -11
  360. package/src/rbac/components/PagePermissionGuard.tsx +77 -203
  361. package/src/rbac/components/PagePermissionProvider.tsx +13 -11
  362. package/src/rbac/components/PermissionEnforcer.tsx +24 -62
  363. package/src/rbac/components/RoleBasedRouter.tsx +14 -12
  364. package/src/rbac/components/SecureDataProvider.tsx +13 -11
  365. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
  366. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
  367. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
  368. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
  369. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
  370. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
  371. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
  372. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
  373. package/src/rbac/engine.ts +4 -2
  374. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
  375. package/src/rbac/hooks/index.ts +3 -0
  376. package/src/rbac/hooks/useCan.test.ts +101 -53
  377. package/src/rbac/hooks/usePermissions.ts +108 -41
  378. package/src/rbac/hooks/useRBAC.test.ts +11 -3
  379. package/src/rbac/hooks/useRBAC.ts +83 -40
  380. package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
  381. package/src/rbac/hooks/useResolvedScope.ts +128 -70
  382. package/src/rbac/hooks/useSecureSupabase.ts +36 -19
  383. package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
  384. package/src/rbac/request-deduplication.ts +1 -1
  385. package/src/rbac/secureClient.ts +72 -12
  386. package/src/rbac/security.ts +29 -23
  387. package/src/rbac/types.ts +10 -0
  388. package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
  389. package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
  390. package/src/rbac/utils/__tests__/eventContext.test.ts +8 -3
  391. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +74 -12
  392. package/src/rbac/utils/contextValidator.ts +288 -0
  393. package/src/rbac/utils/eventContext.ts +52 -3
  394. package/src/services/AuthService.ts +37 -8
  395. package/src/services/EventService.ts +165 -21
  396. package/src/services/OrganisationService.ts +125 -137
  397. package/src/services/__tests__/EventService.test.ts +26 -21
  398. package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
  399. package/src/services/__tests__/OrganisationService.test.ts +218 -86
  400. package/src/types/database.generated.ts +166 -201
  401. package/src/types/file-reference.ts +13 -10
  402. package/src/types/supabase.ts +2 -2
  403. package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
  404. package/src/utils/app/appNameResolver.test.ts +346 -73
  405. package/src/utils/context/superAdminOverride.ts +58 -0
  406. package/src/utils/file-reference/index.ts +65 -37
  407. package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
  408. package/src/utils/google-places/googlePlacesUtils.ts +1 -1
  409. package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
  410. package/src/utils/google-places/types.ts +1 -1
  411. package/src/utils/request-deduplication.ts +4 -4
  412. package/src/utils/security/secureDataAccess.test.ts +1 -1
  413. package/src/utils/security/secureDataAccess.ts +7 -4
  414. package/src/utils/storage/README.md +1 -1
  415. package/src/utils/storage/helpers.test.ts +1 -1
  416. package/src/utils/storage/helpers.ts +38 -19
  417. package/src/utils/storage/types.ts +15 -8
  418. package/src/utils/validation/__tests__/csrf.test.ts +105 -0
  419. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
  420. package/src/vite-env.d.ts +2 -2
  421. package/dist/chunk-3GOZZZYH.js.map +0 -1
  422. package/dist/chunk-DDM4CCYT.js.map +0 -1
  423. package/dist/chunk-E7UAOUMY.js +0 -75
  424. package/dist/chunk-E7UAOUMY.js.map +0 -1
  425. package/dist/chunk-F2IMUDXZ.js.map +0 -1
  426. package/dist/chunk-HEHYGYOX.js.map +0 -1
  427. package/dist/chunk-IM4QE42D.js.map +0 -1
  428. package/dist/chunk-MX64ZF6I.js.map +0 -1
  429. package/dist/chunk-SAUPYVLF.js.map +0 -1
  430. package/dist/chunk-THRPYOFK.js.map +0 -1
  431. package/dist/chunk-UCQSRW7Z.js.map +0 -1
  432. package/dist/chunk-VGZZXKBR.js.map +0 -1
  433. package/dist/chunk-YGPFYGA6.js.map +0 -1
  434. package/dist/chunk-YHCN776L.js.map +0 -1
  435. /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-WKRZD47S.js.map} +0 -0
  436. /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-FTSG5XH7.js.map} +0 -0
  437. /package/dist/{api-YP7XD5L6.js.map → api-IHKALJZD.js.map} +0 -0
  438. /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
@@ -127,7 +127,7 @@ export function BulkOperationsDropdown({
127
127
  disabled={!hasSelection}
128
128
  className={`min-w-[140px] h-9 px-3 py-2 text-sm font-medium ${className || ''}`}
129
129
  >
130
- <MoreHorizontal className="h-4 w-4 mr-2 flex-shrink-0" />
130
+ <MoreHorizontal className="size-4 mr-2 flex-shrink-0" />
131
131
  <span className="truncate">
132
132
  Bulk Actions ({selectedCount})
133
133
  </span>
@@ -149,7 +149,7 @@ export function BulkOperationsDropdown({
149
149
  variant === 'destructive' ? 'text-destructive focus:text-destructive' : ''
150
150
  }`}
151
151
  >
152
- <Icon className="h-4 w-4" />
152
+ <Icon className="size-4" />
153
153
  <span>{label}</span>
154
154
  </SelectItem>
155
155
  );
@@ -108,7 +108,7 @@ export function ColumnFilter({
108
108
  variant="ghost"
109
109
  onClick={clearFilter}
110
110
  >
111
- <X className="h-3 w-3" />
111
+ <X className="size-3" />
112
112
  </Button>
113
113
  )}
114
114
  {hasFilter && (
@@ -30,7 +30,7 @@ export function ColumnVisibilityDropdown<TData>({
30
30
  <Button
31
31
  variant="outline"
32
32
  >
33
- <Settings2 className="h-4 w-4 mr-2 flex-shrink-0" />
33
+ <Settings2 className="size-4 mr-2 flex-shrink-0" />
34
34
  <span className="truncate">Columns</span>
35
35
  </Button>
36
36
  </SelectTrigger>
@@ -49,7 +49,7 @@ export function ColumnVisibilityDropdown<TData>({
49
49
  });
50
50
  }}
51
51
  >
52
- <Eye className="h-3 w-3 mr-1" />
52
+ <Eye className="size-3 mr-1" />
53
53
  Show All
54
54
  </Button>
55
55
  <Button
@@ -64,7 +64,7 @@ export function ColumnVisibilityDropdown<TData>({
64
64
  });
65
65
  }}
66
66
  >
67
- <EyeOff className="h-3 w-3 mr-1" />
67
+ <EyeOff className="size-3 mr-1" />
68
68
  Hide All
69
69
  </Button>
70
70
  </div>
@@ -222,14 +222,14 @@ export function DataTableBody<TData extends DataRecord>({
222
222
  variant="ghost"
223
223
  size="sm"
224
224
  onClick={hierarchical.isAllExpanded ? hierarchical.collapseAll : hierarchical.expandAll}
225
- className="h-8 w-8 p-0"
225
+ className="size-8 p-0"
226
226
  aria-label={hierarchical.isAllExpanded ? 'Collapse all' : 'Expand all'}
227
227
  title={hierarchical.isAllExpanded ? 'Collapse all' : 'Expand all'}
228
228
  >
229
229
  {hierarchical.isAllExpanded ? (
230
- <ChevronDown className="h-4 w-4" />
230
+ <ChevronDown className="size-4" />
231
231
  ) : (
232
- <ChevronRight className="h-4 w-4" />
232
+ <ChevronRight className="size-4" />
233
233
  )}
234
234
  </Button>
235
235
  </th>
@@ -263,11 +263,11 @@ export function DataTableBody<TData extends DataRecord>({
263
263
  ? header.column.columnDef.header(header.getContext())
264
264
  : header.column.columnDef.header}
265
265
  {header.column.getIsSorted() === 'asc' ? (
266
- <ChevronUp className="h-4 w-4" />
266
+ <ChevronUp className="size-4" />
267
267
  ) : header.column.getIsSorted() === 'desc' ? (
268
- <ChevronDown className="h-4 w-4" />
268
+ <ChevronDown className="size-4" />
269
269
  ) : (
270
- <ChevronsUpDown className="h-4 w-4" />
270
+ <ChevronsUpDown className="size-4" />
271
271
  )}
272
272
  </div>
273
273
  </Button>
@@ -308,19 +308,19 @@ export function DataTableBody<TData extends DataRecord>({
308
308
  <>
309
309
  <button
310
310
  onClick={onSaveCreation}
311
- className="h-8 w-8 p-0 bg-app-main-500 text-app-main-50 rounded hover:bg-app-main-600 flex items-center justify-center"
311
+ className="size-8 p-0 bg-app-main-500 text-app-main-50 rounded hover:bg-app-main-600 flex items-center justify-center"
312
312
  title="Save new row"
313
313
  >
314
- <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
314
+ <svg className="size-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
315
315
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
316
316
  </svg>
317
317
  </button>
318
318
  <button
319
319
  onClick={onCancelCreation}
320
- className="h-8 w-8 p-0 bg-app-sec-500 text-app-main-50 rounded hover:bg-app-sec-600 flex items-center justify-center"
320
+ className="size-8 p-0 bg-app-sec-500 text-app-main-50 rounded hover:bg-app-sec-600 flex items-center justify-center"
321
321
  title="Cancel new row"
322
322
  >
323
- <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
323
+ <svg className="size-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
324
324
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
325
325
  </svg>
326
326
  </button>
@@ -368,9 +368,9 @@ export function DataTableBody<TData extends DataRecord>({
368
368
  className="p-0 h-auto mr-2"
369
369
  >
370
370
  {isExpanded ? (
371
- <ChevronDown className="h-4 w-4" />
371
+ <ChevronDown className="size-4" />
372
372
  ) : (
373
- <ChevronRight className="h-4 w-4" />
373
+ <ChevronRight className="size-4" />
374
374
  )}
375
375
  </Button>
376
376
  <span className="text-sm">
@@ -1120,11 +1120,11 @@ function DataTableInternal<TData extends DataRecord>(props: DataTableCoreProps<T
1120
1120
  ? header.column.columnDef.header(header.getContext())
1121
1121
  : header.column.columnDef.header}
1122
1122
  {header.column.getIsSorted() === 'asc' ? (
1123
- <ChevronUp className="h-4 w-4" />
1123
+ <ChevronUp className="size-4" />
1124
1124
  ) : header.column.getIsSorted() === 'desc' ? (
1125
- <ChevronDown className="h-4 w-4" />
1125
+ <ChevronDown className="size-4" />
1126
1126
  ) : (
1127
- <ChevronsUpDown className="h-4 w-4" />
1127
+ <ChevronsUpDown className="size-4" />
1128
1128
  )}
1129
1129
  </Button>
1130
1130
  ) : (
@@ -204,7 +204,7 @@ export function DataTableToolbar<TData extends DataRecord>({
204
204
  variant="outline"
205
205
  onClick={onToggleFilterRow}
206
206
  >
207
- <Filter className="h-4 w-4 mr-2 flex-shrink-0" />
207
+ <Filter className="size-4 mr-2 flex-shrink-0" />
208
208
  <span className="truncate">
209
209
  {showFilterRow ? 'Hide Filters' : 'Show Filters'}
210
210
  </span>
@@ -217,7 +217,7 @@ export function DataTableToolbar<TData extends DataRecord>({
217
217
  variant="outline"
218
218
  onClick={onCreateRow}
219
219
  >
220
- <Plus className="h-4 w-4 mr-2 flex-shrink-0" />
220
+ <Plus className="size-4 mr-2 flex-shrink-0" />
221
221
  <span className="truncate">Add Row</span>
222
222
  </Button>
223
223
  )}
@@ -229,7 +229,7 @@ export function DataTableToolbar<TData extends DataRecord>({
229
229
  onClick={onImportClick}
230
230
  data-restore-target="datatable-import-button"
231
231
  >
232
- <Upload className="h-4 w-4 mr-2 flex-shrink-0" />
232
+ <Upload className="size-4 mr-2 flex-shrink-0" />
233
233
  <span className="truncate">Import</span>
234
234
  </Button>
235
235
  )}
@@ -240,7 +240,7 @@ export function DataTableToolbar<TData extends DataRecord>({
240
240
  variant="outline"
241
241
  onClick={onExport}
242
242
  >
243
- <Download className="h-4 w-4 mr-2 flex-shrink-0" />
243
+ <Download className="size-4 mr-2 flex-shrink-0" />
244
244
  <span className="truncate">Export</span>
245
245
  </Button>
246
246
  )}
@@ -252,7 +252,7 @@ export function DataTableToolbar<TData extends DataRecord>({
252
252
  onClick={() => onDeleteSelected?.(rowSelection)}
253
253
  disabled={Object.values(rowSelection).filter(Boolean).length === 0}
254
254
  >
255
- <Trash2 className="h-4 w-4 mr-2 flex-shrink-0" />
255
+ <Trash2 className="size-4 mr-2 flex-shrink-0" />
256
256
  <span className="truncate">Delete</span>
257
257
  </Button>
258
258
  )}
@@ -121,11 +121,11 @@ export function DraggableColumnHeader<TData>({
121
121
  ? header.column.columnDef.header(header.getContext())
122
122
  : header.column.columnDef.header}
123
123
  {header.column.getIsSorted() === 'asc' ? (
124
- <ChevronUp className="h-4 w-4" />
124
+ <ChevronUp className="size-4" />
125
125
  ) : header.column.getIsSorted() === 'desc' ? (
126
- <ChevronDown className="h-4 w-4" />
126
+ <ChevronDown className="size-4" />
127
127
  ) : (
128
- <ChevronsUpDown className="h-4 w-4" />
128
+ <ChevronsUpDown className="size-4" />
129
129
  )}
130
130
  </div>
131
131
  </Button>
@@ -378,10 +378,10 @@ export function EditableRow<TData extends DataRecord>({
378
378
  cell.column.id === 'actions' ? (
379
379
  <div className="flex gap-1">
380
380
  <Button onClick={onSave} size="sm" variant="default" aria-label="Save changes">
381
- <Check className="h-4 w-4" />
381
+ <Check className="size-4" />
382
382
  </Button>
383
383
  <Button onClick={onCancel} size="sm" variant="outline" aria-label="Cancel editing">
384
- <X className="h-4 w-4" />
384
+ <X className="size-4" />
385
385
  </Button>
386
386
  </div>
387
387
  ) : (
@@ -36,7 +36,7 @@ export function EmptyState({
36
36
  <Icon
37
37
  role="img"
38
38
  aria-hidden="true"
39
- className="h-12 w-12 text-muted-foreground mb-4"
39
+ className="size-12 text-muted-foreground mb-4"
40
40
  data-testid={Icon === Database ? 'lucide-database' : Icon === User ? 'lucide-user' : 'custom-icon'}
41
41
  />
42
42
  <h3 className="text-lg font-semibold mb-2">
@@ -50,14 +50,14 @@ export function EmptyState({
50
50
  <div className="flex gap-2">
51
51
  {isFiltered && onClearFilters && (
52
52
  <Button variant="outline" onClick={onClearFilters}>
53
- <Search className="h-4 w-4 mr-2" />
53
+ <Search className="size-4 mr-2" />
54
54
  Clear filters
55
55
  </Button>
56
56
  )}
57
57
 
58
58
  {action && (
59
59
  <Button onClick={action.onClick}>
60
- <Plus className="h-4 w-4 mr-2" />
60
+ <Plus className="size-4 mr-2" />
61
61
  {action.label}
62
62
  </Button>
63
63
  )}
@@ -29,9 +29,9 @@ export function GroupHeader<TData>({
29
29
  className="p-0 h-auto mr-2"
30
30
  >
31
31
  {isExpanded ? (
32
- <ChevronDown className="h-4 w-4" />
32
+ <ChevronDown className="size-4" />
33
33
  ) : (
34
- <ChevronRight className="h-4 w-4" />
34
+ <ChevronRight className="size-4" />
35
35
  )}
36
36
  </Button>
37
37
  <span className="text-sm">
@@ -62,7 +62,7 @@ export function GroupingDropdown<TData extends DataRecord>({
62
62
  variant="outline"
63
63
  className={className || ''}
64
64
  >
65
- <Group className="h-4 w-4 mr-2 flex-shrink-0" />
65
+ <Group className="size-4 mr-2 flex-shrink-0" />
66
66
  <span className="truncate">Grouping</span>
67
67
  </Button>
68
68
  </SelectTrigger>
@@ -375,7 +375,7 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
375
375
 
376
376
  <div className="space-y-4">
377
377
  <div className="border-2 border-dashed border-sec-200 rounded-lg p-6 text-center">
378
- <FileText className="h-8 w-8 mx-auto text-sec-400 mb-2" />
378
+ <FileText className="size-8 mx-auto text-sec-400 mb-2" />
379
379
  <p className="text-sec-600 mb-2">
380
380
  {file ? `Selected: ${file.name}` : uploadText}
381
381
  </p>
@@ -389,7 +389,7 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
389
389
  size="sm"
390
390
  onClick={() => fileInputRef.current?.click()}
391
391
  >
392
- <Upload className="h-4 w-4 mr-2" />
392
+ <Upload className="size-4 mr-2" />
393
393
  {selectFileButtonText}
394
394
  </Button>
395
395
  <Input
@@ -403,7 +403,7 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
403
403
 
404
404
  {error && (
405
405
  <div className="flex items-center gap-2 p-3 bg-acc-50 border border-acc-200 rounded text-acc-700">
406
- <AlertCircle className="h-4 w-4" />
406
+ <AlertCircle className="size-4" />
407
407
  <span className="text-sm">{error}</span>
408
408
  </div>
409
409
  )}
@@ -411,7 +411,7 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
411
411
  {validationErrors.length > 0 && (
412
412
  <div className="space-y-2">
413
413
  <div className="flex items-center gap-2 p-3 bg-acc-50 border border-acc-200 rounded text-acc-700">
414
- <AlertCircle className="h-4 w-4" />
414
+ <AlertCircle className="size-4" />
415
415
  <span className="text-sm font-medium">
416
416
  {validationErrors.length} validation error{validationErrors.length !== 1 ? 's' : ''} found
417
417
  </span>
@@ -4,7 +4,7 @@ export function LoadingState() {
4
4
  return (
5
5
  <div className="p-8 text-center">
6
6
  <div className="flex items-center justify-center space-x-2">
7
- <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary"></div>
7
+ <div className="animate-spin rounded-full size-6 border-b-2 border-primary"></div>
8
8
  <span aria-live="polite" className="text-muted-foreground">Loading...</span>
9
9
  </div>
10
10
  </div>
@@ -76,11 +76,11 @@ export function PaginationControls<TData extends DataRecord>({
76
76
  const getModeIcon = () => {
77
77
  switch (paginationMode) {
78
78
  case 'server':
79
- return <Server className="h-3 w-3" />;
79
+ return <Server className="size-3" />;
80
80
  case 'hybrid':
81
- return <Database className="h-3 w-3" />;
81
+ return <Database className="size-3" />;
82
82
  default:
83
- return <Zap className="h-3 w-3" />;
83
+ return <Zap className="size-3" />;
84
84
  }
85
85
  };
86
86
 
@@ -157,49 +157,49 @@ export function PaginationControls<TData extends DataRecord>({
157
157
  <Button
158
158
  variant="outline"
159
159
  size="sm"
160
- className="h-8 w-8 p-0"
160
+ className="size-8 p-0"
161
161
  onClick={goToFirstPage}
162
162
  disabled={!canPreviousPage || isLoading}
163
163
  aria-label="Go to first page"
164
164
  tabIndex={0}
165
165
  >
166
- <ChevronsLeft className="h-4 w-4" />
166
+ <ChevronsLeft className="size-4" />
167
167
  </Button>
168
168
 
169
169
  <Button
170
170
  variant="outline"
171
171
  size="sm"
172
- className="h-8 w-8 p-0"
172
+ className="size-8 p-0"
173
173
  onClick={goToPreviousPage}
174
174
  disabled={!canPreviousPage || isLoading}
175
175
  aria-label="Go to previous page"
176
176
  tabIndex={0}
177
177
  >
178
- <ChevronLeft className="h-4 w-4" />
178
+ <ChevronLeft className="size-4" />
179
179
  </Button>
180
180
 
181
181
  <Button
182
182
  variant="outline"
183
183
  size="sm"
184
- className="h-8 w-8 p-0"
184
+ className="size-8 p-0"
185
185
  onClick={goToNextPage}
186
186
  disabled={!canNextPage || isLoading}
187
187
  aria-label="Go to next page"
188
188
  tabIndex={0}
189
189
  >
190
- <ChevronRight className="h-4 w-4" />
190
+ <ChevronRight className="size-4" />
191
191
  </Button>
192
192
 
193
193
  <Button
194
194
  variant="outline"
195
195
  size="sm"
196
- className="h-8 w-8 p-0"
196
+ className="size-8 p-0"
197
197
  onClick={goToLastPage}
198
198
  disabled={!canNextPage || isLoading}
199
199
  aria-label="Go to last page"
200
200
  tabIndex={0}
201
201
  >
202
- <ChevronsRight className="h-4 w-4" />
202
+ <ChevronsRight className="size-4" />
203
203
  </Button>
204
204
  </footer>
205
205
  );
@@ -594,9 +594,9 @@ const RowComponent = React.memo(({
594
594
  className="p-0 h-auto mr-2"
595
595
  >
596
596
  {isExpanded ? (
597
- <ChevronDown className="h-4 w-4" />
597
+ <ChevronDown className="size-4" />
598
598
  ) : (
599
- <ChevronRight className="h-4 w-4" />
599
+ <ChevronRight className="size-4" />
600
600
  )}
601
601
  </Button>
602
602
  <span className="text-sm">
@@ -755,14 +755,14 @@ const RowComponent = React.memo(({
755
755
  variant="ghost"
756
756
  size="sm"
757
757
  onClick={() => hierarchical?.state?.toggleRow(rowId)}
758
- className="h-6 w-6 p-0 flex-shrink-0"
758
+ className="size-6 p-0 flex-shrink-0"
759
759
  aria-label={isExpanded ? 'Collapse row' : 'Expand row'}
760
760
  title={isExpanded ? 'Collapse row' : 'Expand row'}
761
761
  >
762
762
  {isExpanded ? (
763
- <ChevronDown className="h-4 w-4" />
763
+ <ChevronDown className="size-4" />
764
764
  ) : (
765
- <ChevronRight className="h-4 w-4" />
765
+ <ChevronRight className="size-4" />
766
766
  )}
767
767
  </Button>
768
768
  )}
@@ -1039,19 +1039,19 @@ export function UnifiedTableBody<TData extends Record<string, any>>({
1039
1039
  >
1040
1040
  <button
1041
1041
  onClick={onSaveCreation}
1042
- className="h-8 w-8 p-0 hover:bg-muted/50 flex items-center justify-center"
1042
+ className="size-8 p-0 hover:bg-muted/50 flex items-center justify-center"
1043
1043
  title="Save new row"
1044
1044
  >
1045
- <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1045
+ <svg className="size-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1046
1046
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
1047
1047
  </svg>
1048
1048
  </button>
1049
1049
  <button
1050
1050
  onClick={onCancelCreation}
1051
- className="h-8 w-8 p-0 hover:bg-muted/50 flex items-center justify-center"
1051
+ className="size-8 p-0 hover:bg-muted/50 flex items-center justify-center"
1052
1052
  title="Cancel new row"
1053
1053
  >
1054
- <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1054
+ <svg className="size-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
1055
1055
  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
1056
1056
  </svg>
1057
1057
  </button>
@@ -35,9 +35,9 @@ export function ViewRowModal<TData extends Record<string, any>>({
35
35
  variant="ghost"
36
36
  size="sm"
37
37
  onClick={onClose}
38
- className="h-6 w-6 p-0"
38
+ className="size-6 p-0"
39
39
  >
40
- <X className="h-4 w-4" />
40
+ <X className="size-4" />
41
41
  </Button>
42
42
  </DialogTitle>
43
43
  </DialogHeader>
@@ -14,35 +14,6 @@ import userEvent from '@testing-library/user-event';
14
14
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
15
15
  import { AccessDeniedPage } from '../AccessDeniedPage';
16
16
 
17
- // Mock lucide-react icons
18
- vi.mock('lucide-react', () => ({
19
- ShieldX: ({ className }: { className?: string }) => (
20
- <div data-testid="shield-x-icon" className={className}>ShieldX</div>
21
- ),
22
- ArrowLeft: ({ className }: { className?: string }) => (
23
- <div data-testid="arrow-left-icon" className={className}>ArrowLeft</div>
24
- ),
25
- RefreshCw: ({ className }: { className?: string }) => (
26
- <div data-testid="refresh-cw-icon" className={className}>RefreshCw</div>
27
- ),
28
- }));
29
-
30
- // Mock Card component - need to match the actual import path
31
- vi.mock('../../../Card/Card', () => ({
32
- Card: ({ children, className }: any) => (
33
- <article data-testid="card" className={className}>{children}</article>
34
- ),
35
- }));
36
-
37
- // Mock Button component
38
- vi.mock('../../Button/Button', () => ({
39
- Button: ({ children, onClick, variant, className, ...props }: any) => (
40
- <button onClick={onClick} data-variant={variant} className={className} {...props}>
41
- {children}
42
- </button>
43
- ),
44
- }));
45
-
46
17
  describe('[component] AccessDeniedPage', () => {
47
18
  beforeAll(() => {
48
19
  // Set up navigator globally for all tests (needed for userEvent cleanup)
@@ -190,7 +161,7 @@ describe('[component] AccessDeniedPage', () => {
190
161
  it('renders ShieldX icon', () => {
191
162
  render(<AccessDeniedPage resource="users" />);
192
163
 
193
- expect(screen.getByTestId('shield-x-icon')).toBeInTheDocument();
164
+ expect(screen.getByTestId('lucide-shieldx')).toBeInTheDocument();
194
165
  });
195
166
 
196
167
  it('displays resource information', () => {
@@ -408,19 +379,19 @@ describe('[component] AccessDeniedPage', () => {
408
379
  const handleRetry = vi.fn();
409
380
 
410
381
  render(
411
- <AccessDeniedPage
412
- resource="users"
382
+ <AccessDeniedPage
383
+ resource="users"
413
384
  onRetry={handleRetry}
414
385
  />
415
386
  );
416
387
 
417
- expect(screen.getByTestId('refresh-cw-icon')).toBeInTheDocument();
388
+ expect(screen.getByTestId('lucide-refreshcw')).toBeInTheDocument();
418
389
  });
419
390
 
420
391
  it('renders ArrowLeft icon in back button', () => {
421
392
  render(<AccessDeniedPage resource="users" />);
422
393
 
423
- expect(screen.getByTestId('arrow-left-icon')).toBeInTheDocument();
394
+ expect(screen.getByTestId('lucide-arrowleft')).toBeInTheDocument();
424
395
  });
425
396
  });
426
397
 
@@ -479,7 +450,7 @@ describe('[component] AccessDeniedPage', () => {
479
450
  it('has proper icon structure', () => {
480
451
  render(<AccessDeniedPage resource="users" />);
481
452
 
482
- expect(screen.getByTestId('shield-x-icon')).toBeInTheDocument();
453
+ expect(screen.getByTestId('lucide-shieldx')).toBeInTheDocument();
483
454
  });
484
455
  });
485
456
 
@@ -529,9 +500,12 @@ describe('[component] AccessDeniedPage', () => {
529
500
  });
530
501
  }
531
502
 
532
- render(<AccessDeniedPage resource="users" />);
503
+ const { container } = render(<AccessDeniedPage resource="users" />);
533
504
 
534
- expect(screen.getByTestId('card')).toBeInTheDocument();
505
+ const card = screen.getByRole('article');
506
+ expect(card).toBeInTheDocument();
507
+ expect(container.firstChild).toContainElement(card);
508
+ expect(card.className).toContain('max-w-md');
535
509
  });
536
510
  });
537
511