@jmruthers/pace-core 0.6.10 → 0.6.11

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 (726) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/audit-tool/00-dependencies.cjs +46 -13
  3. package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
  4. package/audit-tool/audits/02-project-structure.cjs +13 -3
  5. package/audit-tool/audits/03-architecture.cjs +78 -4
  6. package/audit-tool/audits/04-code-quality.cjs +9 -2
  7. package/audit-tool/audits/05-styling.cjs +19 -7
  8. package/audit-tool/audits/06-security-rbac.cjs +105 -14
  9. package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
  10. package/audit-tool/audits/08-testing-documentation.cjs +11 -3
  11. package/audit-tool/audits/09-operations.cjs +19 -7
  12. package/audit-tool/index.cjs +22 -11
  13. package/audit-tool/utils/report-utils.cjs +4 -0
  14. package/cursor-rules/01-pace-core-compliance.mdc +1 -0
  15. package/cursor-rules/02-project-structure.mdc +1 -0
  16. package/cursor-rules/03-architecture.mdc +3 -1
  17. package/cursor-rules/04-code-quality.mdc +1 -0
  18. package/cursor-rules/05-styling.mdc +41 -7
  19. package/cursor-rules/06-security-rbac.mdc +2 -1
  20. package/cursor-rules/07-api-tech-stack.mdc +1 -0
  21. package/cursor-rules/08-testing-documentation.mdc +1 -0
  22. package/cursor-rules/09-operations.mdc +1 -0
  23. package/dist/{DataTable-SAXFG4XI.js → DataTable-EFYP2QLE.js} +10 -7
  24. package/dist/{InactivityServiceProvider-DHryoh6K.d.ts → InactivityServiceProvider-BbxwwDz1.d.ts} +10 -1
  25. package/dist/{UnifiedAuthProvider-CiBAl9-s.d.ts → UnifiedAuthProvider-Bkt_tzdS.d.ts} +56 -24
  26. package/dist/{api-F47QJ7FX.js → api-BZR2CYXL.js} +3 -2
  27. package/dist/api-result-USV1Czr-.d.ts +51 -0
  28. package/dist/{audit-Z6ZZBWLU.js → audit-HI2DHUVU.js} +2 -1
  29. package/dist/{auth-BZOJqrdd.d.ts → auth-JvdRVaud.d.ts} +1 -1
  30. package/dist/{chunk-KSNLMI7N.js → chunk-2DL2WSOE.js} +1 -155
  31. package/dist/{chunk-MPY44PWB.js → chunk-2OEVOGGR.js} +4648 -3560
  32. package/dist/chunk-44CNXN4P.js +15 -0
  33. package/dist/{chunk-Y4PF6HIM.js → chunk-4R3T5ENU.js} +867 -786
  34. package/dist/{chunk-LNHFAF4X.js → chunk-7A6IMHH2.js} +289 -247
  35. package/dist/chunk-CU2BU2MQ.js +2 -0
  36. package/dist/{chunk-JJEYZ3DX.js → chunk-D6BMFMQZ.js} +37 -2
  37. package/dist/{chunk-BCTXBU6U.js → chunk-ENLXB7GP.js} +88 -71
  38. package/dist/{chunk-FBZ7U3ID.js → chunk-J2KQK6DG.js} +937 -987
  39. package/dist/{chunk-TFIPNIPE.js → chunk-KJXRL3XE.js} +3300 -2245
  40. package/dist/{chunk-3GWSPISD.js → chunk-L5LFKKLJ.js} +1 -1
  41. package/dist/{chunk-X5EAU5G7.js → chunk-PCSHBLPB.js} +132 -114
  42. package/dist/{chunk-NIU6DPQV.js → chunk-QRYSEPHB.js} +2 -0
  43. package/dist/{chunk-KYURMOQM.js → chunk-V7FTM2LU.js} +423 -320
  44. package/dist/chunk-WY6Y7KC3.js +264 -0
  45. package/dist/{chunk-FN52B75D.js → chunk-XOJME5T7.js} +176 -15
  46. package/dist/{chunk-7YDC7LMU.js → chunk-XPFVT3GN.js} +71 -66
  47. package/dist/{chunk-66R6RLUZ.js → chunk-YFTFFJIV.js} +3 -3
  48. package/dist/{chunk-W46INAVW.js → chunk-YYTWKVHO.js} +688 -570
  49. package/dist/components.d.ts +8 -7
  50. package/dist/components.js +17 -15
  51. package/dist/{database.generated-DT8JTZiP.d.ts → database.generated-qkdoiVrJ.d.ts} +45 -10
  52. package/dist/eslint-rules/index.cjs +3 -0
  53. package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
  54. package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
  55. package/dist/{event-WTAQuGcq.d.ts → event-BfCox3N2.d.ts} +36 -10
  56. package/dist/{file-reference-BavO2eQj.d.ts → file-reference-DU1hcawx.d.ts} +29 -13
  57. package/dist/hooks.d.ts +22 -9
  58. package/dist/hooks.js +34 -25
  59. package/dist/icons/index.d.ts +1 -0
  60. package/dist/icons/index.js +1 -0
  61. package/dist/index.d.ts +66 -177
  62. package/dist/index.js +316 -340
  63. package/dist/pagination-BW1mqywp.d.ts +201 -0
  64. package/dist/providers.d.ts +6 -5
  65. package/dist/providers.js +5 -3
  66. package/dist/rbac/index.d.ts +123 -138
  67. package/dist/rbac/index.js +10 -8
  68. package/dist/theming/runtime.d.ts +19 -2
  69. package/dist/theming/runtime.js +1 -1
  70. package/dist/{timezone-K-ptz3HO.d.ts → timezone-BTWWXKVY.d.ts} +1 -1
  71. package/dist/types.d.ts +17 -10
  72. package/dist/types.js +1 -0
  73. package/dist/{usePublicPageContext-vxBlEHO9.d.ts → usePublicPageContext-B91dGYW1.d.ts} +433 -356
  74. package/dist/{usePublicRouteParams-G3Ks53mk.d.ts → usePublicRouteParams-BgV6VhMi.d.ts} +73 -4
  75. package/dist/utils.d.ts +163 -145
  76. package/dist/utils.js +42 -25
  77. package/docs/api/modules.md +782 -643
  78. package/docs/api-reference/rpc-functions.md +12 -3
  79. package/docs/core-concepts/rbac-system.md +8 -0
  80. package/docs/getting-started/cursor-rules.md +17 -20
  81. package/docs/getting-started/dependencies.md +1 -1
  82. package/docs/getting-started/setup.md +235 -0
  83. package/docs/implementation-guides/authentication.md +27 -0
  84. package/docs/implementation-guides/data-tables.md +176 -3
  85. package/docs/migration/ApiResult-migration.md +25 -0
  86. package/docs/rbac/api-reference.md +33 -31
  87. package/docs/standards/0-standards-overview.md +50 -15
  88. package/docs/standards/1-pace-core-compliance-standards.md +62 -57
  89. package/docs/standards/2-project-structure-standards.md +33 -16
  90. package/docs/standards/3-architecture-standards.md +41 -1
  91. package/docs/standards/4-code-quality-standards.md +26 -6
  92. package/docs/standards/5-styling-standards.md +35 -1
  93. package/docs/standards/6-security-rbac-standards.md +66 -0
  94. package/docs/standards/7-api-tech-stack-standards.md +25 -14
  95. package/docs/standards/8-testing-documentation-standards.md +31 -0
  96. package/docs/standards/9-operations-standards.md +19 -0
  97. package/docs/standards/README.md +20 -201
  98. package/docs/testing/test-setup-for-consumers.md +2 -0
  99. package/docs/troubleshooting/common-issues.md +17 -1
  100. package/docs/troubleshooting/organisation-context-setup.md +8 -0
  101. package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
  102. package/eslint-config-pace-core.cjs +20 -0
  103. package/package.json +14 -20
  104. package/scripts/{build-docs-incremental.js → build-docs.js} +3 -2
  105. package/scripts/setup.cjs +536 -0
  106. package/scripts/validate.cjs +480 -0
  107. package/src/__tests__/helpers/{__tests__/component-test-utils.test.tsx → component-test-utils.test.tsx} +3 -3
  108. package/src/__tests__/helpers/{__tests__/optimized-test-setup.test.ts → optimized-test-setup.test.ts} +2 -2
  109. package/src/__tests__/helpers/{__tests__/supabaseMock.test.ts → supabaseMock.test.ts} +2 -2
  110. package/src/__tests__/helpers/{__tests__/test-providers.test.tsx → test-providers.test.tsx} +1 -1
  111. package/src/__tests__/helpers/test-providers.tsx +37 -39
  112. package/src/__tests__/helpers/{__tests__/test-utils.test.tsx → test-utils.test.tsx} +4 -3
  113. package/src/__tests__/helpers/{__tests__/timer-utils.test.ts → timer-utils.test.ts} +2 -2
  114. package/src/assets/app-icons/index.test.ts +304 -0
  115. package/src/components/AddressField/AddressField.test.tsx +1 -1
  116. package/src/components/AddressField/AddressField.tsx +238 -212
  117. package/src/components/Button/Button.tsx +1 -1
  118. package/src/components/Card/Card.test.tsx +172 -17
  119. package/src/components/Card/Card.tsx +19 -10
  120. package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
  121. package/src/components/ContextSelector/{__tests__/ContextSelector.test.tsx → ContextSelector.test.tsx} +6 -6
  122. package/src/components/ContextSelector/ContextSelector.tsx +66 -280
  123. package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
  124. package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
  125. package/src/components/DataTable/AUDIT_REPORT.md +59 -44
  126. package/src/components/DataTable/{__tests__/DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx} +6 -6
  127. package/src/components/DataTable/{__tests__/DataTable.default-state.test.tsx → DataTable.default-state.test.tsx} +5 -5
  128. package/src/components/DataTable/{__tests__/DataTable.export.test.tsx → DataTable.export.test.tsx} +10 -10
  129. package/src/components/DataTable/{__tests__/DataTable.grouping-aggregation.test.tsx → DataTable.grouping-aggregation.test.tsx} +6 -6
  130. package/src/components/DataTable/{__tests__/DataTable.hooks.test.tsx → DataTable.hooks.test.tsx} +6 -6
  131. package/src/components/DataTable/{__tests__/DataTable.select-label-display.test.tsx → DataTable.select-label-display.test.tsx} +6 -6
  132. package/src/components/DataTable/DataTable.test.tsx +787 -416
  133. package/src/components/DataTable/DataTable.tsx +12 -12
  134. package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
  135. package/src/components/DataTable/{__tests__/DataTableCore.test-setup.ts → DataTableCore.test-setup.ts} +10 -9
  136. package/src/components/DataTable/{__tests__/DataTableCore.test.tsx → DataTableCore.test.tsx} +8 -8
  137. package/src/components/DataTable/{__tests__/README.md → README.md} +17 -7
  138. package/src/components/DataTable/TESTING.md +101 -0
  139. package/src/components/DataTable/{__tests__/a11y.basic.test.tsx → a11y.basic.test.tsx} +34 -34
  140. package/src/components/DataTable/components/DataTableCore.tsx +104 -864
  141. package/src/components/DataTable/components/{__tests__/GroupingDropdown.test.tsx → GroupingDropdown.test.tsx} +17 -8
  142. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  143. package/src/components/DataTable/components/ImportModal.tsx +61 -559
  144. package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
  145. package/src/components/DataTable/context/{__tests__/DataTableContext.test.tsx → DataTableContext.test.tsx} +2 -2
  146. package/src/components/DataTable/context/DataTableContext.tsx +7 -6
  147. package/src/components/DataTable/core/{__tests__/ColumnFactory.test.ts → ColumnFactory.test.ts} +2 -2
  148. package/src/components/DataTable/hooks/{__tests__/useColumnOrderPersistence.test.ts → useColumnOrderPersistence.test.ts} +2 -2
  149. package/src/components/DataTable/hooks/{__tests__/useColumnVisibilityPersistence.test.ts → useColumnVisibilityPersistence.test.ts} +2 -2
  150. package/src/components/DataTable/hooks/{__tests__/useDataTableConfiguration.test.ts → useDataTableConfiguration.test.ts} +3 -3
  151. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
  152. package/src/components/DataTable/hooks/{__tests__/useDataTableDataPipeline.test.ts → useDataTableDataPipeline.test.ts} +6 -6
  153. package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
  154. package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
  155. package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
  156. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +238 -0
  157. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
  158. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
  159. package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
  160. package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
  161. package/src/components/DataTable/hooks/{__tests__/useDataTablePermissions.test.ts → useDataTablePermissions.test.ts} +11 -11
  162. package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
  163. package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
  164. package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
  165. package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
  166. package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
  167. package/src/components/DataTable/hooks/useDataTableScope.test.ts +110 -0
  168. package/src/components/DataTable/hooks/useDataTableScope.ts +123 -0
  169. package/src/components/DataTable/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +47 -5
  170. package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
  171. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
  172. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
  173. package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
  174. package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
  175. package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
  176. package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
  177. package/src/components/DataTable/hooks/{__tests__/useEffectiveColumnOrder.test.ts → useEffectiveColumnOrder.test.ts} +2 -2
  178. package/src/components/DataTable/hooks/{__tests__/useHierarchicalState.test.ts → useHierarchicalState.test.ts} +2 -2
  179. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.test.ts +3 -3
  180. package/src/components/DataTable/{components/hooks → hooks}/useImportModalFocus.ts +2 -2
  181. package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
  182. package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
  183. package/src/components/DataTable/hooks/{__tests__/useKeyboardNavigation.test.ts → useKeyboardNavigation.test.ts} +3 -3
  184. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
  185. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.test.ts +3 -3
  186. package/src/components/DataTable/{components/hooks → hooks}/usePermissionTracking.ts +3 -3
  187. package/src/components/DataTable/hooks/{__tests__/useServerSideDataEffect.test.ts → useServerSideDataEffect.test.ts} +2 -2
  188. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
  189. package/src/components/DataTable/hooks/{__tests__/useTableColumns.test.ts → useTableColumns.test.ts} +2 -2
  190. package/src/components/DataTable/hooks/{__tests__/useTableHandlers.test.ts → useTableHandlers.test.ts} +25 -4
  191. package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
  192. package/src/components/DataTable/index.ts +18 -17
  193. package/src/components/DataTable/{__tests__/keyboard.test.tsx → keyboard.test.tsx} +41 -63
  194. package/src/components/DataTable/{__tests__/mocks → mocks}/MockRBACProvider.tsx +1 -1
  195. package/src/components/DataTable/{__tests__/pagination.modes.test.tsx → pagination.modes.test.tsx} +6 -6
  196. package/src/components/DataTable/{__tests__/ssr.strict-mode.test.tsx → ssr.strict-mode.test.tsx} +2 -2
  197. package/src/components/DataTable/{__tests__/styles.test.ts → styles.test.ts} +1 -4
  198. package/src/components/DataTable/styles.ts +0 -1
  199. package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
  200. package/src/components/DataTable/{__tests__/test-utils → test-utils}/dataFactories.ts +2 -2
  201. package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
  202. package/src/components/DataTable/{__tests__/test-utils/sharedTestUtils.tsx → test-utils/sharedTestUtils.ts} +97 -66
  203. package/src/components/DataTable/{__tests__/test-utils.ts → test-utils.ts} +1 -1
  204. package/src/components/DataTable/types/actions.ts +71 -0
  205. package/src/components/DataTable/types/base.ts +39 -0
  206. package/src/components/DataTable/types/columns.ts +125 -0
  207. package/src/components/DataTable/types/export.ts +32 -0
  208. package/src/components/DataTable/types/features.ts +81 -0
  209. package/src/components/DataTable/types/hierarchical.ts +44 -0
  210. package/src/components/DataTable/types/index.ts +43 -0
  211. package/src/components/DataTable/types/pagination.ts +85 -0
  212. package/src/components/DataTable/types/performance.ts +47 -0
  213. package/src/components/DataTable/types/props.ts +62 -0
  214. package/src/components/DataTable/types/rbac.ts +45 -0
  215. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableCore.test.tsx +430 -28
  216. package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
  217. package/src/components/DataTable/{components/__tests__ → ui/layout}/DataTableErrorBoundary.test.tsx +4 -4
  218. package/src/components/DataTable/{components → ui/layout}/DataTableErrorBoundary.tsx +7 -7
  219. package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
  220. package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
  221. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
  222. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
  223. package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
  224. package/src/components/DataTable/{components → ui/modals}/DataTableModals.tsx +36 -28
  225. package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
  226. package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
  227. package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
  228. package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
  229. package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
  230. package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
  231. package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
  232. package/src/components/DataTable/{components/__tests__ → ui/shared}/AccessDeniedPage.test.tsx +2 -2
  233. package/src/components/DataTable/{components → ui/shared}/AccessDeniedPage.tsx +2 -2
  234. package/src/components/DataTable/{components/__tests__ → ui/shared}/ActionButtons.test.tsx +6 -4
  235. package/src/components/DataTable/{components → ui/shared}/ActionButtons.tsx +4 -4
  236. package/src/components/DataTable/{components/__tests__ → ui/shared}/ColumnFilter.test.tsx +29 -16
  237. package/src/components/DataTable/{components → ui/shared}/ColumnFilter.tsx +4 -4
  238. package/src/components/DataTable/{components/__tests__ → ui/shared}/PaginationControls.test.tsx +38 -16
  239. package/src/components/DataTable/{components → ui/shared}/PaginationControls.tsx +21 -15
  240. package/src/components/DataTable/{components/__tests__ → ui/shared}/SortIndicator.test.tsx +2 -2
  241. package/src/components/DataTable/{components → ui/shared}/SortIndicator.tsx +1 -1
  242. package/src/components/DataTable/{components/__tests__ → ui/table}/EditFields.test.tsx +3 -3
  243. package/src/components/DataTable/{components → ui/table}/EditFields.tsx +138 -69
  244. package/src/components/DataTable/{components/__tests__ → ui/table}/EditableRow.test.tsx +36 -27
  245. package/src/components/DataTable/{components → ui/table}/EditableRow.tsx +86 -104
  246. package/src/components/DataTable/{components/__tests__ → ui/table}/EmptyState.test.tsx +2 -62
  247. package/src/components/DataTable/{components → ui/table}/EmptyState.tsx +7 -15
  248. package/src/components/DataTable/{components/__tests__ → ui/table}/FilterRow.test.tsx +5 -4
  249. package/src/components/DataTable/{components → ui/table}/FilterRow.tsx +3 -3
  250. package/src/components/DataTable/{components/__tests__ → ui/table}/LoadingState.test.tsx +6 -10
  251. package/src/components/DataTable/{components → ui/table}/LoadingState.tsx +4 -4
  252. package/src/components/DataTable/{components/__tests__ → ui/table}/RowComponent.test.tsx +412 -17
  253. package/src/components/DataTable/{components → ui/table}/RowComponent.tsx +183 -177
  254. package/src/components/DataTable/{components/__tests__ → ui/table}/UnifiedTableBody.test.tsx +425 -16
  255. package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
  256. package/src/components/DataTable/{components/__tests__ → ui/table}/cellValueUtils.test.ts +2 -2
  257. package/src/components/DataTable/{components → ui/table}/cellValueUtils.ts +1 -1
  258. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/BulkOperationsDropdown.test.tsx +12 -5
  259. package/src/components/DataTable/{components → ui/toolbar}/BulkOperationsDropdown.tsx +3 -3
  260. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/ColumnVisibilityDropdown.test.tsx +7 -4
  261. package/src/components/DataTable/{components → ui/toolbar}/ColumnVisibilityDropdown.tsx +7 -7
  262. package/src/components/DataTable/{components/__tests__ → ui/toolbar}/DataTableToolbar.test.tsx +4 -4
  263. package/src/components/DataTable/{components → ui/toolbar}/DataTableToolbar.tsx +4 -4
  264. package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
  265. package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
  266. package/src/components/DataTable/utils/{__tests__/a11yUtils.test.ts → a11yUtils.test.ts} +2 -2
  267. package/src/components/DataTable/utils/{__tests__/aggregationUtils.test.ts → aggregationUtils.test.ts} +3 -3
  268. package/src/components/DataTable/utils/{__tests__/columnUtils.test.ts → columnUtils.test.ts} +2 -2
  269. package/src/components/DataTable/utils/csvParse.test.ts +74 -0
  270. package/src/components/DataTable/utils/csvParse.ts +65 -0
  271. package/src/components/DataTable/utils/{__tests__/errorHandling.test.ts → errorHandling.test.ts} +2 -2
  272. package/src/components/DataTable/utils/{__tests__/exportUtils.test.ts → exportUtils.test.ts} +3 -3
  273. package/src/components/DataTable/utils/{__tests__/flexibleImport.test.ts → flexibleImport.test.ts} +2 -2
  274. package/src/components/DataTable/utils/flexibleImport.ts +3 -186
  275. package/src/components/DataTable/utils/{__tests__/hierarchicalSorting.test.ts → hierarchicalSorting.test.ts} +3 -3
  276. package/src/components/DataTable/utils/{__tests__/hierarchicalUtils.test.ts → hierarchicalUtils.test.ts} +3 -3
  277. package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
  278. package/src/components/DataTable/utils/importDateParser.ts +114 -0
  279. package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
  280. package/src/components/DataTable/utils/importValueParser.ts +91 -0
  281. package/src/components/DataTable/utils/{__tests__/paginationUtils.test.ts → paginationUtils.test.ts} +2 -2
  282. package/src/components/DataTable/utils/paginationUtils.ts +6 -3
  283. package/src/components/DataTable/utils/{__tests__/performanceUtils.test.ts → performanceUtils.test.ts} +3 -3
  284. package/src/components/DataTable/utils/{__tests__/rowUtils.test.ts → rowUtils.test.ts} +3 -3
  285. package/src/components/DataTable/utils/{__tests__/selectFieldUtils.test.ts → selectFieldUtils.test.ts} +66 -3
  286. package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
  287. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
  288. package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
  289. package/src/components/Dialog/Dialog.test-utils.ts +49 -0
  290. package/src/components/Dialog/Dialog.test.tsx +896 -89
  291. package/src/components/Dialog/Dialog.tsx +174 -882
  292. package/src/components/Dialog/dialogLock.test.ts +238 -0
  293. package/src/components/Dialog/dialogLock.ts +98 -0
  294. package/src/components/Dialog/index.ts +2 -0
  295. package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
  296. package/src/components/Dialog/useDialogDimensions.ts +140 -0
  297. package/src/components/Dialog/useDialogLifecycle.test.ts +358 -0
  298. package/src/components/Dialog/useDialogLifecycle.ts +135 -0
  299. package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
  300. package/src/components/Dialog/useDialogPersistence.ts +357 -0
  301. package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
  302. package/src/components/FileDisplay/FileDisplay.tsx +24 -656
  303. package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
  304. package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
  305. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
  306. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
  307. package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
  308. package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
  309. package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
  310. package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
  311. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
  312. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
  313. package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
  314. package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
  315. package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
  316. package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
  317. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
  318. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
  319. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
  320. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
  321. package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
  322. package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
  323. package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
  324. package/src/components/FileDisplay/fallbackUtils.ts +44 -0
  325. package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
  326. package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
  327. package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
  328. package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
  329. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.test.ts +40 -42
  330. package/src/components/FileDisplay/useFileDisplay.ts +515 -0
  331. package/src/{hooks/__tests__ → components/FileDisplay}/useFileDisplay.unit.test.ts +406 -77
  332. package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
  333. package/src/{hooks/public → components/FileDisplay}/usePublicFileDisplay.test.ts +94 -88
  334. package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
  335. package/src/components/FileUpload/FileUpload.test.tsx +16 -10
  336. package/src/components/FileUpload/FileUpload.tsx +107 -525
  337. package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
  338. package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
  339. package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
  340. package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
  341. package/src/components/FileUpload/useFileUploadManager.ts +454 -0
  342. package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
  343. package/src/components/FileUpload/useResolvedAppId.ts +77 -0
  344. package/src/components/Footer/Footer.test.tsx +6 -292
  345. package/src/components/Footer/Footer.tsx +8 -125
  346. package/src/components/Form/Form.test.tsx +44 -27
  347. package/src/components/Form/Form.tsx +64 -287
  348. package/src/components/Form/useFormPersistence.ts +257 -0
  349. package/src/components/Header/Header.test.tsx +17 -18
  350. package/src/components/Header/Header.tsx +10 -1
  351. package/src/components/Input/Input.tsx +1 -1
  352. package/src/components/Label/Label.test.tsx +1 -1
  353. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
  354. package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
  355. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
  356. package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
  357. package/src/components/NavigationMenu/index.ts +6 -1
  358. package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
  359. package/src/components/NavigationMenu/{__tests__/useNavigationFiltering.test.ts → useNavigationFiltering.test.ts} +68 -53
  360. package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
  361. package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
  362. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +77 -62
  363. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
  364. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
  365. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
  366. package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
  367. package/src/components/PaceAppLayout/useFilteredNavItems.ts +304 -0
  368. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +142 -0
  369. package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
  370. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
  371. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +79 -0
  372. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
  373. package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
  374. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
  376. package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
  377. package/src/components/Progress/Progress.tsx +1 -2
  378. package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
  379. package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
  380. package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
  381. package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
  382. package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
  383. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
  384. package/src/components/Select/Select.test.tsx +1 -1
  385. package/src/components/Select/Select.tsx +28 -18
  386. package/src/components/Select/{__tests__/context.test.tsx → context.test.tsx} +3 -3
  387. package/src/components/Select/{utils/__tests__/text.test.tsx → text.test.tsx} +2 -2
  388. package/src/components/Select/{utils/text.ts → text.ts} +1 -1
  389. package/src/components/Select/{hooks/__tests__/useSelectEvents.test.ts → useSelectEvents.test.ts} +5 -5
  390. package/src/components/Select/{hooks/useSelectEvents.ts → useSelectEvents.ts} +2 -2
  391. package/src/components/Select/{hooks/__tests__/useSelectSearch.test.tsx → useSelectSearch.test.tsx} +7 -7
  392. package/src/components/Select/{hooks/useSelectSearch.ts → useSelectSearch.ts} +2 -2
  393. package/src/components/Select/{hooks/__tests__/useSelectState.test.ts → useSelectState.test.ts} +16 -2
  394. package/src/components/Select/{hooks/useSelectState.ts → useSelectState.ts} +3 -3
  395. package/src/components/Table/Table.test.tsx +348 -0
  396. package/src/components/Tabs/Tabs.test.tsx +270 -0
  397. package/src/components/Tabs/Tabs.tsx +1 -1
  398. package/src/components/Toast/Toast.test.tsx +420 -0
  399. package/src/components/{__tests__/index.test.ts → index.test.ts} +2 -2
  400. package/src/constants/{__tests__/performance.test.ts → performance.test.ts} +2 -2
  401. package/src/hooks/{__tests__/ServiceHooks.test.tsx → ServiceHooks.test.tsx} +8 -8
  402. package/src/hooks/{__tests__/hooks.integration.test.tsx → hooks.integration.test.tsx} +11 -11
  403. package/src/hooks/index.ts +7 -4
  404. package/src/hooks/{__tests__/index.unit.test.ts → index.unit.test.ts} +2 -2
  405. package/src/hooks/public/usePublicEvent.test.ts +1 -1
  406. package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
  407. package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
  408. package/src/hooks/services/useAuth.ts +9 -7
  409. package/src/hooks/useAddressAutocomplete.test.ts +22 -22
  410. package/src/hooks/useAddressAutocomplete.ts +90 -75
  411. package/src/hooks/{__tests__/useAppConfig.unit.test.ts → useAppConfig.unit.test.ts} +328 -22
  412. package/src/hooks/{__tests__/useComponentPerformance.unit.test.tsx → useComponentPerformance.unit.test.tsx} +27 -41
  413. package/src/hooks/useDataTablePerformance.ts +100 -120
  414. package/src/hooks/{__tests__/useDataTablePerformance.unit.test.ts → useDataTablePerformance.unit.test.ts} +5 -5
  415. package/src/hooks/{__tests__/useDataTableState.test.ts → useDataTableState.test.ts} +2 -2
  416. package/src/hooks/{__tests__/useDebounce.unit.test.ts → useDebounce.unit.test.ts} +2 -2
  417. package/src/hooks/useEventTheme.test.ts +4 -1
  418. package/src/hooks/useEventTheme.ts +49 -21
  419. package/src/hooks/useEvents.ts +41 -1
  420. package/src/hooks/{__tests__/useEvents.unit.test.ts → useEvents.unit.test.ts} +5 -5
  421. package/src/hooks/useFileReference.test.ts +44 -41
  422. package/src/hooks/useFileReference.ts +182 -173
  423. package/src/hooks/useFileUrl.ts +1 -1
  424. package/src/hooks/{__tests__/useFileUrl.unit.test.ts → useFileUrl.unit.test.ts} +26 -36
  425. package/src/hooks/{__tests__/useFileUrlCache.test.ts → useFileUrlCache.test.ts} +8 -8
  426. package/src/hooks/useFileUrlCache.ts +1 -1
  427. package/src/hooks/{__tests__/useFocusManagement.unit.test.ts → useFocusManagement.unit.test.ts} +2 -2
  428. package/src/hooks/{__tests__/useFocusTrap.unit.test.tsx → useFocusTrap.unit.test.tsx} +2 -2
  429. package/src/hooks/{__tests__/useFormDialog.test.ts → useFormDialog.test.ts} +2 -2
  430. package/src/hooks/useInactivityTracker.ts +138 -131
  431. package/src/hooks/{__tests__/useInactivityTracker.unit.test.ts → useInactivityTracker.unit.test.ts} +3 -3
  432. package/src/hooks/{__tests__/useIsMobile.unit.test.ts → useIsMobile.unit.test.ts} +2 -2
  433. package/src/hooks/useIsPrint.ts +62 -0
  434. package/src/hooks/useIsPrint.unit.test.ts +545 -0
  435. package/src/hooks/{__tests__/useKeyboardShortcuts.unit.test.ts → useKeyboardShortcuts.unit.test.ts} +2 -2
  436. package/src/hooks/{__tests__/useOrganisationPermissions.unit.test.tsx → useOrganisationPermissions.unit.test.tsx} +4 -4
  437. package/src/hooks/useOrganisationSecurity.test.ts +3 -3
  438. package/src/hooks/useOrganisationSecurity.ts +190 -201
  439. package/src/hooks/{__tests__/useOrganisationSecurity.unit.test.tsx → useOrganisationSecurity.unit.test.tsx} +61 -63
  440. package/src/hooks/{__tests__/useOrganisations.unit.test.ts → useOrganisations.unit.test.ts} +5 -5
  441. package/src/hooks/{__tests__/usePerformanceMonitor.unit.test.ts → usePerformanceMonitor.unit.test.ts} +13 -14
  442. package/src/hooks/{__tests__/usePermissionCache.test.ts → usePermissionCache.test.ts} +26 -27
  443. package/src/hooks/usePermissionCache.ts +276 -271
  444. package/src/hooks/{__tests__/usePreventTabReload.test.ts → usePreventTabReload.test.ts} +2 -2
  445. package/src/hooks/{__tests__/usePublicEvent.simple.test.ts → usePublicEvent.simple.test.ts} +4 -4
  446. package/src/hooks/{__tests__/usePublicEvent.test.ts → usePublicEvent.test.ts} +4 -4
  447. package/src/hooks/{__tests__/usePublicEvent.unit.test.ts → usePublicEvent.unit.test.ts} +4 -4
  448. package/src/hooks/{__tests__/usePublicFileDisplay.test.ts → usePublicFileDisplay.test.ts} +12 -12
  449. package/src/hooks/{__tests__/usePublicRouteParams.unit.test.ts → usePublicRouteParams.unit.test.ts} +3 -3
  450. package/src/hooks/{__tests__/useQueryCache.test.ts → useQueryCache.test.ts} +2 -2
  451. package/src/hooks/useQueryCache.ts +0 -2
  452. package/src/hooks/{__tests__/useRBAC.unit.test.ts → useRBAC.unit.test.ts} +55 -38
  453. package/src/hooks/{__tests__/useSessionDraft.test.ts → useSessionDraft.test.ts} +2 -2
  454. package/src/hooks/{__tests__/useSessionRestoration.unit.test.tsx → useSessionRestoration.unit.test.tsx} +10 -19
  455. package/src/hooks/useStorage.ts +21 -16
  456. package/src/hooks/{__tests__/useStorage.unit.test.ts → useStorage.unit.test.ts} +38 -75
  457. package/src/hooks/{__tests__/useToast.test.ts → useToast.test.ts} +2 -2
  458. package/src/hooks/{__tests__/useToast.unit.test.tsx → useToast.unit.test.tsx} +2 -2
  459. package/src/hooks/{__tests__/useZodForm.unit.test.tsx → useZodForm.unit.test.tsx} +2 -2
  460. package/src/icons/{__tests__/index.test.ts → index.test.ts} +2 -2
  461. package/src/icons/index.ts +2 -0
  462. package/src/{__tests__/index.test.ts → index.test.ts} +3 -7
  463. package/src/index.ts +15 -7
  464. package/src/providers/{__tests__/AuthProvider.test.tsx → AuthProvider.test.tsx} +3 -3
  465. package/src/providers/{__tests__/EventProvider.test.tsx → EventProvider.test.tsx} +3 -3
  466. package/src/providers/InactivityProvider.test-helper.tsx +40 -0
  467. package/src/providers/{__tests__/InactivityProvider.test.tsx → InactivityProvider.test.tsx} +14 -21
  468. package/src/providers/{__tests__/ProviderLifecycle.test.tsx → ProviderLifecycle.test.tsx} +4 -4
  469. package/src/providers/{__tests__/UnifiedAuthProvider.test.tsx → UnifiedAuthProvider.test.tsx} +1 -1
  470. package/src/providers/{__tests__/index.test.ts → index.test.ts} +2 -2
  471. package/src/providers/services/{__tests__/AuthServiceProvider.integration.test.tsx → AuthServiceProvider.integration.test.tsx} +4 -4
  472. package/src/providers/services/{__tests__/AuthServiceProvider.test.tsx → AuthServiceProvider.test.tsx} +7 -7
  473. package/src/providers/services/{__tests__/EventServiceProvider.test.tsx → EventServiceProvider.test.tsx} +7 -7
  474. package/src/providers/services/{__tests__/InactivityServiceProvider.test.tsx → InactivityServiceProvider.test.tsx} +5 -5
  475. package/src/providers/services/{__tests__/OrganisationServiceProvider.test.tsx → OrganisationServiceProvider.test.tsx} +6 -6
  476. package/src/providers/services/UnifiedAuthContext.ts +30 -27
  477. package/src/providers/services/{__tests__/UnifiedAuthProvider.advanced.test.tsx → UnifiedAuthProvider.advanced.test.tsx} +8 -9
  478. package/src/providers/services/{__tests__/UnifiedAuthProvider.appId.test.tsx → UnifiedAuthProvider.appId.test.tsx} +25 -25
  479. package/src/providers/services/{__tests__/UnifiedAuthProvider.integration.test.tsx → UnifiedAuthProvider.integration.test.tsx} +14 -11
  480. package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
  481. package/src/providers/services/{__tests__/contexts.test.tsx → contexts.test.tsx} +6 -6
  482. package/src/providers/services/{__tests__/useUnifiedAuth.test.tsx → useUnifiedAuth.test.tsx} +6 -6
  483. package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
  484. package/src/providers/useInactivity.test-helper.ts +27 -0
  485. package/src/rbac/{__tests__/adapters.comprehensive.test.tsx → adapters.comprehensive.test.tsx} +24 -24
  486. package/src/rbac/adapters.test.tsx +22 -22
  487. package/src/rbac/adapters.tsx +29 -29
  488. package/src/rbac/api.test.ts +973 -42
  489. package/src/rbac/api.ts +228 -253
  490. package/src/rbac/{__tests__/audit-batched.test.ts → audit-batched.test.ts} +6 -6
  491. package/src/rbac/audit.ts +4 -1
  492. package/src/rbac/{__tests__/auth-rbac-security.integration.test.tsx → auth-rbac-security.integration.test.tsx} +1 -1
  493. package/src/rbac/{__tests__/auth-rbac.e2e.test.tsx → auth-rbac.e2e.test.tsx} +27 -34
  494. package/src/rbac/cache-invalidation.test.ts +715 -0
  495. package/src/rbac/components/{__tests__/AccessDenied.test.tsx → AccessDenied.test.tsx} +3 -3
  496. package/src/rbac/components/{__tests__/NavigationGuard.test.tsx → NavigationGuard.test.tsx} +13 -11
  497. package/src/{__tests__/rbac/PagePermissionGuard.test.tsx → rbac/components/PagePermissionGuard.guard.test.tsx} +33 -19
  498. package/src/rbac/components/{__tests__/PagePermissionGuard.performance.test.tsx → PagePermissionGuard.performance.test.tsx} +30 -9
  499. package/src/rbac/components/{__tests__/PagePermissionGuard.race-condition.test.tsx → PagePermissionGuard.race-condition.test.tsx} +7 -7
  500. package/src/rbac/components/{__tests__/PagePermissionGuard.test.tsx → PagePermissionGuard.test.tsx} +10 -10
  501. package/src/rbac/components/PagePermissionGuard.tsx +177 -372
  502. package/src/rbac/components/{__tests__/PagePermissionGuard.verification.test.tsx → PagePermissionGuard.verification.test.tsx} +7 -7
  503. package/src/rbac/config.ts +58 -18
  504. package/src/rbac/{__tests__/engine.comprehensive.test.ts → engine.comprehensive.test.ts} +3 -3
  505. package/src/rbac/engine.test.ts +494 -0
  506. package/src/rbac/errors.ts +89 -55
  507. package/src/rbac/hooks/permissions/runPermissionCheck.ts +77 -0
  508. package/src/rbac/hooks/permissions/{__tests__/useAccessLevel.test.ts → useAccessLevel.test.ts} +40 -40
  509. package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
  510. package/src/rbac/hooks/permissions/{__tests__/useCan.test.ts → useCan.test.ts} +41 -41
  511. package/src/rbac/hooks/permissions/useCan.ts +170 -252
  512. package/src/rbac/hooks/permissions/{__tests__/useMultiplePermissions.test.ts → useMultiplePermissions.test.ts} +49 -49
  513. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +6 -2
  514. package/src/rbac/hooks/permissions/{__tests__/usePermissions.test.ts → usePermissions.test.ts} +10 -12
  515. package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
  516. package/src/rbac/hooks/useCan.test.ts +42 -42
  517. package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
  518. package/src/rbac/hooks/usePageGuardScope.ts +117 -0
  519. package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
  520. package/src/rbac/hooks/{__tests__/usePermissions.integration.test.ts → usePermissions.integration.test.ts} +9 -9
  521. package/src/{__tests__/hooks/usePermissions.test.ts → rbac/hooks/usePermissions.stability.test.ts} +18 -18
  522. package/src/rbac/hooks/usePermissions.test.ts +54 -54
  523. package/src/rbac/hooks/useRBAC.test.ts +313 -217
  524. package/src/rbac/hooks/useRBAC.ts +145 -81
  525. package/src/rbac/hooks/useResourcePermissions.test.ts +25 -25
  526. package/src/rbac/hooks/useResourcePermissions.ts +68 -134
  527. package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
  528. package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
  529. package/src/rbac/hooks/useRoleManagement.ts +153 -585
  530. package/src/rbac/hooks/{__tests__/useSecureSupabase.test.ts → useSecureSupabase.test.ts} +17 -17
  531. package/src/rbac/hooks/useSecureSupabase.ts +10 -2
  532. package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
  533. package/src/rbac/{__tests__/performance.test.ts → performance.test.ts} +1 -1
  534. package/src/rbac/{__tests__/rbac-core.test.tsx → rbac-core.test.tsx} +3 -3
  535. package/src/rbac/{__tests__/rbac-engine-core-logic.test.ts → rbac-engine-core-logic.test.ts} +2 -2
  536. package/src/rbac/{__tests__/rbac-engine-simplified.test.ts → rbac-engine-simplified.test.ts} +3 -3
  537. package/src/rbac/{__tests__/rbac-functions.test.ts → rbac-functions.test.ts} +57 -0
  538. package/src/rbac/{__tests__/rbac-role-isolation.test.ts → rbac-role-isolation.test.ts} +2 -2
  539. package/src/rbac/request-deduplication.test.ts +14 -9
  540. package/src/rbac/request-deduplication.ts +5 -4
  541. package/src/rbac/{__tests__/scenarios.user-role.test.tsx → scenarios.user-role.test.tsx} +23 -23
  542. package/src/rbac/secureClient.test.ts +514 -83
  543. package/src/rbac/secureClient.ts +8 -2
  544. package/src/rbac/security.test.ts +323 -0
  545. package/src/rbac/types/roleManagement.ts +66 -0
  546. package/src/rbac/utils/{__tests__/clientSecurity.test.ts → clientSecurity.test.ts} +4 -4
  547. package/src/rbac/utils/{__tests__/contextValidator.test.ts → contextValidator.test.ts} +4 -4
  548. package/src/rbac/utils/contextValidator.ts +5 -1
  549. package/src/rbac/utils/{__tests__/deep-equal.test.ts → deep-equal.test.ts} +1 -1
  550. package/src/rbac/utils/{__tests__/eventContext.test.ts → eventContext.test.ts} +36 -21
  551. package/src/rbac/utils/eventContext.ts +37 -33
  552. package/src/rbac/utils/fetchPermissionMap.ts +13 -0
  553. package/src/rbac/utils/permissionMapHelpers.ts +34 -0
  554. package/src/rbac/utils/roleManagementRpc.ts +303 -0
  555. package/src/services/{__tests__/AuthService.edge-cases.test.ts → AuthService.edge-cases.test.ts} +19 -19
  556. package/src/services/{__tests__/AuthService.restoreSession.test.ts → AuthService.restoreSession.test.ts} +2 -2
  557. package/src/services/{__tests__/AuthService.test.ts → AuthService.test.ts} +89 -55
  558. package/src/services/AuthService.ts +184 -205
  559. package/src/services/{__tests__/BaseService.edge-cases.test.ts → BaseService.edge-cases.test.ts} +3 -3
  560. package/src/services/{__tests__/BaseService.test.ts → BaseService.test.ts} +2 -2
  561. package/src/services/{__tests__/EventService.edge-cases.test.ts → EventService.edge-cases.test.ts} +27 -24
  562. package/src/services/{__tests__/EventService.eventColours.test.ts → EventService.eventColours.test.ts} +1 -1
  563. package/src/services/{__tests__/EventService.test.ts → EventService.test.ts} +256 -24
  564. package/src/services/EventService.ts +242 -312
  565. package/src/services/{__tests__/InactivityService.edge-cases.test.ts → InactivityService.edge-cases.test.ts} +3 -3
  566. package/src/services/{__tests__/InactivityService.lifecycle.test.ts → InactivityService.lifecycle.test.ts} +2 -2
  567. package/src/services/{__tests__/InactivityService.test.ts → InactivityService.test.ts} +179 -4
  568. package/src/services/InactivityService.ts +172 -213
  569. package/src/services/{__tests__/OrganisationService.edge-cases.test.ts → OrganisationService.edge-cases.test.ts} +5 -5
  570. package/src/services/{__tests__/OrganisationService.pagination.test.ts → OrganisationService.pagination.test.ts} +4 -4
  571. package/src/services/{__tests__/OrganisationService.test.ts → OrganisationService.test.ts} +410 -7
  572. package/src/services/OrganisationService.ts +184 -238
  573. package/src/services/base/BaseService.test.ts +1 -1
  574. package/src/services/interfaces/{__tests__/IAuthService.test.ts → IAuthService.test.ts} +21 -27
  575. package/src/services/interfaces/IAuthService.ts +10 -9
  576. package/src/services/interfaces/{__tests__/IEventService.test.ts → IEventService.test.ts} +4 -4
  577. package/src/services/interfaces/{__tests__/IInactivityService.test.ts → IInactivityService.test.ts} +3 -3
  578. package/src/services/interfaces/{__tests__/IOrganisationService.test.ts → IOrganisationService.test.ts} +3 -3
  579. package/src/styles/core.css +243 -12
  580. package/src/theming/{__tests__/parseEventColours.test.ts → parseEventColours.test.ts} +1 -1
  581. package/src/theming/{__tests__/runtime.test.ts → runtime.test.ts} +8 -17
  582. package/src/theming/runtime.ts +71 -2
  583. package/src/types/api-result.ts +53 -0
  584. package/src/types/{__tests__/core.test.ts → core.test.ts} +2 -2
  585. package/src/types/{__tests__/database-generated.test.ts → database-generated.test.ts} +3 -3
  586. package/src/types/database.generated.ts +45 -10
  587. package/src/types/event.ts +38 -18
  588. package/src/types/{__tests__/file-reference.test.ts → file-reference.test.ts} +13 -13
  589. package/src/types/file-reference.ts +37 -12
  590. package/src/types/{__tests__/guards.test.ts → guards.test.ts} +2 -2
  591. package/src/types/{__tests__/index.test.ts → index.test.ts} +2 -2
  592. package/src/types/index.ts +3 -0
  593. package/src/types/{__tests__/organisation.roles.test.ts → organisation.roles.test.ts} +1 -1
  594. package/src/types/{__tests__/organisation.test.ts → organisation.test.ts} +3 -31
  595. package/src/types/organisation.ts +15 -15
  596. package/src/types/supabase.ts +13 -4
  597. package/src/types/{__tests__/theme.test.ts → theme.test.ts} +1 -1
  598. package/src/types/{__tests__/type-validation.test.ts → type-validation.test.ts} +1 -1
  599. package/src/types/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  600. package/src/utils/app/appIdResolver.test.ts +98 -71
  601. package/src/utils/app/appIdResolver.ts +31 -20
  602. package/src/utils/{__tests__/appConfig.unit.test.ts → appConfig.unit.test.ts} +1 -1
  603. package/src/utils/{__tests__/audit.unit.test.ts → audit.unit.test.ts} +1 -1
  604. package/src/utils/{__tests__/auth-utils.unit.test.ts → auth-utils.unit.test.ts} +16 -17
  605. package/src/utils/{__tests__/bundleAnalysis.unit.test.ts → bundleAnalysis.unit.test.ts} +35 -35
  606. package/src/utils/{__tests__/cn.unit.test.ts → cn.unit.test.ts} +1 -1
  607. package/src/utils/context/organisationContext.test.ts +105 -91
  608. package/src/utils/context/organisationContext.ts +29 -40
  609. package/src/utils/core/{__tests__/cn.test.ts → cn.test.ts} +3 -3
  610. package/src/utils/core/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +2 -2
  611. package/src/utils/core/{__tests__/logger.test.ts → logger.test.ts} +2 -2
  612. package/src/utils/core/mergeRefs.ts +24 -0
  613. package/src/utils/{__tests__/debugLogger.test.ts → debugLogger.test.ts} +1 -1
  614. package/src/utils/{__tests__/deviceFingerprint.unit.test.ts → deviceFingerprint.unit.test.ts} +1 -1
  615. package/src/utils/dynamic/createLazyComponent.tsx +9 -1
  616. package/src/utils/dynamic/{__tests__/dynamicUtils.test.ts → dynamicUtils.test.ts} +2 -2
  617. package/src/utils/dynamic/{__tests__/lazyLoad.test.tsx → lazyLoad.test.tsx} +2 -2
  618. package/src/utils/{__tests__/dynamicUtils.unit.test.ts → dynamicUtils.unit.test.ts} +1 -1
  619. package/src/utils/file-reference/{__tests__/file-reference.test.ts → file-reference.test.ts} +214 -289
  620. package/src/utils/file-reference/index.ts +330 -347
  621. package/src/utils/{__tests__/formatDate.unit.test.ts → formatDate.unit.test.ts} +2 -2
  622. package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
  623. package/src/utils/formatting/formatNumber.test.ts +1 -1
  624. package/src/utils/{__tests__/formatting.unit.test.ts → formatting.unit.test.ts} +1 -1
  625. package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
  626. package/src/utils/google-places/googlePlacesUtils.ts +67 -99
  627. package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
  628. package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
  629. package/src/utils/{__tests__/index.unit.test.ts → index.unit.test.ts} +1 -1
  630. package/src/utils/{__tests__/lazyLoad.unit.test.tsx → lazyLoad.unit.test.tsx} +13 -14
  631. package/src/utils/location/location.test.ts +1 -1
  632. package/src/utils/{__tests__/logger.unit.test.ts → logger.unit.test.ts} +1 -1
  633. package/src/utils/{__tests__/organisationContext.unit.test.ts → organisationContext.unit.test.ts} +37 -48
  634. package/src/utils/performance/{__tests__/bundleAnalysis.test.ts → bundleAnalysis.test.ts} +2 -2
  635. package/src/utils/performance/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  636. package/src/utils/performance/{__tests__/performanceBudgets.test.ts → performanceBudgets.test.ts} +2 -2
  637. package/src/utils/{__tests__/performanceBenchmark.test.ts → performanceBenchmark.test.ts} +2 -2
  638. package/src/utils/{__tests__/performanceBudgets.unit.test.ts → performanceBudgets.unit.test.ts} +2 -2
  639. package/src/utils/{__tests__/permissionTypes.unit.test.ts → permissionTypes.unit.test.ts} +1 -1
  640. package/src/utils/{__tests__/permissionUtils.unit.test.ts → permissionUtils.unit.test.ts} +1 -1
  641. package/src/utils/permissions/{__tests__/permissionTypes.test.ts → permissionTypes.test.ts} +2 -2
  642. package/src/utils/persistence/{__tests__/keyDerivation.test.ts → keyDerivation.test.ts} +2 -2
  643. package/src/utils/persistence/{__tests__/sensitiveFieldDetection.test.ts → sensitiveFieldDetection.test.ts} +2 -2
  644. package/src/utils/{__tests__/request-deduplication.test.ts → request-deduplication.test.ts} +2 -2
  645. package/src/utils/{__tests__/sanitization.unit.test.ts → sanitization.unit.test.ts} +1 -1
  646. package/src/utils/{__tests__/schemaUtils.unit.test.ts → schemaUtils.unit.test.ts} +1 -1
  647. package/src/utils/{__tests__/secureDataAccess.unit.test.ts → secureDataAccess.unit.test.ts} +2 -2
  648. package/src/utils/{__tests__/secureErrors.unit.test.ts → secureErrors.unit.test.ts} +4 -4
  649. package/src/utils/{__tests__/secureStorage.unit.test.ts → secureStorage.unit.test.ts} +1 -1
  650. package/src/utils/security/auth-utils.ts +34 -23
  651. package/src/utils/security/secureDataAccess.ts +241 -281
  652. package/src/utils/security/secureErrors.test.ts +1 -1
  653. package/src/utils/security/secureStorage.test.ts +1 -1
  654. package/src/utils/security/security.test.ts +25 -17
  655. package/src/utils/security/security.ts +15 -18
  656. package/src/utils/security/securityMonitor.test.ts +1 -1
  657. package/src/utils/{__tests__/security.unit.test.ts → security.unit.test.ts} +21 -15
  658. package/src/utils/{__tests__/securityMonitor.unit.test.ts → securityMonitor.unit.test.ts} +1 -1
  659. package/src/utils/{__tests__/sessionTracking.unit.test.ts → sessionTracking.unit.test.ts} +12 -12
  660. package/src/utils/storage/{__tests__/config.unit.test.ts → config.unit.test.ts} +2 -2
  661. package/src/utils/storage/helpers.test.ts +88 -102
  662. package/src/utils/storage/helpers.ts +173 -251
  663. package/src/utils/storage/{__tests__/index.unit.test.ts → index.unit.test.ts} +3 -3
  664. package/src/utils/storage/types.ts +7 -0
  665. package/src/utils/supabase/createBaseClient.test.ts +1 -1
  666. package/src/utils/timezone/timezone.test.ts +1 -1
  667. package/src/utils/{__tests__/timezone.test.ts → timezone.test.ts} +2 -2
  668. package/src/utils/validation/{__tests__/common.test.ts → common.test.ts} +2 -2
  669. package/src/utils/validation/{__tests__/csrf.test.ts → csrf.test.ts} +56 -28
  670. package/src/utils/validation/csrf.ts +42 -41
  671. package/src/utils/validation/{__tests__/htmlSanitization.unit.test.ts → htmlSanitization.unit.test.ts} +2 -2
  672. package/src/utils/validation/{__tests__/passwordSchema.test.ts → passwordSchema.test.ts} +2 -2
  673. package/src/utils/validation/{__tests__/schema.test.ts → schema.test.ts} +2 -2
  674. package/src/utils/validation/{__tests__/sqlInjectionProtection.test.ts → sqlInjectionProtection.test.ts} +2 -2
  675. package/src/utils/validation/{__tests__/user.test.ts → user.test.ts} +2 -2
  676. package/src/utils/validation/{__tests__/validation.test.ts → validation.test.ts} +2 -2
  677. package/src/utils/validation/{__tests__/validationUtils.test.ts → validationUtils.test.ts} +2 -2
  678. package/src/utils/{__tests__/validation.unit.test.ts → validation.unit.test.ts} +1 -1
  679. package/src/utils/{__tests__/validationUtils.unit.test.ts → validationUtils.unit.test.ts} +5 -2
  680. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
  681. package/dist/chunk-KPYQWGFQ.js +0 -183
  682. package/dist/types-D05dCGma.d.ts +0 -521
  683. package/scripts/eslint-audit.cjs +0 -222
  684. package/scripts/generate-docs.js +0 -157
  685. package/scripts/install-cursor-rules.cjs +0 -255
  686. package/scripts/install-eslint-config.cjs +0 -349
  687. package/scripts/setup-build-cache.js +0 -73
  688. package/scripts/validate-pre-publish.js +0 -145
  689. package/src/__tests__/integration/UserProfile.test.tsx +0 -124
  690. package/src/__tests__/public-recipe-view.test.ts +0 -228
  691. package/src/__tests__/rls-policies.test.ts +0 -472
  692. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
  693. package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
  694. package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
  695. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
  696. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
  697. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
  698. package/src/components/DataTable/core/ActionManager.ts +0 -235
  699. package/src/components/DataTable/core/ColumnManager.ts +0 -204
  700. package/src/components/DataTable/core/DataManager.ts +0 -190
  701. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
  702. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  703. package/src/components/DataTable/core/StateManager.ts +0 -312
  704. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
  705. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
  706. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
  707. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
  708. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
  709. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
  710. package/src/components/DataTable/core/interfaces.ts +0 -338
  711. package/src/components/DataTable/types.ts +0 -764
  712. package/src/hooks/public/usePublicFileDisplay.ts +0 -534
  713. package/src/hooks/useFileDisplay.ts +0 -748
  714. package/src/providers/OrganisationProvider.test.tsx +0 -40
  715. package/src/providers/OrganisationProvider.tsx +0 -92
  716. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
  717. package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
  718. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
  719. package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
  720. /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
  721. /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
  722. /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
  723. /package/src/providers/{__tests__/README.md → README.md} +0 -0
  724. /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
  725. /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
  726. /package/src/types/{__tests__/README.md → README.md} +0 -0
