@jmruthers/pace-core 0.5.76 → 0.5.78

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 (447) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
  3. package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
  4. package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
  5. package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
  6. package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
  7. package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
  8. package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
  9. package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
  10. package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
  11. package/dist/chunk-2OGV6IRV.js.map +1 -0
  12. package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
  13. package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
  14. package/dist/chunk-CVMVPYAL.js.map +1 -0
  15. package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
  16. package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
  17. package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
  18. package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
  19. package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
  20. package/dist/chunk-LRQ6RBJC.js.map +1 -0
  21. package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
  22. package/dist/chunk-MNJXXD6C.js.map +1 -0
  23. package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
  24. package/dist/chunk-PTR5PMPE.js.map +1 -0
  25. package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
  26. package/dist/chunk-Q7APDV6H.js.map +1 -0
  27. package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
  28. package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
  29. package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
  30. package/dist/chunk-S63MFSY6.js.map +1 -0
  31. package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
  32. package/dist/chunk-WUXCWRL6.js +20 -0
  33. package/dist/chunk-WUXCWRL6.js.map +1 -0
  34. package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
  35. package/dist/chunk-YVVGHRGI.js.map +1 -0
  36. package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
  37. package/dist/chunk-ZMNXIJP4.js.map +1 -0
  38. package/dist/components.d.ts +6 -6
  39. package/dist/components.js +14 -18
  40. package/dist/components.js.map +1 -1
  41. package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
  42. package/dist/hooks.d.ts +5 -5
  43. package/dist/hooks.js +8 -9
  44. package/dist/hooks.js.map +1 -1
  45. package/dist/index.d.ts +19 -27
  46. package/dist/index.js +21 -29
  47. package/dist/index.js.map +1 -1
  48. package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
  49. package/dist/providers.d.ts +7 -21
  50. package/dist/providers.js +3 -10
  51. package/dist/rbac/index.d.ts +71 -221
  52. package/dist/rbac/index.js +15 -16
  53. package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
  54. package/dist/types.d.ts +3 -3
  55. package/dist/types.js +61 -18
  56. package/dist/types.js.map +1 -1
  57. package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
  58. package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
  59. package/dist/utils.d.ts +2 -2
  60. package/dist/utils.js +52 -9
  61. package/dist/utils.js.map +1 -1
  62. package/docs/CONTENT_AUDIT_REPORT.md +253 -0
  63. package/docs/DOCUMENTATION_AUDIT.md +172 -0
  64. package/docs/README.md +142 -147
  65. package/docs/STYLE_GUIDE.md +37 -0
  66. package/docs/api/classes/ColumnFactory.md +17 -17
  67. package/docs/api/classes/ErrorBoundary.md +1 -1
  68. package/docs/api/classes/InvalidScopeError.md +4 -4
  69. package/docs/api/classes/MissingUserContextError.md +4 -4
  70. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  71. package/docs/api/classes/PermissionDeniedError.md +5 -5
  72. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  73. package/docs/api/classes/RBACAuditManager.md +8 -8
  74. package/docs/api/classes/RBACCache.md +35 -5
  75. package/docs/api/classes/RBACEngine.md +49 -20
  76. package/docs/api/classes/RBACError.md +4 -4
  77. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  78. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  79. package/docs/api/classes/StorageUtils.md +1 -1
  80. package/docs/api/enums/FileCategory.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +4 -4
  82. package/docs/api/interfaces/ButtonProps.md +1 -1
  83. package/docs/api/interfaces/CardProps.md +1 -1
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +11 -0
  88. package/docs/api/interfaces/DataTableAction.md +65 -29
  89. package/docs/api/interfaces/DataTableColumn.md +36 -23
  90. package/docs/api/interfaces/DataTableProps.md +80 -38
  91. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  92. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  93. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  94. package/docs/api/interfaces/EventLogoProps.md +1 -1
  95. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  96. package/docs/api/interfaces/FileMetadata.md +1 -1
  97. package/docs/api/interfaces/FileReference.md +1 -1
  98. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  99. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
  107. package/docs/api/interfaces/NavigationContextType.md +9 -9
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACLogger.md +1 -1
  133. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  134. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  135. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  136. package/docs/api/interfaces/RouteConfig.md +2 -2
  137. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  138. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  139. package/docs/api/interfaces/StorageConfig.md +1 -1
  140. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  141. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  142. package/docs/api/interfaces/StorageListOptions.md +1 -1
  143. package/docs/api/interfaces/StorageListResult.md +1 -1
  144. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  145. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  146. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  147. package/docs/api/interfaces/StyleImport.md +1 -1
  148. package/docs/api/interfaces/SwitchProps.md +1 -1
  149. package/docs/api/interfaces/ToastActionElement.md +1 -1
  150. package/docs/api/interfaces/ToastProps.md +1 -1
  151. package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
  152. package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
  153. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  155. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  159. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  160. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  161. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  162. package/docs/api/interfaces/UserEventAccess.md +11 -11
  163. package/docs/api/interfaces/UserMenuProps.md +1 -1
  164. package/docs/api/interfaces/UserProfile.md +1 -1
  165. package/docs/api/modules.md +251 -269
  166. package/docs/api-reference/components.md +193 -0
  167. package/docs/api-reference/hooks.md +265 -0
  168. package/docs/api-reference/providers.md +6 -0
  169. package/docs/api-reference/types.md +6 -0
  170. package/docs/api-reference/utilities.md +207 -0
  171. package/docs/architecture/README.md +6 -0
  172. package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
  173. package/docs/architecture/rbac-security-architecture.md +258 -0
  174. package/docs/architecture/services.md +9 -1
  175. package/docs/best-practices/README.md +6 -0
  176. package/docs/best-practices/accessibility.md +6 -0
  177. package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
  178. package/docs/best-practices/deployment.md +6 -0
  179. package/docs/best-practices/performance.md +475 -2
  180. package/docs/best-practices/security.md +6 -0
  181. package/docs/best-practices/testing.md +6 -0
  182. package/docs/core-concepts/authentication.md +6 -0
  183. package/docs/core-concepts/events.md +6 -0
  184. package/docs/core-concepts/organisations.md +6 -0
  185. package/docs/core-concepts/permissions.md +6 -0
  186. package/docs/core-concepts/rbac-system.md +8 -0
  187. package/docs/documentation-index.md +121 -182
  188. package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
  189. package/docs/getting-started/documentation-index.md +40 -0
  190. package/docs/getting-started/examples/README.md +878 -35
  191. package/docs/{faq.md → getting-started/faq.md} +7 -1
  192. package/docs/getting-started/installation-guide.md +6 -0
  193. package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
  194. package/docs/implementation-guides/app-layout.md +6 -0
  195. package/docs/implementation-guides/authentication.md +1021 -0
  196. package/docs/implementation-guides/component-styling.md +6 -0
  197. package/docs/implementation-guides/data-tables.md +1264 -2076
  198. package/docs/implementation-guides/dynamic-colors.md +6 -0
  199. package/docs/implementation-guides/event-theming-summary.md +6 -0
  200. package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
  201. package/docs/implementation-guides/file-upload-storage.md +6 -0
  202. package/docs/implementation-guides/forms.md +6 -0
  203. package/docs/implementation-guides/inactivity-tracking.md +6 -0
  204. package/docs/implementation-guides/navigation.md +6 -0
  205. package/docs/implementation-guides/organisation-security.md +6 -0
  206. package/docs/implementation-guides/permission-enforcement.md +6 -0
  207. package/docs/implementation-guides/public-pages-advanced.md +6 -0
  208. package/docs/implementation-guides/public-pages.md +6 -0
  209. package/docs/migration/MIGRATION_GUIDE.md +827 -351
  210. package/docs/migration/README.md +7 -1
  211. package/docs/migration/organisation-context-timing-fix.md +6 -0
  212. package/docs/migration/rbac-migration.md +44 -1
  213. package/docs/migration/service-architecture.md +6 -0
  214. package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
  215. package/docs/migration/v0.4.16-css-first-approach.md +6 -0
  216. package/docs/migration/v0.4.17-source-path-fix.md +6 -0
  217. package/docs/rbac/README-rbac-rls-integration.md +6 -0
  218. package/docs/rbac/README.md +6 -0
  219. package/docs/rbac/advanced-patterns.md +6 -0
  220. package/docs/rbac/api-reference.md +7 -1
  221. package/docs/rbac/breaking-changes-v3.md +222 -0
  222. package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
  223. package/docs/rbac/examples.md +6 -0
  224. package/docs/rbac/getting-started.md +6 -0
  225. package/docs/rbac/migration-guide.md +260 -0
  226. package/docs/rbac/quick-start.md +70 -13
  227. package/docs/rbac/rbac-rls-integration.md +6 -0
  228. package/docs/rbac/super-admin-guide.md +6 -0
  229. package/docs/rbac/troubleshooting.md +6 -0
  230. package/docs/security/README.md +6 -0
  231. package/docs/security/checklist.md +6 -0
  232. package/docs/styles/README.md +7 -1
  233. package/docs/{usage.md → styles/usage.md} +6 -0
  234. package/docs/testing/README.md +6 -0
  235. package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
  236. package/docs/troubleshooting/README.md +387 -5
  237. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
  238. package/docs/troubleshooting/common-issues.md +6 -0
  239. package/docs/troubleshooting/database-view-compatibility.md +6 -0
  240. package/docs/troubleshooting/organisation-context-setup.md +6 -0
  241. package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
  242. package/docs/troubleshooting/styling-issues.md +6 -0
  243. package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
  244. package/package.json +1 -1
  245. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
  246. package/src/__tests__/helpers/test-providers.tsx +3 -53
  247. package/src/components/DataTable/DataTable.test.tsx +319 -0
  248. package/src/components/DataTable/DataTable.tsx +32 -11
  249. package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
  250. package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
  251. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
  252. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
  253. package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
  254. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
  255. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
  256. package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
  257. package/src/components/DataTable/components/ActionButtons.tsx +88 -104
  258. package/src/components/DataTable/components/DataTableCore.tsx +309 -337
  259. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
  260. package/src/components/DataTable/components/DataTableModals.tsx +22 -1
  261. package/src/components/DataTable/components/EditableRow.tsx +69 -84
  262. package/src/components/DataTable/components/EmptyState.tsx +5 -1
  263. package/src/components/DataTable/components/ImportModal.tsx +65 -36
  264. package/src/components/DataTable/components/PaginationControls.tsx +40 -100
  265. package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
  266. package/src/components/DataTable/context/DataTableContext.tsx +1 -1
  267. package/src/components/DataTable/core/ColumnFactory.ts +5 -0
  268. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
  269. package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
  270. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
  271. package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
  272. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
  273. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
  274. package/src/components/DataTable/hooks/index.ts +7 -0
  275. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
  276. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
  277. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
  278. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
  280. package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
  281. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
  282. package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
  283. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
  284. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
  285. package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
  286. package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
  287. package/src/components/DataTable/index.ts +12 -3
  288. package/src/components/DataTable/types.ts +129 -9
  289. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
  290. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
  291. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
  292. package/src/components/DataTable/utils/a11yUtils.ts +244 -0
  293. package/src/components/DataTable/utils/debugTools.ts +609 -0
  294. package/src/components/DataTable/utils/exportUtils.ts +114 -16
  295. package/src/components/DataTable/utils/flexibleImport.ts +202 -32
  296. package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
  297. package/src/components/DataTable/utils/index.ts +2 -0
  298. package/src/components/DataTable/utils/paginationUtils.ts +350 -0
  299. package/src/components/DataTable/utils/rowUtils.ts +6 -5
  300. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
  301. package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
  302. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
  303. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
  304. package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
  305. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
  306. package/src/components/Select/Select.tsx +1 -0
  307. package/src/components/examples/PermissionExample.tsx +173 -0
  308. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  309. package/src/examples/PublicEventPage.tsx +274 -0
  310. package/src/examples/PublicPageApp.tsx +308 -0
  311. package/src/examples/PublicPageUsageExample.tsx +216 -0
  312. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
  313. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
  314. package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
  315. package/src/hooks/useOrganisationPermissions.test.ts +42 -18
  316. package/src/hooks/useOrganisationPermissions.ts +12 -6
  317. package/src/hooks/useOrganisationSecurity.test.ts +138 -85
  318. package/src/hooks/useOrganisationSecurity.ts +41 -10
  319. package/src/index.ts +0 -1
  320. package/src/providers/AuthProvider.simplified.tsx +880 -0
  321. package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
  322. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
  323. package/src/providers/index.ts +0 -1
  324. package/src/providers/services/EventServiceProvider.tsx +19 -15
  325. package/src/providers/services/InactivityServiceProvider.tsx +19 -15
  326. package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
  327. package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
  328. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
  329. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
  330. package/src/rbac/README.md +1 -1
  331. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
  332. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
  333. package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
  334. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
  335. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
  336. package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
  337. package/src/rbac/adapters.tsx +26 -69
  338. package/src/rbac/api.test.ts +90 -27
  339. package/src/rbac/api.ts +61 -10
  340. package/src/rbac/audit.test.ts +33 -38
  341. package/src/rbac/audit.ts +21 -6
  342. package/src/rbac/cache.ts +33 -1
  343. package/src/rbac/components/NavigationGuard.tsx +11 -11
  344. package/src/rbac/components/NavigationProvider.test.tsx +11 -5
  345. package/src/rbac/components/NavigationProvider.tsx +37 -13
  346. package/src/rbac/components/PagePermissionGuard.tsx +111 -50
  347. package/src/rbac/components/PagePermissionProvider.tsx +5 -5
  348. package/src/rbac/components/PermissionEnforcer.tsx +11 -11
  349. package/src/rbac/components/RoleBasedRouter.tsx +5 -5
  350. package/src/rbac/components/SecureDataProvider.tsx +5 -5
  351. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
  352. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
  353. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
  354. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
  355. package/src/rbac/engine.test.simple.ts +19 -13
  356. package/src/rbac/engine.test.ts +1 -0
  357. package/src/rbac/engine.ts +330 -766
  358. package/src/rbac/errors.ts +156 -0
  359. package/src/rbac/hooks/usePermissions.ts +32 -10
  360. package/src/rbac/hooks/useRBAC.test.ts +126 -512
  361. package/src/rbac/hooks/useRBAC.ts +147 -193
  362. package/src/rbac/hooks/useResolvedScope.ts +12 -0
  363. package/src/rbac/index.ts +7 -4
  364. package/src/rbac/security.ts +109 -18
  365. package/src/rbac/types.ts +12 -1
  366. package/src/services/AuthService.ts +2 -15
  367. package/src/services/EventService.ts +43 -46
  368. package/src/services/OrganisationService.ts +51 -31
  369. package/src/services/__tests__/AuthService.test.ts +1 -1
  370. package/src/services/__tests__/EventService.test.ts +1 -1
  371. package/src/services/__tests__/OrganisationService.test.ts +1 -1
  372. package/src/services/base/BaseService.ts +8 -0
  373. package/src/styles/base.css +208 -0
  374. package/src/styles/semantic.css +24 -0
  375. package/src/types/database.generated.ts +7347 -0
  376. package/src/types/database.ts +20 -0
  377. package/src/utils/logger.ts +179 -0
  378. package/src/utils/organisationContext.ts +11 -4
  379. package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
  380. package/dist/appNameResolver-UURKN7NF.js +0 -22
  381. package/dist/audit-6TOCAMKO.js.map +0 -1
  382. package/dist/chunk-B2WTCLCV.js.map +0 -1
  383. package/dist/chunk-FGMFQSHX.js.map +0 -1
  384. package/dist/chunk-K34IM5CT.js.map +0 -1
  385. package/dist/chunk-KHJS6VIA.js.map +0 -1
  386. package/dist/chunk-KK73ZB4E.js.map +0 -1
  387. package/dist/chunk-M5IWZRBT.js.map +0 -1
  388. package/dist/chunk-ULBI5JGB.js +0 -109
  389. package/dist/chunk-ULBI5JGB.js.map +0 -1
  390. package/dist/chunk-WN6XJWOS.js.map +0 -1
  391. package/dist/chunk-XLZ7U46Z.js.map +0 -1
  392. package/dist/chunk-Y6TXWPJO.js.map +0 -1
  393. package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
  394. package/docs/TERMINOLOGY.md +0 -231
  395. package/docs/api/interfaces/RBACContextType.md +0 -468
  396. package/docs/api/interfaces/RBACProviderProps.md +0 -107
  397. package/docs/best-practices/performance-expansion.md +0 -473
  398. package/docs/breaking-changes.md +0 -179
  399. package/docs/consuming-app-example.md +0 -290
  400. package/docs/documentation-templates.md +0 -539
  401. package/docs/examples/navigation-menu-auth-fix.md +0 -344
  402. package/docs/getting-started/examples/basic-auth-app.md +0 -520
  403. package/docs/getting-started/examples/full-featured-app.md +0 -616
  404. package/docs/getting-started/quick-start.md +0 -376
  405. package/docs/implementation-guides/datatable-filtering.md +0 -313
  406. package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
  407. package/docs/implementation-guides/hierarchical-datatable.md +0 -850
  408. package/docs/implementation-guides/large-datasets.md +0 -281
  409. package/docs/implementation-guides/performance.md +0 -403
  410. package/docs/migration/quick-migration-guide.md +0 -320
  411. package/docs/migration-guide.md +0 -193
  412. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
  413. package/docs/performance/README.md +0 -551
  414. package/docs/style-guide.md +0 -964
  415. package/docs/troubleshooting/authentication-issues.md +0 -334
  416. package/docs/troubleshooting/debugging.md +0 -1117
  417. package/docs/troubleshooting/migration.md +0 -918
  418. package/src/__tests__/hooks/usePermissions.test.ts +0 -261
  419. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
  420. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
  421. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
  422. package/src/hooks/services/usePermissions.ts +0 -70
  423. package/src/hooks/services/useRBACService.ts +0 -30
  424. package/src/hooks/usePermissionCheck.ts +0 -150
  425. package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
  426. package/src/providers/services/RBACServiceProvider.tsx +0 -79
  427. package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
  428. package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
  429. package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
  430. package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
  431. package/src/rbac/providers/RBACProvider.tsx +0 -645
  432. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
  433. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
  434. package/src/rbac/providers/index.ts +0 -11
  435. package/src/services/RBACService.ts +0 -522
  436. package/src/services/__tests__/RBACService.test.ts +0 -492
  437. package/src/services/interfaces/IRBACService.ts +0 -62
  438. package/src/utils/appNameResolver.test 2.ts +0 -494
  439. /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
  440. /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
  441. /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
  442. /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
  443. /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
  444. /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
  445. /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
  446. /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
  447. /package/docs/{app.css.example → styles/app.css.example} +0 -0
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @file DataTable data pipeline hook
3
+ * @description Encapsulates hierarchical validation, sorting, and data source
4
+ * resolution so the main DataTable component can focus on orchestration.
5
+ */
6
+
7
+ import { useMemo } from 'react';
8
+ import { useHierarchicalState, type HierarchicalState } from './useHierarchicalState';
9
+ import { validateHierarchicalData } from '../utils/hierarchicalUtils';
10
+ import {
11
+ sortHierarchicalDataByStructure,
12
+ sortHierarchicalDataWithSorting,
13
+ } from '../utils/hierarchicalSorting';
14
+ import type {
15
+ DataRecord,
16
+ HierarchicalConfig,
17
+ HierarchicalDataRow,
18
+ NormalizedDataTableFeatureConfig,
19
+ PaginationMode,
20
+ ServerSideResponse,
21
+ } from '../types';
22
+ import type { SortingState } from '@tanstack/react-table';
23
+
24
+ export interface UseDataTableDataPipelineParams<TData extends DataRecord> {
25
+ data: TData[];
26
+ features: NormalizedDataTableFeatureConfig;
27
+ hierarchical?: HierarchicalConfig;
28
+ sorting: SortingState;
29
+ finalPaginationMode: PaginationMode;
30
+ serverData: ServerSideResponse<TData> | null;
31
+ }
32
+
33
+ export interface UseDataTableDataPipelineResult<TData extends DataRecord> {
34
+ finalTableData: TData[];
35
+ dataCount: number;
36
+ hierarchicalState?: HierarchicalState<HierarchicalDataRow>;
37
+ hierarchicalValidation: { isValid: boolean; errors: string[] };
38
+ }
39
+
40
+ export function useDataTableDataPipeline<TData extends DataRecord>({
41
+ data,
42
+ features,
43
+ hierarchical,
44
+ sorting,
45
+ finalPaginationMode,
46
+ serverData,
47
+ }: UseDataTableDataPipelineParams<TData>): UseDataTableDataPipelineResult<TData> {
48
+ const hierarchicalEnabled = Boolean(features.hierarchical && hierarchical?.enabled);
49
+
50
+ const hierarchicalValidation = useMemo(() => {
51
+ if (!hierarchicalEnabled) {
52
+ return { isValid: true, errors: [] as string[] };
53
+ }
54
+
55
+ return validateHierarchicalData(data as unknown as HierarchicalDataRow[]);
56
+ }, [data, hierarchicalEnabled]);
57
+
58
+ const structuredHierarchicalData = useMemo(() => {
59
+ if (!hierarchicalEnabled || !hierarchicalValidation.isValid) {
60
+ return data;
61
+ }
62
+
63
+ return sortHierarchicalDataByStructure(data as unknown as HierarchicalDataRow[]) as unknown as TData[];
64
+ }, [data, hierarchicalEnabled, hierarchicalValidation.isValid]);
65
+
66
+ const hierarchicalState = useHierarchicalState<HierarchicalDataRow>(
67
+ (hierarchicalEnabled && hierarchicalValidation.isValid
68
+ ? (structuredHierarchicalData as unknown as HierarchicalDataRow[])
69
+ : []) as HierarchicalDataRow[],
70
+ hierarchicalEnabled ? hierarchical : undefined
71
+ );
72
+
73
+ const baseData = useMemo(() => {
74
+ if (finalPaginationMode === 'server') {
75
+ return serverData?.data ?? [];
76
+ }
77
+
78
+ return structuredHierarchicalData;
79
+ }, [finalPaginationMode, serverData?.data, structuredHierarchicalData]);
80
+
81
+ const tableData = useMemo(() => {
82
+ if (!hierarchicalEnabled) {
83
+ return baseData;
84
+ }
85
+
86
+ return (hierarchicalState.visibleRows as unknown as TData[]) ?? [];
87
+ }, [baseData, hierarchicalEnabled, hierarchicalState.visibleRows]);
88
+
89
+ const sortedHierarchicalData = useMemo(() => {
90
+ if (!hierarchicalEnabled || sorting.length === 0) {
91
+ return tableData;
92
+ }
93
+
94
+ const visibleRows = hierarchicalState.visibleRows as unknown as HierarchicalDataRow[];
95
+ return sortHierarchicalDataWithSorting(visibleRows, sorting) as unknown as TData[];
96
+ }, [hierarchicalEnabled, hierarchicalState.visibleRows, sorting, tableData]);
97
+
98
+ const finalTableData = hierarchicalEnabled && sorting.length > 0
99
+ ? sortedHierarchicalData
100
+ : tableData;
101
+
102
+ const dataCount = useMemo(() => {
103
+ if (finalPaginationMode === 'server') {
104
+ return serverData?.totalCount ?? 0;
105
+ }
106
+
107
+ return finalTableData?.length ?? 0;
108
+ }, [finalPaginationMode, finalTableData?.length, serverData?.totalCount]);
109
+
110
+ return {
111
+ finalTableData,
112
+ dataCount,
113
+ hierarchicalState: hierarchicalEnabled ? hierarchicalState : undefined,
114
+ hierarchicalValidation,
115
+ };
116
+ }
117
+
@@ -12,7 +12,14 @@ import { useMemo, useRef } from 'react';
12
12
  import { useUnifiedAuth } from '../../../providers/UnifiedAuthProvider';
