@jmruthers/pace-core 0.5.68 → 0.5.69

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 (375) hide show
  1. package/dist/{DataTable-4IUY7BXB.js → DataTable-MPBSXUC6.js} +5 -6
  2. package/dist/{PublicLoadingSpinner-DdKXTkCZ.d.ts → PublicLoadingSpinner-BOdyU3u-.d.ts} +1 -1
  3. package/dist/{chunk-PXWEDX7Y.js → chunk-2ARQW6VX.js} +3 -3
  4. package/dist/{chunk-MOJXHWDE.js → chunk-6JILXFEA.js} +335 -5
  5. package/dist/chunk-6JILXFEA.js.map +1 -0
  6. package/dist/{chunk-D7ARGIA3.js → chunk-6RBH67W7.js} +23 -6
  7. package/dist/chunk-6RBH67W7.js.map +1 -0
  8. package/dist/{chunk-ZMS23NS5.js → chunk-FJTAWPAQ.js} +3 -5
  9. package/dist/{chunk-ZMS23NS5.js.map → chunk-FJTAWPAQ.js.map} +1 -1
  10. package/dist/{chunk-OPCWH3A4.js → chunk-NO5QHMDX.js} +7 -6
  11. package/dist/chunk-NO5QHMDX.js.map +1 -0
  12. package/dist/{chunk-ZPK5656W.js → chunk-O3NWNXDY.js} +4 -5
  13. package/dist/chunk-O3NWNXDY.js.map +1 -0
  14. package/dist/{chunk-UYA6U6H7.js → chunk-Q2UP3ZWQ.js} +4 -4
  15. package/dist/{chunk-KRCRNXPD.js → chunk-RVYGJPOD.js} +79 -18
  16. package/dist/chunk-RVYGJPOD.js.map +1 -0
  17. package/dist/{chunk-NN45OBIS.js → chunk-UCMHBF7Y.js} +3 -5
  18. package/dist/{chunk-NN45OBIS.js.map → chunk-UCMHBF7Y.js.map} +1 -1
  19. package/dist/{chunk-ZPG4XPV5.js → chunk-V3QO3LL7.js} +5 -7
  20. package/dist/chunk-V3QO3LL7.js.map +1 -0
  21. package/dist/{chunk-U6GPOF6J.js → chunk-ZXJGZLLO.js} +17 -17
  22. package/dist/{chunk-U6GPOF6J.js.map → chunk-ZXJGZLLO.js.map} +1 -1
  23. package/dist/components.d.ts +1 -1
  24. package/dist/components.js +8 -9
  25. package/dist/components.js.map +1 -1
  26. package/dist/hooks.d.ts +1 -1
  27. package/dist/hooks.js +9 -6
  28. package/dist/hooks.js.map +1 -1
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.js +16 -16
  31. package/dist/index.js.map +1 -1
  32. package/dist/providers.js +5 -7
  33. package/dist/rbac/index.js +5 -6
  34. package/dist/{usePublicRouteParams-CdoFxnJK.d.ts → usePublicRouteParams-Ua1Vz-HG.d.ts} +35 -1
  35. package/dist/utils.d.ts +4 -1
  36. package/dist/utils.js +3 -3
  37. package/docs/DOCUMENTATION_CHECKLIST.md +281 -0
  38. package/docs/README.md +22 -10
  39. package/docs/api/classes/ColumnFactory.md +1 -1
  40. package/docs/api/classes/ErrorBoundary.md +1 -1
  41. package/docs/api/classes/InvalidScopeError.md +1 -1
  42. package/docs/api/classes/MissingUserContextError.md +1 -1
  43. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  44. package/docs/api/classes/PermissionDeniedError.md +1 -1
  45. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  46. package/docs/api/classes/RBACAuditManager.md +1 -1
  47. package/docs/api/classes/RBACCache.md +1 -1
  48. package/docs/api/classes/RBACEngine.md +1 -1
  49. package/docs/api/classes/RBACError.md +1 -1
  50. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  51. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  52. package/docs/api/classes/StorageUtils.md +1 -1
  53. package/docs/api/interfaces/AggregateConfig.md +1 -1
  54. package/docs/api/interfaces/ButtonProps.md +1 -1
  55. package/docs/api/interfaces/CardProps.md +1 -1
  56. package/docs/api/interfaces/ColorPalette.md +1 -1
  57. package/docs/api/interfaces/ColorShade.md +1 -1
  58. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  59. package/docs/api/interfaces/DataTableAction.md +1 -1
  60. package/docs/api/interfaces/DataTableColumn.md +1 -1
  61. package/docs/api/interfaces/DataTableProps.md +1 -1
  62. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  63. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  64. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  65. package/docs/api/interfaces/EventContextType.md +1 -1
  66. package/docs/api/interfaces/EventLogoProps.md +1 -1
  67. package/docs/api/interfaces/EventProviderProps.md +1 -1
  68. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  69. package/docs/api/interfaces/FileUploadProps.md +1 -1
  70. package/docs/api/interfaces/FooterProps.md +1 -1
  71. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  72. package/docs/api/interfaces/InputProps.md +1 -1
  73. package/docs/api/interfaces/LabelProps.md +1 -1
  74. package/docs/api/interfaces/LoginFormProps.md +1 -1
  75. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  76. package/docs/api/interfaces/NavigationContextType.md +1 -1
  77. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  78. package/docs/api/interfaces/NavigationItem.md +1 -1
  79. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  80. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  81. package/docs/api/interfaces/Organisation.md +1 -1
  82. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  83. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  84. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  85. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  86. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  87. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  88. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  89. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  90. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  91. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  92. package/docs/api/interfaces/PaletteData.md +1 -1
  93. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  94. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  95. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  96. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  97. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  98. package/docs/api/interfaces/PublicPageHeaderProps.md +2 -2
  99. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  100. package/docs/api/interfaces/RBACConfig.md +1 -1
  101. package/docs/api/interfaces/RBACContextType.md +1 -1
  102. package/docs/api/interfaces/RBACLogger.md +1 -1
  103. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  104. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  105. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  106. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  107. package/docs/api/interfaces/RouteConfig.md +1 -1
  108. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  109. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  110. package/docs/api/interfaces/StorageConfig.md +1 -1
  111. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  112. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  113. package/docs/api/interfaces/StorageListOptions.md +1 -1
  114. package/docs/api/interfaces/StorageListResult.md +1 -1
  115. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  116. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  117. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  118. package/docs/api/interfaces/StyleImport.md +1 -1
  119. package/docs/api/interfaces/SwitchProps.md +1 -1
  120. package/docs/api/interfaces/ToastActionElement.md +1 -1
  121. package/docs/api/interfaces/ToastProps.md +1 -1
  122. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  123. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  124. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  125. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  126. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  127. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  128. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  129. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  130. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  131. package/docs/api/interfaces/UserEventAccess.md +1 -1
  132. package/docs/api/interfaces/UserMenuProps.md +1 -1
  133. package/docs/api/interfaces/UserProfile.md +1 -1
  134. package/docs/api/modules.md +39 -14
  135. package/docs/architecture/services.md +374 -0
  136. package/docs/best-practices/README.md +1 -1
  137. package/docs/best-practices/testing.md +1 -1
  138. package/docs/breaking-changes.md +182 -0
  139. package/docs/common-patterns.md +445 -0
  140. package/docs/core-concepts/authentication.md +26 -11
  141. package/docs/core-concepts/events.md +2 -0
  142. package/docs/core-concepts/organisations.md +2 -0
  143. package/docs/core-concepts/permissions.md +2 -0
  144. package/docs/{INDEX.md → documentation-index.md} +26 -38
  145. package/docs/faq.md +286 -0
  146. package/docs/{FILE_REFERENCE_SYSTEM.md → file-reference-system.md} +1 -1
  147. package/docs/getting-started/installation-guide.md +284 -0
  148. package/docs/getting-started/quick-start.md +8 -1
  149. package/docs/implementation-guides/app-layout.md +3 -1
  150. package/docs/implementation-guides/data-tables.md +2 -0
  151. package/docs/implementation-guides/dynamic-colors.md +47 -2
  152. package/docs/implementation-guides/event-theming-summary.md +220 -0
  153. package/docs/implementation-guides/forms.md +9 -7
  154. package/docs/implementation-guides/navigation.md +2 -0
  155. package/docs/migration/service-architecture.md +351 -0
  156. package/docs/rbac/README-rbac-rls-integration.md +2 -2
  157. package/docs/rbac/README.md +1 -1
  158. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  159. package/docs/rbac/quick-start.md +2 -0
  160. package/docs/rbac/rbac-rls-integration.md +2 -2
  161. package/docs/style-guide.md +136 -1
  162. package/docs/testing/README.md +1 -1
  163. package/docs/troubleshooting/authentication-issues.md +334 -0
  164. package/docs/troubleshooting/common-issues.md +2 -0
  165. package/docs/troubleshooting/styling-issues.md +199 -144
  166. package/docs/usage.md +23 -2
  167. package/package.json +1 -1
  168. package/src/__tests__/{TESTING_GUIDELINES.md → TEST_GUIDE_CURSOR.md} +20 -0
  169. package/src/__tests__/TEST_GUIDE_HUMAN.md +103 -0
  170. package/src/__tests__/fixtures/test-data.ts +90 -0
  171. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +260 -0
  172. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +224 -0
  173. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +273 -0
  174. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +98 -0
  175. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +436 -0
  176. package/src/__tests__/helpers/__tests__/timer-utils.test.ts +371 -0
  177. package/src/__tests__/helpers/component-test-utils.tsx +14 -4
  178. package/src/__tests__/helpers/optimized-test-setup.ts +68 -0
  179. package/src/__tests__/helpers/test-providers.tsx +329 -0
  180. package/src/__tests__/helpers/test-utils.tsx +91 -45
  181. package/src/__tests__/helpers/timer-utils.ts +71 -0
  182. package/src/__tests__/hooks/usePermissions.test.ts +1 -5
  183. package/src/__tests__/integration/UserProfile.test.tsx +1 -5
  184. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +42 -12
  185. package/src/__tests__/setup.ts +34 -28
  186. package/src/components/Alert/Alert.test.tsx +1 -5
  187. package/src/components/Avatar/Avatar.test.tsx +1 -5
  188. package/src/components/Button/Button.test.tsx +4 -20
  189. package/src/components/Card/Card.test.tsx +1 -5
  190. package/src/components/Checkbox/Checkbox.test.tsx +1 -5
  191. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +1 -5
  192. package/src/components/DataTable/__tests__/DataTable.test.tsx +45 -49
  193. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +1 -5
  194. package/src/components/DataTable/__tests__/styles.test.ts +382 -0
  195. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +409 -0
  196. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +634 -0
  197. package/src/components/DataTable/core/__tests__/DataManager.test.ts +519 -0
  198. package/src/components/DataTable/core/__tests__/StateManager.test.ts +714 -0
  199. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +592 -0
  200. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +354 -0
  201. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +539 -0
  202. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +1 -5
  203. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +1 -8
  204. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +34 -38
  205. package/src/components/Footer/Footer.test.tsx +1 -5
  206. package/src/components/Form/Form.test.tsx +22 -35
  207. package/src/components/Header/Header.test.tsx +1 -9
  208. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +1 -5
  209. package/src/components/Input/Input.test.tsx +2 -10
  210. package/src/components/LoginForm/LoginForm.test.tsx +1 -5
  211. package/src/components/NavigationMenu/NavigationMenu.test.tsx +24 -24
  212. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +1 -6
  213. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +6 -16
  214. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +1 -5
  215. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +1 -5
  216. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +1 -7
  217. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +1 -9
  218. package/src/components/PasswordReset/PasswordResetForm.test.tsx +1 -9
  219. package/src/components/PublicLayout/PublicErrorBoundary.tsx +4 -5
  220. package/src/components/PublicLayout/PublicPageHeader.tsx +13 -9
  221. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +666 -0
  222. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +457 -0
  223. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +393 -0
  224. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +351 -0
  225. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +374 -0
  226. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +388 -0
  227. package/src/components/Select/Select.bug-test.tsx +69 -0
  228. package/src/components/Select/Select.refactored.tsx +497 -0
  229. package/src/components/Select/Select.test.tsx +42 -49
  230. package/src/components/Select/Select.tsx +5 -2
  231. package/src/components/Select/hooks.ts +254 -0
  232. package/src/components/Switch/Switch.test.tsx +1 -5
  233. package/src/components/Table/__tests__/Table.test.tsx +775 -0
  234. package/src/components/Toast/Toast.test.tsx +15 -8
  235. package/src/components/Tooltip/Tooltip.test.tsx +1 -5
  236. package/src/components/UserMenu/UserMenu.test.tsx +3 -15
  237. package/src/components/__tests__/FileDisplay.test.tsx +575 -0
  238. package/src/components/__tests__/FileUpload.test.tsx +446 -0
  239. package/src/components/__tests__/SuperAdminGuard.test.tsx +422 -354
  240. package/src/hooks/__tests__/ServiceHooks.test.tsx +613 -0
  241. package/src/hooks/__tests__/hooks.integration.test.tsx +1 -10
  242. package/src/hooks/__tests__/useApiFetch.unit.test.ts +10 -14
  243. package/src/hooks/__tests__/useAppConfig.unit.test.ts +307 -0
  244. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +1 -6
  245. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +1 -5
  246. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +6 -9
  247. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +321 -0
  248. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
  249. package/src/hooks/__tests__/usePublicEventLogo.unit.test.ts +640 -0
  250. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +435 -0
  251. package/src/hooks/__tests__/useRBAC.unit.test.ts +10 -10
  252. package/src/hooks/__tests__/useStorage.unit.test.ts +751 -0
  253. package/src/hooks/index.ts +3 -0
  254. package/src/hooks/public/usePublicEvent.ts +30 -9
  255. package/src/hooks/public/usePublicRouteParams.ts +13 -3
  256. package/src/hooks/services/useAuth.ts +50 -0
  257. package/src/hooks/services/useAuthService.ts +30 -0
  258. package/src/hooks/services/useCurrentEvent.ts +36 -0
  259. package/src/hooks/services/useCurrentOrganisation.ts +52 -0
  260. package/src/hooks/services/useEventService.ts +30 -0
  261. package/src/hooks/services/useInactivityService.ts +30 -0
  262. package/src/hooks/services/useOrganisationService.ts +30 -0
  263. package/src/hooks/services/usePermissions.ts +70 -0
  264. package/src/hooks/services/useRBACService.ts +30 -0
  265. package/src/hooks/useCounter.test.ts +1 -5
  266. package/src/hooks/useEventTheme.ts +86 -0
  267. package/src/hooks/useOrganisationPermissions.test.ts +2 -5
  268. package/src/hooks/useOrganisationSecurity.test.ts +1 -5
  269. package/src/hooks/usePermissionCache.test.ts +1 -5
  270. package/src/hooks/usePermissionCheck.ts +150 -0
  271. package/src/hooks/useSecureDataAccess.test.ts +1 -5
  272. package/src/index.ts +1 -0
  273. package/src/providers/OrganisationProvider.test.tsx +1 -5
  274. package/src/providers/OrganisationProvider.tsx +56 -4
  275. package/src/providers/UnifiedAuthProvider.test.tsx +1 -5
  276. package/src/providers/__tests__/AuthProvider.test.tsx +105 -439
  277. package/src/providers/__tests__/AuthProvider.test.tsx.backup +771 -0
  278. package/src/providers/__tests__/EventProvider.test.tsx +211 -110
  279. package/src/providers/__tests__/EventProvider.test.tsx.backup +824 -0
  280. package/src/providers/__tests__/InactivityProvider.test.tsx +1 -5
  281. package/src/providers/__tests__/OrganisationProvider.test.tsx +97 -261
  282. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +820 -0
  283. package/src/providers/__tests__/ServiceProviders.test.tsx +477 -0
  284. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +72 -504
  285. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +911 -0
  286. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +166 -0
  287. package/src/providers/services/AuthServiceProvider.tsx +65 -0
  288. package/src/providers/services/EventServiceProvider.tsx +83 -0
  289. package/src/providers/services/InactivityServiceProvider.tsx +83 -0
  290. package/src/providers/services/OrganisationServiceProvider.tsx +77 -0
  291. package/src/providers/services/RBACServiceProvider.tsx +79 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +368 -0
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +210 -0
  294. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +269 -0
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +892 -0
  296. package/src/rbac/__tests__/engine.comprehensive.test.ts +954 -0
  297. package/src/rbac/__tests__/integration.authflow.test.tsx +1 -5
  298. package/src/rbac/__tests__/integration.navigation.test.tsx +1 -4
  299. package/src/rbac/__tests__/rbac-core.test.tsx +2 -7
  300. package/src/rbac/__tests__/rbac-functions.test.ts +1 -9
  301. package/src/rbac/__tests__/rbac-integration.test.ts +1 -9
  302. package/src/rbac/api.test.ts +1 -9
  303. package/src/rbac/cache.test.ts +10 -8
  304. package/src/rbac/cli/__tests__/policy-manager.test.ts +339 -0
  305. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +1 -5
  306. package/src/rbac/components/NavigationProvider.test.tsx +1 -5
  307. package/src/rbac/components/PagePermissionProvider.test.tsx +1 -5
  308. package/src/rbac/components/SecureDataProvider.test.tsx +1 -5
  309. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +25 -29
  310. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +27 -30
  311. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +23 -27
  312. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +18 -22
  313. package/src/rbac/config.test.ts +1 -5
  314. package/src/rbac/hooks/useCan.test.ts +262 -9
  315. package/src/rbac/hooks/usePermissions.test.ts +246 -6
  316. package/src/rbac/hooks/useRBAC.simple.test.ts +1 -5
  317. package/src/rbac/hooks/useRBAC.test.ts +472 -198
  318. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +1 -9
  319. package/src/services/AuthService.ts +416 -0
  320. package/src/services/EventService.ts +366 -0
  321. package/src/services/InactivityService.ts +388 -0
  322. package/src/services/OrganisationService.ts +592 -0
  323. package/src/services/RBACService.ts +522 -0
  324. package/src/services/__tests__/AuthService.test.ts +356 -0
  325. package/src/services/__tests__/BaseService.test.ts +314 -0
  326. package/src/services/__tests__/EventService.test.ts +489 -0
  327. package/src/services/__tests__/InactivityService.test.ts +403 -0
  328. package/src/services/__tests__/OrganisationService.test.ts +660 -0
  329. package/src/services/__tests__/RBACService.test.ts +492 -0
  330. package/src/services/base/BaseService.ts +87 -0
  331. package/src/services/interfaces/IAuthService.ts +39 -0
  332. package/src/services/interfaces/IEventService.ts +30 -0
  333. package/src/services/interfaces/IInactivityService.ts +31 -0
  334. package/src/services/interfaces/IOrganisationService.ts +41 -0
  335. package/src/services/interfaces/IRBACService.ts +62 -0
  336. package/src/theming/__tests__/runtime.test.ts +540 -0
  337. package/src/types/__tests__/file-reference.test.ts +447 -0
  338. package/src/types/__tests__/organisation.test.ts +1133 -0
  339. package/src/types/__tests__/theme.test.ts +830 -0
  340. package/src/types/__tests__/type-validation.test.ts +527 -0
  341. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +1 -5
  342. package/src/utils/__tests__/debugLogger.test.ts +417 -0
  343. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -6
  344. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -5
  345. package/src/utils/__tests__/lazyLoad.unit.test.tsx +35 -35
  346. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -5
  347. package/src/utils/__tests__/performanceBudgets.unit.test.ts +5 -11
  348. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -6
  349. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -5
  350. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -5
  351. package/src/utils/__tests__/sessionTracking.unit.test.ts +1 -5
  352. package/src/utils/appIdResolver.test.ts +6 -10
  353. package/src/utils/appNameResolver.simple.test.ts +142 -0
  354. package/src/utils/appNameResolver.test.ts +31 -458
  355. package/src/utils/appNameResolver.test.ts.backup +494 -0
  356. package/src/utils/debugLogger.ts +26 -5
  357. package/src/utils/formatDate.test.ts +1 -5
  358. package/src/utils/organisationContext.test.ts +1 -5
  359. package/src/utils/performanceBudgets.ts +3 -4
  360. package/src/utils/secureDataAccess.test.ts +1 -5
  361. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -5
  362. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +1 -5
  363. package/dist/chunk-D7ARGIA3.js.map +0 -1
  364. package/dist/chunk-IPCH4YPT.js +0 -315
  365. package/dist/chunk-IPCH4YPT.js.map +0 -1
  366. package/dist/chunk-KRCRNXPD.js.map +0 -1
  367. package/dist/chunk-MOJXHWDE.js.map +0 -1
  368. package/dist/chunk-OPCWH3A4.js.map +0 -1
  369. package/dist/chunk-ZPG4XPV5.js.map +0 -1
  370. package/dist/chunk-ZPK5656W.js.map +0 -1
  371. package/docs/getting-started/installation.md +0 -269
  372. package/src/__tests__/REBUILD_PLAN.md +0 -223
  373. /package/dist/{DataTable-4IUY7BXB.js.map → DataTable-MPBSXUC6.js.map} +0 -0
  374. /package/dist/{chunk-PXWEDX7Y.js.map → chunk-2ARQW6VX.js.map} +0 -0
  375. /package/dist/{chunk-UYA6U6H7.js.map → chunk-Q2UP3ZWQ.js.map} +0 -0