@@ -1,505 +1,876 @@
1
1
  /**
2
2
  * @file DataTable Component Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Components/DataTable/__tests__
4
+ * @module Components/DataTable
5
5
  * @since 0.4.0
6
6
  *
7
- * Comprehensive test suite for DataTable wrapper component following testing guidelines.
8
- * Tests cover feature normalization, validation logic, prop forwarding, and edge cases.
7
+ * Comprehensive test suite for DataTable component following testing guidelines.
8
+ * Tests cover all major functionality, edge cases, and user interactions.
9
9
  */
10
10
 
11
11
  import React from 'react';
12
- import { render, screen, cleanup, waitFor } from '@testing-library/react';
13
- import { vi, describe, it, expect, beforeEach, afterEach, beforeAll, afterAll } from 'vitest';
12
+ import { render, screen } from '@testing-library/react';
13
+ import userEvent from '@testing-library/user-event';
14
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
14
15
  import { DataTable } from './DataTable';
15
- import { createTestData, createTestColumns, testDataScenarios } from './__tests__/test-utils/dataFactories';
16
- import { createDefaultFeatures, createFullFeatures, createFeaturesWithEnabled } from './__tests__/test-utils';
17
- import type { DataTableFeatureConfig } from './types';
18
- import { DataTableCore } from './components/DataTableCore';
19
-
20
- // Mock DataTableCore to focus on wrapper logic
21
- // Note: Must define mock inside factory due to hoisting
22
- vi.mock('./components/DataTableCore', () => {
23
- const mockDataTableCore = vi.fn(({ features, ...props }: import('./components/DataTableCore').DataTableCoreProps<import('./types').DataRecord>) => (
24
- <div
25
- data-testid="data-table-core"
26
- data-features={JSON.stringify(features)}
27
- data-title={props.title}
28
- data-description={props.description}
29
- data-variant={props.variant}
30
- data-class-name={props.className}
31
- data-page-id={props.rbac?.pageId}
32
- data-page-name={props.rbac?.pageName}
33
- >
34
- Mock DataTableCore
16
+ import type { DataTableColumn } from './types';
17
+ import { createTestData, createTestColumns, testDataScenarios } from './test-utils/dataFactories';
18
+ import { createDefaultFeatures, createReadOnlyFeatures, createFullFeatures } from './test-utils';
19
+
20
+ // Mock the RBAC hooks
21
+ vi.mock('../../rbac/hooks', () => ({
22
+ useCan: vi.fn(() => ({
23
+ can: true,
24
+ isLoading: false,
25
+ error: null,
26
+ })),
27
+ }));
28
+
29
+ // Mock the auth provider
30
+ const mockUseUnifiedAuthFn = vi.fn(() => ({
31
+ user: { id: 'test-user', email: 'test@example.com' },
32
+ isAuthenticated: true,
33
+ isLoading: false,
34
+ error: null,
35
+ selectedOrganisation: { id: 'test-org' },
36
+ selectedEvent: { event_id: 'test-event' },
37
+ supabase: {},
38
+ }));
39
+
40
+ vi.mock('../../providers/services/UnifiedAuthProvider', () => ({
41
+ useUnifiedAuth: () => mockUseUnifiedAuthFn(),
42
+ UnifiedAuthProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
43
+ }));
44
+
45
+ // Mock the DataTableCore component to focus on DataTable logic
46
+ vi.mock('./ui/layout/DataTableCore', () => ({
47
+ DataTableCore: ({ children, ...props }: any) => (
48
+ <div role="table" {...props}>
49
+ {children}
35
50
  </div>
36
- ));
37
-
38
- return {
39
- DataTableCore: mockDataTableCore,
40
- };
41
- });
51
+ ),
52
+ }));
42
53
 
