@jmruthers/pace-core 0.4.1 → 0.5.3

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 (660) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/README.md +231 -229
  3. package/dist/{DataTable-2LB6HI6V.js → DataTable-ZQDRE46Q.js} +15 -17
  4. package/dist/{DataTable-BDBqkU-i.d.ts → DataTable-ltTFXHS3.d.ts} +25 -51
  5. package/dist/{Table-CIm9IWqk.d.ts → PublicLoadingSpinner-Bq_-BeK-.d.ts} +635 -122
  6. package/dist/{UnifiedAuthProvider-V7y63NjT.d.ts → RBACProvider-BO4ilsQB.d.ts} +11 -36
  7. package/dist/UnifiedAuthProvider-DGQsy-vY.d.ts +103 -0
  8. package/dist/{api-AIJ3IJX3.js → api-H5A3H4IR.js} +6 -4
  9. package/dist/{appConfig-fB1pP_v3.d.ts → appConfig-BVGyuvI7.d.ts} +1 -1
  10. package/dist/appNameResolver-7GHF5ED2.js +22 -0
  11. package/dist/{audit-PD5L5ZSC.js → audit-BUW3LMJB.js} +3 -3
  12. package/dist/chunk-5H3C2SWM.js +3293 -0
  13. package/dist/chunk-5H3C2SWM.js.map +1 -0
  14. package/dist/chunk-5SIXIV7R.js +1925 -0
  15. package/dist/chunk-5SIXIV7R.js.map +1 -0
  16. package/dist/{chunk-YNU5QJ4S.js → chunk-7BNPOCLL.js} +22 -5
  17. package/dist/chunk-7BNPOCLL.js.map +1 -0
  18. package/dist/{chunk-4ZTIEYU2.js → chunk-CDQ3PX7L.js} +1 -1
  19. package/dist/chunk-CDQ3PX7L.js.map +1 -0
  20. package/dist/chunk-GNTALZV3.js +17 -0
  21. package/dist/chunk-GNTALZV3.js.map +1 -0
  22. package/dist/chunk-GWSBHC4J.js +1349 -0
  23. package/dist/chunk-GWSBHC4J.js.map +1 -0
  24. package/dist/{chunk-JUUNUW3O.js → chunk-HD7PYDUV.js} +14 -5
  25. package/dist/chunk-HD7PYDUV.js.map +1 -0
  26. package/dist/{chunk-H4PZ4B3Y.js → chunk-HXX35Q2M.js} +113 -27
  27. package/dist/chunk-HXX35Q2M.js.map +1 -0
  28. package/dist/chunk-K6B7BLSE.js +388 -0
  29. package/dist/chunk-K6B7BLSE.js.map +1 -0
  30. package/dist/chunk-M4RW7PIP.js +5441 -0
  31. package/dist/chunk-M4RW7PIP.js.map +1 -0
  32. package/dist/chunk-MZBUOP4P.js +119 -0
  33. package/dist/chunk-MZBUOP4P.js.map +1 -0
  34. package/dist/chunk-N2EUGZRW.js +98 -0
  35. package/dist/chunk-N2EUGZRW.js.map +1 -0
  36. package/dist/chunk-NQ4TOOO6.js +20 -0
  37. package/dist/chunk-NQ4TOOO6.js.map +1 -0
  38. package/dist/{chunk-DC5AMYBS.js → chunk-PLDDJCW6.js} +15 -5
  39. package/dist/chunk-PLDDJCW6.js.map +1 -0
  40. package/dist/{chunk-IOX76PSM.js → chunk-PVMYVQSM.js} +270 -28
  41. package/dist/chunk-PVMYVQSM.js.map +1 -0
  42. package/dist/{chunk-4MCJAK7J.js → chunk-QKHFMQ5R.js} +2155 -4853
  43. package/dist/chunk-QKHFMQ5R.js.map +1 -0
  44. package/dist/chunk-QVYBYGT2.js +428 -0
  45. package/dist/chunk-QVYBYGT2.js.map +1 -0
  46. package/dist/{chunk-WHLSWC6W.js → chunk-SS3E6QLB.js} +16 -61
  47. package/dist/chunk-SS3E6QLB.js.map +1 -0
  48. package/dist/chunk-WJARTBCT.js +128 -0
  49. package/dist/chunk-WJARTBCT.js.map +1 -0
  50. package/dist/chunk-YDJW5XTN.js +84 -0
  51. package/dist/chunk-YDJW5XTN.js.map +1 -0
  52. package/dist/components.d.ts +907 -10
  53. package/dist/components.js +3237 -204
  54. package/dist/components.js.map +1 -1
  55. package/dist/{database-CAMsquLm.d.ts → database-C3Szpi5J.d.ts} +28 -11
  56. package/dist/hooks.d.ts +7 -6
  57. package/dist/hooks.js +33 -11
  58. package/dist/hooks.js.map +1 -1
  59. package/dist/index.d.ts +247 -111
  60. package/dist/index.js +330 -185
  61. package/dist/index.js.map +1 -1
  62. package/dist/{organisation-DLNNQhPB.d.ts → organisation-CO3Sh3_D.d.ts} +1 -1
  63. package/dist/providers.d.ts +5 -4
  64. package/dist/providers.js +14 -5
  65. package/dist/rbac/index.d.ts +964 -839
  66. package/dist/rbac/index.js +58 -1970
  67. package/dist/rbac/index.js.map +1 -1
  68. package/dist/styles/core.css +364 -0
  69. package/dist/styles/fonts/georama-italic.woff2 +0 -0
  70. package/dist/styles/fonts/georama.woff2 +0 -0
  71. package/dist/styles/fonts/open-sans-italic.woff2 +0 -0
  72. package/dist/styles/fonts/open-sans.woff2 +0 -0
  73. package/dist/styles/fonts/reddit-mono.woff2 +0 -0
  74. package/dist/styles/index.d.ts +36 -0
  75. package/dist/styles/index.js +24 -0
  76. package/dist/styles/index.js.map +1 -0
  77. package/dist/theming/runtime.d.ts +73 -0
  78. package/dist/theming/runtime.js +16 -0
  79. package/dist/theming/runtime.js.map +1 -0
  80. package/dist/{types-Bavn44NW.d.ts → types-BRDU7N6w.d.ts} +79 -33
  81. package/dist/types.d.ts +5 -5
  82. package/dist/types.js +7 -2
  83. package/dist/types.js.map +1 -1
  84. package/dist/{unified-BtRpPbmp.d.ts → unified-CMPjE_fv.d.ts} +0 -1
  85. package/dist/usePublicRouteParams-B2OcAsur.d.ts +477 -0
  86. package/dist/utils.d.ts +83 -60
  87. package/dist/utils.js +293 -55651
  88. package/dist/utils.js.map +1 -1
  89. package/dist/validation.d.ts +1 -1
  90. package/dist/validation.js +1 -1
  91. package/docs/INDEX.md +192 -0
  92. package/docs/README.md +46 -32
  93. package/docs/api/README.md +231 -229
  94. package/docs/api/classes/ErrorBoundary.md +1 -1
  95. package/docs/api/classes/InvalidScopeError.md +73 -0
  96. package/docs/api/classes/MissingUserContextError.md +66 -0
  97. package/docs/api/classes/OrganisationContextRequiredError.md +66 -0
  98. package/docs/api/classes/PermissionDeniedError.md +73 -0
  99. package/docs/api/classes/PublicErrorBoundary.md +132 -0
  100. package/docs/api/classes/RBACAuditManager.md +270 -0
  101. package/docs/api/classes/RBACCache.md +284 -0
  102. package/docs/api/classes/RBACEngine.md +141 -0
  103. package/docs/api/classes/RBACError.md +76 -0
  104. package/docs/api/classes/RBACNotInitializedError.md +66 -0
  105. package/docs/api/classes/SecureSupabaseClient.md +135 -0
  106. package/docs/api/interfaces/AggregateConfig.md +4 -4
  107. package/docs/api/interfaces/ButtonProps.md +2 -2
  108. package/docs/api/interfaces/CardProps.md +2 -2
  109. package/docs/api/interfaces/ColorPalette.md +1 -1
  110. package/docs/api/interfaces/ColorShade.md +1 -1
  111. package/docs/api/interfaces/DataAccessRecord.md +96 -0
  112. package/docs/api/interfaces/DataTableAction.md +98 -7
  113. package/docs/api/interfaces/DataTableColumn.md +131 -12
  114. package/docs/api/interfaces/DataTableProps.md +77 -274
  115. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +235 -0
  118. package/docs/api/interfaces/EventContextType.md +7 -7
  119. package/docs/api/interfaces/EventLogoProps.md +152 -0
  120. package/docs/api/interfaces/EventProviderProps.md +2 -2
  121. package/docs/api/interfaces/FileSizeLimits.md +7 -0
  122. package/docs/api/interfaces/FileUploadProps.md +154 -0
  123. package/docs/api/interfaces/FooterProps.md +1 -1
  124. package/docs/api/interfaces/InactivityWarningModalProps.md +115 -0
  125. package/docs/api/interfaces/InputProps.md +2 -2
  126. package/docs/api/interfaces/LabelProps.md +1 -1
  127. package/docs/api/interfaces/LoginFormProps.md +1 -1
  128. package/docs/api/interfaces/NavigationAccessRecord.md +107 -0
  129. package/docs/api/interfaces/NavigationContextType.md +164 -0
  130. package/docs/api/interfaces/NavigationGuardProps.md +139 -0
  131. package/docs/api/interfaces/NavigationItem.md +1 -1
  132. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  133. package/docs/api/interfaces/NavigationProviderProps.md +117 -0
  134. package/docs/api/interfaces/Organisation.md +1 -1
  135. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  136. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  137. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  138. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  139. package/docs/api/interfaces/PaceAppLayoutProps.md +26 -26
  140. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  141. package/docs/api/interfaces/PageAccessRecord.md +85 -0
  142. package/docs/api/interfaces/PagePermissionContextType.md +140 -0
  143. package/docs/api/interfaces/PagePermissionGuardProps.md +153 -0
  144. package/docs/api/interfaces/PagePermissionProviderProps.md +119 -0
  145. package/docs/api/interfaces/PaletteData.md +1 -1
  146. package/docs/api/interfaces/PermissionEnforcerProps.md +153 -0
  147. package/docs/api/interfaces/PublicErrorBoundaryProps.md +94 -0
  148. package/docs/api/interfaces/PublicErrorBoundaryState.md +68 -0
  149. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +86 -0
  150. package/docs/api/interfaces/PublicPageFooterProps.md +112 -0
  151. package/docs/api/interfaces/PublicPageHeaderProps.md +138 -0
  152. package/docs/api/interfaces/PublicPageLayoutProps.md +138 -0
  153. package/docs/api/interfaces/RBACConfig.md +99 -0
  154. package/docs/api/interfaces/RBACContextType.md +474 -0
  155. package/docs/api/interfaces/RBACLogger.md +112 -0
  156. package/docs/api/interfaces/RBACProviderProps.md +107 -0
  157. package/docs/api/interfaces/RoleBasedRouterContextType.md +151 -0
  158. package/docs/api/interfaces/RoleBasedRouterProps.md +156 -0
  159. package/docs/api/interfaces/RouteAccessRecord.md +107 -0
  160. package/docs/api/interfaces/RouteConfig.md +121 -0
  161. package/docs/api/interfaces/SecureDataContextType.md +168 -0
  162. package/docs/api/interfaces/SecureDataProviderProps.md +132 -0
  163. package/docs/api/interfaces/StorageConfig.md +41 -0
  164. package/docs/api/interfaces/StorageFileInfo.md +74 -0
  165. package/docs/api/interfaces/StorageFileMetadata.md +140 -0
  166. package/docs/api/interfaces/StorageListOptions.md +86 -0
  167. package/docs/api/interfaces/StorageListResult.md +41 -0
  168. package/docs/api/interfaces/StorageUploadOptions.md +88 -0
  169. package/docs/api/interfaces/StorageUploadResult.md +63 -0
  170. package/docs/api/interfaces/StorageUrlOptions.md +47 -0
  171. package/docs/api/interfaces/StyleImport.md +2 -2
  172. package/docs/api/interfaces/ToastActionElement.md +1 -1
  173. package/docs/api/interfaces/ToastProps.md +1 -1
  174. package/docs/api/interfaces/UnifiedAuthContextType.md +465 -64
  175. package/docs/api/interfaces/UnifiedAuthProviderProps.md +95 -9
  176. package/docs/api/interfaces/UseInactivityTrackerOptions.md +136 -0
  177. package/docs/api/interfaces/UseInactivityTrackerReturn.md +123 -0
  178. package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
  179. package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
  180. package/docs/api/interfaces/UsePublicEventOptions.md +34 -0
  181. package/docs/api/interfaces/UsePublicEventReturn.md +68 -0
  182. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +94 -0
  183. package/docs/api/interfaces/UserEventAccess.md +14 -14
  184. package/docs/api/interfaces/UserMenuProps.md +6 -6
  185. package/docs/api/interfaces/UserProfile.md +1 -1
  186. package/docs/api/modules.md +4233 -1134
  187. package/docs/api-reference/components.md +761 -43
  188. package/docs/api-reference/hooks.md +126 -0
  189. package/docs/api-reference/providers.md +141 -65
  190. package/docs/api-reference/types.md +66 -36
  191. package/docs/api-reference/utilities.md +1 -1
  192. package/docs/architecture/README.md +1 -2
  193. package/docs/best-practices/README.md +400 -0
  194. package/docs/consuming-app-example.md +42 -96
  195. package/docs/consuming-app-vite-config.md +233 -0
  196. package/docs/core-concepts/events.md +3 -3
  197. package/docs/core-concepts/organisations.md +0 -1
  198. package/docs/core-concepts/rbac-system.md +23 -10
  199. package/docs/documentation-style-checklist.md +8 -2
  200. package/docs/examples/navigation-menu-auth-fix.md +344 -0
  201. package/docs/getting-started/examples/README.md +15 -1
  202. package/docs/getting-started/examples/basic-auth-app.md +444 -119
  203. package/docs/getting-started/examples/full-featured-app.md +6 -6
  204. package/docs/getting-started/installation.md +231 -52
  205. package/docs/getting-started/quick-start.md +121 -24
  206. package/docs/implementation-guides/app-layout.md +133 -108
  207. package/docs/implementation-guides/data-tables.md +1011 -29
  208. package/docs/implementation-guides/forms.md +3 -3
  209. package/docs/implementation-guides/hierarchical-datatable.md +850 -0
  210. package/docs/implementation-guides/large-datasets.md +2 -2
  211. package/docs/implementation-guides/navigation.md +1 -1
  212. package/docs/implementation-guides/permission-enforcement.md +4 -4
  213. package/docs/implementation-guides/public-pages.md +752 -0
  214. package/docs/migration/README.md +18 -8
  215. package/docs/migration/quick-migration-guide.md +320 -0
  216. package/docs/migration/rbac-migration.md +50 -0
  217. package/docs/migration/v0.4.15-tailwind-scanning.md +272 -0
  218. package/docs/migration/v0.4.16-css-first-approach.md +306 -0
  219. package/docs/migration/v0.4.17-source-path-fix.md +229 -0
  220. package/docs/migration-guide.md +77 -105
  221. package/docs/performance/README.md +1 -4
  222. package/docs/print-components/README.md +258 -0
  223. package/docs/print-components/api-reference.md +636 -0
  224. package/docs/print-components/examples/README.md +204 -0
  225. package/docs/print-components/examples/basic-report.tsx +92 -0
  226. package/docs/print-components/examples/card-catalog.tsx +149 -0
  227. package/docs/print-components/examples/cover-page-report.tsx +163 -0
  228. package/docs/print-components/quick-start.md +363 -0
  229. package/docs/quick-reference.md +53 -36
  230. package/docs/rbac/README.md +136 -69
  231. package/docs/rbac/api-reference.md +39 -8
  232. package/docs/rbac/examples.md +237 -66
  233. package/docs/rbac/getting-started.md +131 -16
  234. package/docs/rbac/quick-start.md +499 -323
  235. package/docs/rbac/troubleshooting.md +240 -262
  236. package/docs/security/README.md +50 -1
  237. package/docs/styles/README.md +226 -111
  238. package/docs/testing/README.md +6 -10
  239. package/docs/troubleshooting/README.md +497 -0
  240. package/docs/troubleshooting/common-issues.md +604 -14
  241. package/docs/troubleshooting/styling-issues.md +219 -0
  242. package/docs/troubleshooting/tailwind-content-scanning.md +213 -0
  243. package/docs/usage.md +54 -91
  244. package/docs/visual-testing.md +0 -7
  245. package/package.json +47 -25
  246. package/src/__mocks__/lucide-react.ts +181 -0
  247. package/src/__tests__/REBUILD_PLAN.md +223 -0
  248. package/src/__tests__/TESTING_GUIDELINES.md +341 -0
  249. package/src/__tests__/fixtures/mocks.ts +93 -0
  250. package/src/__tests__/helpers/component-test-utils.tsx +145 -0
  251. package/src/__tests__/helpers/test-utils.tsx +117 -0
  252. package/src/__tests__/integration/UserProfile.test.tsx +128 -0
  253. package/src/__tests__/setup.ts +71 -0
  254. package/src/__tests__/templates/accessibility.test.template.tsx +279 -0
  255. package/src/__tests__/templates/component.test.template.tsx +144 -0
  256. package/src/__tests__/templates/hook.test.template.ts +173 -0
  257. package/src/__tests__/templates/integration.test.template.tsx +199 -0
  258. package/src/__tests__/types/test.types.ts +106 -0
  259. package/src/components/Alert/Alert.test.tsx +496 -0
  260. package/src/components/Alert/Alert.tsx +134 -0
  261. package/src/components/Alert/index.ts +2 -0
  262. package/src/components/Avatar/Avatar.test.tsx +484 -0
  263. package/src/components/Avatar/Avatar.tsx +84 -0
  264. package/src/components/Avatar/index.ts +2 -0
  265. package/src/components/Button/Button.test.tsx +662 -0
  266. package/src/components/Button/Button.tsx +270 -0
  267. package/src/components/Button/index.ts +2 -0
  268. package/src/components/Card/Card.test.tsx +593 -0
  269. package/src/components/Card/Card.tsx +271 -0
  270. package/src/components/Card/index.ts +1 -0
  271. package/src/components/Checkbox/Checkbox.test.tsx +461 -0
  272. package/src/components/Checkbox/Checkbox.tsx +75 -0
  273. package/src/components/Checkbox/__mocks__/Checkbox.tsx +2 -0
  274. package/src/components/Checkbox/index.ts +2 -0
  275. package/src/components/DataTable/DataTable.tsx +446 -0
  276. package/src/components/DataTable/__tests__/README.md +145 -0
  277. package/src/components/DataTable/__tests__/mocks/MockRBACProvider.tsx +66 -0
  278. package/src/components/DataTable/__tests__/test-utils/dataFactories.ts +103 -0
  279. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +381 -0
  280. package/src/components/DataTable/__tests__/test-utils.ts +94 -0
  281. package/src/components/DataTable/components/AccessDeniedPage.tsx +168 -0
  282. package/src/components/DataTable/components/ActionButtons.tsx +194 -0
  283. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +160 -0
  284. package/src/components/DataTable/components/ColumnFilter.tsx +114 -0
  285. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +100 -0
  286. package/src/components/DataTable/components/DataTableBody.tsx +461 -0
  287. package/src/components/DataTable/components/DataTableCore.tsx +1027 -0
  288. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +214 -0
  289. package/src/components/DataTable/components/DataTableModals.tsx +87 -0
  290. package/src/components/DataTable/components/DataTableToolbar.tsx +262 -0
  291. package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
  292. package/src/components/DataTable/components/EditableRow.tsx +159 -0
  293. package/src/components/DataTable/components/EmptyState.tsx +64 -0
  294. package/src/components/DataTable/components/ExpandButton.tsx +113 -0
  295. package/src/components/DataTable/components/FilterRow.tsx +100 -0
  296. package/src/components/DataTable/components/GroupHeader.tsx +42 -0
  297. package/src/components/DataTable/components/GroupingDropdown.tsx +96 -0
  298. package/src/components/DataTable/components/ImportModal.tsx +345 -0
  299. package/src/components/DataTable/components/LoadingState.tsx +12 -0
  300. package/src/components/DataTable/components/PaginationControls.tsx +332 -0
  301. package/src/components/DataTable/components/UnifiedTableBody.tsx +742 -0
  302. package/src/components/DataTable/components/ViewRowModal.tsx +68 -0
  303. package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
  304. package/src/components/DataTable/components/index.ts +16 -0
  305. package/src/components/DataTable/context/DataTableContext.tsx +97 -0
  306. package/src/components/DataTable/core/ActionManager.ts +235 -0
  307. package/src/components/DataTable/core/ColumnFactory.ts +268 -0
  308. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  309. package/src/components/DataTable/core/DataManager.ts +188 -0
  310. package/src/components/DataTable/core/DataTableContext.tsx +181 -0
  311. package/src/components/DataTable/core/LocalDataAdapter.ts +264 -0
  312. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  313. package/src/components/DataTable/core/StateManager.ts +311 -0
  314. package/src/components/DataTable/core/index.ts +8 -0
  315. package/src/components/DataTable/core/interfaces.ts +338 -0
  316. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +419 -0
  317. package/src/components/DataTable/examples/HierarchicalExample.tsx +475 -0
  318. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +176 -0
  319. package/src/components/DataTable/examples/PerformanceExample.tsx +505 -0
  320. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +95 -0
  321. package/src/components/DataTable/hooks/useColumnReordering.ts +110 -0
  322. package/src/components/DataTable/hooks/useDataTableState.ts +325 -0
  323. package/src/components/DataTable/hooks/useHierarchicalState.ts +174 -0
  324. package/src/components/DataTable/index.ts +68 -0
  325. package/src/components/DataTable/styles.ts +171 -0
  326. package/src/components/DataTable/types.ts +511 -0
  327. package/src/components/DataTable/utils/debugTools.ts +583 -0
  328. package/src/components/DataTable/utils/errorHandling.ts +494 -0
  329. package/src/components/DataTable/utils/exportUtils.ts +126 -0
  330. package/src/components/DataTable/utils/flexibleImport.ts +510 -0
  331. package/src/components/DataTable/utils/hierarchicalSorting.ts +151 -0
  332. package/src/components/DataTable/utils/hierarchicalUtils.ts +218 -0
  333. package/src/components/DataTable/utils/index.ts +1 -0
  334. package/src/components/DataTable/utils/performanceUtils.ts +351 -0
  335. package/src/components/Dialog/Dialog.test.tsx +1139 -0
  336. package/src/components/Dialog/Dialog.tsx +782 -0
  337. package/src/components/Dialog/README.md +804 -0
  338. package/src/components/Dialog/examples/BasicHtmlTest.tsx +55 -0
  339. package/src/components/Dialog/examples/DebugHtmlExample.tsx +68 -0
  340. package/src/components/Dialog/examples/HtmlDialogExample.tsx +202 -0
  341. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +61 -0
  342. package/src/components/Dialog/examples/SmartDialogExample.tsx +322 -0
  343. package/src/components/Dialog/index.ts +12 -0
  344. package/src/components/Dialog/utils/safeHtml.ts +185 -0
  345. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +752 -0
  346. package/src/components/ErrorBoundary/ErrorBoundary.tsx +312 -0
  347. package/src/components/ErrorBoundary/index.ts +8 -0
  348. package/src/components/EventSelector/EventSelector.tsx +360 -0
  349. package/src/components/EventSelector/index.ts +3 -0
  350. package/src/components/EventSelector/types.ts +79 -0
  351. package/src/components/FileUpload/FileUpload.example.tsx +218 -0
  352. package/src/components/FileUpload/FileUpload.test.tsx +665 -0
  353. package/src/components/FileUpload/FileUpload.tsx +237 -0
  354. package/src/components/FileUpload/index.ts +6 -0
  355. package/src/components/Footer/Footer.test.tsx +482 -0
  356. package/src/components/Footer/Footer.tsx +197 -0
  357. package/src/components/Footer/index.ts +17 -0
  358. package/src/components/Form/Form.test.tsx +1158 -0
  359. package/src/components/Form/Form.tsx +166 -0
  360. package/src/components/Form/FormErrorSummary.tsx +113 -0
  361. package/src/components/Form/FormField.tsx +249 -0
  362. package/src/components/Form/FormFieldset.tsx +127 -0
  363. package/src/components/Form/FormLiveRegion.tsx +198 -0
  364. package/src/components/Form/index.ts +26 -0
  365. package/src/components/Header/Header.test.tsx +582 -0
  366. package/src/components/Header/Header.tsx +301 -0
  367. package/src/components/Header/index.ts +4 -0
  368. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +489 -0
  369. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +164 -0
  370. package/src/components/InactivityWarningModal/index.ts +9 -0
  371. package/src/components/Input/Input.test.tsx +466 -0
  372. package/src/components/Input/Input.tsx +201 -0
  373. package/src/components/Input/__mocks__/Input.tsx +2 -0
  374. package/src/components/Input/index.ts +9 -0
  375. package/src/components/Label/Label.tsx +186 -0
  376. package/src/components/Label/index.ts +2 -0
  377. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +450 -0
  378. package/src/components/LoadingSpinner/LoadingSpinner.tsx +98 -0
  379. package/src/components/LoadingSpinner/index.ts +3 -0
  380. package/src/components/LoginForm/LoginForm.test.tsx +816 -0
  381. package/src/components/LoginForm/LoginForm.tsx +273 -0
  382. package/src/components/LoginForm/index.ts +3 -0
  383. package/src/components/NavigationMenu/NavigationMenu.test.tsx +883 -0
  384. package/src/components/NavigationMenu/NavigationMenu.tsx +698 -0
  385. package/src/components/NavigationMenu/index.ts +10 -0
  386. package/src/components/NavigationMenu/types.ts +85 -0
  387. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +748 -0
  388. package/src/components/OrganisationSelector/OrganisationSelector.tsx +304 -0
  389. package/src/components/OrganisationSelector/index.ts +9 -0
  390. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +891 -0
  391. package/src/components/PaceAppLayout/PaceAppLayout.tsx +699 -0
  392. package/src/components/PaceAppLayout/README.md +278 -0
  393. package/src/components/PaceAppLayout/index.ts +1 -0
  394. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +475 -0
  395. package/src/components/PaceLoginPage/PaceLoginPage.tsx +221 -0
  396. package/src/components/PaceLoginPage/index.ts +1 -0
  397. package/src/components/PasswordReset/PasswordChangeForm.test.tsx +621 -0
  398. package/src/components/PasswordReset/PasswordChangeForm.tsx +186 -0
  399. package/src/components/PasswordReset/PasswordResetForm.test.tsx +605 -0
  400. package/src/components/PasswordReset/PasswordResetForm.tsx +201 -0
  401. package/src/components/PasswordReset/index.ts +4 -0
  402. package/src/components/PrintButton/PrintButton.tsx +321 -0
  403. package/src/components/PrintButton/PrintButtonGroup.tsx +84 -0
  404. package/src/components/PrintButton/PrintToolbar.tsx +94 -0
  405. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +438 -0
  406. package/src/components/PrintButton/index.ts +33 -0
  407. package/src/components/PrintButton/types.ts +173 -0
  408. package/src/components/PrintCard/PrintCard.tsx +154 -0
  409. package/src/components/PrintCard/PrintCardContent.tsx +57 -0
  410. package/src/components/PrintCard/PrintCardFooter.tsx +60 -0
  411. package/src/components/PrintCard/PrintCardGrid.tsx +91 -0
  412. package/src/components/PrintCard/PrintCardHeader.tsx +78 -0
  413. package/src/components/PrintCard/PrintCardImage.tsx +81 -0
  414. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +239 -0
  415. package/src/components/PrintCard/index.ts +34 -0
  416. package/src/components/PrintCard/types.ts +171 -0
  417. package/src/components/PrintDataTable/PrintDataTable.tsx +215 -0
  418. package/src/components/PrintDataTable/PrintTableGroup.tsx +90 -0
  419. package/src/components/PrintDataTable/PrintTableRow.tsx +76 -0
  420. package/src/components/PrintDataTable/index.ts +25 -0
  421. package/src/components/PrintDataTable/types.ts +67 -0
  422. package/src/components/PrintFooter/PrintFooter.tsx +183 -0
  423. package/src/components/PrintFooter/PrintFooterContent.tsx +71 -0
  424. package/src/components/PrintFooter/PrintFooterInfo.tsx +86 -0
  425. package/src/components/PrintFooter/PrintPageNumber.tsx +90 -0
  426. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +390 -0
  427. package/src/components/PrintFooter/index.ts +30 -0
  428. package/src/components/PrintFooter/types.ts +149 -0
  429. package/src/components/PrintGrid/PrintGrid.tsx +180 -0
  430. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +109 -0
  431. package/src/components/PrintGrid/PrintGridContainer.tsx +128 -0
  432. package/src/components/PrintGrid/PrintGridItem.tsx +220 -0
  433. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +359 -0
  434. package/src/components/PrintGrid/index.ts +31 -0
  435. package/src/components/PrintGrid/types.ts +159 -0
  436. package/src/components/PrintHeader/PrintCoverHeader.tsx +230 -0
  437. package/src/components/PrintHeader/PrintHeader.tsx +150 -0
  438. package/src/components/PrintHeader/index.ts +17 -0
  439. package/src/components/PrintHeader/types.ts +42 -0
  440. package/src/components/PrintLayout/PrintLayout.tsx +122 -0
  441. package/src/components/PrintLayout/PrintLayoutContext.tsx +66 -0
  442. package/src/components/PrintLayout/PrintPageBreak.tsx +52 -0
  443. package/src/components/PrintLayout/examples/PrintShowcase.tsx +230 -0
  444. package/src/components/PrintLayout/index.ts +19 -0
  445. package/src/components/PrintLayout/types.ts +37 -0
  446. package/src/components/PrintPageBreak/PrintPageBreak.tsx +120 -0
  447. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +90 -0
  448. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +112 -0
  449. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +279 -0
  450. package/src/components/PrintPageBreak/index.ts +23 -0
  451. package/src/components/PrintPageBreak/types.ts +94 -0
  452. package/src/components/PrintSection/PrintColumn.tsx +104 -0
  453. package/src/components/PrintSection/PrintDivider.tsx +101 -0
  454. package/src/components/PrintSection/PrintSection.tsx +129 -0
  455. package/src/components/PrintSection/PrintSectionContent.tsx +75 -0
  456. package/src/components/PrintSection/PrintSectionHeader.tsx +97 -0
  457. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +258 -0
  458. package/src/components/PrintSection/index.ts +33 -0
  459. package/src/components/PrintSection/types.ts +155 -0
  460. package/src/components/PrintText/PrintText.tsx +116 -0
  461. package/src/components/PrintText/index.ts +16 -0
  462. package/src/components/PrintText/types.ts +24 -0
  463. package/src/components/Progress/Progress.tsx +116 -0
  464. package/src/components/Progress/index.ts +3 -0
  465. package/src/components/PublicLayout/EventLogo.tsx +287 -0
  466. package/src/components/PublicLayout/PublicErrorBoundary.tsx +279 -0
  467. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +208 -0
  468. package/src/components/PublicLayout/PublicPageContextChecker.tsx +130 -0
  469. package/src/components/PublicLayout/PublicPageDebugger.tsx +104 -0
  470. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +162 -0
  471. package/src/components/PublicLayout/PublicPageFooter.tsx +124 -0
  472. package/src/components/PublicLayout/PublicPageHeader.tsx +178 -0
  473. package/src/components/PublicLayout/PublicPageLayout.tsx +232 -0
  474. package/src/components/PublicLayout/PublicPageProvider.tsx +137 -0
  475. package/src/components/PublicLayout/index.ts +51 -0
  476. package/src/components/Select/Select.test.tsx +948 -0
  477. package/src/components/Select/Select.tsx +660 -0
  478. package/src/components/Select/index.ts +1 -0
  479. package/src/components/SuperAdminGuard.tsx +116 -0
  480. package/src/components/Table/Table.tsx +222 -0
  481. package/src/components/Table/index.ts +11 -0
  482. package/src/components/Toast/Toast.test.tsx +586 -0
  483. package/src/components/Toast/Toast.tsx +339 -0
  484. package/src/components/Toast/index.ts +14 -0
  485. package/src/components/Tooltip/Tooltip.test.tsx +852 -0
  486. package/src/components/Tooltip/Tooltip.tsx +167 -0
  487. package/src/components/Tooltip/index.ts +7 -0
  488. package/src/components/UserMenu/UserMenu.test.tsx +702 -0
  489. package/src/components/UserMenu/UserMenu.tsx +243 -0
  490. package/src/components/UserMenu/index.ts +3 -0
  491. package/src/components/examples/PermissionExample.tsx +150 -0
  492. package/src/components/index.ts +434 -0
  493. package/src/components.ts +19 -0
  494. package/src/constants/performance.ts +14 -0
  495. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  496. package/src/examples/PublicEventPage.tsx +274 -0
  497. package/src/examples/PublicPageApp.tsx +308 -0
  498. package/src/examples/PublicPageUsageExample.tsx +216 -0
  499. package/src/hooks/index.ts +56 -0
  500. package/src/hooks/public/index.ts +34 -0
  501. package/src/hooks/public/usePublicEvent.ts +261 -0
  502. package/src/hooks/public/usePublicEventLogo.ts +285 -0
  503. package/src/hooks/public/usePublicRouteParams.ts +259 -0
  504. package/src/hooks/useAppConfig.ts +94 -0
  505. package/src/hooks/useComponentPerformance.ts +39 -0
  506. package/src/hooks/useCounter.test.ts +135 -0
  507. package/src/hooks/useDataTablePerformance.ts +387 -0
  508. package/src/hooks/useDataTableState.ts +110 -0
  509. package/src/hooks/useDebounce.test.ts +375 -0
  510. package/src/hooks/useDebounce.ts +18 -0
  511. package/src/hooks/useFocusManagement.ts +161 -0
  512. package/src/hooks/useFocusTrap.ts +155 -0
  513. package/src/hooks/useInactivityTracker.ts +372 -0
  514. package/src/hooks/useIsMobile.ts +42 -0
  515. package/src/hooks/useKeyboardShortcuts.ts +237 -0
  516. package/src/hooks/useOrganisationPermissions.test.ts +528 -0
  517. package/src/hooks/useOrganisationPermissions.ts +208 -0
  518. package/src/hooks/useOrganisationSecurity.test.ts +734 -0
  519. package/src/hooks/useOrganisationSecurity.ts +262 -0
  520. package/src/hooks/usePerformanceMonitor.ts +128 -0
  521. package/src/hooks/usePermissionCache.test.ts +542 -0
  522. package/src/hooks/usePermissionCache.ts +455 -0
  523. package/src/hooks/useSecureDataAccess.ts +586 -0
  524. package/src/hooks/useStorage.ts +274 -0
  525. package/src/hooks/useToast.ts +242 -0
  526. package/src/hooks/useZodForm.ts +28 -0
  527. package/src/index.ts +199 -0
  528. package/src/providers/AuthProvider.tsx +369 -0
  529. package/src/providers/EventProvider.tsx +324 -0
  530. package/src/providers/InactivityProvider.tsx +238 -0
  531. package/src/providers/OrganisationProvider.tsx +588 -0
  532. package/src/providers/UnifiedAuthProvider.tsx +327 -0
  533. package/src/providers/index.ts +17 -0
  534. package/src/rbac/README.md +885 -0
  535. package/src/rbac/__tests__/integration.test.tsx +218 -0
  536. package/src/rbac/adapters.tsx +726 -0
  537. package/src/rbac/api.test.ts +441 -0
  538. package/src/rbac/api.ts +339 -0
  539. package/src/rbac/audit-enhanced.ts +339 -0
  540. package/src/rbac/audit.ts +338 -0
  541. package/src/rbac/cache.ts +215 -0
  542. package/src/rbac/components/EnhancedNavigationMenu.tsx +294 -0
  543. package/src/rbac/components/NavigationGuard.tsx +294 -0
  544. package/src/rbac/components/NavigationProvider.tsx +314 -0
  545. package/src/rbac/components/PagePermissionGuard.tsx +430 -0
  546. package/src/rbac/components/PagePermissionProvider.tsx +274 -0
  547. package/src/rbac/components/PermissionEnforcer.tsx +307 -0
  548. package/src/rbac/components/RoleBasedRouter.tsx +425 -0
  549. package/src/rbac/components/SecureDataProvider.tsx +319 -0
  550. package/src/rbac/components/index.ts +64 -0
  551. package/src/rbac/config.ts +133 -0
  552. package/src/rbac/docs/event-based-apps.md +285 -0
  553. package/src/rbac/engine.ts +1026 -0
  554. package/src/rbac/eslint-rules.js +285 -0
  555. package/src/rbac/examples/CompleteRBACExample.tsx +323 -0
  556. package/src/rbac/examples/EventBasedApp.tsx +238 -0
  557. package/src/rbac/hooks/index.ts +21 -0
  558. package/src/rbac/hooks/useCan.test.ts +461 -0
  559. package/src/rbac/hooks/usePermissions.test.ts +359 -0
  560. package/src/rbac/hooks/usePermissions.ts +567 -0
  561. package/src/rbac/hooks/useRBAC.simple.test.ts +90 -0
  562. package/src/rbac/hooks/useRBAC.test.ts +503 -0
  563. package/src/rbac/hooks/useRBAC.ts +262 -0
  564. package/src/rbac/index.ts +109 -0
  565. package/src/rbac/permissions.ts +293 -0
  566. package/src/rbac/providers/RBACProvider.tsx +634 -0
  567. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +687 -0
  568. package/src/rbac/providers/index.ts +11 -0
  569. package/src/rbac/secureClient.ts +244 -0
  570. package/src/rbac/security.ts +346 -0
  571. package/src/rbac/testing/index.tsx +340 -0
  572. package/src/rbac/types.ts +343 -0
  573. package/src/rbac/utils/eventContext.ts +83 -0
  574. package/src/styles/core.css +364 -0
  575. package/src/styles/index.ts +51 -0
  576. package/src/theming/runtime.ts +187 -0
  577. package/src/types/database.ts +472 -0
  578. package/src/types/guards.ts +30 -0
  579. package/src/types/index.ts +25 -0
  580. package/src/types/organisation.ts +184 -0
  581. package/src/types/security.ts +70 -0
  582. package/src/types/supabase.ts +166 -0
  583. package/src/types/theme.ts +6 -0
  584. package/src/types/unified.ts +262 -0
  585. package/src/types/validation.ts +164 -0
  586. package/src/types/vitest-globals.d.ts +43 -0
  587. package/src/utils/__mocks__/supabaseMock.ts +75 -0
  588. package/src/utils/__mocks__/supabaseMock.tsx +198 -0
  589. package/src/utils/appConfig.ts +47 -0
  590. package/src/utils/appIdResolver.ts +130 -0
  591. package/src/utils/appNameResolver.ts +190 -0
  592. package/src/utils/audit.ts +127 -0
  593. package/src/utils/auth-utils.ts +96 -0
  594. package/src/utils/bundleAnalysis.ts +129 -0
  595. package/src/utils/cn.ts +7 -0
  596. package/src/utils/debugLogger.ts +46 -0
  597. package/src/utils/deviceFingerprint.ts +215 -0
  598. package/src/utils/dynamicUtils.ts +105 -0
  599. package/src/utils/formatDate.test.ts +241 -0
  600. package/src/utils/formatting.ts +77 -0
  601. package/src/utils/index.ts +145 -0
  602. package/src/utils/lazyLoad.tsx +44 -0
  603. package/src/utils/organisationContext.ts +135 -0
  604. package/src/utils/performanceBenchmark.ts +64 -0
  605. package/src/utils/performanceBudgets.ts +111 -0
  606. package/src/utils/permissionTypes.ts +37 -0
  607. package/src/utils/permissionUtils.ts +31 -0
  608. package/src/utils/print/PrintDataProcessor.ts +390 -0
  609. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +397 -0
  610. package/src/utils/print/index.ts +29 -0
  611. package/src/utils/print/types.ts +196 -0
  612. package/src/utils/print/usePrintOptimization.ts +272 -0
  613. package/src/utils/sanitization.ts +264 -0
  614. package/src/utils/schemaUtils.ts +37 -0
  615. package/src/utils/secureDataAccess.ts +361 -0
  616. package/src/utils/secureErrors.ts +79 -0
  617. package/src/utils/secureStorage.ts +244 -0
  618. package/src/utils/security.ts +156 -0
  619. package/src/utils/securityMonitor.ts +45 -0
  620. package/src/utils/sessionTracking.ts +170 -0
  621. package/src/utils/storage/README.md +348 -0
  622. package/src/utils/storage/config.ts +100 -0
  623. package/src/utils/storage/helpers.ts +359 -0
  624. package/src/utils/storage/index.ts +36 -0
  625. package/src/utils/storage/types.ts +90 -0
  626. package/src/utils/validation.ts +111 -0
  627. package/src/utils/validationUtils.ts +120 -0
  628. package/src/validation/common.ts +53 -0
  629. package/src/validation/csrf.ts +214 -0
  630. package/src/validation/index.ts +43 -0
  631. package/src/validation/passwordSchema.ts +125 -0
  632. package/src/validation/sanitization.ts +96 -0
  633. package/src/validation/schemaUtils.ts +42 -0
  634. package/src/validation/sqlInjectionProtection.ts +242 -0
  635. package/src/validation/user.ts +34 -0
  636. package/dist/chunk-4MCJAK7J.js.map +0 -1
  637. package/dist/chunk-4ZTIEYU2.js.map +0 -1
  638. package/dist/chunk-H4PZ4B3Y.js.map +0 -1
  639. package/dist/chunk-IOX76PSM.js.map +0 -1
  640. package/dist/chunk-JUUNUW3O.js.map +0 -1
  641. package/dist/chunk-KK6WIDK6.js +0 -63
  642. package/dist/chunk-KK6WIDK6.js.map +0 -1
  643. package/dist/chunk-U7DY5T33.js +0 -11
  644. package/dist/chunk-U7DY5T33.js.map +0 -1
  645. package/dist/chunk-WHLSWC6W.js.map +0 -1
  646. package/dist/chunk-XI7QFSSC.js +0 -790
  647. package/dist/chunk-XI7QFSSC.js.map +0 -1
  648. package/dist/chunk-XIJMMBDD.js +0 -73
  649. package/dist/chunk-XIJMMBDD.js.map +0 -1
  650. package/dist/chunk-YNU5QJ4S.js.map +0 -1
  651. package/dist/chunk-YWYCNGWH.js +0 -2070
  652. package/dist/chunk-YWYCNGWH.js.map +0 -1
  653. package/dist/chunk-ZJ3UKPIW.js +0 -952
  654. package/dist/chunk-ZJ3UKPIW.js.map +0 -1
  655. package/dist/useAppConfig-CZNJJsT_.d.ts +0 -148
  656. package/dist/{DataTable-2LB6HI6V.js.map → DataTable-ZQDRE46Q.js.map} +0 -0
  657. package/dist/{api-AIJ3IJX3.js.map → api-H5A3H4IR.js.map} +0 -0
  658. package/dist/{audit-PD5L5ZSC.js.map → appNameResolver-7GHF5ED2.js.map} +0 -0
  659. package/dist/{chunk-DC5AMYBS.js.map → audit-BUW3LMJB.js.map} +0 -0
  660. package/dist/{validation-D2-NNCCE.d.ts → validation-PM_iOaTI.d.ts} +6 -6