13
13
  import { useCan, useResolvedScope } from '../../../rbac/hooks';
14
14
  import { useToast } from '../../../hooks/useToast';
15
- import type { DataTableFeatureConfig, DataTableRBACConfig } from '../types';
15
+ import { createLogger } from '../../../utils/logger';
16
+ import {
17
+ normalizeDataTableFeatures,
18
+ type DataTableFeatureConfig,
19
+ type DataTableRBACConfig,
20
+ type NormalizedDataTableFeatureConfig,
21
+ } from '../types';
22
+ import type { Permission } from '../../../rbac/types';
16
23
 
17
24
  export interface UseDataTablePermissionsReturn {
18
25
  permissions: {
@@ -23,14 +30,15 @@ export interface UseDataTablePermissionsReturn {
23
30
  canExport: ReturnType<typeof useCan>;
24
31
  canImport: ReturnType<typeof useCan>;
25
32
  };
26
- secureFeatures: DataTableFeatureConfig;
33
+ secureFeatures: NormalizedDataTableFeatureConfig;
27
34
  effectivePageId: string | undefined;
28
35
  }
29
36
 
30
37
  export function useDataTablePermissions<TData extends Record<string, any>>(
31
38
  rbac: DataTableRBACConfig,
32
- features: DataTableFeatureConfig
39
+ features: DataTableFeatureConfig = {}
33
40
  ): UseDataTablePermissionsReturn {
41
+ const logger = createLogger('DataTablePermissions');
34
42
  const authResult = useUnifiedAuth();
35
43
  const user = authResult.user;
36
44
 
@@ -61,11 +69,21 @@ export function useDataTablePermissions<TData extends Record<string, any>>(
61
69
  */
62
70
 
63
71
  // Use shared scope resolution hook for consistent RBAC scoping
64
- const { selectedOrganisationId, selectedEventId, supabase } = useUnifiedAuth();
65
- const { resolvedScope: rawResolvedScope } = useResolvedScope({
72
+ const { selectedOrganisation, selectedEvent, supabase, organisations } = useUnifiedAuth();
73
+
74
+ // Debug logging to understand organisation context
75
+ logger.debug('Organisation context:', {
76
+ hasSelectedOrg: !!selectedOrganisation,
77
+ selectedOrgId: selectedOrganisation?.id,
78
+ hasOrganisations: organisations?.length > 0,
79
+ organisationCount: organisations?.length,
80
+ selectedEvent: selectedEvent?.event_id
81
+ });
82
+
83
+ const { resolvedScope: rawResolvedScope, isLoading: scopeLoading } = useResolvedScope({
66
84
  supabase,
67
- selectedOrganisationId,
68
- selectedEventId
85
+ selectedOrganisationId: selectedOrganisation?.id || null,
86
+ selectedEventId: selectedEvent?.event_id || null
69
87
  });
70
88
 
71
89
  /**
@@ -113,32 +131,58 @@ export function useDataTablePermissions<TData extends Record<string, any>>(
113
131
  /**
114
132
  * Effective scope for permission checks.
115
133
  *
116
- * Fallback to empty scope if no organisation resolved yet. This ensures:
117
- * - Permission hooks always receive valid scope objects (never undefined/null)
118
- * - Components handle loading states gracefully
119
- * - No accidental data leakage between organisations (zero-trust model)
134
+ * Only use the resolved scope if it has a valid organisationId and scope resolution is complete.
135
+ * This ensures permission checks only happen when we have proper context.
120
136
  */
121
- const effectiveScope = stableScope.organisationId ? stableScope : { organisationId: '', eventId: undefined, appId: undefined };
137
+ const effectiveScope = (!scopeLoading && stableScope.organisationId) ? stableScope : null;
138
+
139
+ // Always call hooks with consistent parameters to avoid React hooks order violations
140
+ const userId = user?.id || '';
141
+ const readPermission = `read:page.${effectivePageId}` as unknown as Permission;
142
+ const createPermission = `create:page.${effectivePageId}` as unknown as Permission;
143
+ const updatePermission = `update:page.${effectivePageId}` as unknown as Permission;
144
+ const deletePermission = `delete:page.${effectivePageId}` as unknown as Permission;
145
+
146
+ // Always use a consistent scope object to prevent hooks order violations
147
+ // When scope is loading or invalid, use empty scope which will cause useCan to return false
148
+ const consistentScope = effectiveScope || { organisationId: '', eventId: undefined, appId: undefined };
122
149
 
123
150
  const permissions = {
124
- canRead: useCan(user?.id || '', effectiveScope, `read:page.${effectivePageId}` as any, effectivePageId, true),
125
- canCreate: useCan(user?.id || '', effectiveScope, `create:page.${effectivePageId}` as any, effectivePageId, true),
126
- canUpdate: useCan(user?.id || '', effectiveScope, `update:page.${effectivePageId}` as any, effectivePageId, true),
127
- canDelete: useCan(user?.id || '', effectiveScope, `delete:page.${effectivePageId}` as any, effectivePageId, true),
128
- canExport: useCan(user?.id || '', effectiveScope, `read:page.${effectivePageId}` as any, effectivePageId, true), // Use read permission for export
129
- canImport: useCan(user?.id || '', effectiveScope, `create:page.${effectivePageId}` as any, effectivePageId, true), // Use create permission for import
151
+ canRead: useCan(userId, consistentScope, readPermission, effectivePageId, true),
152
+ canCreate: useCan(userId, consistentScope, createPermission, effectivePageId, true),
153
+ canUpdate: useCan(userId, consistentScope, updatePermission, effectivePageId, true),
154
+ canDelete: useCan(userId, consistentScope, deletePermission, effectivePageId, true),
155
+ canExport: useCan(userId, consistentScope, readPermission, effectivePageId, true), // Use read permission for export
156
+ canImport: useCan(userId, consistentScope, createPermission, effectivePageId, true), // Use create permission for import
130
157
  };
158
+
159
+ // Debug logging for permissions
160
+ logger.debug('Permission check results:', {
161
+ canRead: permissions.canRead.can,
162
+ canReadLoading: permissions.canRead.isLoading,
163
+ canReadError: permissions.canRead.error?.message,
164
+ canCreate: permissions.canCreate.can,
165
+ pageName: effectivePageId,
166
+ scope: consistentScope,
167
+ hasValidScope: !!effectiveScope,
168
+ scopeLoading: scopeLoading
169
+ });
131
170
 
132
171
  // MANDATORY: Features are automatically filtered by permissions
133
- const secureFeatures: DataTableFeatureConfig = useMemo(() => ({
134
- ...features,
135
- creation: features.creation && permissions.canCreate.can,
136
- editing: features.editing && permissions.canUpdate.can,
137
- deletion: features.deletion && permissions.canDelete.can,
138
- deleteSelected: features.deleteSelected && permissions.canDelete.can,
139
- export: features.export && permissions.canExport.can,
140
- import: features.import && permissions.canImport.can,
141
- }), [features, permissions.canCreate.can, permissions.canUpdate.can, permissions.canDelete.can, permissions.canExport.can, permissions.canImport.can]);
172
+ const normalizedFeatures = useMemo(
173
+ () => normalizeDataTableFeatures(features),
174
+ [features]
175
+ );
176
+
177
+ const secureFeatures: NormalizedDataTableFeatureConfig = useMemo(() => ({
178
+ ...normalizedFeatures,
179
+ creation: normalizedFeatures.creation && permissions.canCreate.can,
180
+ editing: normalizedFeatures.editing && permissions.canUpdate.can,
181
+ deletion: normalizedFeatures.deletion && permissions.canDelete.can,
182
+ deleteSelected: normalizedFeatures.deleteSelected && permissions.canDelete.can,
183
+ export: normalizedFeatures.export && permissions.canExport.can,
184
+ import: normalizedFeatures.import && permissions.canImport.can,
185
+ }), [normalizedFeatures, permissions.canCreate.can, permissions.canUpdate.can, permissions.canDelete.can, permissions.canExport.can, permissions.canImport.can]);
142
186
 
143
187
  return {
144
188
  permissions,
@@ -17,7 +17,10 @@ import type {
17
17
  ExpandedState,
18
18
  PaginationState
19
19
  } from '@tanstack/react-table';
20
- import type { DataRecord } from '../types';
20
+ import type { DataRecord, CellValue, RowId } from '../types';
21
+
22
+ // Re-export types for external use
23
+ export type { DataRecord, CellValue, RowId };
21
24
 
22
25
  // ============================================================================
23
26
  // STATE INTERFACE
@@ -38,9 +41,9 @@ export interface DataTableState<TData extends DataRecord> {
38
41
 
39
42
  // Editing state
40
43
  isCreating: boolean;
41
- creationData: Record<string, any>;
42
- editingRowId: string | null;
43
- editingData: Record<string, any>;
44
+ creationData: Record<string, CellValue>;
45
+ editingRowId: RowId | null;
46
+ editingData: Record<string, CellValue>;
44
47
 
45
48
  // UI state
46
49
  showImportModal: boolean;
@@ -50,6 +53,31 @@ export interface DataTableState<TData extends DataRecord> {
50
53
  searchQuery: string;
51
54
  }
52
55
 
56
+ export interface DataTableStateActions<TData extends DataRecord> {
57
+ setSorting: (sorting: SortingState) => void;
58
+ setColumnFilters: (filters: ColumnFiltersState) => void;
59
+ setColumnVisibility: (visibility: VisibilityState) => void;
60
+ setGrouping: (grouping: GroupingState) => void;
61
+ setExpanded: (expanded: ExpandedState) => void;
62
+ setPagination: (pagination: PaginationState) => void;
63
+ setColumnOrder: (order: string[]) => void;
64
+ setRowSelection: (
65
+ selection: Record<string, boolean> | ((old: Record<string, boolean>) => Record<string, boolean>)
66
+ ) => void;
67
+ toggleRowSelection: (rowId: string, selected: boolean) => void;
68
+ clearRowSelection: () => void;
69
+ setCreating: (isCreating: boolean) => void;
70
+ setCreationData: (data: Record<string, CellValue>) => void;
71
+ clearCreationData: () => void;
72
+ setEditingRow: (rowId: RowId | null, data: Record<string, CellValue>) => void;
73
+ clearEditing: () => void;
74
+ setImportModal: (show: boolean) => void;
75
+ setFilterRow: (show: boolean) => void;
76
+ setSearchQuery: (query: string) => void;
77
+ resetState: () => void;
78
+ initializeState: (partialState: Partial<DataTableState<TData>>) => void;
79
+ }
80
+
53
81
  // ============================================================================
54
82
  // ACTION TYPES
55
83
  // ============================================================================
@@ -66,9 +94,9 @@ export type DataTableAction<TData extends DataRecord> =
66
94
  | { type: 'TOGGLE_ROW_SELECTION'; payload: { rowId: string; selected: boolean } }
67
95
  | { type: 'CLEAR_ROW_SELECTION' }
68
96
  | { type: 'SET_CREATING'; payload: boolean }
69
- | { type: 'SET_CREATION_DATA'; payload: Record<string, any> }
97
+ | { type: 'SET_CREATION_DATA'; payload: Record<string, CellValue> }
70
98
  | { type: 'CLEAR_CREATION_DATA' }
71
- | { type: 'SET_EDITING_ROW'; payload: { rowId: string | null; data: Record<string, any> } }
99
+ | { type: 'SET_EDITING_ROW'; payload: { rowId: RowId | null; data: Record<string, CellValue> } }
72
100
  | { type: 'CLEAR_EDITING' }
73
101
  | { type: 'SET_IMPORT_MODAL'; payload: boolean }
74
102
  | { type: 'SET_FILTER_ROW'; payload: boolean }
@@ -228,8 +256,8 @@ export function useDataTableState<TData extends DataRecord>({
228
256
  // ACTION CREATORS
229
257
  // ============================================================================
230
258
 
231
- const actions = useMemo(() => ({
232
- setSorting: (sorting: SortingState) =>
259
+ const actions = useMemo<DataTableStateActions<TData>>(() => ({
260
+ setSorting: (sorting: SortingState) =>
233
261
  dispatch({ type: 'SET_SORTING', payload: sorting }),
234
262
 
235
263
  setColumnFilters: (filters: ColumnFiltersState) =>
@@ -270,13 +298,13 @@ export function useDataTableState<TData extends DataRecord>({
270
298
  setCreating: (isCreating: boolean) =>
271
299
  dispatch({ type: 'SET_CREATING', payload: isCreating }),
272
300
 
273
- setCreationData: (data: Record<string, any>) =>
301
+ setCreationData: (data: Record<string, CellValue>) =>
274
302
  dispatch({ type: 'SET_CREATION_DATA', payload: data }),
275
303
 
276
304
  clearCreationData: () =>
277
305
  dispatch({ type: 'CLEAR_CREATION_DATA' }),
278
306
 
279
- setEditingRow: (rowId: string | null, data: Record<string, any>) =>
307
+ setEditingRow: (rowId: RowId | null, data: Record<string, CellValue>) =>
280
308
  dispatch({ type: 'SET_EDITING_ROW', payload: { rowId, data } }),
281
309
 
282
310
  clearEditing: () =>
@@ -294,7 +322,7 @@ export function useDataTableState<TData extends DataRecord>({
294
322
  resetState: () =>
295
323
  dispatch({ type: 'RESET_STATE' }),
296
324
 
297
- initializeState: (partialState: Partial<DataTableState<TData>>) =>
325
+ initializeState: (partialState: Partial<DataTableState<TData>>) =>
298
326
  dispatch({ type: 'INITIALIZE_STATE', payload: partialState })
299
327
  }), [state.rowSelection, onRowSelectionChange]);
300
328
 
@@ -0,0 +1,33 @@
1
+ import { useMemo } from 'react';
2
+
3
+ import type { DataRecord, DataTableColumn } from '../types';
4
+
5
+ interface UseEffectiveColumnOrderOptions<TData extends DataRecord> {
6
+ columns: DataTableColumn<TData>[];
7
+ externalColumnOrder?: string[];
8
+ selectionEnabled: boolean;
9
+ }
10
+
11
+ export function useEffectiveColumnOrder<TData extends DataRecord>({
12
+ columns,
13
+ externalColumnOrder,
14
+ selectionEnabled,
15
+ }: UseEffectiveColumnOrderOptions<TData>): string[] {
16
+ const baseOrder = useMemo(() => {
17
+ if (externalColumnOrder && externalColumnOrder.length > 0) {
18
+ return externalColumnOrder;
19
+ }
20
+
21
+ return columns
22
+ .map(column => column.id || column.accessorKey || '')
23
+ .filter((identifier): identifier is string => Boolean(identifier));
24
+ }, [columns, externalColumnOrder]);
25
+
26
+ return useMemo(() => {
27
+ if (selectionEnabled && !baseOrder.includes('select')) {
28
+ return ['select', ...baseOrder];
29
+ }
30
+
31
+ return baseOrder;
32
+ }, [baseOrder, selectionEnabled]);
33
+ }
@@ -8,6 +8,20 @@
8
8
  import { useState, useCallback, useMemo, useEffect } from 'react';
9
9
  import type { HierarchicalDataRow, HierarchicalConfig } from '../types';
10
10
 
11
+ export interface HierarchicalState<TData extends HierarchicalDataRow> {
12
+ expandedRows: Set<string>;
13
+ visibleRows: TData[];
14
+ toggleRow: (rowId: string) => void;
15
+ expandAll: () => void;
16
+ collapseAll: () => void;
17
+ setExpandedIds: (ids: string[]) => void;
18
+ isExpanded: (rowId: string) => boolean;
19
+ hasChildren: (rowId: string) => boolean;
20
+ getChildrenCount: (rowId: string) => number;
21
+ getExpandedIds: () => string[];
22
+ parentChildMap: Map<string, TData[]>;
23
+ }
24
+
11
25
  /**
12
26
  * Hook for managing hierarchical expand/collapse state
13
27
  *
@@ -20,7 +34,7 @@ import type { HierarchicalDataRow, HierarchicalConfig } from '../types';
20
34
  export function useHierarchicalState<TData extends HierarchicalDataRow>(
21
35
  data: TData[],
22
36
  config?: HierarchicalConfig
23
- ) {
37
+ ): HierarchicalState<TData> {
24
38
  // Memoize initial state to prevent recreation
25
39
  const initialExpandedState = useMemo(() => {
26
40
  if (!config?.defaultExpanded) {