43
- // Mock the logger utility
44
- // Create a module-level mock logger that can be accessed in tests
45
- const mockLogger = {
46
- info: vi.fn(),
47
- warn: vi.fn(),
48
- error: vi.fn(),
49
- };
50
-
51
- // Note: Must define mock inside factory due to hoisting
52
- vi.mock('../../utils/core/logger', () => {
53
- return {
54
- createLogger: () => mockLogger,
55
- };
56
- });
57
-
58
- // Store original console.log to spy on it
59
- const originalConsoleLog = console.log;
60
- const consoleLogSpy = vi.fn();
61
- beforeAll(() => {
62
- console.log = consoleLogSpy;
63
- });
64
-
65
- afterAll(() => {
66
- console.log = originalConsoleLog;
67
- });
68
-
69
- describe('[component] DataTable', () => {
70
- const testData = createTestData(3);
71
- const testColumns = createTestColumns();
72
- const defaultRBAC = { pageId: 'test-page-id' };
73
- const baseProps = {
74
- data: testData,
75
- columns: testColumns,
76
- rbac: defaultRBAC,
77
- };
78
-
79
- // Helper to get the mocked DataTableCore function
80
- const getMockedDataTableCore = () => vi.mocked(DataTableCore);
54
+ describe('DataTable Component', () => {
55
+ const mockData = createTestData(5);
56
+ const mockColumns = createTestColumns();
57
+ const mockRBAC = { pageId: 'test-page' };
81
58
 
82
59
  beforeEach(() => {
83
60
  vi.clearAllMocks();
84
- consoleLogSpy.mockClear();
85
61
  });
86
62
 
87
- afterEach(() => {
88
- cleanup();
89
- });
63
+ describe('Rendering', () => {
64
+ it('renders with basic props', () => {
65
+ render(
66
+ <DataTable
67
+ data={mockData}
68
+ columns={mockColumns}
69
+ rbac={mockRBAC}
70
+ features={createDefaultFeatures()}
71
+ />
72
+ );
90
73
 
91
- describe('Rendering', () => {
92
- it('renders DataTableCore with required props', () => {
93
- render(<DataTable {...baseProps} />);
94
-
95
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
96
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(1);
74
+ expect(screen.getByRole('table')).toBeInTheDocument();
97
75
  });
98
76
 
99
77
  it('renders with title and description', () => {
100
78
  render(
101
- <DataTable
102
- {...baseProps}
103
- title="Test Table"
104
- description="Test description"
79
+ <DataTable
80
+ data={mockData}
81
+ columns={mockColumns}
82
+ rbac={mockRBAC}
83
+ features={createDefaultFeatures()}
84
+ title="Test Table"
85
+ description="Test description"
105
86
  />
106
87
  );
107
-
108
- const core = screen.getByTestId('data-table-core');
109
- expect(core).toHaveAttribute('data-title', 'Test Table');
110
- expect(core).toHaveAttribute('data-description', 'Test description');
111
- });
112
88
 
113
- it('renders with custom variant', () => {
114
- render(<DataTable {...baseProps} variant="compact" />);
115
-
116
- const core = screen.getByTestId('data-table-core');
117
- expect(core).toHaveAttribute('data-variant', 'compact');
89
+ expect(screen.getByRole('table')).toBeInTheDocument();
118
90
  });
119
91
 
120
92
  it('renders with custom className', () => {
121
- render(<DataTable {...baseProps} className="custom-table-class" />);
122
-
123
- const core = screen.getByTestId('data-table-core');
124
- expect(core).toHaveAttribute('data-class-name', 'custom-table-class');
93
+ render(
94
+ <DataTable
95
+ data={mockData}
96
+ columns={mockColumns}
97
+ rbac={mockRBAC}
98
+ features={createDefaultFeatures()}
99
+ className="custom-table"
100
+ />
101
+ );
102
+
103
+ const table = screen.getByRole('table');
104
+ expect(table).toHaveClass('custom-table');
105
+ });
106
+
107
+ it('renders with variant prop', () => {
108
+ render(
109
+ <DataTable
110
+ data={mockData}
111
+ columns={mockColumns}
112
+ rbac={mockRBAC}
113
+ features={createDefaultFeatures()}
114
+ variant="compact"
115
+ />
116
+ );
117
+
118
+ expect(screen.getByRole('table')).toBeInTheDocument();
119
+ });
120
+
121
+ it('renders with empty data array', () => {
122
+ render(
123
+ <DataTable
124
+ data={[]}
125
+ columns={mockColumns}
126
+ rbac={mockRBAC}
127
+ features={createDefaultFeatures()}
128
+ />
129
+ );
130
+
131
+ expect(screen.getByRole('table')).toBeInTheDocument();
132
+ });
133
+
134
+ it('renders with loading state', () => {
135
+ render(
136
+ <DataTable
137
+ data={mockData}
138
+ columns={mockColumns}
139
+ rbac={mockRBAC}
140
+ features={createDefaultFeatures()}
141
+ isLoading={true}
142
+ />
143
+ );
144
+
145
+ expect(screen.getByRole('table')).toBeInTheDocument();
125
146
  });
126
147
  });
127
148
 
128
149
  describe('Feature Configuration', () => {
129
- it('normalizes undefined features to default disabled features', () => {
130
- render(<DataTable {...baseProps} />);
131
-
132
- const core = screen.getByTestId('data-table-core');
133
- const features = JSON.parse(core.getAttribute('data-features') || '{}');
134
-
135
- expect(features).toMatchObject({
136
- search: false,
137
- pagination: false,
138
- sorting: false,
139
- filtering: false,
140
- import: false,
141
- export: false,
142
- selection: false,
143
- creation: false,
144
- editing: false,
145
- deletion: false,
146
- deleteSelected: false,
147
- grouping: false,
148
- columnVisibility: false,
149
- columnReordering: false,
150
- hierarchical: false,
151
- });
152
- });
153
-
154
- it('normalizes partial features by merging with defaults', () => {
155
- const partialFeatures: DataTableFeatureConfig = {
156
- search: true,
157
- pagination: true,
158
- };
159
-
160
- render(<DataTable {...baseProps} features={partialFeatures} />);
161
-
162
- const core = screen.getByTestId('data-table-core');
163
- const features = JSON.parse(core.getAttribute('data-features') || '{}');
164
-
165
- expect(features.search).toBe(true);
166
- expect(features.pagination).toBe(true);
167
- expect(features.sorting).toBe(false); // Default value
168
- expect(features.editing).toBe(false); // Default value
169
- });
170
-
171
- it('passes fully normalized features to DataTableCore', () => {
172
- const features = createFullFeatures();
173
- render(<DataTable {...baseProps} features={features} />);
174
-
175
- const core = screen.getByTestId('data-table-core');
176
- const normalizedFeatures = JSON.parse(core.getAttribute('data-features') || '{}');
177
-
178
- expect(normalizedFeatures).toMatchObject({
179
- search: true,
180
- pagination: true,
181
- sorting: true,
182
- filtering: true,
183
- import: true,
184
- export: true,
185
- selection: true,
186
- creation: true,
187
- editing: true,
188
- deletion: true,
189
- deleteSelected: true,
190
- });
191
- });
192
-
193
- it('memoizes normalized features when features prop does not change', () => {
194
- const features = createDefaultFeatures();
195
- const { rerender } = render(<DataTable {...baseProps} features={features} />);
196
-
197
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(1);
198
-
199
- rerender(<DataTable {...baseProps} features={features} />);
200
-
201
- // Should not re-normalize if features object reference is the same
202
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(2);
150
+ it('renders with read-only features', () => {
151
+ render(
152
+ <DataTable
153
+ data={mockData}
154
+ columns={mockColumns}
155
+ rbac={mockRBAC}
156
+ features={createReadOnlyFeatures()}
157
+ />
158
+ );
159
+
160
+ expect(screen.getByRole('table')).toBeInTheDocument();
161
+ });
162
+
163
+ it('renders with full features', () => {
164
+ render(
165
+ <DataTable
166
+ data={mockData}
167
+ columns={mockColumns}
168
+ rbac={mockRBAC}
169
+ features={createFullFeatures()}
170
+ />
171
+ );
172
+
173
+ expect(screen.getByRole('table')).toBeInTheDocument();
174
+ });
175
+
176
+ it('renders with custom features configuration', () => {
177
+ const customFeatures = createDefaultFeatures();
178
+ customFeatures.search = true;
179
+ customFeatures.pagination = true;
180
+
181
+ render(
182
+ <DataTable
183
+ data={mockData}
184
+ columns={mockColumns}
185
+ rbac={mockRBAC}
186
+ features={customFeatures}
187
+ />
188
+ );
189
+
190
+ expect(screen.getByRole('table')).toBeInTheDocument();
191
+ });
192
+
193
+ it('handles invalid feature dependencies without crashing', () => {
194
+ const featuresWithInvalidDependency = createDefaultFeatures();
195
+ featuresWithInvalidDependency.deleteSelected = true;
196
+ featuresWithInvalidDependency.deletion = false;
197
+
198
+ render(
199
+ <DataTable
200
+ data={mockData}
201
+ columns={mockColumns}
202
+ rbac={mockRBAC}
203
+ features={featuresWithInvalidDependency}
204
+ />
205
+ );
206
+
207
+ expect(screen.getByRole('table')).toBeInTheDocument();
203
208
  });
204
209
  });
205
210
 
206
- describe('RBAC Configuration', () => {
207
- it('passes rbac with pageId to DataTableCore', () => {
208
- render(<DataTable {...baseProps} rbac={{ pageId: 'custom-page-id' }} />);
209
-
210
- const core = screen.getByTestId('data-table-core');
211
- expect(core).toHaveAttribute('data-page-id', 'custom-page-id');
211
+ describe('Error Handling', () => {
212
+ it('does not throw when features configuration is missing', () => {
213
+ render(
214
+ <DataTable
215
+ data={mockData}
216
+ columns={mockColumns}
217
+ rbac={mockRBAC}
218
+ // @ts-expect-error - intentionally missing features
219
+ features={undefined}
220
+ />
221
+ );
222
+
223
+ expect(screen.getByRole('table')).toBeInTheDocument();
212
224
  });
213
225
 
214
- it('passes rbac with pageName to DataTableCore', () => {
215
- render(<DataTable {...baseProps} rbac={{ pageName: 'custom-page-name' }} />);
216
-
217
- const core = screen.getByTestId('data-table-core');
218
- expect(core).toHaveAttribute('data-page-name', 'custom-page-name');
226
+ it('renders with error component when provided', () => {
227
+ const ErrorComponent = ({ error, retry }: { error: Error; retry: () => void }) => (
228
+ <div data-testid="error-component">
229
+ Error: {error.message}
230
+ <button onClick={retry}>Retry</button>
231
+ </div>
232
+ );
233
+
234
+ render(
235
+ <DataTable
236
+ data={mockData}
237
+ columns={mockColumns}
238
+ rbac={mockRBAC}
239
+ features={createDefaultFeatures()}
240
+ errorComponent={ErrorComponent}
241
+ />
242
+ );
243
+
244
+ expect(screen.getByRole('table')).toBeInTheDocument();
219
245
  });
220
246
  });
221
247
 
222
- describe('Validation and Warnings', () => {
223
- it('logs debug information in development mode', () => {
224
- // Note: Debug logging has been removed from DataTable component
225
- // The component now uses a logger utility instead of console.log
226
- render(<DataTable {...baseProps} />);
227
-
228
- // Verify component renders correctly
229
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
230
- });
231
-
232
- it('logs info message when features are not provided in development', async () => {
233
- // Note: vitest.config.ts sets import.meta.env.MODE to 'development' by default
234
- // This test verifies the development warning when features are not provided
235
- // Skip if not in development mode to avoid false failures
236
- if (import.meta.env.MODE !== 'development') {
237
- return;
238
- }
239
-
240
- // Clear mock before test to ensure clean state
241
- mockLogger.info.mockClear();
242
-
243
- // Render without features prop - should trigger the warning in development mode
244
- render(<DataTable {...baseProps} />);
245
-
246
- // Wait for useEffect to run - it runs after render
247
- // The effect checks: if (!features && import.meta.env?.MODE === 'development')
248
- await waitFor(() => {
249
- expect(mockLogger.info).toHaveBeenCalled();
250
- }, {
251
- timeout: 1000,
252
- interval: 50
253
- });
254
-
255
- // Verify it was called with the correct message
256
- expect(mockLogger.info).toHaveBeenCalledWith(
257
- 'DataTable: no features provided; all capabilities default to disabled. Pass a features object to enable functionality.'
258
- );
259
- });
260
-
261
- it('does not log info message when features are provided', () => {
262
- render(<DataTable {...baseProps} features={createDefaultFeatures()} />);
263
-
264
- expect(mockLogger.info).not.toHaveBeenCalled();
265
- });
266
-
267
- it('warns when deleteSelected is enabled without deletion', () => {
268
- const invalidFeatures = createFeaturesWithEnabled({
269
- deleteSelected: true,
270
- deletion: false,
271
- });
272
-
273
- render(<DataTable {...baseProps} features={invalidFeatures} />);
274
-
275
- expect(mockLogger.warn).toHaveBeenCalledWith(
276
- 'deleteSelected requires deletion to be enabled'
277
- );
278
- });
279
-
280
- it('does not warn when deleteSelected is enabled with deletion', () => {
281
- const validFeatures = createFeaturesWithEnabled({
282
- deleteSelected: true,
283
- deletion: true,
284
- });
285
-
286
- render(<DataTable {...baseProps} features={validFeatures} />);
287
-
288
- expect(mockLogger.warn).not.toHaveBeenCalled();
248
+ describe('Performance Configuration', () => {
249
+ it('renders with performance configuration', () => {
250
+ const performanceConfig = {
251
+ virtualScrolling: true,
252
+ enableChunking: true,
253
+ chunkSize: 1000,
254
+ enableWebWorkers: true,
255
+ };
256
+
257
+ render(
258
+ <DataTable
259
+ data={mockData}
260
+ columns={mockColumns}
261
+ rbac={mockRBAC}
262
+ features={createDefaultFeatures()}
263
+ performance={performanceConfig}
264
+ />
265
+ );
266
+
267
+ expect(screen.getByRole('table')).toBeInTheDocument();
268
+ });
269
+
270
+ it('renders with server-side configuration', () => {
271
+ const serverSideConfig = {
272
+ fetchData: vi.fn(),
273
+ totalCount: 1000,
274
+ pageSize: 25,
275
+ };
276
+
277
+ render(
278
+ <DataTable
279
+ data={mockData}
280
+ columns={mockColumns}
281
+ rbac={mockRBAC}
282
+ features={createDefaultFeatures()}
283
+ serverSide={serverSideConfig}
284
+ />
285
+ );
286
+
287
+ expect(screen.getByRole('table')).toBeInTheDocument();
288
+ });
289
+
290
+ it('renders with pagination mode override', () => {
291
+ render(
292
+ <DataTable
293
+ data={mockData}
294
+ columns={mockColumns}
295
+ rbac={mockRBAC}
296
+ features={createDefaultFeatures()}
297
+ paginationMode="server"
298
+ />
299
+ );
300
+
301
+ expect(screen.getByRole('table')).toBeInTheDocument();
302
+ });
303
+
304
+ it('renders with virtual height configuration', () => {
305
+ render(
306
+ <DataTable
307
+ data={mockData}
308
+ columns={mockColumns}
309
+ rbac={mockRBAC}
310
+ features={createDefaultFeatures()}
311
+ virtualHeight={600}
312
+ />
313
+ );
314
+
315
+ expect(screen.getByRole('table')).toBeInTheDocument();
316
+ });
317
+
318
+ it('renders with initial page size', () => {
319
+ render(
320
+ <DataTable
321
+ data={mockData}
322
+ columns={mockColumns}
323
+ rbac={mockRBAC}
324
+ features={createDefaultFeatures()}
325
+ initialPageSize={50}
326
+ />
327
+ );
328
+
329
+ expect(screen.getByRole('table')).toBeInTheDocument();
289
330
  });
290
331
  });
291
332
 
292
333
  describe('Event Handlers', () => {
293
- it('passes onEditRow handler to DataTableCore', () => {
334
+ it('renders with edit row handler', () => {
294
335
  const onEditRow = vi.fn();
295
- render(<DataTable {...baseProps} onEditRow={onEditRow} />);
296
-
297
- const mockCall = getMockedDataTableCore().mock.calls[0];
298
- expect(mockCall[0]).toHaveProperty('onEditRow', onEditRow);
336
+
337
+ render(
338
+ <DataTable
339
+ data={mockData}
340
+ columns={mockColumns}
341
+ rbac={mockRBAC}
342
+ features={createDefaultFeatures()}
343
+ onEditRow={onEditRow}
344
+ />
345
+ );
346
+
347
+ expect(screen.getByRole('table')).toBeInTheDocument();
299
348
  });
300
349
 
301
- it('passes onDeleteRow handler to DataTableCore', () => {
350
+ it('renders with delete row handler', () => {
302
351
  const onDeleteRow = vi.fn();
303
- render(<DataTable {...baseProps} onDeleteRow={onDeleteRow} />);
304
-
305
- const mockCall = getMockedDataTableCore().mock.calls[0];
306
- expect(mockCall[0]).toHaveProperty('onDeleteRow', onDeleteRow);
352
+
353
+ render(
354
+ <DataTable
355
+ data={mockData}
356
+ columns={mockColumns}
357
+ rbac={mockRBAC}
358
+ features={createDefaultFeatures()}
359
+ onDeleteRow={onDeleteRow}
360
+ />
361
+ );
362
+
363
+ expect(screen.getByRole('table')).toBeInTheDocument();
307
364
  });
308
365
 
309
- it('passes onCreateRow handler to DataTableCore', () => {
366
+ it('renders with create row handler', () => {
310
367
  const onCreateRow = vi.fn();
311
- render(<DataTable {...baseProps} onCreateRow={onCreateRow} />);
312
-
313
- const mockCall = getMockedDataTableCore().mock.calls[0];
314
- expect(mockCall[0]).toHaveProperty('onCreateRow', onCreateRow);
368
+
369
+ render(
370
+ <DataTable
371
+ data={mockData}
372
+ columns={mockColumns}
373
+ rbac={mockRBAC}
374
+ features={createDefaultFeatures()}
375
+ onCreateRow={onCreateRow}
376
+ />
377
+ );
378
+
379
+ expect(screen.getByRole('table')).toBeInTheDocument();
315
380
  });
316
381
 
317
- it('passes onImport handler to DataTableCore', () => {
382
+ it('renders with import handler', () => {
318
383
  const onImport = vi.fn();
319
- render(<DataTable {...baseProps} onImport={onImport} />);
320
-
321
- const mockCall = getMockedDataTableCore().mock.calls[0];
322
- expect(mockCall[0]).toHaveProperty('onImport', onImport);
384
+
385
+ render(
386
+ <DataTable
387
+ data={mockData}
388
+ columns={mockColumns}
389
+ rbac={mockRBAC}
390
+ features={createDefaultFeatures()}
391
+ onImport={onImport}
392
+ />
393
+ );
394
+
395
+ expect(screen.getByRole('table')).toBeInTheDocument();
323
396
  });
324
397
 
325
- it('passes onRowSelectionChange handler to DataTableCore', () => {
398
+ it('renders with row selection change handler', () => {
326
399
  const onRowSelectionChange = vi.fn();
327
- render(<DataTable {...baseProps} onRowSelectionChange={onRowSelectionChange} />);
328
-
329
- const mockCall = getMockedDataTableCore().mock.calls[0];
330
- expect(mockCall[0]).toHaveProperty('onRowSelectionChange', onRowSelectionChange);
400
+
401
+ render(
402
+ <DataTable
403
+ data={mockData}
404
+ columns={mockColumns}
405
+ rbac={mockRBAC}
406
+ features={createDefaultFeatures()}
407
+ onRowSelectionChange={onRowSelectionChange}
408
+ />
409
+ );
410
+
411
+ expect(screen.getByRole('table')).toBeInTheDocument();
331
412
  });
332
413
 
333
- it('passes onDeleteSelected handler to DataTableCore', () => {
414
+ it('renders with controlled selection state', () => {
415
+ const selection = { '1': true, '2': false };
416
+
417
+ render(
418
+ <DataTable
419
+ data={mockData}
420
+ columns={mockColumns}
421
+ rbac={mockRBAC}
422
+ features={createDefaultFeatures()}
423
+ selection={selection}
424
+ />
425
+ );
426
+
427
+ expect(screen.getByRole('table')).toBeInTheDocument();
428
+ });
429
+
430
+ it('renders with delete selected handler', () => {
334
431
  const onDeleteSelected = vi.fn();
335
- render(<DataTable {...baseProps} onDeleteSelected={onDeleteSelected} />);
336
-
337
- const mockCall = getMockedDataTableCore().mock.calls[0];
338
- expect(mockCall[0]).toHaveProperty('onDeleteSelected', onDeleteSelected);
432
+
433
+ render(
434
+ <DataTable
435
+ data={mockData}
436
+ columns={mockColumns}
437
+ rbac={mockRBAC}
438
+ features={createDefaultFeatures()}
439
+ onDeleteSelected={onDeleteSelected}
440
+ />
441
+ );
442
+
443
+ expect(screen.getByRole('table')).toBeInTheDocument();
339
444
  });
340
445
  });
341
446
 
342
- describe('Data Handling', () => {
343
- it('handles empty data array', () => {
344
- // Note: Debug logging has been removed from DataTable component
345
- render(<DataTable {...baseProps} data={[]} />);
346
-
347
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
447
+ describe('Advanced Configuration', () => {
448
+ it('renders with hierarchical configuration', () => {
449
+ const hierarchicalConfig = {
450
+ enabled: true,
451
+ defaultExpanded: true,
452
+ indentSize: 20,
453
+ };
454
+
455
+ render(
456
+ <DataTable
457
+ data={mockData}
458
+ columns={mockColumns}
459
+ rbac={mockRBAC}
460
+ features={createDefaultFeatures()}
461
+ hierarchical={hierarchicalConfig}
462
+ />
463
+ );
464
+
465
+ expect(screen.getByRole('table')).toBeInTheDocument();
466
+ });
467
+
468
+ it('renders with column order configuration', () => {
469
+ const columnOrder = ['name', 'email', 'age'];
470
+
471
+ render(
472
+ <DataTable
473
+ data={mockData}
474
+ columns={mockColumns}
475
+ rbac={mockRBAC}
476
+ features={createDefaultFeatures()}
477
+ columnOrder={columnOrder}
478
+ />
479
+ );
480
+
481
+ expect(screen.getByRole('table')).toBeInTheDocument();
482
+ });
483
+
484
+ it('renders with custom getRowId function', () => {
485
+ const getRowId = (row: any) => `row-${row.id}`;
486
+
487
+ render(
488
+ <DataTable
489
+ data={mockData}
490
+ columns={mockColumns}
491
+ rbac={mockRBAC}
492
+ features={createDefaultFeatures()}
493
+ getRowId={getRowId}
494
+ />
495
+ );
496
+
497
+ expect(screen.getByRole('table')).toBeInTheDocument();
498
+ });
499
+
500
+ it('renders with custom empty state', () => {
501
+ const emptyState = {
502
+ title: 'No data found',
503
+ description: 'Please add some data to get started',
504
+ icon: '📊',
505
+ };
506
+
507
+ render(
508
+ <DataTable
509
+ data={[]}
510
+ columns={mockColumns}
511
+ rbac={mockRBAC}
512
+ features={createDefaultFeatures()}
513
+ emptyState={emptyState}
514
+ />
515
+ );
516
+
517
+ expect(screen.getByRole('table')).toBeInTheDocument();
348
518
  });
349
519
 
350
- it('handles single data item', () => {
351
- // Note: Debug logging has been removed from DataTable component
352
- const singleData = testDataScenarios.single;
353
- render(<DataTable {...baseProps} data={singleData} />);
354
-
355
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
520
+ it('renders with custom loading component', () => {
521
+ const LoadingComponent = () => <div data-testid="custom-loading">Loading...</div>;
522
+
523
+ render(
524
+ <DataTable
525
+ data={mockData}
526
+ columns={mockColumns}
527
+ rbac={mockRBAC}
528
+ features={createDefaultFeatures()}
529
+ loadingComponent={LoadingComponent}
530
+ />
531
+ );
532
+
533
+ expect(screen.getByRole('table')).toBeInTheDocument();
356
534
  });
357
535
 
536
+ it('renders with custom actions', () => {
537
+ const actions = [
538
+ {
539
+ id: 'custom-action',
540
+ label: 'Custom Action',
541
+ onClick: vi.fn(),
542
+ },
543
+ ];
544
+
545
+ render(
546
+ <DataTable
547
+ data={mockData}
548
+ columns={mockColumns}
549
+ rbac={mockRBAC}
550
+ features={createDefaultFeatures()}
551
+ actions={actions}
552
+ />
553
+ );
554
+
555
+ expect(screen.getByRole('table')).toBeInTheDocument();
556
+ });
557
+ });
558
+
559
+ describe('Data Scenarios', () => {
358
560
  it('handles large dataset', () => {
359
- // Note: Debug logging has been removed from DataTable component
360
561
  const largeData = testDataScenarios.large;
361
- render(<DataTable {...baseProps} data={largeData} />);
362
-
363
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
562
+
563
+ render(
564
+ <DataTable
565
+ data={largeData}
566
+ columns={mockColumns}
567
+ rbac={mockRBAC}
568
+ features={createDefaultFeatures()}
569
+ />
570
+ );
571
+
572
+ expect(screen.getByRole('table')).toBeInTheDocument();
364
573
  });
365
574
 
366
- it('handles data with null values', () => {
367
- const dataWithNulls = testDataScenarios.withNulls;
368
- render(<DataTable {...baseProps} data={dataWithNulls} />);
369
-
370
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
575
+ it('handles single record', () => {
576
+ const singleRecord = [mockData[0]];
577
+
578
+ render(
579
+ <DataTable
580
+ data={singleRecord}
581
+ columns={mockColumns}
582
+ rbac={mockRBAC}
583
+ features={createDefaultFeatures()}
584
+ />
585
+ );
586
+
587
+ expect(screen.getByRole('table')).toBeInTheDocument();
371
588
  });
372
- });
373
589
 
374
- describe('Performance Configuration', () => {
375
- it('passes performance config to DataTableCore', () => {
376
- const performance = {
377
- virtualScrolling: true,
378
- enableChunking: true,
379
- };
380
-
381
- render(<DataTable {...baseProps} performance={performance} />);
382
-
383
- const mockCall = getMockedDataTableCore().mock.calls[0];
384
- expect(mockCall[0]).toHaveProperty('performance', performance);
590
+ it('handles complex data types', () => {
591
+ const complexData = [
592
+ {
593
+ id: '1',
594
+ name: 'John Doe',
595
+ email: 'john@example.com',
596
+ metadata: { role: 'admin', permissions: ['read', 'write'] },
597
+ tags: ['urgent', 'important'],
598
+ createdAt: new Date('2023-01-01'),
599
+ isActive: true,
600
+ },
601
+ ];
602
+
603
+ render(
604
+ <DataTable
605
+ data={complexData}
606
+ columns={mockColumns}
607
+ rbac={mockRBAC}
608
+ features={createDefaultFeatures()}
609
+ />
610
+ );
611
+
612
+ expect(screen.getByRole('table')).toBeInTheDocument();
385
613
  });
614
+ });
386
615
 
387
- it('passes serverSide config to DataTableCore', () => {
388
- const serverSide = {
389
- fetchData: vi.fn(),
390
- enableServerSorting: true,
616
+ describe('RBAC Integration', () => {
617
+ it('renders with RBAC configuration', () => {
618
+ const rbacConfig = {
619
+ pageId: 'user-management',
620
+ resource: 'users',
621
+ action: 'read',
391
622
  };
392
-
393
- render(<DataTable {...baseProps} serverSide={serverSide} />);
394
-
395
- const mockCall = getMockedDataTableCore().mock.calls[0];
396
- expect(mockCall[0]).toHaveProperty('serverSide', serverSide);
623
+
624
+ render(
625
+ <DataTable
626
+ data={mockData}
627
+ columns={mockColumns}
628
+ rbac={rbacConfig}
629
+ features={createDefaultFeatures()}
630
+ />
631
+ );
632
+
633
+ expect(screen.getByRole('table')).toBeInTheDocument();
397
634
  });
398
635
 
399
- it('passes paginationMode to DataTableCore', () => {
400
- render(<DataTable {...baseProps} paginationMode="server" />);
401
-
402
- const mockCall = getMockedDataTableCore().mock.calls[0];
403
- expect(mockCall[0]).toHaveProperty('paginationMode', 'server');
636
+ it('renders with minimal RBAC configuration', () => {
637
+ const minimalRBAC = { pageId: 'test' };
638
+
639
+ render(
640
+ <DataTable
641
+ data={mockData}
642
+ columns={mockColumns}
643
+ rbac={minimalRBAC}
644
+ features={createDefaultFeatures()}
645
+ />
646
+ );
647
+
648
+ expect(screen.getByRole('table')).toBeInTheDocument();
404
649
  });
405
650
  });
406
651
 
407
- describe('Component Integration', () => {
408
- it('passes all props to DataTableCore except features', () => {
409
- const allProps = {
410
- ...baseProps,
411
- title: 'Test Table',
412
- description: 'Test description',
413
- variant: 'compact' as const,
414
- className: 'custom-class',
415
- features: createFullFeatures(),
416
- onEditRow: vi.fn(),
417
- onDeleteRow: vi.fn(),
418
- onCreateRow: vi.fn(),
419
- onImport: vi.fn(),
420
- onRowSelectionChange: vi.fn(),
421
- onDeleteSelected: vi.fn(),
422
- performance: { virtualScrolling: true },
423
- initialPageSize: 25,
424
- };
425
-
426
- render(<DataTable {...allProps} />);
427
-
428
- const mockDataTableCore = getMockedDataTableCore();
429
- const lastCall = mockDataTableCore.mock.calls[mockDataTableCore.mock.calls.length - 1][0];
430
-
431
- expect(lastCall).toMatchObject({
432
- data: allProps.data,
433
- columns: allProps.columns,
434
- rbac: allProps.rbac,
435
- title: allProps.title,
436
- description: allProps.description,
437
- variant: allProps.variant,
438
- className: allProps.className,
439
- onEditRow: allProps.onEditRow,
440
- onDeleteRow: allProps.onDeleteRow,
441
- onCreateRow: allProps.onCreateRow,
442
- onImport: allProps.onImport,
443
- onRowSelectionChange: allProps.onRowSelectionChange,
444
- onDeleteSelected: allProps.onDeleteSelected,
445
- performance: allProps.performance,
446
- initialPageSize: allProps.initialPageSize,
447
- });
448
-
449
- // Features should be normalized, not the original object
450
- expect(lastCall.features).toBeDefined();
451
- expect(lastCall.features).not.toBe(allProps.features);
652
+ describe('Accessibility', () => {
653
+ it('renders with proper accessibility attributes', () => {
654
+ render(
655
+ <DataTable
656
+ data={mockData}
657
+ columns={mockColumns}
658
+ rbac={mockRBAC}
659
+ features={createDefaultFeatures()}
660
+ title="User Management"
661
+ />
662
+ );
663
+
664
+ expect(screen.getByRole('table')).toBeInTheDocument();
665
+ });
666
+
667
+ it('renders with ARIA labels when provided', () => {
668
+ render(
669
+ <DataTable
670
+ data={mockData}
671
+ columns={mockColumns}
672
+ rbac={mockRBAC}
673
+ features={createDefaultFeatures()}
674
+ title="User Management"
675
+ description="Manage user accounts and permissions"
676
+ />
677
+ );
678
+
679
+ expect(screen.getByRole('table')).toBeInTheDocument();
452
680
  });
453
681
  });
454
682
 
455
- describe('Memory Management', () => {
456
- it('cleans up resources on unmount', () => {
457
- const { unmount } = render(<DataTable {...baseProps} />);
458
-
459
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
460
-
461
- unmount();
462
- expect(screen.queryByTestId('data-table-core')).not.toBeInTheDocument();
463
- });
464
-
465
- it('handles rapid mount/unmount cycles', () => {
466
- const { unmount: unmount1 } = render(<DataTable {...baseProps} />);
467
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
468
- unmount1();
469
-
470
- const { unmount: unmount2 } = render(<DataTable {...baseProps} />);
471
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
472
- unmount2();
473
-
474
- expect(screen.queryByTestId('data-table-core')).not.toBeInTheDocument();
683
+ describe('Performance Optimization', () => {
684
+ it('renders with React.memo optimization', () => {
685
+ const { rerender } = render(
686
+ <DataTable
687
+ data={mockData}
688
+ columns={mockColumns}
689
+ rbac={mockRBAC}
690
+ features={createDefaultFeatures()}
691
+ />
692
+ );
693
+
694
+ // Re-render with same props should not cause issues
695
+ rerender(
696
+ <DataTable
697
+ data={mockData}
698
+ columns={mockColumns}
699
+ rbac={mockRBAC}
700
+ features={createDefaultFeatures()}
701
+ />
702
+ );
703
+
704
+ expect(screen.getByRole('table')).toBeInTheDocument();
705
+ });
706
+
707
+ it('handles prop changes efficiently', () => {
708
+ const { rerender } = render(
709
+ <DataTable
710
+ data={mockData}
711
+ columns={mockColumns}
712
+ rbac={mockRBAC}
713
+ features={createDefaultFeatures()}
714
+ />
715
+ );
716
+
717
+ // Change title prop
718
+ rerender(
719
+ <DataTable
720
+ data={mockData}
721
+ columns={mockColumns}
722
+ rbac={mockRBAC}
723
+ features={createDefaultFeatures()}
724
+ title="Updated Title"
725
+ />
726
+ );
727
+
728
+ expect(screen.getByRole('table')).toBeInTheDocument();
475
729
  });
476
730
  });
477
731
 
478
732
  describe('Edge Cases', () => {
479
- it('handles missing columns gracefully', () => {
480
- // Note: Debug logging has been removed from DataTable component
481
- render(<DataTable {...baseProps} columns={[]} />);
482
-
483
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
484
- });
485
-
486
- it('handles undefined rbac pageId and pageName', () => {
487
- // Note: Debug logging has been removed from DataTable component
488
- render(<DataTable {...baseProps} rbac={{}} />);
489
-
490
- expect(screen.getByTestId('data-table-core')).toBeInTheDocument();
491
- });
492
-
493
- it('handles rapid feature prop changes', () => {
494
- const { rerender } = render(<DataTable {...baseProps} features={{ search: true }} />);
495
-
496
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(1);
497
-
498
- rerender(<DataTable {...baseProps} features={{ search: false }} />);
499
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(2);
500
-
501
- rerender(<DataTable {...baseProps} features={{ search: true, pagination: true }} />);
502
- expect(getMockedDataTableCore()).toHaveBeenCalledTimes(3);
733
+ it('handles null data gracefully', () => {
734
+ render(
735
+ <DataTable
736
+ // @ts-expect-error - testing null data handling
737
+ data={null}
738
+ columns={mockColumns}
739
+ rbac={mockRBAC}
740
+ features={createDefaultFeatures()}
741
+ />
742
+ );
743
+
744
+ expect(screen.getByRole('table')).toBeInTheDocument();
745
+ });
746
+
747
+ it('handles undefined columns gracefully', () => {
748
+ render(
749
+ <DataTable
750
+ data={mockData}
751
+ // @ts-expect-error - testing undefined columns handling
752
+ columns={undefined}
753
+ rbac={mockRBAC}
754
+ features={createDefaultFeatures()}
755
+ />
756
+ );
757
+
758
+ expect(screen.getByRole('table')).toBeInTheDocument();
759
+ });
760
+
761
+ it('handles empty columns array', () => {
762
+ render(
763
+ <DataTable
764
+ data={mockData}
765
+ columns={[]}
766
+ rbac={mockRBAC}
767
+ features={createDefaultFeatures()}
768
+ />
769
+ );
770
+
771
+ expect(screen.getByRole('table')).toBeInTheDocument();
772
+ });
773
+
774
+ it('handles missing RBAC configuration', () => {
775
+ render(
776
+ <DataTable
777
+ data={mockData}
778
+ columns={mockColumns}
779
+ // @ts-expect-error - intentionally missing rbac
780
+ rbac={undefined}
781
+ features={createDefaultFeatures()}
782
+ />
783
+ );
784
+
785
+ expect(screen.getByRole('table')).toBeInTheDocument();
503
786
  });
504
787
  });
505
- });
788
+
789
+ describe('TypeScript Integration', () => {
790
+ it('maintains type safety with generic data types', () => {
791
+ interface CustomData {
792
+ id: string;
793
+ customField: string;
794
+ }
795
+
796
+ const customData: CustomData[] = [
797
+ { id: '1', customField: 'value1' },
798
+ { id: '2', customField: 'value2' },
799
+ ];
800
+
801
+ const customColumns: DataTableColumn<CustomData>[] = [
802
+ {
803
+ id: 'id',
804
+ header: 'ID',
805
+ accessorKey: 'id',
806
+ },
807
+ {
808
+ id: 'customField',
809
+ header: 'Custom Field',
810
+ accessorKey: 'customField',
811
+ },
812
+ ];
813
+
814
+ render(
815
+ <DataTable
816
+ data={customData}
817
+ columns={customColumns}
818
+ rbac={mockRBAC}
819
+ features={createDefaultFeatures()}
820
+ />
821
+ );
822
+
823
+ expect(screen.getByRole('table')).toBeInTheDocument();
824
+ });
825
+
826
+ it('handles complex nested data types', () => {
827
+ interface NestedData {
828
+ id: string;
829
+ user: {
830
+ name: string;
831
+ profile: {
832
+ avatar: string;
833
+ settings: Record<string, any>;
834
+ };
835
+ };
836
+ }
837
+
838
+ const nestedData: NestedData[] = [
839
+ {
840
+ id: '1',
841
+ user: {
842
+ name: 'John Doe',
843
+ profile: {
844
+ avatar: 'avatar.jpg',
845
+ settings: { theme: 'dark', notifications: true },
846
+ },
847
+ },
848
+ },
849
+ ];
850
+
851
+ const nestedColumns: DataTableColumn<NestedData>[] = [
852
+ {
853
+ id: 'id',
854
+ header: 'ID',
855
+ accessorKey: 'id',
856
+ },
857
+ {
858
+ id: 'user.name',
859
+ header: 'Name',
860
+ accessorKey: 'user.name',
861
+ },
862
+ ];
863
+
864
+ render(
865
+ <DataTable
866
+ data={nestedData}
867
+ columns={nestedColumns}
868
+ rbac={mockRBAC}
869
+ features={createDefaultFeatures()}
870
+ />
871
+ );
872
+
873
+ expect(screen.getByRole('table')).toBeInTheDocument();
874
+ });
875
+ });
876
+ });