@@ -0,0 +1,592 @@
1
+ /**
2
+ * @file useDataTableState Hook Tests
3
+ * @package @jmruthers/pace-core
4
+ * @module Components/DataTable/Hooks/__tests__
5
+ * @since 0.4.0
6
+ */
7
+
8
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
9
+ import { renderHook, act } from '@testing-library/react';
10
+ import { useDataTableState, dataTableReducer } from '../useDataTableState';
11
+ import type { DataRecord, SortingState, ColumnFiltersState, VisibilityState, GroupingState, ExpandedState, PaginationState } from '../../types';
12
+
13
+ interface TestData extends DataRecord {
14
+ id: string;
15
+ name: string;
16
+ email: string;
17
+ age: number;
18
+ active: boolean;
19
+ }
20
+
21
+ const mockData: TestData[] = [
22
+ { id: '1', name: 'John Doe', email: 'john@example.com', age: 30, active: true },
23
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com', age: 25, active: false },
24
+ { id: '3', name: 'Bob Johnson', email: 'bob@example.com', age: 35, active: true }
25
+ ];
26
+
27
+ describe('[unit] dataTableReducer', () => {
28
+ const initialState = {
29
+ sorting: [],
30
+ columnFilters: [],
31
+ columnVisibility: {},
32
+ grouping: [],
33
+ expanded: {},
34
+ pagination: { pageIndex: 0, pageSize: 10 },
35
+ columnOrder: ['id', 'name', 'email'],
36
+ rowSelection: {},
37
+ isCreating: false,
38
+ creationData: {},
39
+ editingRowId: null,
40
+ editingData: {},
41
+ showImportModal: false,
42
+ showFilterRow: false,
43
+ searchQuery: ''
44
+ };
45
+
46
+ it('handles SET_SORTING action', () => {
47
+ const newSorting: SortingState = [{ id: 'name', desc: false }];
48
+ const action = { type: 'SET_SORTING' as const, payload: newSorting };
49
+
50
+ const result = dataTableReducer(initialState, action);
51
+
52
+ expect(result.sorting).toEqual(newSorting);
53
+ expect(result).toEqual({ ...initialState, sorting: newSorting });
54
+ });
55
+
56
+ it('handles SET_COLUMN_FILTERS action', () => {
57
+ const newFilters: ColumnFiltersState = [{ id: 'name', value: 'John' }];
58
+ const action = { type: 'SET_COLUMN_FILTERS' as const, payload: newFilters };
59
+
60
+ const result = dataTableReducer(initialState, action);
61
+
62
+ expect(result.columnFilters).toEqual(newFilters);
63
+ });
64
+
65
+ it('handles SET_COLUMN_VISIBILITY action', () => {
66
+ const newVisibility: VisibilityState = { name: false, email: true };
67
+ const action = { type: 'SET_COLUMN_VISIBILITY' as const, payload: newVisibility };
68
+
69
+ const result = dataTableReducer(initialState, action);
70
+
71
+ expect(result.columnVisibility).toEqual(newVisibility);
72
+ });
73
+
74
+ it('handles SET_GROUPING action', () => {
75
+ const newGrouping: GroupingState = ['name'];
76
+ const action = { type: 'SET_GROUPING' as const, payload: newGrouping };
77
+
78
+ const result = dataTableReducer(initialState, action);
79
+
80
+ expect(result.grouping).toEqual(newGrouping);
81
+ });
82
+
83
+ it('handles SET_EXPANDED action', () => {
84
+ const newExpanded: ExpandedState = { '1': true };
85
+ const action = { type: 'SET_EXPANDED' as const, payload: newExpanded };
86
+
87
+ const result = dataTableReducer(initialState, action);
88
+
89
+ expect(result.expanded).toEqual(newExpanded);
90
+ });
91
+
92
+ it('handles SET_PAGINATION action', () => {
93
+ const newPagination: PaginationState = { pageIndex: 2, pageSize: 25 };
94
+ const action = { type: 'SET_PAGINATION' as const, payload: newPagination };
95
+
96
+ const result = dataTableReducer(initialState, action);
97
+
98
+ expect(result.pagination).toEqual(newPagination);
99
+ });
100
+
101
+ it('handles SET_COLUMN_ORDER action', () => {
102
+ const newOrder = ['name', 'id', 'email'];
103
+ const action = { type: 'SET_COLUMN_ORDER' as const, payload: newOrder };
104
+
105
+ const result = dataTableReducer(initialState, action);
106
+
107
+ expect(result.columnOrder).toEqual(newOrder);
108
+ });
109
+
110
+ it('handles SET_ROW_SELECTION action', () => {
111
+ const newSelection = { '1': true, '2': false };
112
+ const action = { type: 'SET_ROW_SELECTION' as const, payload: newSelection };
113
+
114
+ const result = dataTableReducer(initialState, action);
115
+
116
+ expect(result.rowSelection).toEqual(newSelection);
117
+ });
118
+
119
+ it('handles TOGGLE_ROW_SELECTION action', () => {
120
+ const initialStateWithSelection = { ...initialState, rowSelection: { '1': true } };
121
+ const action = { type: 'TOGGLE_ROW_SELECTION' as const, payload: { rowId: '2', selected: true } };
122
+
123
+ const result = dataTableReducer(initialStateWithSelection, action);
124
+
125
+ expect(result.rowSelection).toEqual({ '1': true, '2': true });
126
+ });
127
+
128
+ it('handles CLEAR_ROW_SELECTION action', () => {
129
+ const initialStateWithSelection = { ...initialState, rowSelection: { '1': true, '2': true } };
130
+ const action = { type: 'CLEAR_ROW_SELECTION' as const };
131
+
132
+ const result = dataTableReducer(initialStateWithSelection, action);
133
+
134
+ expect(result.rowSelection).toEqual({});
135
+ });
136
+
137
+ it('handles SET_CREATING action', () => {
138
+ const action = { type: 'SET_CREATING' as const, payload: true };
139
+
140
+ const result = dataTableReducer(initialState, action);
141
+
142
+ expect(result.isCreating).toBe(true);
143
+ });
144
+
145
+ it('handles SET_CREATION_DATA action', () => {
146
+ const creationData = { name: 'New User', email: 'new@example.com' };
147
+ const action = { type: 'SET_CREATION_DATA' as const, payload: creationData };
148
+
149
+ const result = dataTableReducer(initialState, action);
150
+
151
+ expect(result.creationData).toEqual(creationData);
152
+ });
153
+
154
+ it('handles CLEAR_CREATION_DATA action', () => {
155
+ const initialStateWithCreationData = { ...initialState, creationData: { name: 'Test' } };
156
+ const action = { type: 'CLEAR_CREATION_DATA' as const };
157
+
158
+ const result = dataTableReducer(initialStateWithCreationData, action);
159
+
160
+ expect(result.creationData).toEqual({});
161
+ });
162
+
163
+ it('handles SET_EDITING_ROW action', () => {
164
+ const editingData = { rowId: '1', data: { name: 'Updated Name' } };
165
+ const action = { type: 'SET_EDITING_ROW' as const, payload: editingData };
166
+
167
+ const result = dataTableReducer(initialState, action);
168
+
169
+ expect(result.editingRowId).toBe('1');
170
+ expect(result.editingData).toEqual({ name: 'Updated Name' });
171
+ });
172
+
173
+ it('handles CLEAR_EDITING action', () => {
174
+ const initialStateWithEditing = {
175
+ ...initialState,
176
+ editingRowId: '1',
177
+ editingData: { name: 'Test' }
178
+ };
179
+ const action = { type: 'CLEAR_EDITING' as const };
180
+
181
+ const result = dataTableReducer(initialStateWithEditing, action);
182
+
183
+ expect(result.editingRowId).toBe(null);
184
+ expect(result.editingData).toEqual({});
185
+ });
186
+
187
+ it('handles SET_IMPORT_MODAL action', () => {
188
+ const action = { type: 'SET_IMPORT_MODAL' as const, payload: true };
189
+
190
+ const result = dataTableReducer(initialState, action);
191
+
192
+ expect(result.showImportModal).toBe(true);
193
+ });
194
+
195
+ it('handles SET_FILTER_ROW action', () => {
196
+ const action = { type: 'SET_FILTER_ROW' as const, payload: true };
197
+
198
+ const result = dataTableReducer(initialState, action);
199
+
200
+ expect(result.showFilterRow).toBe(true);
201
+ });
202
+
203
+ it('handles SET_SEARCH_QUERY action', () => {
204
+ const action = { type: 'SET_SEARCH_QUERY' as const, payload: 'search term' };
205
+
206
+ const result = dataTableReducer(initialState, action);
207
+
208
+ expect(result.searchQuery).toBe('search term');
209
+ });
210
+
211
+ it('handles RESET_STATE action', () => {
212
+ const modifiedState = {
213
+ ...initialState,
214
+ sorting: [{ id: 'name', desc: true }],
215
+ columnFilters: [{ id: 'name', value: 'test' }],
216
+ rowSelection: { '1': true },
217
+ isCreating: true,
218
+ searchQuery: 'test query'
219
+ };
220
+
221
+ const action = { type: 'RESET_STATE' as const };
222
+
223
+ const result = dataTableReducer(modifiedState, action);
224
+
225
+ // RESET_STATE calls createInitialState() which uses default values
226
+ expect(result.columnOrder).toEqual([]);
227
+ expect(result.sorting).toEqual([]);
228
+ expect(result.columnFilters).toEqual([]);
229
+ expect(result.rowSelection).toEqual({});
230
+ expect(result.isCreating).toBe(false);
231
+ expect(result.searchQuery).toBe('');
232
+ });
233
+
234
+ it('handles INITIALIZE_STATE action', () => {
235
+ const partialState = {
236
+ sorting: [{ id: 'name', desc: false }],
237
+ searchQuery: 'initial search'
238
+ };
239
+
240
+ const action = { type: 'INITIALIZE_STATE' as const, payload: partialState };
241
+
242
+ const result = dataTableReducer(initialState, action);
243
+
244
+ expect(result.sorting).toEqual(partialState.sorting);
245
+ expect(result.searchQuery).toBe(partialState.searchQuery);
246
+ expect(result.columnFilters).toEqual(initialState.columnFilters); // Should remain unchanged
247
+ });
248
+
249
+ it('returns same state for unknown action', () => {
250
+ const unknownAction = { type: 'UNKNOWN_ACTION' as any, payload: null };
251
+
252
+ const result = dataTableReducer(initialState, unknownAction);
253
+
254
+ expect(result).toBe(initialState);
255
+ });
256
+ });
257
+
258
+ describe('[unit] useDataTableState', () => {
259
+ it('initializes with default state', () => {
260
+ const { result } = renderHook(() => useDataTableState<TestData>());
261
+
262
+ expect(result.current.state.sorting).toEqual([]);
263
+ expect(result.current.state.columnFilters).toEqual([]);
264
+ expect(result.current.state.columnVisibility).toEqual({});
265
+ expect(result.current.state.grouping).toEqual([]);
266
+ expect(result.current.state.expanded).toEqual({});
267
+ expect(result.current.state.pagination).toEqual({ pageIndex: 0, pageSize: 10 });
268
+ expect(result.current.state.columnOrder).toEqual([]);
269
+ expect(result.current.state.rowSelection).toEqual({});
270
+ expect(result.current.state.isCreating).toBe(false);
271
+ expect(result.current.state.creationData).toEqual({});
272
+ expect(result.current.state.editingRowId).toBe(null);
273
+ expect(result.current.state.editingData).toEqual({});
274
+ expect(result.current.state.showImportModal).toBe(false);
275
+ expect(result.current.state.showFilterRow).toBe(false);
276
+ expect(result.current.state.searchQuery).toBe('');
277
+ });
278
+
279
+ it('initializes with custom options', () => {
280
+ const options = {
281
+ initialPageSize: 25,
282
+ columnIds: ['id', 'name', 'email'],
283
+ initialRowSelection: { '1': true }
284
+ };
285
+
286
+ const { result } = renderHook(() => useDataTableState<TestData>(options));
287
+
288
+ expect(result.current.state.pagination.pageSize).toBe(25);
289
+ expect(result.current.state.columnOrder).toEqual(['id', 'name', 'email']);
290
+ expect(result.current.state.rowSelection).toEqual({ '1': true });
291
+ });
292
+
293
+ it('provides action creators', () => {
294
+ const { result } = renderHook(() => useDataTableState<TestData>());
295
+
296
+ expect(typeof result.current.actions.setSorting).toBe('function');
297
+ expect(typeof result.current.actions.setColumnFilters).toBe('function');
298
+ expect(typeof result.current.actions.setColumnVisibility).toBe('function');
299
+ expect(typeof result.current.actions.setGrouping).toBe('function');
300
+ expect(typeof result.current.actions.setExpanded).toBe('function');
301
+ expect(typeof result.current.actions.setPagination).toBe('function');
302
+ expect(typeof result.current.actions.setColumnOrder).toBe('function');
303
+ expect(typeof result.current.actions.setRowSelection).toBe('function');
304
+ expect(typeof result.current.actions.toggleRowSelection).toBe('function');
305
+ expect(typeof result.current.actions.clearRowSelection).toBe('function');
306
+ expect(typeof result.current.actions.setCreating).toBe('function');
307
+ expect(typeof result.current.actions.setCreationData).toBe('function');
308
+ expect(typeof result.current.actions.clearCreationData).toBe('function');
309
+ expect(typeof result.current.actions.setEditingRow).toBe('function');
310
+ expect(typeof result.current.actions.clearEditing).toBe('function');
311
+ expect(typeof result.current.actions.setImportModal).toBe('function');
312
+ expect(typeof result.current.actions.setFilterRow).toBe('function');
313
+ expect(typeof result.current.actions.setSearchQuery).toBe('function');
314
+ expect(typeof result.current.actions.resetState).toBe('function');
315
+ });
316
+
317
+ it('updates state when actions are called', () => {
318
+ const { result } = renderHook(() => useDataTableState<TestData>());
319
+
320
+ act(() => {
321
+ result.current.actions.setSorting([{ id: 'name', desc: false }]);
322
+ });
323
+
324
+ expect(result.current.state.sorting).toEqual([{ id: 'name', desc: false }]);
325
+ });
326
+
327
+ it('updates column filters', () => {
328
+ const { result } = renderHook(() => useDataTableState<TestData>());
329
+
330
+ act(() => {
331
+ result.current.actions.setColumnFilters([{ id: 'name', value: 'John' }]);
332
+ });
333
+
334
+ expect(result.current.state.columnFilters).toEqual([{ id: 'name', value: 'John' }]);
335
+ });
336
+
337
+ it('updates column visibility', () => {
338
+ const { result } = renderHook(() => useDataTableState<TestData>());
339
+
340
+ act(() => {
341
+ result.current.actions.setColumnVisibility({ name: false, email: true });
342
+ });
343
+
344
+ expect(result.current.state.columnVisibility).toEqual({ name: false, email: true });
345
+ });
346
+
347
+ it('updates grouping', () => {
348
+ const { result } = renderHook(() => useDataTableState<TestData>());
349
+
350
+ act(() => {
351
+ result.current.actions.setGrouping(['name']);
352
+ });
353
+
354
+ expect(result.current.state.grouping).toEqual(['name']);
355
+ });
356
+
357
+ it('updates expanded state', () => {
358
+ const { result } = renderHook(() => useDataTableState<TestData>());
359
+
360
+ act(() => {
361
+ result.current.actions.setExpanded({ '1': true });
362
+ });
363
+
364
+ expect(result.current.state.expanded).toEqual({ '1': true });
365
+ });
366
+
367
+ it('updates pagination', () => {
368
+ const { result } = renderHook(() => useDataTableState<TestData>());
369
+
370
+ act(() => {
371
+ result.current.actions.setPagination({ pageIndex: 2, pageSize: 25 });
372
+ });
373
+
374
+ expect(result.current.state.pagination).toEqual({ pageIndex: 2, pageSize: 25 });
375
+ });
376
+
377
+ it('updates column order', () => {
378
+ const { result } = renderHook(() => useDataTableState<TestData>());
379
+
380
+ act(() => {
381
+ result.current.actions.setColumnOrder(['name', 'id', 'email']);
382
+ });
383
+
384
+ expect(result.current.state.columnOrder).toEqual(['name', 'id', 'email']);
385
+ });
386
+
387
+ it('updates row selection', () => {
388
+ const { result } = renderHook(() => useDataTableState<TestData>());
389
+
390
+ act(() => {
391
+ result.current.actions.setRowSelection({ '1': true, '2': false });
392
+ });
393
+
394
+ expect(result.current.state.rowSelection).toEqual({ '1': true, '2': false });
395
+ });
396
+
397
+ it('toggles row selection', () => {
398
+ const { result } = renderHook(() => useDataTableState<TestData>());
399
+
400
+ act(() => {
401
+ result.current.actions.toggleRowSelection('1', true);
402
+ });
403
+
404
+ expect(result.current.state.rowSelection).toEqual({ '1': true });
405
+
406
+ act(() => {
407
+ result.current.actions.toggleRowSelection('1', false);
408
+ });
409
+
410
+ expect(result.current.state.rowSelection).toEqual({ '1': false });
411
+ });
412
+
413
+ it('clears row selection', () => {
414
+ const { result } = renderHook(() => useDataTableState<TestData>());
415
+
416
+ act(() => {
417
+ result.current.actions.setRowSelection({ '1': true, '2': true });
418
+ });
419
+
420
+ expect(result.current.state.rowSelection).toEqual({ '1': true, '2': true });
421
+
422
+ act(() => {
423
+ result.current.actions.clearRowSelection();
424
+ });
425
+
426
+ expect(result.current.state.rowSelection).toEqual({});
427
+ });
428
+
429
+ it('updates creating state', () => {
430
+ const { result } = renderHook(() => useDataTableState<TestData>());
431
+
432
+ act(() => {
433
+ result.current.actions.setCreating(true);
434
+ });
435
+
436
+ expect(result.current.state.isCreating).toBe(true);
437
+ });
438
+
439
+ it('updates creation data', () => {
440
+ const { result } = renderHook(() => useDataTableState<TestData>());
441
+ const creationData = { name: 'New User', email: 'new@example.com' };
442
+
443
+ act(() => {
444
+ result.current.actions.setCreationData(creationData);
445
+ });
446
+
447
+ expect(result.current.state.creationData).toEqual(creationData);
448
+ });
449
+
450
+ it('clears creation data', () => {
451
+ const { result } = renderHook(() => useDataTableState<TestData>());
452
+
453
+ act(() => {
454
+ result.current.actions.setCreationData({ name: 'Test' });
455
+ });
456
+
457
+ expect(result.current.state.creationData).toEqual({ name: 'Test' });
458
+
459
+ act(() => {
460
+ result.current.actions.clearCreationData();
461
+ });
462
+
463
+ expect(result.current.state.creationData).toEqual({});
464
+ });
465
+
466
+ it('updates editing row', () => {
467
+ const { result } = renderHook(() => useDataTableState<TestData>());
468
+
469
+ act(() => {
470
+ result.current.actions.setEditingRow('1', { name: 'Updated Name' });
471
+ });
472
+
473
+ expect(result.current.state.editingRowId).toBe('1');
474
+ expect(result.current.state.editingData).toEqual({ name: 'Updated Name' });
475
+ });
476
+
477
+ it('clears editing state', () => {
478
+ const { result } = renderHook(() => useDataTableState<TestData>());
479
+
480
+ act(() => {
481
+ result.current.actions.setEditingRow('1', { name: 'Test' });
482
+ });
483
+
484
+ expect(result.current.state.editingRowId).toBe('1');
485
+
486
+ act(() => {
487
+ result.current.actions.clearEditing();
488
+ });
489
+
490
+ expect(result.current.state.editingRowId).toBe(null);
491
+ expect(result.current.state.editingData).toEqual({});
492
+ });
493
+
494
+ it('updates import modal state', () => {
495
+ const { result } = renderHook(() => useDataTableState<TestData>());
496
+
497
+ act(() => {
498
+ result.current.actions.setImportModal(true);
499
+ });
500
+
501
+ expect(result.current.state.showImportModal).toBe(true);
502
+ });
503
+
504
+ it('updates filter row state', () => {
505
+ const { result } = renderHook(() => useDataTableState<TestData>());
506
+
507
+ act(() => {
508
+ result.current.actions.setFilterRow(true);
509
+ });
510
+
511
+ expect(result.current.state.showFilterRow).toBe(true);
512
+ });
513
+
514
+ it('updates search query', () => {
515
+ const { result } = renderHook(() => useDataTableState<TestData>());
516
+
517
+ act(() => {
518
+ result.current.actions.setSearchQuery('search term');
519
+ });
520
+
521
+ expect(result.current.state.searchQuery).toBe('search term');
522
+ });
523
+
524
+ it('resets state to initial values', () => {
525
+ const { result } = renderHook(() => useDataTableState<TestData>());
526
+
527
+ // Modify state
528
+ act(() => {
529
+ result.current.actions.setSorting([{ id: 'name', desc: true }]);
530
+ result.current.actions.setColumnFilters([{ id: 'name', value: 'test' }]);
531
+ result.current.actions.setRowSelection({ '1': true });
532
+ result.current.actions.setSearchQuery('test query');
533
+ });
534
+
535
+ expect(result.current.state.sorting).toEqual([{ id: 'name', desc: true }]);
536
+ expect(result.current.state.columnFilters).toEqual([{ id: 'name', value: 'test' }]);
537
+ expect(result.current.state.rowSelection).toEqual({ '1': true });
538
+ expect(result.current.state.searchQuery).toBe('test query');
539
+
540
+ // Reset state
541
+ act(() => {
542
+ result.current.actions.resetState();
543
+ });
544
+
545
+ expect(result.current.state.sorting).toEqual([]);
546
+ expect(result.current.state.columnFilters).toEqual([]);
547
+ expect(result.current.state.rowSelection).toEqual({});
548
+ expect(result.current.state.searchQuery).toBe('');
549
+ });
550
+
551
+ it('calls onRowSelectionChange callback when provided', () => {
552
+ const onRowSelectionChange = vi.fn();
553
+ const { result } = renderHook(() =>
554
+ useDataTableState<TestData>({ onRowSelectionChange })
555
+ );
556
+
557
+ act(() => {
558
+ result.current.actions.setRowSelection({ '1': true });
559
+ });
560
+
561
+ expect(onRowSelectionChange).toHaveBeenCalledWith({ '1': true });
562
+ });
563
+
564
+ it('provides computed values', () => {
565
+ const { result } = renderHook(() => useDataTableState<TestData>());
566
+
567
+ expect(result.current.computed).toBeDefined();
568
+ expect(typeof result.current.computed).toBe('object');
569
+ });
570
+
571
+ it('provides clearFilters function', () => {
572
+ const { result } = renderHook(() => useDataTableState<TestData>());
573
+
574
+ expect(typeof result.current.clearFilters).toBe('function');
575
+ });
576
+
577
+ it('maintains state consistency across multiple actions', () => {
578
+ const { result } = renderHook(() => useDataTableState<TestData>());
579
+
580
+ act(() => {
581
+ result.current.actions.setSorting([{ id: 'name', desc: false }]);
582
+ result.current.actions.setColumnFilters([{ id: 'name', value: 'John' }]);
583
+ result.current.actions.setPagination({ pageIndex: 1, pageSize: 25 });
584
+ result.current.actions.setRowSelection({ '1': true, '2': false });
585
+ });
586
+
587
+ expect(result.current.state.sorting).toEqual([{ id: 'name', desc: false }]);
588
+ expect(result.current.state.columnFilters).toEqual([{ id: 'name', value: 'John' }]);
589
+ expect(result.current.state.pagination).toEqual({ pageIndex: 1, pageSize: 25 });
590
+ expect(result.current.state.rowSelection).toEqual({ '1': true, '2': false });
591
+ });
592
+ });