@jmruthers/pace-core 0.5.181 → 0.5.183

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 (756) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +16 -2
  3. package/dist/{AuthService-DYuQPJj6.d.ts → AuthService-B-cd2MA4.d.ts} +9 -11
  4. package/dist/{DataTable-CWAZZcXC.d.ts → DataTable-Bz8ffqyA.d.ts} +1 -1
  5. package/dist/{DataTable-UA6CL4JI.js → DataTable-QAB34V6K.js} +14 -15
  6. package/dist/UnifiedAuthProvider-7F6T4B6K.js +13 -0
  7. package/dist/{UnifiedAuthProvider-DJxGTftH.d.ts → UnifiedAuthProvider-F86d7dSi.d.ts} +5 -6
  8. package/dist/{api-45XYYO2A.js → api-ROMBCNKU.js} +5 -5
  9. package/dist/{audit-64X3VJXB.js → audit-WRS3KJKI.js} +4 -4
  10. package/dist/auth-BZOJqrdd.d.ts +49 -0
  11. package/dist/{chunk-CX5M4ZAG.js → chunk-5DRSZLL2.js} +1 -1
  12. package/dist/chunk-5DRSZLL2.js.map +1 -0
  13. package/dist/{chunk-BESYRHQM.js → chunk-6C4YBBJM.js} +10 -7
  14. package/dist/chunk-6C4YBBJM.js.map +1 -0
  15. package/dist/{chunk-PLDDJCW6.js → chunk-7D4SUZUM.js} +2 -13
  16. package/dist/{chunk-HRO5HWN2.js → chunk-CSOFYHAG.js} +55 -162
  17. package/dist/chunk-CSOFYHAG.js.map +1 -0
  18. package/dist/{chunk-ANBQRTPX.js → chunk-E66EQZE6.js} +3 -5
  19. package/dist/{chunk-ANBQRTPX.js.map → chunk-E66EQZE6.js.map} +1 -1
  20. package/dist/{chunk-Q5QRDWKI.js → chunk-F2IMUDXZ.js} +4 -6
  21. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  22. package/dist/{chunk-SBVILCCA.js → chunk-FSFQFJCU.js} +28 -6
  23. package/dist/chunk-FSFQFJCU.js.map +1 -0
  24. package/dist/chunk-FUEYYMX5.js +2296 -0
  25. package/dist/chunk-FUEYYMX5.js.map +1 -0
  26. package/dist/{chunk-FFKNH6U5.js → chunk-HKIT6O7W.js} +3 -5
  27. package/dist/{chunk-FFKNH6U5.js.map → chunk-HKIT6O7W.js.map} +1 -1
  28. package/dist/chunk-KQCRWDSA.js +1 -0
  29. package/dist/{chunk-S5OFRT4M.js → chunk-KUEN3HFB.js} +6 -6
  30. package/dist/chunk-KUEN3HFB.js.map +1 -0
  31. package/dist/chunk-LMC26NLJ.js +84 -0
  32. package/dist/chunk-LMC26NLJ.js.map +1 -0
  33. package/dist/{chunk-BVYWGZVV.js → chunk-M7W4CP3M.js} +52 -19
  34. package/dist/chunk-M7W4CP3M.js.map +1 -0
  35. package/dist/{chunk-HZLDFOE4.js → chunk-MI7HBHN3.js} +164 -243
  36. package/dist/chunk-MI7HBHN3.js.map +1 -0
  37. package/dist/{chunk-PPMP5J6T.js → chunk-PWAHJW4G.js} +180 -29
  38. package/dist/chunk-PWAHJW4G.js.map +1 -0
  39. package/dist/chunk-PWLANIRT.js +127 -0
  40. package/dist/{chunk-XDNLUEXI.js.map → chunk-PWLANIRT.js.map} +1 -1
  41. package/dist/chunk-QCDXODCA.js +75 -0
  42. package/dist/chunk-QCDXODCA.js.map +1 -0
  43. package/dist/{chunk-D7LCGMVS.js → chunk-QETLRQI6.js} +526 -887
  44. package/dist/chunk-QETLRQI6.js.map +1 -0
  45. package/dist/{chunk-5MT24GKJ.js → chunk-QUVSNGIP.js} +264 -262
  46. package/dist/chunk-QUVSNGIP.js.map +1 -0
  47. package/dist/chunk-QXHPKYJV.js +113 -0
  48. package/dist/chunk-QXHPKYJV.js.map +1 -0
  49. package/dist/{chunk-OWAG3GSU.js → chunk-R77UEZ4E.js} +11 -1
  50. package/dist/chunk-R77UEZ4E.js.map +1 -0
  51. package/dist/{chunk-ZYTYSTO5.js → chunk-RA3JUFMW.js} +314 -161
  52. package/dist/chunk-RA3JUFMW.js.map +1 -0
  53. package/dist/{chunk-ERISIBYU.js → chunk-SQGMNID3.js} +3 -8
  54. package/dist/chunk-SQGMNID3.js.map +1 -0
  55. package/dist/{chunk-XJ2HZOBU.js → chunk-UHNYIBXL.js} +1 -1
  56. package/dist/chunk-UHNYIBXL.js.map +1 -0
  57. package/{src/utils/secureStorage.ts → dist/chunk-VBXEHIUJ.js} +113 -88
  58. package/dist/{chunk-7QCC6MCP.js.map → chunk-VBXEHIUJ.js.map} +1 -1
  59. package/dist/{chunk-VZ4VDGTB.js → chunk-W22JP75J.js} +5 -13
  60. package/dist/{chunk-VZ4VDGTB.js.map → chunk-W22JP75J.js.map} +1 -1
  61. package/dist/components.d.ts +12 -93
  62. package/dist/components.js +23 -106
  63. package/dist/components.js.map +1 -1
  64. package/dist/core-CUElvH_C.d.ts +164 -0
  65. package/dist/database.generated-CBmg2950.d.ts +8284 -0
  66. package/dist/event-CW5YB_2p.d.ts +239 -0
  67. package/dist/{file-reference-C6Gkn77H.d.ts → file-reference-D06mEEWW.d.ts} +7 -5
  68. package/dist/functions-D_kgHktt.d.ts +208 -0
  69. package/dist/hooks.d.ts +54 -7
  70. package/dist/hooks.js +204 -17
  71. package/dist/hooks.js.map +1 -1
  72. package/dist/{EventLogo-B3V3otev.d.ts → index-Bl--n7-T.d.ts} +387 -397
  73. package/dist/index.d.ts +94 -261
  74. package/dist/index.js +314 -126
  75. package/dist/index.js.map +1 -1
  76. package/dist/providers.d.ts +7 -8
  77. package/dist/providers.js +6 -13
  78. package/dist/rbac/index.d.ts +171 -101
  79. package/dist/rbac/index.js +23 -17
  80. package/dist/styles/index.d.ts +1 -3
  81. package/dist/styles/index.js +2 -17
  82. package/dist/theming/runtime.js +3 -3
  83. package/dist/types-UU913iLA.d.ts +102 -0
  84. package/dist/{types-Dfz9dmVH.d.ts → types-_x1f4QBF.d.ts} +6 -6
  85. package/dist/types.d.ts +88 -227
  86. package/dist/types.js +64 -112
  87. package/dist/types.js.map +1 -1
  88. package/dist/{usePublicRouteParams-B7PabvuH.d.ts → usePublicRouteParams-JJczomYq.d.ts} +203 -6
  89. package/dist/utils.d.ts +299 -13
  90. package/dist/utils.js +481 -55
  91. package/dist/utils.js.map +1 -1
  92. package/dist/validation-643vUDZW.d.ts +177 -0
  93. package/docs/DOCUMENTATION_REVIEW_TRACKER.md +511 -0
  94. package/docs/README.md +9 -8
  95. package/docs/api/README.md +16 -2
  96. package/docs/api/classes/ColumnFactory.md +1 -1
  97. package/docs/api/classes/ErrorBoundary.md +1 -1
  98. package/docs/api/classes/InvalidScopeError.md +4 -4
  99. package/docs/api/classes/MissingUserContextError.md +4 -4
  100. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  101. package/docs/api/classes/PermissionDeniedError.md +4 -4
  102. package/docs/api/classes/RBACAuditManager.md +14 -14
  103. package/docs/api/classes/RBACCache.md +1 -1
  104. package/docs/api/classes/RBACEngine.md +2 -2
  105. package/docs/api/classes/RBACError.md +4 -4
  106. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  107. package/docs/api/classes/SecureSupabaseClient.md +29 -9
  108. package/docs/api/classes/StorageUtils.md +1 -1
  109. package/docs/api/enums/FileCategory.md +17 -17
  110. package/docs/api/enums/RBACErrorCode.md +228 -0
  111. package/docs/api/enums/RPCFunction.md +118 -0
  112. package/docs/api/interfaces/AggregateConfig.md +1 -1
  113. package/docs/api/interfaces/BadgeProps.md +1 -1
  114. package/docs/api/interfaces/ButtonProps.md +2 -2
  115. package/docs/api/interfaces/CalendarProps.md +1 -1
  116. package/docs/api/interfaces/CardProps.md +29 -3
  117. package/docs/api/interfaces/ColorPalette.md +1 -1
  118. package/docs/api/interfaces/ColorShade.md +1 -1
  119. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  120. package/docs/api/interfaces/DataRecord.md +1 -1
  121. package/docs/api/interfaces/DataTableAction.md +2 -2
  122. package/docs/api/interfaces/DataTableColumn.md +6 -6
  123. package/docs/api/interfaces/DataTableProps.md +1 -1
  124. package/docs/api/interfaces/DataTableToolbarButton.md +2 -2
  125. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  126. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  127. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  128. package/docs/api/interfaces/ExportColumn.md +5 -5
  129. package/docs/api/interfaces/ExportOptions.md +4 -4
  130. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  131. package/docs/api/interfaces/FileMetadata.md +13 -13
  132. package/docs/api/interfaces/FileReference.md +12 -12
  133. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  134. package/docs/api/interfaces/FileUploadOptions.md +10 -10
  135. package/docs/api/interfaces/FileUploadProps.md +19 -19
  136. package/docs/api/interfaces/FooterProps.md +1 -1
  137. package/docs/api/interfaces/FormFieldProps.md +166 -0
  138. package/docs/api/interfaces/FormProps.md +113 -0
  139. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  140. package/docs/api/interfaces/InactivityWarningModalProps.md +8 -8
  141. package/docs/api/interfaces/InputProps.md +2 -2
  142. package/docs/api/interfaces/LabelProps.md +8 -8
  143. package/docs/api/interfaces/LoginFormProps.md +1 -1
  144. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  145. package/docs/api/interfaces/NavigationContextType.md +1 -1
  146. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  147. package/docs/api/interfaces/NavigationItem.md +17 -73
  148. package/docs/api/interfaces/NavigationMenuProps.md +38 -53
  149. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  150. package/docs/api/interfaces/Organisation.md +13 -13
  151. package/docs/api/interfaces/OrganisationContextType.md +21 -21
  152. package/docs/api/interfaces/OrganisationMembership.md +15 -15
  153. package/docs/api/interfaces/OrganisationProviderProps.md +59 -2
  154. package/docs/api/interfaces/OrganisationSecurityError.md +5 -5
  155. package/docs/api/interfaces/PaceAppLayoutProps.md +26 -39
  156. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  157. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  158. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  159. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  160. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  161. package/docs/api/interfaces/PaletteData.md +1 -1
  162. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  163. package/docs/api/interfaces/ProgressProps.md +50 -0
  164. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  165. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  166. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  167. package/docs/api/interfaces/PublicPageLayoutProps.md +15 -15
  168. package/docs/api/interfaces/RBACAccessValidateParams.md +52 -0
  169. package/docs/api/interfaces/RBACAccessValidateResult.md +41 -0
  170. package/docs/api/interfaces/RBACAuditLogParams.md +85 -0
  171. package/docs/api/interfaces/RBACAuditLogResult.md +52 -0
  172. package/docs/api/interfaces/RBACConfig.md +2 -2
  173. package/docs/api/interfaces/RBACContext.md +52 -0
  174. package/docs/api/interfaces/RBACLogger.md +1 -1
  175. package/docs/api/interfaces/RBACPageAccessCheckParams.md +74 -0
  176. package/docs/api/interfaces/RBACPermissionCheckParams.md +74 -0
  177. package/docs/api/interfaces/RBACPermissionCheckResult.md +52 -0
  178. package/docs/api/interfaces/RBACPermissionsGetParams.md +63 -0
  179. package/docs/api/interfaces/RBACPermissionsGetResult.md +63 -0
  180. package/docs/api/interfaces/RBACResult.md +58 -0
  181. package/docs/api/interfaces/RBACRoleGrantParams.md +63 -0
  182. package/docs/api/interfaces/RBACRoleGrantResult.md +52 -0
  183. package/docs/api/interfaces/RBACRoleRevokeParams.md +63 -0
  184. package/docs/api/interfaces/RBACRoleRevokeResult.md +52 -0
  185. package/docs/api/interfaces/RBACRoleValidateParams.md +52 -0
  186. package/docs/api/interfaces/RBACRoleValidateResult.md +63 -0
  187. package/docs/api/interfaces/RBACRolesListParams.md +52 -0
  188. package/docs/api/interfaces/RBACRolesListResult.md +74 -0
  189. package/docs/api/interfaces/RBACSessionTrackParams.md +74 -0
  190. package/docs/api/interfaces/RBACSessionTrackResult.md +52 -0
  191. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  192. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  193. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  194. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  195. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  196. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  197. package/docs/api/interfaces/RouteConfig.md +1 -1
  198. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  199. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  200. package/docs/api/interfaces/SessionRestorationLoaderProps.md +15 -2
  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 +43 -2
  215. package/docs/api/interfaces/TextareaProps.md +2 -2
  216. package/docs/api/interfaces/ToastActionElement.md +1 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +61 -61
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  220. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  221. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  222. package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
  223. package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
  224. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  225. package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
  226. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  227. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  228. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  229. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  230. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  231. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  232. package/docs/api/interfaces/UserEventAccess.md +1 -1
  233. package/docs/api/interfaces/UserMenuProps.md +4 -4
  234. package/docs/api/interfaces/UserProfile.md +7 -7
  235. package/docs/api/modules.md +484 -462
  236. package/docs/api-reference/components.md +186 -15
  237. package/docs/api-reference/deprecated.md +376 -0
  238. package/docs/api-reference/hooks.md +149 -19
  239. package/docs/api-reference/providers.md +61 -6
  240. package/docs/api-reference/rpc-functions.md +397 -0
  241. package/docs/api-reference/types.md +135 -78
  242. package/docs/api-reference/utilities.md +51 -380
  243. package/docs/architecture/README.md +49 -3
  244. package/docs/architecture/database-schema-requirements.md +40 -3
  245. package/docs/architecture/rbac-security-architecture.md +41 -4
  246. package/docs/architecture/services.md +127 -42
  247. package/docs/best-practices/README.md +51 -5
  248. package/docs/best-practices/accessibility.md +32 -3
  249. package/docs/best-practices/common-patterns.md +50 -3
  250. package/docs/best-practices/deployment.md +50 -4
  251. package/docs/best-practices/performance.md +50 -3
  252. package/docs/best-practices/security.md +94 -41
  253. package/docs/best-practices/testing.md +33 -4
  254. package/docs/core-concepts/authentication.md +5 -5
  255. package/docs/core-concepts/events.md +3 -3
  256. package/docs/core-concepts/organisations.md +3 -3
  257. package/docs/core-concepts/permissions.md +3 -3
  258. package/docs/core-concepts/rbac-system.md +5 -5
  259. package/docs/documentation-index.md +30 -8
  260. package/docs/getting-started/documentation-index.md +1 -1
  261. package/docs/getting-started/examples/README.md +7 -5
  262. package/docs/getting-started/examples/basic-auth-app.md +3 -0
  263. package/docs/getting-started/examples/full-featured-app.md +5 -3
  264. package/docs/getting-started/faq.md +6 -6
  265. package/docs/getting-started/installation-guide.md +192 -13
  266. package/docs/getting-started/local-development.md +303 -0
  267. package/docs/getting-started/quick-reference.md +3 -3
  268. package/docs/getting-started/quick-start.md +517 -0
  269. package/docs/implementation-guides/app-layout.md +45 -3
  270. package/docs/implementation-guides/authentication.md +66 -7
  271. package/docs/implementation-guides/component-styling.md +53 -3
  272. package/docs/implementation-guides/data-tables.md +76 -7
  273. package/docs/implementation-guides/datatable-filtering.md +1 -2
  274. package/docs/implementation-guides/datatable-rbac-usage.md +0 -1
  275. package/docs/implementation-guides/dynamic-colors.md +155 -4
  276. package/docs/implementation-guides/file-reference-system.md +72 -3
  277. package/docs/implementation-guides/file-upload-storage.md +72 -3
  278. package/docs/implementation-guides/forms.md +53 -3
  279. package/docs/implementation-guides/inactivity-tracking.md +53 -3
  280. package/docs/implementation-guides/large-datasets.md +1 -1
  281. package/docs/implementation-guides/navigation.md +55 -5
  282. package/docs/implementation-guides/organisation-security.md +72 -3
  283. package/docs/implementation-guides/performance.md +57 -1
  284. package/docs/implementation-guides/permission-enforcement.md +81 -8
  285. package/docs/implementation-guides/public-pages.md +560 -14
  286. package/docs/migration/MIGRATION_GUIDE.md +409 -50
  287. package/docs/migration/README.md +37 -3
  288. package/docs/migration/organisation-context-timing-fix.md +39 -4
  289. package/docs/migration/quick-migration-guide.md +41 -5
  290. package/docs/migration/rbac-migration.md +59 -3
  291. package/docs/migration/service-architecture.md +77 -14
  292. package/docs/rbac/README.md +79 -3
  293. package/docs/rbac/advanced-patterns.md +47 -3
  294. package/docs/rbac/api-reference.md +77 -8
  295. package/docs/rbac/event-based-apps.md +50 -5
  296. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  297. package/docs/rbac/examples.md +39 -3
  298. package/docs/rbac/getting-started.md +63 -4
  299. package/docs/rbac/quick-start.md +57 -5
  300. package/docs/rbac/rbac-rls-integration.md +68 -6
  301. package/docs/rbac/super-admin-guide.md +47 -3
  302. package/docs/rbac/troubleshooting.md +3 -3
  303. package/docs/security/README.md +68 -3
  304. package/docs/security/checklist.md +50 -3
  305. package/docs/standards/01-architecture-standard.md +39 -0
  306. package/docs/standards/02-api-and-rpc-standard.md +39 -0
  307. package/docs/standards/03-component-standard.md +32 -0
  308. package/docs/standards/04-code-style-standard.md +32 -0
  309. package/docs/standards/05-security-standard.md +30 -0
  310. package/docs/standards/06-testing-and-docs-standard.md +29 -0
  311. package/docs/standards/README.md +35 -0
  312. package/docs/styles/README.md +89 -8
  313. package/docs/testing/README.md +175 -24
  314. package/docs/troubleshooting/README.md +50 -3
  315. package/docs/troubleshooting/common-issues.md +271 -5
  316. package/docs/troubleshooting/debugging.md +54 -1
  317. package/docs/troubleshooting/migration.md +54 -1
  318. package/docs/troubleshooting/organisation-context-setup.md +29 -3
  319. package/docs/troubleshooting/styling-issues.md +246 -4
  320. package/{src/components/DataTable/examples → examples/DataTable}/GroupingAggregationExample.tsx +1 -1
  321. package/examples/{components 2/DataTable/HierarchicalActionsExample.tsx → DataTable/HierarchicalActionsExample.tsx} +7 -6
  322. package/{src/components/DataTable/examples → examples/DataTable}/HierarchicalExample.tsx +8 -6
  323. package/examples/{components 2/DataTable/PerformanceExample.tsx → DataTable/PerformanceExample.tsx} +2 -2
  324. package/examples/{components 2/DataTable/index.ts → DataTable/index.ts} +1 -0
  325. package/{src/components/Dialog/examples → examples/Dialog}/HtmlDialogExample.tsx +3 -3
  326. package/examples/{components 2/Dialog/ScrollableDialogExample.tsx → Dialog/ScrollableDialogExample.tsx} +1 -1
  327. package/{src/components/Dialog/examples → examples/Dialog}/SmartDialogExample.tsx +1 -1
  328. package/examples/{components 2/Dialog/index.ts → Dialog/index.ts} +0 -3
  329. package/examples/{features/public-pages → PublicPages}/CorrectPublicPageImplementation.tsx +52 -17
  330. package/examples/{features/public-pages → PublicPages}/PublicEventPage.tsx +65 -35
  331. package/examples/{features/public-pages → PublicPages}/PublicPageApp.tsx +52 -18
  332. package/examples/{features/public-pages → PublicPages}/PublicPageUsageExample.tsx +28 -15
  333. package/examples/README.md +81 -33
  334. package/examples/index.ts +14 -12
  335. package/examples/{RBAC → rbac}/CompleteRBACExample.tsx +1 -1
  336. package/examples/{features/rbac → rbac}/EventBasedApp.tsx +4 -4
  337. package/examples/{features/rbac → rbac}/PermissionExample.tsx +5 -3
  338. package/package.json +21 -27
  339. package/src/__tests__/helpers/test-utils.tsx +29 -3
  340. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +7 -5
  341. package/src/components/Alert/Alert.test.tsx +2 -2
  342. package/src/components/Alert/Alert.tsx +4 -4
  343. package/src/components/Avatar/Avatar.test.tsx +17 -6
  344. package/src/components/Badge/Badge.test.tsx +1 -1
  345. package/src/components/Badge/Badge.tsx +2 -2
  346. package/src/components/Button/Button.test.tsx +2 -2
  347. package/src/components/Button/Button.tsx +11 -7
  348. package/src/components/Calendar/Calendar.test.tsx +41 -8
  349. package/src/components/Calendar/Calendar.tsx +39 -36
  350. package/src/components/Card/Card.tsx +51 -13
  351. package/src/components/Checkbox/Checkbox.test.tsx +36 -12
  352. package/src/components/DataTable/DataTable.test.tsx +1 -1
  353. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +13 -7
  354. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +14 -42
  355. package/src/components/DataTable/__tests__/DataTable.export.test.tsx +13 -10
  356. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +14 -11
  357. package/src/components/DataTable/__tests__/DataTable.hooks.test.tsx +4 -2
  358. package/src/components/DataTable/__tests__/DataTable.test.tsx +13 -7
  359. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +13 -10
  360. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +15 -11
  361. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +12 -6
  362. package/src/components/DataTable/__tests__/keyboard.test.tsx +12 -6
  363. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +10 -6
  364. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +1 -1
  365. package/src/components/DataTable/components/DataTableBody.tsx +10 -25
  366. package/src/components/DataTable/components/DataTableCore.tsx +1 -1
  367. package/src/components/DataTable/components/FilterRow.tsx +3 -1
  368. package/src/components/DataTable/components/ImportModal.tsx +1 -1
  369. package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -9
  370. package/src/components/DataTable/core/ColumnFactory.ts +6 -6
  371. package/src/components/DataTable/core/DataTableContext.tsx +14 -10
  372. package/src/components/DataTable/core/LocalDataAdapter.ts +2 -1
  373. package/src/components/DataTable/core/PluginRegistry.ts +3 -3
  374. package/src/components/DataTable/core/StateManager.ts +12 -11
  375. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +104 -0
  376. package/src/components/DataTable/core/__tests__/DataManager.test.ts +101 -0
  377. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +84 -0
  378. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +102 -0
  379. package/src/components/DataTable/core/__tests__/StateManager.test.ts +104 -0
  380. package/src/components/DataTable/core/interfaces.ts +17 -17
  381. package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +124 -0
  382. package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +117 -0
  383. package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +102 -0
  384. package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +53 -0
  385. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +0 -2
  386. package/src/components/DataTable/hooks/useDataTablePermissions.ts +9 -8
  387. package/src/components/DataTable/types.ts +5 -5
  388. package/src/components/DataTable/utils/aggregationUtils.ts +4 -4
  389. package/src/components/DataTable/utils/columnUtils.ts +3 -2
  390. package/src/components/DataTable/utils/debugTools.ts +1 -1
  391. package/src/components/DataTable/utils/exportUtils.ts +6 -6
  392. package/src/components/DataTable/utils/hierarchicalSorting.ts +6 -6
  393. package/src/components/DataTable/utils/hierarchicalUtils.ts +0 -8
  394. package/src/components/DataTable/utils/index.ts +0 -1
  395. package/src/components/DataTable/utils/performanceUtils.ts +9 -4
  396. package/src/components/Dialog/Dialog.test.tsx +49 -27
  397. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +13 -8
  398. package/src/components/EventSelector/EventSelector.test.tsx +60 -12
  399. package/src/components/EventSelector/EventSelector.tsx +38 -15
  400. package/src/components/EventSelector/index.ts +2 -2
  401. package/src/components/FileDisplay/FileDisplay.test.tsx +143 -85
  402. package/src/components/FileDisplay/FileDisplay.tsx +1 -0
  403. package/src/components/FileUpload/FileUpload.test.tsx +532 -152
  404. package/src/components/FileUpload/FileUpload.tsx +43 -8
  405. package/src/components/Footer/Footer.test.tsx +19 -14
  406. package/src/components/Form/Form.test.tsx +96 -14
  407. package/src/components/Form/Form.tsx +210 -1
  408. package/src/components/Form/index.ts +3 -7
  409. package/src/components/Header/Header.test.tsx +24 -17
  410. package/src/components/Header/Header.tsx +3 -1
  411. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -4
  412. package/src/components/Input/Input.test.tsx +61 -36
  413. package/src/components/Label/{__tests__/Label.test.tsx → Label.test.tsx} +2 -2
  414. package/src/components/Label/Label.tsx +2 -3
  415. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +6 -5
  416. package/src/components/LoadingSpinner/LoadingSpinner.tsx +6 -2
  417. package/src/components/LoginForm/LoginForm.test.tsx +14 -13
  418. package/src/components/LoginForm/LoginForm.tsx +1 -1
  419. package/src/components/LoginForm/index.ts +7 -0
  420. package/src/components/NavigationMenu/NavigationMenu.test.tsx +233 -20
  421. package/src/components/NavigationMenu/NavigationMenu.tsx +191 -55
  422. package/src/components/NavigationMenu/index.ts +1 -1
  423. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +20 -11
  424. package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
  425. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.integration.test.tsx → PaceAppLayout.integration.test.tsx} +272 -79
  426. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.performance.test.tsx → PaceAppLayout.performance.test.tsx} +155 -32
  427. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.security.test.tsx → PaceAppLayout.security.test.tsx} +211 -65
  428. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +498 -210
  429. package/src/components/PaceAppLayout/PaceAppLayout.tsx +63 -64
  430. package/src/components/PaceAppLayout/test-setup.tsx +192 -0
  431. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +193 -39
  432. package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.test.tsx +2 -2
  433. package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.tsx +10 -4
  434. package/src/components/PasswordChange/index.ts +2 -0
  435. package/src/components/Progress/Progress.test.tsx +11 -0
  436. package/src/components/Progress/Progress.tsx +1 -1
  437. package/src/components/Progress/index.ts +10 -0
  438. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +2 -1
  439. package/src/components/PublicLayout/PublicLayout.test.tsx +1210 -0
  440. package/src/components/PublicLayout/PublicPageLayout.tsx +190 -36
  441. package/src/components/PublicLayout/PublicPageProvider.tsx +8 -7
  442. package/src/components/PublicLayout/index.ts +10 -28
  443. package/src/components/Select/Select.test.tsx +7 -7
  444. package/src/components/Select/Select.tsx +277 -11
  445. package/src/components/Select/index.ts +1 -2
  446. package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +232 -0
  447. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +40 -19
  448. package/src/components/Table/{__tests__/Table.test.tsx → Table.test.tsx} +94 -41
  449. package/src/components/Tabs/Tabs.test.tsx +10 -9
  450. package/src/components/Tabs/Tabs.tsx +61 -33
  451. package/src/components/Textarea/Textarea.test.tsx +31 -18
  452. package/src/components/Toast/Toast.tsx +2 -2
  453. package/src/components/Tooltip/Tooltip.test.tsx +1 -1
  454. package/src/components/UserMenu/UserMenu.test.tsx +7 -6
  455. package/src/components/UserMenu/UserMenu.tsx +2 -2
  456. package/src/components/index.ts +5 -4
  457. package/src/constants/performance.ts +19 -8
  458. package/src/hooks/__tests__/useAppConfig.unit.test.ts +21 -22
  459. package/src/hooks/__tests__/useEvents.unit.test.ts +5 -4
  460. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
  461. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -0
  462. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +16 -11
  463. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -3
  464. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +1 -3
  465. package/src/hooks/__tests__/useRBAC.unit.test.ts +24 -2
  466. package/src/hooks/index.ts +4 -0
  467. package/src/hooks/public/index.ts +2 -0
  468. package/src/hooks/public/usePublicEvent.ts +4 -6
  469. package/src/hooks/public/usePublicEventLogo.test.ts +147 -0
  470. package/src/hooks/public/usePublicRouteParams.ts +1 -1
  471. package/src/hooks/services/useAuth.ts +2 -4
  472. package/src/hooks/services/useCurrentEvent.ts +1 -1
  473. package/src/hooks/useAppConfig.ts +1 -1
  474. package/src/hooks/useDataTablePerformance.ts +2 -2
  475. package/src/hooks/useEventTheme.ts +1 -1
  476. package/src/hooks/useEvents.ts +51 -10
  477. package/src/hooks/useOrganisationPermissions.test.ts +3 -3
  478. package/src/hooks/useOrganisationPermissions.ts +1 -1
  479. package/src/hooks/useOrganisationSecurity.ts +2 -2
  480. package/src/hooks/usePermissionCache.test.ts +9 -9
  481. package/src/hooks/usePermissionCache.ts +2 -2
  482. package/src/index.ts +19 -12
  483. package/src/providers/OrganisationProvider.tsx +73 -9
  484. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +113 -13
  485. package/src/providers/__tests__/AuthProvider.test.tsx +2 -1
  486. package/src/providers/__tests__/EventProvider.test.tsx +24 -15
  487. package/src/providers/__tests__/OrganisationProvider.test.tsx +87 -36
  488. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +80 -24
  489. package/src/providers/index.ts +0 -3
  490. package/src/providers/services/AuthServiceProvider.tsx +2 -17
  491. package/src/providers/services/EventServiceProvider.tsx +11 -16
  492. package/src/providers/services/InactivityServiceProvider.tsx +9 -12
  493. package/src/providers/services/OrganisationServiceProvider.tsx +9 -12
  494. package/src/providers/services/UnifiedAuthProvider.tsx +85 -18
  495. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +11 -4
  496. package/src/rbac/__tests__/scenarios.user-role.test.tsx +105 -21
  497. package/src/rbac/adapters.tsx +1 -1
  498. package/src/rbac/api.ts +20 -4
  499. package/src/rbac/audit-enhanced.ts +47 -2
  500. package/src/rbac/audit.ts +47 -2
  501. package/src/rbac/components/NavigationGuard.tsx +1 -1
  502. package/src/rbac/components/NavigationProvider.test.tsx +7 -6
  503. package/src/rbac/components/NavigationProvider.tsx +1 -1
  504. package/src/rbac/components/PagePermissionGuard.tsx +1 -1
  505. package/src/rbac/components/PagePermissionProvider.test.tsx +7 -6
  506. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  507. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  508. package/src/rbac/components/RoleBasedRouter.tsx +1 -1
  509. package/src/rbac/components/SecureDataProvider.test.tsx +7 -6
  510. package/src/rbac/components/SecureDataProvider.tsx +1 -1
  511. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +6 -6
  512. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +11 -10
  513. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +10 -11
  514. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +19 -15
  515. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +13 -12
  516. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +19 -15
  517. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +18 -18
  518. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +11 -10
  519. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +8 -7
  520. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +10 -11
  521. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +48 -19
  522. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +476 -0
  523. package/src/rbac/hooks/index.ts +3 -0
  524. package/src/rbac/hooks/usePermissions.ts +31 -85
  525. package/src/rbac/hooks/useRBAC.test.ts +13 -1
  526. package/src/rbac/hooks/useRBAC.ts +13 -67
  527. package/src/rbac/hooks/useResolvedScope.ts +11 -0
  528. package/src/rbac/hooks/useSecureSupabase.ts +308 -0
  529. package/src/rbac/index.ts +3 -0
  530. package/src/rbac/secureClient.ts +53 -6
  531. package/src/rbac/security.ts +37 -1
  532. package/src/{types/rbac-functions.ts → rbac/types/functions.ts} +30 -30
  533. package/src/rbac/types.ts +3 -2
  534. package/src/services/AuthService.ts +33 -25
  535. package/src/services/EventService.ts +56 -44
  536. package/src/services/InactivityService.ts +33 -53
  537. package/src/services/OrganisationService.ts +36 -40
  538. package/src/services/__tests__/AuthService.restoreSession.test.ts +6 -2
  539. package/src/services/__tests__/EventService.test.ts +67 -33
  540. package/src/services/interfaces/IEventService.ts +1 -1
  541. package/src/styles/core.css +2 -2
  542. package/src/styles/index.test.ts +21 -0
  543. package/src/styles/index.ts +1 -5
  544. package/src/types/__tests__/guards.test.ts +1 -1
  545. package/src/types/__tests__/organisation.roles.test.ts +55 -0
  546. package/src/types/__tests__/type-validation.test.ts +0 -1
  547. package/src/types/auth.ts +42 -2
  548. package/src/types/core.ts +251 -0
  549. package/src/types/database.ts +11 -496
  550. package/src/types/event.ts +102 -0
  551. package/src/types/file-reference.ts +6 -4
  552. package/src/types/guards.ts +2 -1
  553. package/src/types/index.ts +48 -14
  554. package/src/types/lodash.debounce.d.ts +15 -0
  555. package/src/types/organisation.ts +14 -10
  556. package/src/types/supabase.ts +15 -17
  557. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -1
  558. package/src/utils/__tests__/validationUtils.unit.test.ts +0 -29
  559. package/src/utils/app/appNameResolver.ts +1 -1
  560. package/src/utils/audit/audit.test.ts +65 -0
  561. package/src/utils/device/deviceFingerprint.test.ts +171 -0
  562. package/src/utils/dynamic/dynamicUtils.ts +3 -2
  563. package/src/utils/file-reference/index.ts +25 -6
  564. package/src/utils/security/secureErrors.ts +1 -1
  565. package/src/utils/validation/__tests__/validationUtils.test.ts +72 -0
  566. package/src/utils/validation/index.ts +6 -12
  567. package/src/utils/validation/validationUtils.ts +0 -13
  568. package/dist/UnifiedAuthProvider-B37ATQHE.js +0 -16
  569. package/dist/auth-DReDSLq9.d.ts +0 -16
  570. package/dist/chunk-3JI76CYK.js +0 -2444
  571. package/dist/chunk-3JI76CYK.js.map +0 -1
  572. package/dist/chunk-56XJ3TU6.js +0 -11
  573. package/dist/chunk-56XJ3TU6.js.map +0 -1
  574. package/dist/chunk-5MT24GKJ.js.map +0 -1
  575. package/dist/chunk-7QCC6MCP.js +0 -288
  576. package/dist/chunk-BESYRHQM.js.map +0 -1
  577. package/dist/chunk-BJPBT3CU.js +0 -21
  578. package/dist/chunk-BJPBT3CU.js.map +0 -1
  579. package/dist/chunk-BVYWGZVV.js.map +0 -1
  580. package/dist/chunk-CX5M4ZAG.js.map +0 -1
  581. package/dist/chunk-D7LCGMVS.js.map +0 -1
  582. package/dist/chunk-EGI6MUL6.js +0 -27
  583. package/dist/chunk-EGI6MUL6.js.map +0 -1
  584. package/dist/chunk-ERISIBYU.js.map +0 -1
  585. package/dist/chunk-HRO5HWN2.js.map +0 -1
  586. package/dist/chunk-HZLDFOE4.js.map +0 -1
  587. package/dist/chunk-JISYG63F.js +0 -70
  588. package/dist/chunk-JISYG63F.js.map +0 -1
  589. package/dist/chunk-LIMSTKYD.js +0 -61
  590. package/dist/chunk-LIMSTKYD.js.map +0 -1
  591. package/dist/chunk-OWAG3GSU.js.map +0 -1
  592. package/dist/chunk-PPMP5J6T.js.map +0 -1
  593. package/dist/chunk-Q5QRDWKI.js.map +0 -1
  594. package/dist/chunk-S5OFRT4M.js.map +0 -1
  595. package/dist/chunk-SBVILCCA.js.map +0 -1
  596. package/dist/chunk-TUMEWN34.js +0 -15
  597. package/dist/chunk-TUMEWN34.js.map +0 -1
  598. package/dist/chunk-XDNLUEXI.js +0 -138
  599. package/dist/chunk-XJ2HZOBU.js.map +0 -1
  600. package/dist/chunk-ZYTYSTO5.js.map +0 -1
  601. package/dist/chunk-ZZ2SS7NI.js +0 -237
  602. package/dist/chunk-ZZ2SS7NI.js.map +0 -1
  603. package/dist/database-C6jy7EOu.d.ts +0 -500
  604. package/dist/organisation-D6qRDtbF.d.ts +0 -93
  605. package/dist/schema-DTDZQe2u.d.ts +0 -28
  606. package/dist/unified-DQ4VcT7H.d.ts +0 -198
  607. package/dist/useInactivityTracker-TO6ZOF35.js +0 -11
  608. package/dist/validation.d.ts +0 -47
  609. package/dist/validation.js +0 -24
  610. package/dist/validation.js.map +0 -1
  611. package/docs/DOCUMENTATION_AUDIT.md +0 -172
  612. package/docs/DOCUMENTATION_STANDARD.md +0 -137
  613. package/docs/api/classes/PublicErrorBoundary.md +0 -132
  614. package/docs/api/interfaces/EventLogoProps.md +0 -152
  615. package/docs/api/interfaces/PublicErrorBoundaryProps.md +0 -94
  616. package/docs/api/interfaces/PublicErrorBoundaryState.md +0 -68
  617. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +0 -86
  618. package/docs/architecture/rpc-function-standards.md +0 -1106
  619. package/docs/getting-started/consuming-app-vite-config.md +0 -239
  620. package/docs/implementation-guides/event-theming-summary.md +0 -226
  621. package/docs/implementation-guides/public-pages-advanced.md +0 -1038
  622. package/docs/migration/v0.4.15-tailwind-scanning.md +0 -278
  623. package/docs/migration/v0.4.16-css-first-approach.md +0 -312
  624. package/docs/migration/v0.4.17-source-path-fix.md +0 -235
  625. package/docs/rbac/RBAC_EVENT_CONTEXT_LOADING.md +0 -222
  626. package/docs/rbac/RBAC_LOGIN_SAFETY_FIX.md +0 -95
  627. package/docs/rbac/RBAC_V0.5.147_FIX.md +0 -117
  628. package/docs/rbac/README-rbac-rls-integration.md +0 -374
  629. package/docs/styles/usage.md +0 -227
  630. package/docs/testing/visual-testing.md +0 -120
  631. package/docs/troubleshooting/DEBUG_NETWORK_ERROR.md +0 -152
  632. package/docs/troubleshooting/FIX_SUPABASE_CORS.md +0 -184
  633. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +0 -193
  634. package/docs/troubleshooting/database-view-compatibility.md +0 -125
  635. package/docs/troubleshooting/react-hooks-issue-analysis.md +0 -172
  636. package/docs/troubleshooting/tailwind-content-scanning.md +0 -219
  637. package/examples/RBAC/EventBasedApp.tsx +0 -239
  638. package/examples/RBAC/PermissionExample.tsx +0 -151
  639. package/examples/STRUCTURE.md +0 -125
  640. package/examples/components 2/DataTable/HierarchicalExample.tsx +0 -475
  641. package/examples/components 2/Dialog/BasicHtmlTest.tsx +0 -55
  642. package/examples/components 2/Dialog/DebugHtmlExample.tsx +0 -68
  643. package/examples/components 2/Dialog/HtmlDialogExample.tsx +0 -202
  644. package/examples/components 2/Dialog/SimpleHtmlTest.tsx +0 -61
  645. package/examples/components 2/Dialog/SmartDialogExample.tsx +0 -322
  646. package/examples/components 2/index.ts +0 -11
  647. package/examples/features/index.ts +0 -12
  648. package/examples/features/rbac/CompleteRBACExample.tsx +0 -324
  649. package/examples/features/rbac/index.ts +0 -13
  650. package/examples/public-pages/CorrectPublicPageImplementation.tsx +0 -301
  651. package/examples/public-pages/PublicEventPage.tsx +0 -274
  652. package/examples/public-pages/PublicPageApp.tsx +0 -308
  653. package/examples/public-pages/PublicPageUsageExample.tsx +0 -216
  654. package/examples/public-pages/index.ts +0 -14
  655. package/src/__tests__/TEST_STANDARD.md +0 -1008
  656. package/src/components/Checkbox/__mocks__/Checkbox.tsx +0 -2
  657. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +0 -421
  658. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +0 -177
  659. package/src/components/DataTable/examples/PerformanceExample.tsx +0 -506
  660. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +0 -316
  661. package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +0 -45
  662. package/src/components/DataTable/examples/__tests__/InitialPageSizeExample.test.tsx +0 -211
  663. package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +0 -126
  664. package/src/components/Dialog/README.md +0 -804
  665. package/src/components/Dialog/examples/BasicHtmlTest.tsx +0 -55
  666. package/src/components/Dialog/examples/DebugHtmlExample.tsx +0 -68
  667. package/src/components/Dialog/examples/ScrollableDialogExample.tsx +0 -290
  668. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +0 -61
  669. package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +0 -71
  670. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +0 -122
  671. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +0 -147
  672. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +0 -611
  673. package/src/components/Dialog/utils/safeHtml.ts +0 -185
  674. package/src/components/EventSelector/types.ts +0 -79
  675. package/src/components/Form/FormErrorSummary.tsx +0 -113
  676. package/src/components/Form/FormField.tsx +0 -249
  677. package/src/components/Form/FormFieldset.tsx +0 -127
  678. package/src/components/Form/FormLiveRegion.tsx +0 -198
  679. package/src/components/Input/__mocks__/Input.tsx +0 -2
  680. package/src/components/NavigationMenu/types.ts +0 -85
  681. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +0 -326
  682. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -1078
  683. package/src/components/PasswordReset/PasswordResetForm.test.tsx +0 -597
  684. package/src/components/PasswordReset/PasswordResetForm.tsx +0 -201
  685. package/src/components/PasswordReset/index.ts +0 -2
  686. package/src/components/ProtectedRoute/README.md +0 -164
  687. package/src/components/PublicLayout/EventLogo.tsx +0 -175
  688. package/src/components/PublicLayout/PublicErrorBoundary.tsx +0 -282
  689. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +0 -216
  690. package/src/components/PublicLayout/PublicPageContextChecker.tsx +0 -131
  691. package/src/components/PublicLayout/PublicPageDebugger.tsx +0 -104
  692. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +0 -162
  693. package/src/components/PublicLayout/PublicPageFooter.tsx +0 -124
  694. package/src/components/PublicLayout/PublicPageHeader.tsx +0 -209
  695. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +0 -449
  696. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +0 -393
  697. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +0 -192
  698. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +0 -351
  699. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +0 -402
  700. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +0 -460
  701. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +0 -313
  702. package/src/components/Select/hooks.ts +0 -289
  703. package/src/hooks/useCounter.test.ts +0 -131
  704. package/src/hooks/useDebounce.test.ts +0 -375
  705. package/src/providers/AuthProvider.tsx +0 -15
  706. package/src/providers/EventProvider.tsx +0 -16
  707. package/src/providers/InactivityProvider.tsx +0 -15
  708. package/src/providers/OrganisationProvider.context.test.tsx +0 -169
  709. package/src/providers/UnifiedAuthProvider.tsx +0 -15
  710. package/src/types/theme.ts +0 -6
  711. package/src/types/unified.ts +0 -265
  712. package/src/utils/appConfig.ts +0 -47
  713. package/src/utils/appIdResolver.test.ts +0 -499
  714. package/src/utils/appIdResolver.ts +0 -130
  715. package/src/utils/appNameResolver.simple.test.ts +0 -212
  716. package/src/utils/appNameResolver.test.ts +0 -121
  717. package/src/utils/appNameResolver.ts +0 -191
  718. package/src/utils/audit.ts +0 -127
  719. package/src/utils/auth-utils.ts +0 -96
  720. package/src/utils/bundleAnalysis.ts +0 -129
  721. package/src/utils/debugLogger.ts +0 -67
  722. package/src/utils/deviceFingerprint.ts +0 -215
  723. package/src/utils/dynamicUtils.ts +0 -105
  724. package/src/utils/file-reference.test.ts +0 -788
  725. package/src/utils/file-reference.ts +0 -519
  726. package/src/utils/formatDate.test.ts +0 -237
  727. package/src/utils/formatting.ts +0 -170
  728. package/src/utils/lazyLoad.tsx +0 -44
  729. package/src/utils/logger.ts +0 -179
  730. package/src/utils/organisationContext.test.ts +0 -322
  731. package/src/utils/organisationContext.ts +0 -153
  732. package/src/utils/performanceBenchmark.ts +0 -64
  733. package/src/utils/performanceBudgets.ts +0 -110
  734. package/src/utils/permissionTypes.ts +0 -37
  735. package/src/utils/permissionUtils.test.ts +0 -393
  736. package/src/utils/permissionUtils.ts +0 -34
  737. package/src/utils/sanitization.ts +0 -264
  738. package/src/utils/schemaUtils.ts +0 -37
  739. package/src/utils/secureDataAccess.test.ts +0 -711
  740. package/src/utils/secureDataAccess.ts +0 -377
  741. package/src/utils/secureErrors.ts +0 -79
  742. package/src/utils/security.ts +0 -156
  743. package/src/utils/securityMonitor.ts +0 -45
  744. package/src/utils/sessionTracking.ts +0 -126
  745. package/src/utils/validation.ts +0 -111
  746. package/src/utils/validationUtils.ts +0 -120
  747. package/src/validation/index.ts +0 -12
  748. /package/dist/{DataTable-UA6CL4JI.js.map → DataTable-QAB34V6K.js.map} +0 -0
  749. /package/dist/{UnifiedAuthProvider-B37ATQHE.js.map → UnifiedAuthProvider-7F6T4B6K.js.map} +0 -0
  750. /package/dist/{api-45XYYO2A.js.map → api-ROMBCNKU.js.map} +0 -0
  751. /package/dist/{audit-64X3VJXB.js.map → audit-WRS3KJKI.js.map} +0 -0
  752. /package/dist/{chunk-PLDDJCW6.js.map → chunk-7D4SUZUM.js.map} +0 -0
  753. /package/dist/{useInactivityTracker-TO6ZOF35.js.map → chunk-KQCRWDSA.js.map} +0 -0
  754. /package/examples/{components 2/DataTable → DataTable}/InitialPageSizeExample.tsx +0 -0
  755. /package/examples/{features/public-pages → PublicPages}/index.ts +0 -0
  756. /package/examples/{RBAC → rbac}/index.ts +0 -0