@@ -0,0 +1,214 @@
1
+ /**
2
+ * @file DataTable Error Boundary
3
+ * @package @jmruthers/pace-core
4
+ * @module Components/DataTable/Components
5
+ * @since 0.4.0
6
+ *
7
+ * Error boundary component for DataTable with fallback UI and error recovery.
8
+ */
9
+
10
+ import React, { Component, ErrorInfo, ReactNode } from 'react';
11
+ import { Alert, AlertDescription, AlertTitle } from '../../Alert/Alert';
12
+ import { Button } from '../../Button/Button';
13
+ // Icons removed to avoid test mocking issues
14
+
15
+ // ============================================================================
16
+ // ERROR BOUNDARY STATE
17
+ // ============================================================================
18
+
19
+ interface ErrorBoundaryState {
20
+ hasError: boolean;
21
+ error: Error | null;
22
+ errorInfo: ErrorInfo | null;
23
+ retryCount: number;
24
+ }
25
+
26
+ // ============================================================================
27
+ // ERROR BOUNDARY PROPS
28
+ // ============================================================================
29
+
30
+ interface DataTableErrorBoundaryProps {
31
+ children: ReactNode;
32
+ fallback?: ReactNode;
33
+ onError?: (error: Error, errorInfo: ErrorInfo) => void;
34
+ onRetry?: () => void;
35
+ maxRetries?: number;
36
+ showRetryButton?: boolean;
37
+ showErrorDetails?: boolean;
38
+ }
39
+
40
+ // ============================================================================
41
+ // ERROR BOUNDARY COMPONENT
42
+ // ============================================================================
43
+
44
+ export class DataTableErrorBoundary extends Component<
45
+ DataTableErrorBoundaryProps,
46
+ ErrorBoundaryState
47
+ > {
48
+ private retryTimeoutId: NodeJS.Timeout | null = null;
49
+
50
+ constructor(props: DataTableErrorBoundaryProps) {
51
+ super(props);
52
+ this.state = {
53
+ hasError: false,
54
+ error: null,
55
+ errorInfo: null,
56
+ retryCount: 0
57
+ };
58
+ }
59
+
60
+ static getDerivedStateFromError(error: Error): Partial<ErrorBoundaryState> {
61
+ return {
62
+ hasError: true,
63
+ error
64
+ };
65
+ }
66
+
67
+ componentDidCatch(error: Error, errorInfo: ErrorInfo) {
68
+ this.setState({
69
+ error,
70
+ errorInfo
71
+ });
72
+
73
+ // Call error handler if provided
74
+ this.props.onError?.(error, errorInfo);
75
+
76
+ // Log error for debugging
77
+ console.error('DataTable Error Boundary caught an error:', error, errorInfo);
78
+ }
79
+
80
+ componentWillUnmount() {
81
+ if (this.retryTimeoutId) {
82
+ clearTimeout(this.retryTimeoutId);
83
+ }
84
+ }
85
+
86
+ handleRetry = () => {
87
+ const { onRetry, maxRetries = 3 } = this.props;
88
+ const { retryCount } = this.state;
89
+
90
+ if (retryCount >= maxRetries) {
91
+ console.warn('DataTable Error Boundary: Maximum retry attempts reached');
92
+ return;
93
+ }
94
+
95
+ // Call custom retry handler if provided
96
+ if (onRetry) {
97
+ onRetry();
98
+ }
99
+
100
+ // Reset error state after a short delay
101
+ this.retryTimeoutId = setTimeout(() => {
102
+ this.setState({
103
+ hasError: false,
104
+ error: null,
105
+ errorInfo: null,
106
+ retryCount: retryCount + 1
107
+ });
108
+ }, 100);
109
+ };
110
+
111
+ handleReset = () => {
112
+ this.setState({
113
+ hasError: false,
114
+ error: null,
115
+ errorInfo: null,
116
+ retryCount: 0
117
+ });
118
+ };
119
+
120
+ render() {
121
+ const {
122
+ children,
123
+ fallback,
124
+ showRetryButton = true,
125
+ showErrorDetails = false,
126
+ maxRetries = 3
127
+ } = this.props;
128
+ const { hasError, error, retryCount } = this.state;
129
+
130
+ if (hasError) {
131
+ // Use custom fallback if provided
132
+ if (fallback) {
133
+ return fallback;
134
+ }
135
+
136
+ // Default error UI
137
+ return (
138
+ <div className="flex items-center justify-center p-8">
139
+ <Alert variant="destructive" className="max-w-md">
140
+ <AlertTitle>DataTable Error</AlertTitle>
141
+ <AlertDescription className="mt-2">
142
+ <span>Something went wrong</span>
143
+ </AlertDescription>
144
+ {error && error.message ? (
145
+ <details className="mt-2">
146
+ <summary className="cursor-pointer text-sm font-medium">
147
+ Error Details
148
+ </summary>
149
+ <pre className="mt-2 text-xs overflow-auto max-h-32">
150
+ {error.message}
151
+ {showErrorDetails && error.stack && (
152
+ <>
153
+ {'\n\nStack Trace:\n'}
154
+ {error.stack}
155
+ </>
156
+ )}
157
+ </pre>
158
+ </details>
159
+ ) : (
160
+ <div className="mt-2">
161
+ <span>An unexpected error occurred</span>
162
+ </div>
163
+ )}
164
+ <div className="mt-4 flex gap-2">
165
+ {showRetryButton && retryCount < maxRetries && (
166
+ <Button
167
+ variant="outline"
168
+ size="sm"
169
+ onClick={this.handleRetry}
170
+ className="flex items-center gap-2"
171
+ >
172
+ Retry ({retryCount + 1}/{maxRetries})
173
+ </Button>
174
+ )}
175
+ <Button
176
+ variant="outline"
177
+ size="sm"
178
+ onClick={this.handleReset}
179
+ >
180
+ Reset
181
+ </Button>
182
+ </div>
183
+ </Alert>
184
+ </div>
185
+ );
186
+ }
187
+
188
+ return children;
189
+ }
190
+ }
191
+
192
+ // ============================================================================
193
+ // HOOK FOR ERROR BOUNDARY
194
+ // ============================================================================
195
+
196
+ export function useDataTableErrorBoundary() {
197
+ const [error, setError] = React.useState<Error | null>(null);
198
+
199
+ const resetError = React.useCallback(() => {
200
+ setError(null);
201
+ }, []);
202
+
203
+ const captureError = React.useCallback((error: Error) => {
204
+ setError(error);
205
+ }, []);
206
+
207
+ React.useEffect(() => {
208
+ if (error) {
209
+ throw error;
210
+ }
211
+ }, [error]);
212
+
213
+ return { captureError, resetError };
214
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @file DataTable Modals Component
3
+ * @package @jmruthers/pace-core
4
+ * @module Components/DataTable/Components
5
+ * @since 0.2.0
6
+ *
7
+ * Container component for all modal dialogs used by the DataTable component.
8
+ * This includes import modals and other data table related dialogs.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * <DataTableModals
13
+ * showImportModal={isImportOpen}
14
+ * onCloseImportModal={() => setIsImportOpen(false)}
15
+ * onImport={handleImportData}
16
+ * importModalConfig={{
17
+ * title: "Import Users",
18
+ * description: "Upload a CSV file with user data."
19
+ * }}
20
+ * />
21
+ * ```
22
+ */
23
+
24
+ import React from 'react';
25
+ import { ImportModal, type ImportModalConfig } from './ImportModal';
26
+
27
+ /**
28
+ * Props interface for the DataTableModals component
29
+ * @public
30
+ */
31
+ export interface DataTableModalsProps {
32
+ // Import modal
33
+ /** Whether the import modal is visible */
34
+ showImportModal: boolean;
35
+ /** Callback function when the import modal is closed */
36
+ onCloseImportModal: () => void;
37
+ /** Callback function when data is imported successfully */
38
+ onImport: (data: any[]) => void | Promise<void>;
39
+ /** Configuration object for customizing import modal text content */
40
+ importModalConfig?: ImportModalConfig;
41
+
42
+ }
43
+
44
+ /**
45
+ * DataTableModals component that renders all modal dialogs for the DataTable
46
+ *
47
+ * @param props - The component props
48
+ * @returns JSX.Element - Container with all data table modal dialogs
49
+ *
50
+ * @example
51
+ * ```tsx
52
+ * const importConfig = {
53
+ * title: "Import Customer Data",
54
+ * description: "Upload a CSV file with customer information to import multiple records.",
55
+ * uploadText: "Choose a customer CSV file",
56
+ * selectFileButtonText: "Browse Files"
57
+ * };
58
+ *
59
+ * <DataTableModals
60
+ * showImportModal={showImport}
61
+ * onCloseImportModal={() => setShowImport(false)}
62
+ * onImport={handleImportedData}
63
+ * importModalConfig={importConfig}
64
+ * isViewModalOpen={showView}
65
+ * onCloseViewModal={() => setShowView(false)}
66
+ * viewModalData={selectedRow}
67
+ * />
68
+ * ```
69
+ */
70
+ export function DataTableModals({
71
+ showImportModal,
72
+ onCloseImportModal,
73
+ onImport,
74
+ importModalConfig,
75
+ }: DataTableModalsProps) {
76
+ return (
77
+ <>
78
+ <ImportModal
79
+ isOpen={showImportModal}
80
+ onClose={onCloseImportModal}
81
+ onImport={onImport}
82
+ config={importModalConfig}
83
+ />
84
+
85
+ </>
86
+ );
87
+ }
@@ -0,0 +1,262 @@
1
+ /**
2
+ * @file DataTable Toolbar Component
3
+ * @package @jmruthers/pace-core
4
+ * @module Components/DataTable/Components
5
+ * @since 0.3.0
6
+ *
7
+ * The DataTable toolbar provides a comprehensive interface for table operations including
8
+ * search, grouping, column visibility, and action buttons. It's positioned above the table
9
+ * and contains all primary user interactions.
10
+ *
11
+ * Features:
12
+ * - Global search with debounced input
13
+ * - Column-based grouping controls
14
+ * - Column visibility toggles
15
+ * - Custom toolbar buttons
16
+ * - Import/Export actions
17
+ * - Row creation button
18
+ * - Responsive layout that adapts to screen size
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * <DataTableToolbar
23
+ * searchable={true}
24
+ * globalFilter=""
25
+ * onGlobalFilterChange={(value) => setFilter(value)}
26
+ * enableGrouping={true}
27
+ * columns={columns}
28
+ * grouping={[]}
29
+ * onGroupByChange={(columnId) => setGroupBy(columnId)}
30
+ * enableColumnVisibility={true}
31
+ * tableColumns={table.getAllColumns()}
32
+ * onColumnVisibilityChange={(id, visible) => toggleColumn(id, visible)}
33
+ * toolbarButtons={customButtons}
34
+ * enableCreation={true}
35
+ * onCreateRow={() => openCreateModal()}
36
+ * enableImport={true}
37
+ * onImportClick={() => openImportModal()}
38
+ * exportable={true}
39
+ * onExport={() => exportData()}
40
+ * />
41
+ * ```
42
+ *
43
+ * @accessibility
44
+ * - Search input has proper aria-label
45
+ * - All buttons have descriptive labels
46
+ * - Keyboard navigation support
47
+ * - Focus management
48
+ *
49
+ * @performance
50
+ * - Search input uses debounced onChange to prevent excessive filtering
51
+ * - Button renders are memoized
52
+ * - Dropdown menus use virtual scrolling for large column lists
53
+ */
54
+
55
+ import React from 'react';
56
+ import { Input } from '../../Input/Input';
57
+ import { Button } from '../../Button/Button';
58
+ import { Search, Plus, Upload, Download, Settings2, Filter, Trash2 } from 'lucide-react';
59
+ import { GroupingDropdown } from './GroupingDropdown';
60
+ import { ColumnVisibilityDropdown } from './ColumnVisibilityDropdown';
61
+ import type { DataTableColumn, DataRecord, SimpleColumn, DataTableFeatureConfig, DataTableRBACConfig } from '../types';
62
+ import type { Column } from '@tanstack/react-table';
63
+
64
+ /**
65
+ * Props for the DataTable toolbar component
66
+ * @template TData - The type of data records in the table
67
+ */
68
+ interface DataTableToolbarProps<TData extends DataRecord = DataRecord> {
69
+ // Feature configuration
70
+ /** Feature configuration for the toolbar */
71
+ features: DataTableFeatureConfig;
72
+
73
+ // MANDATORY RBAC
74
+ /** RBAC configuration - REQUIRED for all DataTables */
75
+ rbac: DataTableRBACConfig;
76
+ /** Permission states for RBAC enforcement */
77
+ permissions: {
78
+ canCreate: { can: boolean; isLoading: boolean };
79
+ canImport: { can: boolean; isLoading: boolean };
80
+ canExport: { can: boolean; isLoading: boolean };
81
+ canDelete: { can: boolean; isLoading: boolean };
82
+ };
83
+
84
+ // Data and state
85
+ /** Current global filter value */
86
+ globalFilter: string;
87
+ /** Callback when global filter changes */
88
+ onGlobalFilterChange: (value: string) => void;
89
+ /** Column definitions for grouping dropdown */
90
+ columns: (DataTableColumn<TData> | SimpleColumn<TData>)[];
91
+ /** Currently applied grouping columns */
92
+ grouping: string[];
93
+ /** Callback when grouping changes */
94
+ onGroupByChange: (columnId: string | null) => void;
95
+ /** Table columns from TanStack Table instance */
96
+ tableColumns: Column<TData, unknown>[];
97
+ /** Callback when column visibility changes */
98
+ onColumnVisibilityChange: (columnId: string, visible: boolean) => void;
99
+ /** Current row selection state */
100
+ rowSelection: Record<string, boolean>;
101
+
102
+ // Callbacks
103
+ /** Callback when create row button is clicked */
104
+ onCreateRow?: () => void;
105
+ /** Callback when import button is clicked */
106
+ onImportClick: () => void;
107
+ /** Callback when export button is clicked */
108
+ onExport: () => void;
109
+ /** Callback when delete selected button is clicked */
110
+ onDeleteSelected?: (selectedRows: Record<string, boolean>) => void;
111
+ /** Callback when filter toggle button is clicked */
112
+ onToggleFilterRow?: () => void;
113
+
114
+ // Filter state
115
+ /** Whether the filter row is currently visible */
116
+ showFilterRow?: boolean;
117
+ }
118
+
119
+ /**
120
+ * DataTable toolbar component that provides search, filtering, and action controls
121
+ *
122
+ * This component renders the top toolbar of the DataTable with various controls including:
123
+ * - Global search input (left side)
124
+ * - Grouping dropdown (left side)
125
+ * - Action buttons and controls (right side)
126
+ *
127
+ * The toolbar uses a responsive flexbox layout that adapts to different screen sizes.
128
+ *
129
+ * @template TData - The type of data records in the table
130
+ * @param props - The toolbar props
131
+ * @returns JSX.Element - The rendered toolbar component
132
+ *
133
+ * @example
134
+ * ```tsx
135
+ * <DataTableToolbar
136
+ * searchable={true}
137
+ * globalFilter="john"
138
+ * onGlobalFilterChange={(value) => setFilter(value)}
139
+ * enableGrouping={true}
140
+ * // ... other props
141
+ * />
142
+ * ```
143
+ */
144
+ export function DataTableToolbar<TData extends DataRecord>({
145
+ features,
146
+ rbac,
147
+ permissions,
148
+ globalFilter,
149
+ onGlobalFilterChange,
150
+ columns,
151
+ grouping,
152
+ onGroupByChange,
153
+ tableColumns,
154
+ onColumnVisibilityChange,
155
+ rowSelection,
156
+ onCreateRow,
157
+ onImportClick,
158
+ onExport,
159
+ onDeleteSelected,
160
+ onToggleFilterRow,
161
+ showFilterRow = false,
162
+ }: DataTableToolbarProps<TData>) {
163
+ const currentGroupBy = grouping.length > 0 ? grouping[0] : null;
164
+
165
+ return (
166
+
167
+ <nav className="flex justify-end flex-wrap gap-2">
168
+ {features.search && (
169
+
170
+ <Input
171
+ id="table-search"
172
+ placeholder="Search..."
173
+ value={globalFilter}
174
+ onChange={(e) => onGlobalFilterChange(e.target.value)}
175
+ aria-label="Search table"
176
+ tabIndex={0}
177
+ className="justify-self-start w-50 flex-1"
178
+ />
179
+
180
+ )}
181
+
182
+
183
+
184
+ {/* Grouping */}
185
+ {features.grouping && (
186
+ <GroupingDropdown
187
+ columns={columns}
188
+ currentGroupBy={currentGroupBy}
189
+ onGroupByChange={onGroupByChange}
190
+ />
191
+ )}
192
+
193
+ {/* Column Visibility */}
194
+ {features.columnVisibility && (
195
+ <ColumnVisibilityDropdown
196
+ columns={tableColumns}
197
+ onColumnVisibilityChange={onColumnVisibilityChange}
198
+ />
199
+ )}
200
+
201
+ {/* Filter Toggle */}
202
+ {features.filtering && onToggleFilterRow && (
203
+ <Button
204
+ variant="outline"
205
+ onClick={onToggleFilterRow}
206
+ >
207
+ <Filter className="h-4 w-4 mr-2 flex-shrink-0" />
208
+ <span className="truncate">
209
+ {showFilterRow ? 'Hide Filters' : 'Show Filters'}
210
+ </span>
211
+ </Button>
212
+ )}
213
+
214
+ {/* Row Creation - ONLY if user has create permission */}
215
+ {features.creation && permissions.canCreate.can && onCreateRow && (
216
+ <Button
217
+ variant="outline"
218
+ onClick={onCreateRow}
219
+ >
220
+ <Plus className="h-4 w-4 mr-2 flex-shrink-0" />
221
+ <span className="truncate">Add Row</span>
222
+ </Button>
223
+ )}
224
+
225
+ {/* Import - ONLY if user has import permission */}
226
+ {features.import && permissions.canImport.can && (
227
+ <Button
228
+ variant="outline"
229
+ onClick={onImportClick}
230
+ >
231
+ <Upload className="h-4 w-4 mr-2 flex-shrink-0" />
232
+ <span className="truncate">Import</span>
233
+ </Button>
234
+ )}
235
+
236
+ {/* Export - ONLY if user has export permission */}
237
+ {features.export && permissions.canExport.can && (
238
+ <Button
239
+ variant="outline"
240
+ onClick={onExport}
241
+ >
242
+ <Download className="h-4 w-4 mr-2 flex-shrink-0" />
243
+ <span className="truncate">Export</span>
244
+ </Button>
245
+ )}
246
+
247
+ {/* Delete Selected - ONLY if user has delete permission */}
248
+ {features.deleteSelected && features.deletion && features.selection && permissions.canDelete.can && (
249
+ <Button
250
+ variant="destructive"
251
+ onClick={() => onDeleteSelected?.(rowSelection)}
252
+ disabled={Object.values(rowSelection).filter(Boolean).length === 0}
253
+ >
254
+ <Trash2 className="h-4 w-4 mr-2 flex-shrink-0" />
255
+ <span className="truncate">Delete</span>
256
+ </Button>
257
+ )}
258
+
259
+ </nav>
260
+
261
+ );
262
+ }
@@ -0,0 +1,144 @@
1
+ import React, { useState } from 'react';
2
+ import { Button } from '../../Button/Button';
3
+ import { ChevronUp, ChevronDown,ChevronsUpDown } from 'lucide-react';
4
+ import { cn } from '../../../utils/cn';
5
+ import type { Header } from '@tanstack/react-table';
6
+
7
+ interface DraggableColumnHeaderProps<TData> {
8
+ header: Header<TData, unknown>;
9
+ onMoveLeft?: () => void;
10
+ onMoveRight?: () => void;
11
+ canMoveLeft?: boolean;
12
+ canMoveRight?: boolean;
13
+ enableReordering?: boolean;
14
+ onColumnDrop?: (draggedColumnId: string, targetColumnId: string) => void;
15
+ }
16
+
17
+ export function DraggableColumnHeader<TData>({
18
+ header,
19
+ onMoveLeft,
20
+ onMoveRight,
21
+ canMoveLeft = false,
22
+ canMoveRight = false,
23
+ enableReordering = false,
24
+ onColumnDrop,
25
+ }: DraggableColumnHeaderProps<TData>) {
26
+ const [isDragging, setIsDragging] = useState(false);
27
+ const [dragOver, setDragOver] = useState(false);
28
+
29
+ const isSortable = header.column.getCanSort ? header.column.getCanSort() : false;
30
+ const ariaSort = isSortable
31
+ ? (header.column.getIsSorted ? (header.column.getIsSorted() === 'asc'
32
+ ? 'ascending'
33
+ : header.column.getIsSorted() === 'desc'
34
+ ? 'descending'
35
+ : 'none') : 'none')
36
+ : undefined;
37
+
38
+ const handleDragStart = (e: React.DragEvent) => {
39
+ if (!enableReordering) return;
40
+
41
+ setIsDragging(true);
42
+ e.dataTransfer.setData('text/plain', header.id);
43
+ e.dataTransfer.effectAllowed = 'move';
44
+
45
+ // Add visual feedback
46
+ if (e.currentTarget instanceof HTMLElement) {
47
+ e.currentTarget.style.opacity = '0.5';
48
+ }
49
+ };
50
+
51
+ const handleDragEnd = (e: React.DragEvent) => {
52
+ setIsDragging(false);
53
+ setDragOver(false);
54
+
55
+ // Reset visual feedback
56
+ if (e.currentTarget instanceof HTMLElement) {
57
+ e.currentTarget.style.opacity = '1';
58
+ }
59
+ };
60
+
61
+ const handleDragOver = (e: React.DragEvent) => {
62
+ if (!enableReordering) return;
63
+
64
+ e.preventDefault();
65
+ e.dataTransfer.dropEffect = 'move';
66
+ setDragOver(true);
67
+ };
68
+
69
+ const handleDragLeave = (e: React.DragEvent) => {
70
+ if (!enableReordering) return;
71
+
72
+ // Only set dragOver to false if we're leaving the element entirely
73
+ if (!e.currentTarget.contains(e.relatedTarget as Node)) {
74
+ setDragOver(false);
75
+ }
76
+ };
77
+
78
+ const handleDrop = (e: React.DragEvent) => {
79
+ if (!enableReordering) return;
80
+
81
+ e.preventDefault();
82
+ setDragOver(false);
83
+
84
+ const draggedHeaderId = e.dataTransfer.getData('text/plain');
85
+ if (draggedHeaderId && draggedHeaderId !== header.id && onColumnDrop) {
86
+ onColumnDrop(draggedHeaderId, header.id);
87
+ }
88
+ };
89
+
90
+ return (
91
+ <th
92
+ className={cn(
93
+ 'px-3 py-2 text-sm font-medium text-left relative group',
94
+ isSortable && 'cursor-pointer hover:bg-sec-50',
95
+ isDragging && 'opacity-50',
96
+ dragOver && 'bg-main-50 border-main-200',
97
+ enableReordering && 'cursor-move'
98
+ )}
99
+ style={{}}
100
+ draggable={enableReordering}
101
+ onDragStart={handleDragStart}
102
+ onDragEnd={handleDragEnd}
103
+ onDragOver={handleDragOver}
104
+ onDragLeave={handleDragLeave}
105
+ onDrop={handleDrop}
106
+ {...(isSortable ? { 'aria-sort': ariaSort } : {})}
107
+ >
108
+ <div className="flex items-center justify-between">
109
+ <div className="flex items-center gap-1 flex-1">
110
+ {header.isPlaceholder ? null : (
111
+ isSortable ? (
112
+ <Button
113
+ variant="ghost"
114
+ className="h-auto p-0 font-medium hover:bg-transparent flex-1 justify-start"
115
+ onClick={header.column.getToggleSortingHandler()}
116
+ aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : 'column'}`}
117
+ tabIndex={0}
118
+ >
119
+ <div className="flex items-center gap-1">
120
+ {typeof header.column.columnDef.header === 'function'
121
+ ? header.column.columnDef.header(header.getContext())
122
+ : header.column.columnDef.header}
123
+ {header.column.getIsSorted() === 'asc' ? (
124
+ <ChevronUp className="h-4 w-4" />
125
+ ) : header.column.getIsSorted() === 'desc' ? (
126
+ <ChevronDown className="h-4 w-4" />
127
+ ) : (
128
+ <ChevronsUpDown className="h-4 w-4" />
129
+ )}
130
+ </div>
131
+ </Button>
132
+ ) : (
133
+ <div className="flex-1">
134
+ {typeof header.column.columnDef.header === 'function'
135
+ ? header.column.columnDef.header(header.getContext())
136
+ : header.column.columnDef.header}
137
+ </div>
138
+ )
139
+ )}
140
+ </div>
141
+ </div>
142
+ </th>
143
+ );
144
+ }