@jmruthers/pace-core 0.5.193 → 0.6.2

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 (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -273,7 +273,7 @@ const TestWrapper = ({ children }: { children: React.ReactNode }) => (
273
273
  );
274
274
 
275
275
  describe('PaceAppLayout Component', () => {
276
- const defaultProps = {
276
+ const baseProps = {
277
277
  appName: 'Test App',
278
278
  };
279
279
 
@@ -296,7 +296,7 @@ describe('PaceAppLayout Component', () => {
296
296
  it('renders with default props', () => {
297
297
  renderWithProviders(
298
298
  <TestWrapper>
299
- <PaceAppLayout {...defaultProps} />
299
+ <PaceAppLayout {...baseProps} />
300
300
  </TestWrapper>,
301
301
  { withRouter: false }
302
302
  );
@@ -309,7 +309,7 @@ describe('PaceAppLayout Component', () => {
309
309
  it('renders with custom app name', () => {
310
310
  renderWithProviders(
311
311
  <TestWrapper>
312
- <PaceAppLayout {...defaultProps} appName="Custom App" />
312
+ <PaceAppLayout {...baseProps} appName="Custom App" />
313
313
  </TestWrapper>,
314
314
  { withRouter: false }
315
315
  );
@@ -325,7 +325,7 @@ describe('PaceAppLayout Component', () => {
325
325
 
326
326
  renderWithProviders(
327
327
  <TestWrapper>
328
- <PaceAppLayout {...defaultProps} navItems={customNavItems} />
328
+ <PaceAppLayout {...baseProps} navItems={customNavItems} />
329
329
  </TestWrapper>,
330
330
  { withRouter: false }
331
331
  );
@@ -337,7 +337,7 @@ describe('PaceAppLayout Component', () => {
337
337
  it('renders with default navigation items when none provided', () => {
338
338
  renderWithProviders(
339
339
  <TestWrapper>
340
- <PaceAppLayout {...defaultProps} />
340
+ <PaceAppLayout {...baseProps} />
341
341
  </TestWrapper>,
342
342
  { withRouter: false }
343
343
  );
@@ -352,7 +352,7 @@ describe('PaceAppLayout Component', () => {
352
352
 
353
353
  renderWithProviders(
354
354
  <TestWrapper>
355
- <PaceAppLayout {...defaultProps} headerActions={headerActions} />
355
+ <PaceAppLayout {...baseProps} headerActions={headerActions} />
356
356
  </TestWrapper>,
357
357
  { withRouter: false }
358
358
  );
@@ -365,7 +365,7 @@ describe('PaceAppLayout Component', () => {
365
365
 
366
366
  renderWithProviders(
367
367
  <TestWrapper>
368
- <PaceAppLayout {...defaultProps} customLogo={customLogo} />
368
+ <PaceAppLayout {...baseProps} customLogo={customLogo} />
369
369
  </TestWrapper>,
370
370
  { withRouter: false }
371
371
  );
@@ -378,7 +378,7 @@ describe('PaceAppLayout Component', () => {
378
378
 
379
379
  renderWithProviders(
380
380
  <TestWrapper>
381
- <PaceAppLayout {...defaultProps} customUserMenu={customUserMenu} />
381
+ <PaceAppLayout {...baseProps} customUserMenu={customUserMenu} />
382
382
  </TestWrapper>,
383
383
  { withRouter: false }
384
384
  );
@@ -389,7 +389,7 @@ describe('PaceAppLayout Component', () => {
389
389
  it('renders with custom header className', () => {
390
390
  renderWithProviders(
391
391
  <TestWrapper>
392
- <PaceAppLayout {...defaultProps} headerClassName="custom-header" />
392
+ <PaceAppLayout {...baseProps} headerClassName="custom-header" />
393
393
  </TestWrapper>,
394
394
  { withRouter: false }
395
395
  );
@@ -402,7 +402,7 @@ describe('PaceAppLayout Component', () => {
402
402
  it('uses default header className when not provided', () => {
403
403
  renderWithProviders(
404
404
  <TestWrapper>
405
- <PaceAppLayout {...defaultProps} />
405
+ <PaceAppLayout {...baseProps} />
406
406
  </TestWrapper>,
407
407
  { withRouter: false }
408
408
  );
@@ -416,7 +416,7 @@ describe('PaceAppLayout Component', () => {
416
416
  it('shows event selector by default', () => {
417
417
  renderWithProviders(
418
418
  <TestWrapper>
419
- <PaceAppLayout {...defaultProps} />
419
+ <PaceAppLayout {...baseProps} />
420
420
  </TestWrapper>,
421
421
  { withRouter: false }
422
422
  );
@@ -427,7 +427,7 @@ describe('PaceAppLayout Component', () => {
427
427
  it('hides event selector when showEventSelector is false', () => {
428
428
  renderWithProviders(
429
429
  <TestWrapper>
430
- <PaceAppLayout {...defaultProps} showEventSelector={false} />
430
+ <PaceAppLayout {...baseProps} showEventSelector={false} />
431
431
  </TestWrapper>,
432
432
  { withRouter: false }
433
433
  );
@@ -438,7 +438,7 @@ describe('PaceAppLayout Component', () => {
438
438
  it('shows event selector when showEventSelector is explicitly true', () => {
439
439
  renderWithProviders(
440
440
  <TestWrapper>
441
- <PaceAppLayout {...defaultProps} showEventSelector={true} />
441
+ <PaceAppLayout {...baseProps} showEventSelector={true} />
442
442
  </TestWrapper>,
443
443
  { withRouter: false }
444
444
  );
@@ -451,7 +451,7 @@ describe('PaceAppLayout Component', () => {
451
451
  it('shows user menu by default', () => {
452
452
  renderWithProviders(
453
453
  <TestWrapper>
454
- <PaceAppLayout {...defaultProps} />
454
+ <PaceAppLayout {...baseProps} />
455
455
  </TestWrapper>,
456
456
  { withRouter: false }
457
457
  );
@@ -462,7 +462,7 @@ describe('PaceAppLayout Component', () => {
462
462
  it('hides user menu when showUserMenu is false', () => {
463
463
  renderWithProviders(
464
464
  <TestWrapper>
465
- <PaceAppLayout {...defaultProps} showUserMenu={false} />
465
+ <PaceAppLayout {...baseProps} showUserMenu={false} />
466
466
  </TestWrapper>,
467
467
  { withRouter: false }
468
468
  );
@@ -476,7 +476,7 @@ describe('PaceAppLayout Component', () => {
476
476
  const user = userEvent.setup();
477
477
  renderWithProviders(
478
478
  <TestWrapper>
479
- <PaceAppLayout {...defaultProps} />
479
+ <PaceAppLayout {...baseProps} />
480
480
  </TestWrapper>,
481
481
  { withRouter: false }
482
482
  );
@@ -489,7 +489,7 @@ describe('PaceAppLayout Component', () => {
489
489
  const user = userEvent.setup();
490
490
  renderWithProviders(
491
491
  <TestWrapper>
492
- <PaceAppLayout {...defaultProps} />
492
+ <PaceAppLayout {...baseProps} />
493
493
  </TestWrapper>,
494
494
  { withRouter: false }
495
495
  );
@@ -507,7 +507,7 @@ describe('PaceAppLayout Component', () => {
507
507
 
508
508
  renderWithProviders(
509
509
  <TestWrapper>
510
- <PaceAppLayout {...defaultProps} navItems={customNavItems} />
510
+ <PaceAppLayout {...baseProps} navItems={customNavItems} />
511
511
  </TestWrapper>,
512
512
  { withRouter: false }
513
513
  );
@@ -522,7 +522,7 @@ describe('PaceAppLayout Component', () => {
522
522
  it('passes current path to header', () => {
523
523
  renderWithProviders(
524
524
  <TestWrapper>
525
- <PaceAppLayout {...defaultProps} />
525
+ <PaceAppLayout {...baseProps} />
526
526
  </TestWrapper>,
527
527
  { withRouter: false }
528
528
  );
@@ -536,7 +536,7 @@ describe('PaceAppLayout Component', () => {
536
536
  it('renders normally when enforcePermissions is false', () => {
537
537
  renderWithProviders(
538
538
  <TestWrapper>
539
- <PaceAppLayout {...defaultProps} enforcePermissions={false} />
539
+ <PaceAppLayout {...baseProps} enforcePermissions={false} />
540
540
  </TestWrapper>,
541
541
  { withRouter: false }
542
542
  );
@@ -575,7 +575,7 @@ describe('PaceAppLayout Component', () => {
575
575
 
576
576
  renderWithProviders(
577
577
  <TestWrapper>
578
- <PaceAppLayout {...defaultProps} enforcePermissions={true} />
578
+ <PaceAppLayout {...baseProps} enforcePermissions={true} />
579
579
  </TestWrapper>,
580
580
  { withRouter: false }
581
581
  );
@@ -602,7 +602,7 @@ describe('PaceAppLayout Component', () => {
602
602
 
603
603
  renderWithProviders(
604
604
  <TestWrapper>
605
- <PaceAppLayout {...defaultProps} enforcePermissions={true} />
605
+ <PaceAppLayout {...baseProps} enforcePermissions={true} />
606
606
  </TestWrapper>,
607
607
  { withRouter: false }
608
608
  );
@@ -635,7 +635,7 @@ describe('PaceAppLayout Component', () => {
635
635
 
636
636
  renderWithProviders(
637
637
  <TestWrapper>
638
- <PaceAppLayout {...defaultProps} enforcePermissions={true} />
638
+ <PaceAppLayout {...baseProps} enforcePermissions={true} />
639
639
  </TestWrapper>,
640
640
  { withRouter: false }
641
641
  );
@@ -667,7 +667,7 @@ describe('PaceAppLayout Component', () => {
667
667
 
668
668
  renderWithProviders(
669
669
  <TestWrapper>
670
- <PaceAppLayout {...defaultProps} enforcePermissions={true} />
670
+ <PaceAppLayout {...baseProps} enforcePermissions={true} />
671
671
  </TestWrapper>,
672
672
  { withRouter: false }
673
673
  );
@@ -704,7 +704,7 @@ describe('PaceAppLayout Component', () => {
704
704
 
705
705
  renderWithProviders(
706
706
  <TestWrapper>
707
- <PaceAppLayout {...defaultProps} enforcePermissions={true} />
707
+ <PaceAppLayout {...baseProps} enforcePermissions={true} />
708
708
  </TestWrapper>,
709
709
  { withRouter: false }
710
710
  );
@@ -742,7 +742,7 @@ describe('PaceAppLayout Component', () => {
742
742
  renderWithProviders(
743
743
  <TestWrapper>
744
744
  <PaceAppLayout
745
- {...defaultProps}
745
+ {...baseProps}
746
746
  enforcePermissions={true}
747
747
  permissionFallback={customFallback}
748
748
  />
@@ -778,7 +778,7 @@ describe('PaceAppLayout Component', () => {
778
778
  renderWithProviders(
779
779
  <TestWrapper>
780
780
  <PaceAppLayout
781
- {...defaultProps}
781
+ {...baseProps}
782
782
  enforcePermissions={true}
783
783
  enforcePagePermissions={true}
784
784
  pagePermissionFallback={pageFallback}
@@ -814,7 +814,7 @@ describe('PaceAppLayout Component', () => {
814
814
  renderWithProviders(
815
815
  <TestWrapper>
816
816
  <PaceAppLayout
817
- {...defaultProps}
817
+ {...baseProps}
818
818
  navItems={customNavItems}
819
819
  enforcePermissions={true}
820
820
  routePermissions={{
@@ -850,7 +850,7 @@ describe('PaceAppLayout Component', () => {
850
850
  renderWithProviders(
851
851
  <TestWrapper>
852
852
  <PaceAppLayout
853
- {...defaultProps}
853
+ {...baseProps}
854
854
  navItems={customNavItems}
855
855
  enforcePermissions={false}
856
856
  routePermissions={{
@@ -875,7 +875,7 @@ describe('PaceAppLayout Component', () => {
875
875
  renderWithProviders(
876
876
  <TestWrapper>
877
877
  <PaceAppLayout
878
- {...defaultProps}
878
+ {...baseProps}
879
879
  enforcePermissions={true}
880
880
  routePermissions={{
881
881
  '/dashboard': 'update',
@@ -889,7 +889,7 @@ describe('PaceAppLayout Component', () => {
889
889
  );
890
890
 
891
891
  await waitFor(() => {
892
- // useCan is called with userId, scope, permission, pageId, useCache, appName
892
+ // useCan is called with userId, scope, permission, pageId, useCache, precomputedSuperAdmin, appName
893
893
  expect(mockUseCan).toHaveBeenCalledWith(
894
894
  'user-123',
895
895
  expect.objectContaining({
@@ -900,6 +900,7 @@ describe('PaceAppLayout Component', () => {
900
900
  'update:page.dashboard-page',
901
901
  'dashboard-page',
902
902
  true,
903
+ expect.any(Boolean), // precomputedSuperAdmin - can be false, null, or undefined during checks
903
904
  'Test App'
904
905
  );
905
906
  }, { timeout: 2000 });
@@ -909,7 +910,7 @@ describe('PaceAppLayout Component', () => {
909
910
  renderWithProviders(
910
911
  <TestWrapper>
911
912
  <PaceAppLayout
912
- {...defaultProps}
913
+ {...baseProps}
913
914
  enforcePermissions={true}
914
915
  defaultPermission="create"
915
916
  routePermissions={{
@@ -921,7 +922,7 @@ describe('PaceAppLayout Component', () => {
921
922
  );
922
923
 
923
924
  await waitFor(() => {
924
- // useCan is called with userId, scope, permission, pageId, useCache, appName
925
+ // useCan is called with userId, scope, permission, pageId, useCache, precomputedSuperAdmin, appName
925
926
  // Uses defaultPermission "create" since /dashboard is not in routePermissions
926
927
  expect(mockUseCan).toHaveBeenCalledWith(
927
928
  'user-123',
@@ -933,6 +934,7 @@ describe('PaceAppLayout Component', () => {
933
934
  'create:page.dashboard',
934
935
  'dashboard',
935
936
  true,
937
+ expect.any(Boolean), // precomputedSuperAdmin - can be false, null, or undefined during checks
936
938
  'Test App'
937
939
  );
938
940
  }, { timeout: 2000 });
@@ -947,7 +949,7 @@ describe('PaceAppLayout Component', () => {
947
949
  renderWithProviders(
948
950
  <TestWrapper>
949
951
  <PaceAppLayout
950
- {...defaultProps}
952
+ {...baseProps}
951
953
  enforcePermissions={true}
952
954
  />
953
955
  </TestWrapper>,
@@ -976,7 +978,7 @@ describe('PaceAppLayout Component', () => {
976
978
  renderWithProviders(
977
979
  <TestWrapper>
978
980
  <PaceAppLayout
979
- {...defaultProps}
981
+ {...baseProps}
980
982
  enforcePermissions={true}
981
983
  onPageAccessDenied={onPageAccessDenied}
982
984
  />
@@ -1004,7 +1006,7 @@ describe('PaceAppLayout Component', () => {
1004
1006
  renderWithProviders(
1005
1007
  <TestWrapper>
1006
1008
  <PaceAppLayout
1007
- {...defaultProps}
1009
+ {...baseProps}
1008
1010
  enforcePermissions={true}
1009
1011
  strictMode={true}
1010
1012
  onStrictModeViolation={onStrictModeViolation}
@@ -1036,7 +1038,7 @@ describe('PaceAppLayout Component', () => {
1036
1038
  renderWithProviders(
1037
1039
  <TestWrapper>
1038
1040
  <PaceAppLayout
1039
- {...defaultProps}
1041
+ {...baseProps}
1040
1042
  roleBasedRouting={true}
1041
1043
  routeConfig={routeConfig}
1042
1044
  onRouteAccessDenied={onRouteAccessDenied}
@@ -1065,7 +1067,7 @@ describe('PaceAppLayout Component', () => {
1065
1067
  renderWithProviders(
1066
1068
  <TestWrapper>
1067
1069
  <PaceAppLayout
1068
- {...defaultProps}
1070
+ {...baseProps}
1069
1071
  roleBasedRouting={true}
1070
1072
  routeConfig={routeConfig}
1071
1073
  strictMode={true}
@@ -1107,7 +1109,7 @@ describe('PaceAppLayout Component', () => {
1107
1109
  renderWithProviders(
1108
1110
  <FallbackWrapper>
1109
1111
  <PaceAppLayout
1110
- {...defaultProps}
1112
+ {...baseProps}
1111
1113
  roleBasedRouting={true}
1112
1114
  strictMode={true}
1113
1115
  fallbackRoute="/no-access"
@@ -1151,7 +1153,7 @@ describe('PaceAppLayout Component', () => {
1151
1153
  renderWithProviders(
1152
1154
  <TestWrapper>
1153
1155
  <PaceAppLayout
1154
- {...defaultProps}
1156
+ {...baseProps}
1155
1157
  enforcePermissions={true}
1156
1158
  />
1157
1159
  </TestWrapper>,
@@ -1193,7 +1195,7 @@ describe('PaceAppLayout Component', () => {
1193
1195
  renderWithProviders(
1194
1196
  <TestWrapper>
1195
1197
  <PaceAppLayout
1196
- {...defaultProps}
1198
+ {...baseProps}
1197
1199
  enforcePermissions={true}
1198
1200
  />
1199
1201
  </TestWrapper>,
@@ -1217,7 +1219,7 @@ describe('PaceAppLayout Component', () => {
1217
1219
  it('renders with proper semantic HTML elements', () => {
1218
1220
  renderWithProviders(
1219
1221
  <TestWrapper>
1220
- <PaceAppLayout {...defaultProps} />
1222
+ <PaceAppLayout {...baseProps} />
1221
1223
  </TestWrapper>,
1222
1224
  { withRouter: false }
1223
1225
  );
@@ -1230,7 +1232,7 @@ describe('PaceAppLayout Component', () => {
1230
1232
  it('provides proper main content area', () => {
1231
1233
  renderWithProviders(
1232
1234
  <TestWrapper>
1233
- <PaceAppLayout {...defaultProps} />
1235
+ <PaceAppLayout {...baseProps} />
1234
1236
  </TestWrapper>,
1235
1237
  { withRouter: false }
1236
1238
  );
@@ -1243,7 +1245,7 @@ describe('PaceAppLayout Component', () => {
1243
1245
  it('renders main content area with proper styling', () => {
1244
1246
  renderWithProviders(
1245
1247
  <TestWrapper>
1246
- <PaceAppLayout {...defaultProps} />
1248
+ <PaceAppLayout {...baseProps} />
1247
1249
  </TestWrapper>,
1248
1250
  { withRouter: false }
1249
1251
  );
@@ -1257,7 +1259,7 @@ describe('PaceAppLayout Component', () => {
1257
1259
  it('has accessible navigation', () => {
1258
1260
  renderWithProviders(
1259
1261
  <TestWrapper>
1260
- <PaceAppLayout {...defaultProps} />
1262
+ <PaceAppLayout {...baseProps} />
1261
1263
  </TestWrapper>,
1262
1264
  { withRouter: false }
1263
1265
  );
@@ -1269,7 +1271,7 @@ describe('PaceAppLayout Component', () => {
1269
1271
  it('has accessible user menu', () => {
1270
1272
  renderWithProviders(
1271
1273
  <TestWrapper>
1272
- <PaceAppLayout {...defaultProps} />
1274
+ <PaceAppLayout {...baseProps} />
1273
1275
  </TestWrapper>,
1274
1276
  { withRouter: false }
1275
1277
  );
@@ -1283,7 +1285,7 @@ describe('PaceAppLayout Component', () => {
1283
1285
  it('provides meaningful text for screen readers', () => {
1284
1286
  renderWithProviders(
1285
1287
  <TestWrapper>
1286
- <PaceAppLayout {...defaultProps} />
1288
+ <PaceAppLayout {...baseProps} />
1287
1289
  </TestWrapper>,
1288
1290
  { withRouter: false }
1289
1291
  );
@@ -1298,7 +1300,7 @@ describe('PaceAppLayout Component', () => {
1298
1300
  const user = userEvent.setup();
1299
1301
  renderWithProviders(
1300
1302
  <TestWrapper>
1301
- <PaceAppLayout {...defaultProps} />
1303
+ <PaceAppLayout {...baseProps} />
1302
1304
  </TestWrapper>,
1303
1305
  { withRouter: false }
1304
1306
  );
@@ -1314,7 +1316,7 @@ describe('PaceAppLayout Component', () => {
1314
1316
  it('handles empty navigation items array', () => {
1315
1317
  renderWithProviders(
1316
1318
  <TestWrapper>
1317
- <PaceAppLayout {...defaultProps} navItems={[]} />
1319
+ <PaceAppLayout {...baseProps} navItems={[]} />
1318
1320
  </TestWrapper>,
1319
1321
  { withRouter: false }
1320
1322
  );
@@ -1332,7 +1334,7 @@ describe('PaceAppLayout Component', () => {
1332
1334
  renderWithProviders(
1333
1335
  <TestWrapper>
1334
1336
  <PaceAppLayout
1335
- {...defaultProps}
1337
+ {...baseProps}
1336
1338
  navItems={navItemsWithoutHref}
1337
1339
  enforcePermissions={false}
1338
1340
  />
@@ -1349,7 +1351,7 @@ describe('PaceAppLayout Component', () => {
1349
1351
  // without breaking. We don't enforce permissions to simplify the test.
1350
1352
  const { rerender } = renderWithProviders(
1351
1353
  <TestWrapper>
1352
- <PaceAppLayout {...defaultProps} enforcePermissions={false} />
1354
+ <PaceAppLayout {...baseProps} enforcePermissions={false} />
1353
1355
  </TestWrapper>,
1354
1356
  { withRouter: false }
1355
1357
  );
@@ -1363,7 +1365,7 @@ describe('PaceAppLayout Component', () => {
1363
1365
  mockLocation.pathname = '/settings';
1364
1366
  rerender(
1365
1367
  <TestWrapper>
1366
- <PaceAppLayout {...defaultProps} enforcePermissions={false} />
1368
+ <PaceAppLayout {...baseProps} enforcePermissions={false} />
1367
1369
  </TestWrapper>
1368
1370
  );
1369
1371
 
@@ -86,7 +86,7 @@
86
86
  * - Permission-based route protection
87
87
  *
88
88
  * @dependencies
89
- * - React 18+ - Component framework
89
+ * - React 19+ - Component framework
90
90
  * - React Router v6 - Routing
91
91
  * - UnifiedAuthProvider - Authentication
92
92
  * - usePermissionCache - Permission management
@@ -121,6 +121,10 @@ import type { PasswordChangeFormError } from '../PasswordChange/PasswordChangeFo
121
121
  // Define Operation type locally since old RBAC types are removed
122
122
  type Operation = 'read' | 'create' | 'update' | 'delete' | 'manage';
123
123
 
124
+ /**
125
+ * Props for the PaceAppLayout component.
126
+ * Configures the application layout including navigation, header, and footer.
127
+ */
124
128
  export interface PaceAppLayoutProps {
125
129
  /** The name of the application to be displayed in the header. */
126
130
  appName: string;
@@ -524,12 +528,15 @@ export function PaceAppLayout({
524
528
  // Pass appName to useCan so it can be passed to isPermitted for PORTAL/ADMIN special case
525
529
  // Only check permissions if enforcePermissions is true and we have a valid permission string
526
530
  const shouldCheckPermission = enforcePermissions && !!currentPermission && !!currentPageId;
531
+ // Pass super admin status to avoid duplicate check - use null if still checking, false/true if known
532
+ const superAdminStatus = isSuperAdminFromRBAC ? true : (isCheckingSuperAdminDirect ? null : isSuperAdminDirect);
527
533
  const { can: canFromHook, isLoading: isCheckingPermission, error: permissionError } = useCan(
528
534
  user?.id || '',
529
535
  scope,
530
536
  shouldCheckPermission ? currentPermission : ('' as Permission),
531
537
  shouldCheckPermission ? currentPageId : '',
532
538
  true, // useCache
539
+ superAdminStatus, // Pass super admin status to avoid duplicate check
533
540
  appName // Pass appName for PORTAL/ADMIN special case
534
541
  );
535
542
 
@@ -817,25 +824,39 @@ export function PaceAppLayout({
817
824
  }, [roleBasedRouting, routeConfig, location.pathname, strictMode, user?.id, fallbackRoute, scope, navigate, auditLog, onRouteAccessDenied, onRouteStrictModeViolation]);
818
825
 
819
826
  const handleSignOut = async () => {
820
- await signOut();
827
+ try {
828
+ await signOut();
829
+ } catch (error) {
830
+ logger.error('PaceAppLayout', 'Failed to sign out', { error: error instanceof Error ? error.message : String(error) });
831
+ }
821
832
  };
822
833
 
823
834
  const handleChangePassword = async (newPassword: string, confirmPassword: string) => {
824
- // The form component in UserMenu already checks for matching passwords
825
- const result = await updatePassword(newPassword);
826
- if (result?.error) {
827
- // The form will display the error message
828
- logger.error('PaceAppLayout', 'Failed to change password', { error: result.error.message });
829
- // Convert AuthError to PasswordChangeFormError
835
+ try {
836
+ // The form component in UserMenu already checks for matching passwords
837
+ const result = await updatePassword(newPassword);
838
+ if (result?.error) {
839
+ // The form will display the error message
840
+ logger.error('PaceAppLayout', 'Failed to change password', { error: result.error.message });
841
+ // Convert AuthError to PasswordChangeFormError
842
+ return {
843
+ error: {
844
+ message: result.error.message,
845
+ code: result.error.name || 'PASSWORD_UPDATE_ERROR'
846
+ }
847
+ };
848
+ }
849
+ // The form will handle closing the modal on success
850
+ return {};
851
+ } catch (error) {
852
+ logger.error('PaceAppLayout', 'Failed to change password', { error: error instanceof Error ? error.message : String(error) });
830
853
  return {
831
854
  error: {
832
- message: result.error.message,
833
- code: result.error.name || 'PASSWORD_UPDATE_ERROR'
855
+ message: error instanceof Error ? error.message : 'An unexpected error occurred',
856
+ code: 'PASSWORD_UPDATE_ERROR'
834
857
  }
835
858
  };
836
859
  }
837
- // The form will handle closing the modal on success
838
- return {};
839
860
  };
840
861
 
841
862
  // CRITICAL: Wait for organisation context to be ready before proceeding
@@ -309,7 +309,7 @@ function App() {
309
309
 
310
310
  ## Dependencies
311
311
 
312
- - React 18+
312
+ - React 19+
313
313
  - React Router v6
314
314
  - UnifiedAuthProvider
315
315
  - Header component
@@ -1,3 +1,4 @@
1
+ /// <reference types="vitest/globals" />
1
2
  /**
2
3
  * @file Shared Test Setup for PaceAppLayout Tests
3
4
  * @package @jmruthers/pace-core
@@ -10,8 +11,6 @@
10
11
  * provides the shared mock data and reset functions that can be imported and used
11
12
  * in the vi.mock() factory functions.
12
13
  */
13
-
14
- import { vi } from 'vitest';
15
14
  import React from 'react';
16
15
 
17
16
  // === MOCK DATA ===
@@ -111,7 +111,7 @@
111
111
  * - Automatic redirect prevention loops
112
112
  *
113
113
  * @dependencies
114
- * - React 18+ - Hooks and effects
114
+ * - React 19+ - Hooks and effects
115
115
  * - React Router v6 - Navigation
116
116
  * - UnifiedAuthProvider - Authentication
117
117
  * - LoginForm component
@@ -131,6 +131,9 @@ import { clearPalette } from '../../theming/runtime';
131
131
  import { EventServiceContext } from '../../providers/services/EventServiceProvider';
132
132
  import { logger } from '../../utils/core/logger';
133
133
 
134
+ /**
135
+ * Props for the PaceLoginPage component.
136
+ */
134
137
  export interface PaceLoginPageProps {
135
138
  /** The name of the application to be displayed on the login form. */
136
139
  appName: string;