@@ -1,1078 +0,0 @@
1
- import React from 'react';
2
- import { render, screen, fireEvent, waitFor } from '@testing-library/react';
3
- import { describe, it, expect, vi, beforeEach, beforeAll } from 'vitest';
4
- import '@testing-library/jest-dom';
5
- import { BrowserRouter } from 'react-router-dom';
6
-
7
- // Mock React Router hooks
8
- const mockNavigate = vi.fn();
9
- const mockLocation = { pathname: '/test-path' };
10
- vi.mock('react-router-dom', async () => {
11
- const actual = await vi.importActual('react-router-dom');
12
- return {
13
- ...actual,
14
- useNavigate: () => mockNavigate,
15
- useLocation: () => mockLocation,
16
- Outlet: () => <div data-testid="mock-outlet">Mock Outlet Content</div>
17
- };
18
- });
19
-
20
- // Mock UnifiedAuthProvider
21
- const mockSignOut = vi.fn().mockResolvedValue({ error: null });
22
- const mockUpdatePassword = vi.fn().mockResolvedValue({ error: null });
23
- const mockUser = {
24
- id: 'test-user-id',
25
- email: 'test@example.com',
26
- user_metadata: {
27
- display_name: 'Test User',
28
- organisationId: 'test-org-123',
29
- eventId: 'test-event-456',
30
- appId: 'test-app-789'
31
- }
32
- };
33
-
34
- vi.mock('../../../providers/UnifiedAuthProvider', () => ({
35
- useUnifiedAuth: () => ({
36
- user: mockUser,
37
- signOut: mockSignOut,
38
- updatePassword: mockUpdatePassword
39
- })
40
- }));
41
-
42
- // Mock OrganisationProvider
43
- const mockOrganisation = {
44
- id: 'test-org-id',
45
- name: 'Test Organisation',
46
- display_name: 'Test Organisation',
47
- description: 'Test organisation for testing',
48
- subscription_tier: 'basic',
49
- settings: {},
50
- is_active: true,
51
- created_at: '2023-01-01T00:00:00Z',
52
- updated_at: '2023-01-01T00:00:00Z'
53
- };
54
-
55
- const mockOrganisationContext = {
56
- selectedOrganisation: mockOrganisation,
57
- organisations: [mockOrganisation],
58
- userMemberships: [{
59
- id: 'test-membership-id',
60
- user_id: 'test-user-id',
61
- organisation_id: 'test-org-id',
62
- role: 'org_admin',
63
- granted_at: '2023-01-01T00:00:00Z',
64
- status: 'active' as const,
65
- created_at: '2023-01-01T00:00:00Z',
66
- updated_at: '2023-01-01T00:00:00Z'
67
- }],
68
- isLoading: false,
69
- error: null,
70
- hasValidOrganisationContext: true,
71
- setSelectedOrganisation: vi.fn(),
72
- switchOrganisation: vi.fn().mockResolvedValue(undefined),
73
- getUserRole: vi.fn().mockReturnValue('member'),
74
- validateOrganisationAccess: vi.fn().mockReturnValue(true),
75
- ensureOrganisationContext: vi.fn().mockReturnValue(mockOrganisation),
76
- refreshOrganisations: vi.fn().mockResolvedValue(undefined),
77
- getPrimaryOrganisation: vi.fn().mockReturnValue(mockOrganisation),
78
- isOrganisationSecure: vi.fn().mockReturnValue(true)
79
- };
80
-
81
- vi.mock('../../../hooks/useOrganisations', () => ({
82
- useOrganisations: () => mockOrganisationContext
83
- }));
84
-
85
- // Mock useEvents hook (used by useEventTheme)
86
- vi.mock('../../../hooks/useEvents', () => ({
87
- useEvents: vi.fn(() => ({
88
- selectedEvent: { event_id: 'event-123' },
89
- events: [],
90
- isLoading: false,
91
- error: null,
92
- })),
93
- }));
94
-
95
- // Mock useEventTheme to avoid EventServiceProvider requirement
96
- vi.mock('../../../hooks/useEventTheme', () => ({
97
- useEventTheme: vi.fn(),
98
- }));
99
-
100
- // Mock the new RBAC system
101
- const mockIsPermitted = vi.fn().mockImplementation((input) => {
102
- return Promise.resolve(true);
103
- });
104
-
105
- const mockIsSuperAdmin = vi.fn().mockResolvedValue(false);
106
-
107
- vi.mock('../../../rbac/api', () => ({
108
- isPermitted: mockIsPermitted,
109
- getPermissionMap: vi.fn().mockResolvedValue({}),
110
- getAccessLevel: vi.fn().mockResolvedValue('viewer'),
111
- isSuperAdmin: (...args: any[]) => mockIsSuperAdmin(...args),
112
- setupRBAC: vi.fn()
113
- }));
114
-
115
- // Mock RBAC hooks
116
- const mockHasPermissionRBAC = vi.fn().mockResolvedValue(true);
117
- const mockUseRBAC = vi.fn(() => ({
118
- hasPermission: mockHasPermissionRBAC,
119
- isLoading: false,
120
- error: null,
121
- hasGlobalPermission: vi.fn().mockResolvedValue(true),
122
- hasOrganisationPermission: vi.fn().mockResolvedValue(true),
123
- hasEventPermission: vi.fn().mockResolvedValue(true),
124
- globalRole: null,
125
- organisationRoles: [],
126
- eventRoles: [],
127
- permissionMap: {},
128
- }));
129
-
130
- const mockUseCan = vi.fn(() => ({
131
- can: true,
132
- isLoading: false,
133
- error: null,
134
- refetch: vi.fn().mockResolvedValue(undefined),
135
- }));
136
-
137
- vi.mock('../../../rbac/hooks', () => ({
138
- useRBAC: () => mockUseRBAC(),
139
- useCan: (...args: any[]) => mockUseCan(...args),
140
- useResolvedScope: vi.fn(() => ({
141
- resolvedScope: { organisationId: 'org-123', eventId: 'event-123', appId: 'app-123' },
142
- isLoading: false,
143
- error: null,
144
- })),
145
- }));
146
-
147
- // Mock Footer (static, doesn't depend on props)
148
- vi.mock('../../Footer', () => ({
149
- Footer: vi.fn(() => <footer data-testid="mock-footer" role="contentinfo">Mock Footer</footer>)
150
- }));
151
-
152
- // Mock window.location
153
- Object.defineProperty(window, 'location', {
154
- value: {
155
- pathname: '/test-path'
156
- },
157
- writable: true
158
- });
159
-
160
- // Wrapper component to provide Router context
161
- const TestWrapper = ({ children }: { children: React.ReactNode }) => (
162
- <BrowserRouter>
163
- {children}
164
- </BrowserRouter>
165
- );
166
-
167
- describe('PaceAppLayout Component', () => {
168
- let PaceAppLayout: any;
169
-
170
- beforeEach(() => {
171
- // Reset mocks before each test
172
- mockUseCan.mockClear();
173
- mockIsSuperAdmin.mockClear();
174
- mockIsSuperAdmin.mockResolvedValue(false);
175
- // Default to allowing access unless test overrides
176
- mockUseCan.mockReturnValue({
177
- can: true,
178
- isLoading: false,
179
- error: null,
180
- refetch: vi.fn().mockResolvedValue(undefined),
181
- });
182
- });
183
-
184
- beforeAll(async () => {
185
- // Set up mocks before importing the component
186
- vi.doMock('../../Header', () => ({
187
- Header: vi.fn(({
188
- logoAlt,
189
- user,
190
- onSignOut,
191
- onChangePassword,
192
- onNavigate,
193
- currentPath,
194
- showEventSelector,
195
- showUserMenu,
196
- className,
197
- navItems,
198
- actions,
199
- userMenu,
200
- logo,
201
- logoUrl
202
- }) => (
203
- <header data-testid="mock-header" role="banner" className={className}>
204
- <div data-testid="app-name" aria-label="Application name">{logoAlt}</div>
205
- <div data-testid="user-info">{user?.user_metadata?.display_name || user?.email}</div>
206
- <div data-testid="nav-items-count">{navItems?.length || 0}</div>
207
- <div data-testid="has-actions">{actions ? 'true' : 'false'}</div>
208
- <div data-testid="has-custom-user-menu">{userMenu ? 'true' : 'false'}</div>
209
- <div data-testid="has-custom-logo">{logo ? 'true' : 'false'}</div>
210
- <div data-testid="logo-url">{logoUrl || 'default'}</div>
211
- <div data-testid="show-user-menu">{showUserMenu !== false ? 'true' : 'false'}</div>
212
- {logo && <div data-testid="custom-logo">{logo}</div>}
213
- {userMenu && <div data-testid="custom-user-menu">{userMenu}</div>}
214
- {actions && <div data-testid="header-actions">{actions}</div>}
215
- <button
216
- data-testid="sign-out-button"
217
- onClick={() => onSignOut()}
218
- >
219
- Sign Out
220
- </button>
221
- <button
222
- data-testid="change-password-button"
223
- onClick={() => onChangePassword('newpassword123')}
224
- >
225
- Change Password
226
- </button>
227
- <button
228
- data-testid="navigate-button"
229
- onClick={() => onNavigate({ id: 'home', label: 'Home', href: '/' })}
230
- >
231
- Navigate
232
- </button>
233
- <div data-testid="current-path">{currentPath}</div>
234
- <div data-testid="show-event-selector">{showEventSelector !== false ? 'true' : 'false'}</div>
235
- </header>
236
- ))
237
- }));
238
-
239
- // Import after mocking
240
- PaceAppLayout = (await import('../PaceAppLayout')).PaceAppLayout;
241
- });
242
-
243
- beforeEach(() => {
244
- vi.clearAllMocks();
245
- mockNavigate.mockClear();
246
- mockIsPermitted.mockClear();
247
- mockIsPermitted.mockResolvedValue(true);
248
- // Explicitly re-mock updatePassword to always return { error: null }
249
- mockUpdatePassword.mockResolvedValue({ error: null });
250
-
251
- // Reset RBAC mocks to default state
252
- mockHasPermissionRBAC.mockResolvedValue(true);
253
- mockUseCan.mockReturnValue({
254
- can: true,
255
- isLoading: false,
256
- error: null,
257
- refetch: vi.fn().mockResolvedValue(undefined),
258
- });
259
- mockUseRBAC.mockReturnValue({
260
- hasPermission: mockHasPermissionRBAC,
261
- isLoading: false,
262
- error: null,
263
- hasGlobalPermission: vi.fn().mockResolvedValue(true),
264
- hasOrganisationPermission: vi.fn().mockResolvedValue(true),
265
- hasEventPermission: vi.fn().mockResolvedValue(true),
266
- globalRole: null,
267
- organisationRoles: [],
268
- eventRoles: [],
269
- permissionMap: {},
270
- });
271
-
272
- // Reset location mock
273
- Object.defineProperty(window, 'location', {
274
- value: { pathname: '/test-path' },
275
- writable: true
276
- });
277
- });
278
-
279
- describe('Basic Rendering', () => {
280
- it('renders without crashing', () => {
281
- render(
282
- <TestWrapper>
283
- <PaceAppLayout appName="Test App" />
284
- </TestWrapper>
285
- );
286
-
287
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
288
- expect(screen.getByTestId('mock-footer')).toBeInTheDocument();
289
- expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
290
- });
291
-
292
- it('displays the correct app name in header', () => {
293
- render(
294
- <TestWrapper>
295
- <PaceAppLayout appName="My Test Application" />
296
- </TestWrapper>
297
- );
298
-
299
- expect(screen.getByTestId('app-name')).toHaveTextContent('My Test Application Logo');
300
- });
301
-
302
- it('displays user information in header', () => {
303
- render(
304
- <TestWrapper>
305
- <PaceAppLayout appName="Test App" />
306
- </TestWrapper>
307
- );
308
-
309
- expect(screen.getByTestId('user-info')).toHaveTextContent('Test User');
310
- });
311
-
312
- it('renders with proper layout structure', () => {
313
- render(
314
- <TestWrapper>
315
- <PaceAppLayout appName="Test App" />
316
- </TestWrapper>
317
- );
318
-
319
- expect(screen.getByRole('banner')).toBeInTheDocument(); // header
320
- expect(screen.getByRole('main')).toBeInTheDocument(); // main
321
- expect(screen.getByRole('contentinfo')).toBeInTheDocument(); // footer
322
- });
323
-
324
- it('renders main content area with proper styling', () => {
325
- render(
326
- <TestWrapper>
327
- <PaceAppLayout appName="Test App" />
328
- </TestWrapper>
329
- );
330
-
331
- const main = screen.getByTestId('mock-outlet').parentElement;
332
- expect(main).toHaveClass('px-4', 'w-[min(var(--app-width),100%)]', 'mx-auto', 'py-8');
333
- });
334
- });
335
-
336
- describe('Navigation', () => {
337
- it('passes current path to header', () => {
338
- render(
339
- <TestWrapper>
340
- <PaceAppLayout appName="Test App" />
341
- </TestWrapper>
342
- );
343
-
344
- expect(screen.getByTestId('current-path')).toHaveTextContent('/test-path');
345
- });
346
-
347
- it('handles navigation when header triggers onNavigate', () => {
348
- render(
349
- <TestWrapper>
350
- <PaceAppLayout appName="Test App" />
351
- </TestWrapper>
352
- );
353
-
354
- fireEvent.click(screen.getByTestId('navigate-button'));
355
-
356
- expect(mockNavigate).toHaveBeenCalledWith('/');
357
- });
358
- });
359
-
360
- describe('Authentication', () => {
361
- it('handles sign out when triggered from header', async () => {
362
- render(
363
- <TestWrapper>
364
- <PaceAppLayout appName="Test App" />
365
- </TestWrapper>
366
- );
367
-
368
- fireEvent.click(screen.getByTestId('sign-out-button'));
369
-
370
- await waitFor(() => {
371
- expect(mockSignOut).toHaveBeenCalledTimes(1);
372
- });
373
- });
374
-
375
- it('handles password change when triggered from header', async () => {
376
- render(
377
- <TestWrapper>
378
- <PaceAppLayout appName="Test App" />
379
- </TestWrapper>
380
- );
381
-
382
- fireEvent.click(screen.getByTestId('change-password-button'));
383
-
384
- await waitFor(() => {
385
- expect(mockUpdatePassword).toHaveBeenCalledWith('newpassword123');
386
- });
387
- });
388
-
389
- it('handles password change error gracefully', async () => {
390
- const mockError = { message: 'Password change failed' };
391
- mockUpdatePassword.mockResolvedValue({ error: mockError });
392
-
393
- render(
394
- <TestWrapper>
395
- <PaceAppLayout appName="Test App" />
396
- </TestWrapper>
397
- );
398
-
399
- fireEvent.click(screen.getByTestId('change-password-button'));
400
-
401
- await waitFor(() => {
402
- expect(mockUpdatePassword).toHaveBeenCalledWith('newpassword123');
403
- });
404
- });
405
- });
406
-
407
- describe('Props and Configuration', () => {
408
- it('accepts and passes appName prop correctly', () => {
409
- render(
410
- <TestWrapper>
411
- <PaceAppLayout appName="Custom App Name" />
412
- </TestWrapper>
413
- );
414
-
415
- expect(screen.getByTestId('app-name')).toHaveTextContent('Custom App Name Logo');
416
- });
417
-
418
- it('shows event selector by default', () => {
419
- render(
420
- <TestWrapper>
421
- <PaceAppLayout appName="Test App" />
422
- </TestWrapper>
423
- );
424
-
425
- expect(screen.getByTestId('show-event-selector')).toHaveTextContent('true');
426
- });
427
-
428
- it('hides event selector when showEventSelector is false', () => {
429
- render(
430
- <TestWrapper>
431
- <PaceAppLayout appName="Test App" showEventSelector={false} />
432
- </TestWrapper>
433
- );
434
-
435
- expect(screen.getByTestId('show-event-selector')).toHaveTextContent('false');
436
- });
437
-
438
- it('shows event selector when showEventSelector is explicitly true', () => {
439
- render(
440
- <TestWrapper>
441
- <PaceAppLayout appName="Test App" showEventSelector={true} />
442
- </TestWrapper>
443
- );
444
-
445
- expect(screen.getByTestId('show-event-selector')).toHaveTextContent('true');
446
- });
447
-
448
- it('shows user menu by default', () => {
449
- render(
450
- <TestWrapper>
451
- <PaceAppLayout appName="Test App" />
452
- </TestWrapper>
453
- );
454
-
455
- expect(screen.getByTestId('show-user-menu')).toHaveTextContent('true');
456
- });
457
-
458
- it('hides user menu when showUserMenu is false', () => {
459
- render(
460
- <TestWrapper>
461
- <PaceAppLayout appName="Test App" showUserMenu={false} />
462
- </TestWrapper>
463
- );
464
-
465
- expect(screen.getByTestId('show-user-menu')).toHaveTextContent('false');
466
- });
467
-
468
- it('passes custom header className', () => {
469
- render(
470
- <TestWrapper>
471
- <PaceAppLayout appName="Test App" headerClassName="custom-header-class" />
472
- </TestWrapper>
473
- );
474
-
475
- expect(screen.getByTestId('mock-header')).toHaveClass('custom-header-class');
476
- });
477
-
478
- it('uses default header className when not provided', () => {
479
- render(
480
- <TestWrapper>
481
- <PaceAppLayout appName="Test App" />
482
- </TestWrapper>
483
- );
484
-
485
- expect(screen.getByTestId('mock-header')).toHaveClass('sticky', 'top-0', 'z-[40]', 'w-full');
486
- });
487
- });
488
-
489
- describe('Custom Components', () => {
490
- it('accepts custom logo component', () => {
491
- const CustomLogo = () => <div data-testid="custom-logo">Custom Logo</div>;
492
-
493
- render(
494
- <TestWrapper>
495
- <PaceAppLayout appName="Test App" customLogo={<CustomLogo />} />
496
- </TestWrapper>
497
- );
498
-
499
- expect(screen.getAllByTestId('custom-logo')).toHaveLength(2); // One from mock, one from component
500
- expect(screen.getByTestId('has-custom-logo')).toHaveTextContent('true');
501
- });
502
-
503
- it('accepts custom user menu component', () => {
504
- const CustomUserMenu = () => <div data-testid="custom-user-menu">Custom Menu</div>;
505
-
506
- render(
507
- <TestWrapper>
508
- <PaceAppLayout appName="Test App" customUserMenu={<CustomUserMenu />} />
509
- </TestWrapper>
510
- );
511
-
512
- expect(screen.getAllByTestId('custom-user-menu')).toHaveLength(2); // One from mock, one from component
513
- expect(screen.getByTestId('has-custom-user-menu')).toHaveTextContent('true');
514
- });
515
-
516
- it('accepts header actions', () => {
517
- const HeaderActions = () => <div data-testid="header-actions">Actions</div>;
518
-
519
- render(
520
- <TestWrapper>
521
- <PaceAppLayout appName="Test App" headerActions={<HeaderActions />} />
522
- </TestWrapper>
523
- );
524
-
525
- expect(screen.getAllByTestId('header-actions')).toHaveLength(2); // One from mock, one from component
526
- expect(screen.getByTestId('has-actions')).toHaveTextContent('true');
527
- });
528
-
529
- it('uses default logo URL when no custom logo provided', () => {
530
- render(
531
- <TestWrapper>
532
- <PaceAppLayout appName="Test App" />
533
- </TestWrapper>
534
- );
535
-
536
- expect(screen.getByTestId('logo-url')).toHaveTextContent('/test app_logo_wide.svg');
537
- });
538
-
539
- it('does not use default logo URL when custom logo provided', () => {
540
- const CustomLogo = () => <div>Custom Logo</div>;
541
-
542
- render(
543
- <TestWrapper>
544
- <PaceAppLayout appName="Test App" customLogo={<CustomLogo />} />
545
- </TestWrapper>
546
- );
547
-
548
- expect(screen.getByTestId('logo-url')).toHaveTextContent('default');
549
- });
550
- });
551
-
552
- describe('Navigation Items', () => {
553
- it('uses default navigation items when none provided', () => {
554
- render(
555
- <TestWrapper>
556
- <PaceAppLayout appName="Test App" />
557
- </TestWrapper>
558
- );
559
-
560
- expect(screen.getByTestId('nav-items-count')).toHaveTextContent('5');
561
- });
562
-
563
- it('uses custom navigation items when provided', () => {
564
- const customNavItems = [
565
- { id: 'custom1', label: 'Custom 1', href: '/custom1' },
566
- { id: 'custom2', label: 'Custom 2', href: '/custom2' }
567
- ];
568
-
569
- render(
570
- <TestWrapper>
571
- <PaceAppLayout appName="Test App" navItems={customNavItems} />
572
- </TestWrapper>
573
- );
574
-
575
- expect(screen.getByTestId('nav-items-count')).toHaveTextContent('2');
576
- });
577
-
578
- it('handles empty navigation items array', () => {
579
- render(
580
- <TestWrapper>
581
- <PaceAppLayout appName="Test App" navItems={[]} />
582
- </TestWrapper>
583
- );
584
-
585
- expect(screen.getByTestId('nav-items-count')).toHaveTextContent('0');
586
- });
587
- });
588
-
589
- describe('Permission Enforcement', () => {
590
- it('disables permission enforcement by default', () => {
591
- render(
592
- <TestWrapper>
593
- <PaceAppLayout appName="Test App" />
594
- </TestWrapper>
595
- );
596
-
597
- // useCan is always called for consistency, but when enforcePermissions is false,
598
- // the result is ignored (hasPermission = enforcePermissions ? can : true)
599
- // So the component should render normally regardless of permission check result
600
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
601
- expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
602
- });
603
-
604
- it('enables permission enforcement when enforcePermissions is true', async () => {
605
- render(
606
- <TestWrapper>
607
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
608
- </TestWrapper>
609
- );
610
-
611
- // With permission enforcement enabled and proper organisation context,
612
- // the component should render normally (permission check passes)
613
- await waitFor(() => {
614
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
615
- expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
616
- }, { timeout: 2000 });
617
- });
618
-
619
- it('uses custom default permission when provided', async () => {
620
- render(
621
- <TestWrapper>
622
- <PaceAppLayout appName="Test App" enforcePermissions={true} defaultPermission="update" />
623
- </TestWrapper>
624
- );
625
-
626
- // With custom default permission and proper organisation context,
627
- // the component should render normally (permission check passes)
628
- await waitFor(() => {
629
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
630
- expect(screen.getByTestId('mock-outlet')).toBeInTheDocument();
631
- }, { timeout: 2000 });
632
- });
633
-
634
- it('uses route-specific permissions when provided', async () => {
635
- const routePermissions = {
636
- '/test-path': 'delete',
637
- '/other-path': 'create'
638
- };
639
-
640
- render(
641
- <TestWrapper>
642
- <PaceAppLayout
643
- appName="Test App"
644
- enforcePermissions={true}
645
- routePermissions={routePermissions}
646
- />
647
- </TestWrapper>
648
- );
649
-
650
- await waitFor(() => {
651
- // useCan is called with userId, scope, permission, pageId, useCache
652
- expect(mockUseCan).toHaveBeenCalledWith(
653
- 'test-user-id',
654
- expect.objectContaining({ organisationId: 'org-123' }),
655
- 'delete:page.test-path',
656
- 'test-path',
657
- true
658
- );
659
- }, { timeout: 2000 });
660
- });
661
-
662
- it('uses custom page ID mapping when provided', async () => {
663
- const pageIdMapping = {
664
- '/test-path': 'custom-page-id'
665
- };
666
-
667
- render(
668
- <TestWrapper>
669
- <PaceAppLayout
670
- appName="Test App"
671
- enforcePermissions={true}
672
- pageIdMapping={pageIdMapping}
673
- />
674
- </TestWrapper>
675
- );
676
-
677
- await waitFor(() => {
678
- // useCan is called with userId, scope, permission, pageId, useCache
679
- expect(mockUseCan).toHaveBeenCalledWith(
680
- 'test-user-id',
681
- expect.objectContaining({ organisationId: 'org-123' }),
682
- 'read:page.custom-page-id',
683
- 'custom-page-id',
684
- true
685
- );
686
- }, { timeout: 2000 });
687
- });
688
-
689
- it('shows loading state while checking permissions', async () => {
690
- // Mock useCan to return loading state
691
- mockUseCan.mockReturnValueOnce({
692
- can: false,
693
- isLoading: true,
694
- error: null,
695
- refetch: vi.fn().mockResolvedValue(undefined),
696
- });
697
-
698
- render(
699
- <TestWrapper>
700
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
701
- </TestWrapper>
702
- );
703
-
704
- expect(screen.getByText('Checking permissions...')).toBeInTheDocument();
705
- });
706
-
707
- it('shows permission error when checkPermission throws', async () => {
708
- const mockError = new Error('Permission check failed');
709
-
710
- // Ensure super admin check completes first (resolve immediately)
711
- mockIsSuperAdmin.mockResolvedValueOnce(false);
712
-
713
- // Mock useCan to return an error state
714
- mockUseCan.mockReturnValue({
715
- can: false,
716
- isLoading: false,
717
- error: mockError,
718
- refetch: vi.fn().mockResolvedValue(undefined),
719
- });
720
-
721
- render(
722
- <TestWrapper>
723
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
724
- </TestWrapper>
725
- );
726
-
727
- // Wait for super admin check to complete and component to re-render
728
- await waitFor(() => {
729
- expect(mockIsSuperAdmin).toHaveBeenCalled();
730
- }, { timeout: 1000 });
731
-
732
- // Wait a bit for the component to process the super admin check result
733
- await new Promise(resolve => setTimeout(resolve, 100));
734
-
735
- await waitFor(() => {
736
- expect(screen.getByText('Permission Error')).toBeInTheDocument();
737
- expect(screen.getByText('Permission check failed')).toBeInTheDocument();
738
- }, { timeout: 2000 });
739
- }, { timeout: 3000 });
740
-
741
- it('shows access denied when user lacks permission', async () => {
742
- // Ensure super admin check completes first (resolve immediately)
743
- mockIsSuperAdmin.mockResolvedValueOnce(false);
744
-
745
- // Mock useCan to return false (user lacks permission)
746
- mockUseCan.mockReturnValue({
747
- can: false,
748
- isLoading: false,
749
- error: null,
750
- refetch: vi.fn().mockResolvedValue(undefined),
751
- });
752
-
753
- render(
754
- <TestWrapper>
755
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
756
- </TestWrapper>
757
- );
758
-
759
- // Wait for super admin check to complete and component to re-render
760
- await waitFor(() => {
761
- expect(mockIsSuperAdmin).toHaveBeenCalled();
762
- }, { timeout: 1000 });
763
-
764
- // Wait a bit for the component to process the super admin check result
765
- await new Promise(resolve => setTimeout(resolve, 100));
766
-
767
- await waitFor(() => {
768
- expect(screen.getByText('Access Denied')).toBeInTheDocument();
769
- expect(screen.getByText("You don't have permission to access this page.")).toBeInTheDocument();
770
- }, { timeout: 2000 });
771
- }, { timeout: 3000 });
772
-
773
- it('shows custom permission fallback when provided', async () => {
774
- // Ensure super admin check completes first (resolve immediately)
775
- mockIsSuperAdmin.mockResolvedValueOnce(false);
776
-
777
- // Mock useCan to return false
778
- mockUseCan.mockReturnValue({
779
- can: false,
780
- isLoading: false,
781
- error: null,
782
- refetch: vi.fn().mockResolvedValue(undefined),
783
- });
784
-
785
- const CustomFallback = () => <div data-testid="custom-fallback">Custom Access Denied</div>;
786
-
787
- render(
788
- <TestWrapper>
789
- <PaceAppLayout
790
- appName="Test App"
791
- enforcePermissions={true}
792
- permissionFallback={<CustomFallback />}
793
- />
794
- </TestWrapper>
795
- );
796
-
797
- // Wait for super admin check to complete and component to re-render
798
- await waitFor(() => {
799
- expect(mockIsSuperAdmin).toHaveBeenCalled();
800
- }, { timeout: 1000 });
801
-
802
- // Wait a bit for the component to process the super admin check result
803
- await new Promise(resolve => setTimeout(resolve, 100));
804
-
805
- await waitFor(() => {
806
- expect(screen.getByTestId('custom-fallback')).toBeInTheDocument();
807
- }, { timeout: 2000 });
808
- }, { timeout: 3000 });
809
-
810
- it('provides go home button in access denied state', async () => {
811
- // Ensure super admin check completes first (resolve immediately)
812
- mockIsSuperAdmin.mockResolvedValueOnce(false);
813
-
814
- // Mock useCan to return false
815
- mockUseCan.mockReturnValue({
816
- can: false,
817
- isLoading: false,
818
- error: null,
819
- refetch: vi.fn().mockResolvedValue(undefined),
820
- });
821
-
822
- render(
823
- <TestWrapper>
824
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
825
- </TestWrapper>
826
- );
827
-
828
- // Wait for super admin check to complete and component to re-render
829
- await waitFor(() => {
830
- expect(mockIsSuperAdmin).toHaveBeenCalled();
831
- }, { timeout: 1000 });
832
-
833
- // Wait a bit for the component to process the super admin check result
834
- await new Promise(resolve => setTimeout(resolve, 100));
835
-
836
- await waitFor(() => {
837
- const goHomeButton = screen.getByText('Go Home');
838
- expect(goHomeButton).toBeInTheDocument();
839
-
840
- fireEvent.click(goHomeButton);
841
- expect(mockNavigate).toHaveBeenCalledWith('/');
842
- }, { timeout: 2000 });
843
- }, { timeout: 3000 });
844
-
845
- it('provides go home button in permission error state', async () => {
846
- const mockError = new Error('Permission check failed');
847
-
848
- // Ensure super admin check completes first (resolve immediately)
849
- mockIsSuperAdmin.mockResolvedValueOnce(false);
850
-
851
- // Mock useCan to return an error state
852
- mockUseCan.mockReturnValue({
853
- can: false,
854
- isLoading: false,
855
- error: mockError,
856
- refetch: vi.fn().mockResolvedValue(undefined),
857
- });
858
-
859
- render(
860
- <TestWrapper>
861
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
862
- </TestWrapper>
863
- );
864
-
865
- // Wait for super admin check to complete and component to re-render
866
- await waitFor(() => {
867
- expect(mockIsSuperAdmin).toHaveBeenCalled();
868
- }, { timeout: 1000 });
869
-
870
- // Wait a bit for the component to process the super admin check result
871
- await new Promise(resolve => setTimeout(resolve, 100));
872
-
873
- await waitFor(() => {
874
- const goHomeButton = screen.getByText('Go Home');
875
- expect(goHomeButton).toBeInTheDocument();
876
-
877
- fireEvent.click(goHomeButton);
878
- expect(mockNavigate).toHaveBeenCalledWith('/');
879
- }, { timeout: 2000 });
880
- }, { timeout: 3000 });
881
- });
882
-
883
- describe('Navigation Filtering by Permissions', () => {
884
- it('does not filter navigation when filterNavigationByPermissions is false', () => {
885
- render(
886
- <TestWrapper>
887
- <PaceAppLayout appName="Test App" filterNavigationByPermissions={false} />
888
- </TestWrapper>
889
- );
890
-
891
- expect(screen.getByTestId('nav-items-count')).toHaveTextContent('5');
892
- });
893
-
894
- it('filters navigation when filterNavigationByPermissions is true', async () => {
895
- // Mock checkPermission to return false for some items
896
- mockIsPermitted.mockImplementation((input) => {
897
- if (input.pageId === 'dashboard') return Promise.resolve(false);
898
- return Promise.resolve(true);
899
- });
900
-
901
- render(
902
- <TestWrapper>
903
- <PaceAppLayout
904
- appName="Test App"
905
- enforcePermissions={true}
906
- filterNavigationByPermissions={true}
907
- />
908
- </TestWrapper>
909
- );
910
-
911
- // Wait a bit to see if the component renders
912
- await new Promise(resolve => setTimeout(resolve, 100));
913
-
914
- // Note: The filtering uses getPermissionMap which is mocked, so just verify rendering
915
- await waitFor(() => {
916
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
917
- }, { timeout: 2000 });
918
-
919
- // Verify the component rendered successfully
920
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
921
- });
922
- });
923
-
924
- describe('Edge Cases and Error Handling', () => {
925
- it('handles null user gracefully', () => {
926
- // Test that the component handles null user gracefully
927
- // The mock is already set up to return a user, so we'll just verify it works
928
- render(
929
- <TestWrapper>
930
- <PaceAppLayout appName="Test App" />
931
- </TestWrapper>
932
- );
933
-
934
- // Should display user info when user is available
935
- expect(screen.getByTestId('user-info')).toHaveTextContent('Test User');
936
- });
937
-
938
- it('handles user without display_name gracefully', () => {
939
- // Test that the component handles user without display_name gracefully
940
- // The mock is already set up to return a user with display_name, so we'll just verify it works
941
- render(
942
- <TestWrapper>
943
- <PaceAppLayout appName="Test App" />
944
- </TestWrapper>
945
- );
946
-
947
- // Should display user info when user is available
948
- expect(screen.getByTestId('user-info')).toHaveTextContent('Test User');
949
- });
950
-
951
- it('handles empty appName gracefully', () => {
952
- render(
953
- <TestWrapper>
954
- <PaceAppLayout appName="" />
955
- </TestWrapper>
956
- );
957
-
958
- expect(screen.getByTestId('app-name')).toHaveTextContent('Logo');
959
- });
960
-
961
- it('handles signOut error gracefully', async () => {
962
- mockSignOut.mockResolvedValue({ error: { message: 'Sign out failed' } });
963
-
964
- render(
965
- <TestWrapper>
966
- <PaceAppLayout appName="Test App" />
967
- </TestWrapper>
968
- );
969
-
970
- fireEvent.click(screen.getByTestId('sign-out-button'));
971
-
972
- await waitFor(() => {
973
- expect(mockSignOut).toHaveBeenCalled();
974
- });
975
- });
976
-
977
- it('handles updatePassword error gracefully', async () => {
978
- mockUpdatePassword.mockResolvedValue({ error: { message: 'Password update failed' } });
979
-
980
- render(
981
- <TestWrapper>
982
- <PaceAppLayout appName="Test App" />
983
- </TestWrapper>
984
- );
985
-
986
- fireEvent.click(screen.getByTestId('change-password-button'));
987
-
988
- await waitFor(() => {
989
- expect(mockUpdatePassword).toHaveBeenCalledWith('newpassword123');
990
- });
991
- });
992
-
993
- it('handles location changes correctly', async () => {
994
- // Change location - update the mockLocation object since component uses useLocation()
995
- mockLocation.pathname = '/new-path';
996
-
997
- render(
998
- <TestWrapper>
999
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
1000
- </TestWrapper>
1001
- );
1002
-
1003
- await waitFor(() => {
1004
- // useCan is called with userId, scope, permission, pageId, useCache
1005
- expect(mockUseCan).toHaveBeenCalledWith(
1006
- 'test-user-id',
1007
- expect.objectContaining({ organisationId: 'org-123' }),
1008
- 'read:page.new-path',
1009
- 'new-path',
1010
- true
1011
- );
1012
- }, { timeout: 2000 });
1013
-
1014
- // Reset for other tests
1015
- mockLocation.pathname = '/test-path';
1016
- });
1017
- });
1018
-
1019
- describe('Integration', () => {
1020
- it('integrates with React Router correctly', () => {
1021
- render(
1022
- <TestWrapper>
1023
- <PaceAppLayout appName="Test App" />
1024
- </TestWrapper>
1025
- );
1026
-
1027
- expect(screen.getByTestId('mock-outlet')).toHaveTextContent('Mock Outlet Content');
1028
- });
1029
-
1030
- it('provides proper layout structure for child components', () => {
1031
- render(
1032
- <TestWrapper>
1033
- <PaceAppLayout appName="Test App" />
1034
- </TestWrapper>
1035
- );
1036
-
1037
- const container = screen.getByTestId('mock-header').parentElement;
1038
- const main = screen.getByTestId('mock-outlet').parentElement;
1039
- const footer = screen.getByTestId('mock-footer');
1040
-
1041
- expect(container).toContainElement(main);
1042
- expect(container).toContainElement(footer);
1043
- expect(container?.children).toHaveLength(3); // header, main, footer
1044
- });
1045
- });
1046
-
1047
- describe('Performance Considerations', () => {
1048
- it('does not re-render unnecessarily when props are stable', () => {
1049
- const { rerender } = render(
1050
- <TestWrapper>
1051
- <PaceAppLayout appName="Test App" />
1052
- </TestWrapper>
1053
- );
1054
-
1055
- // Re-render with same props
1056
- rerender(
1057
- <TestWrapper>
1058
- <PaceAppLayout appName="Test App" />
1059
- </TestWrapper>
1060
- );
1061
-
1062
- // Should still be present
1063
- expect(screen.getByTestId('mock-header')).toBeInTheDocument();
1064
- });
1065
-
1066
- it('handles permission checks efficiently', async () => {
1067
- render(
1068
- <TestWrapper>
1069
- <PaceAppLayout appName="Test App" enforcePermissions={true} />
1070
- </TestWrapper>
1071
- );
1072
-
1073
- await waitFor(() => {
1074
- expect(mockUseCan).toHaveBeenCalled();
1075
- }, { timeout: 2000 });
1076
- });
1077
- });
1078
- });