@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,7 +1,7 @@
1
1
  /**
2
2
  * @file Editable Row Component Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Components/DataTable/Components/__tests__
4
+ * @module Components/DataTable/Components
5
5
  * @since 0.4.0
6
6
  *
7
7
  * Comprehensive test suite for EditableRow component following testing guidelines.
@@ -13,7 +13,7 @@ import { render, screen, renderHook } from '@testing-library/react';
13
13
  import userEvent from '@testing-library/user-event';
14
14
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
15
15
  import { useReactTable, getCoreRowModel, type ColumnDef } from '@tanstack/react-table';
16
- import { EditableRow } from '../EditableRow';
16
+ import { EditableRow } from './EditableRow';
17
17
  import type { DataRecord } from '../../types';
18
18
 
19
19
  // Mock Button component
@@ -44,31 +44,40 @@ vi.mock('../../Input/Input', () => ({
44
44
  )),
45
45
  }));
46
46
 
47
- // Mock Select components
48
- vi.mock('../../Select/Select', () => ({
49
- Select: ({ children, value, onValueChange, onOpenChange }: any) => (
50
- <div data-testid="select" data-value={value}>
51
- {children}
52
- <button onClick={() => onOpenChange(true)} data-testid="select-open">Open</button>
53
- <button onClick={() => onValueChange('option1')} data-testid="select-change">Change</button>
54
- </div>
55
- ),
56
- SelectTrigger: ({ children, className }: any) => (
57
- <div data-testid="select-trigger" className={className}>{children}</div>
58
- ),
59
- SelectValue: ({ placeholder }: any) => <div data-testid="select-value">{placeholder}</div>,
60
- SelectContent: ({ children, searchable, searchPlaceholder }: any) => (
61
- <div data-testid="select-content" data-searchable={searchable} data-placeholder={searchPlaceholder}>
62
- {children}
63
- </div>
64
- ),
65
- SelectItem: ({ children, value }: any) => (
66
- <div data-testid="select-item" data-value={value}>{children}</div>
67
- ),
68
- SelectGroup: ({ children }: any) => <div data-testid="select-group">{children}</div>,
69
- SelectLabel: ({ children }: any) => <div data-testid="select-label">{children}</div>,
70
- SelectSeparator: () => <div data-testid="select-separator" />,
71
- }));
47
+ // Mock Select components - pass value via context so SelectTrigger can show data-value
48
+ vi.mock('../../Select/Select', async () => {
49
+ const React = await import('react');
50
+ const Ctx = React.createContext<string>('');
51
+ return {
52
+ Select: ({ children, value, onValueChange, onOpenChange }: any) => (
53
+ <Ctx.Provider value={value ?? ''}>
54
+ <div data-testid="select" data-value={value}>
55
+ {children}
56
+ <button onClick={() => onOpenChange?.(true)} data-testid="select-open">Open</button>
57
+ <button onClick={() => onValueChange?.('option1')} data-testid="select-change">Change</button>
58
+ </div>
59
+ </Ctx.Provider>
60
+ ),
61
+ SelectTrigger: ({ children, className }: any) => {
62
+ const value = React.useContext(Ctx);
63
+ return (
64
+ <div data-testid="select-trigger" data-value={value} className={className}>{children}</div>
65
+ );
66
+ },
67
+ SelectValue: ({ placeholder }: any) => <div data-testid="select-value">{placeholder}</div>,
68
+ SelectContent: ({ children, searchable, searchPlaceholder }: any) => (
69
+ <div data-testid="select-content" data-searchable={searchable} data-placeholder={searchPlaceholder}>
70
+ {children}
71
+ </div>
72
+ ),
73
+ SelectItem: ({ children, value }: any) => (
74
+ <div data-testid="select-item" data-value={value}>{children}</div>
75
+ ),
76
+ SelectGroup: ({ children }: any) => <div data-testid="select-group">{children}</div>,
77
+ SelectLabel: ({ children }: any) => <div data-testid="select-label">{children}</div>,
78
+ SelectSeparator: () => <div data-testid="select-separator" />,
79
+ };
80
+ });
72
81
 
73
82
  // Mock lucide-react icons - need to include ChevronDown for Select
74
83
  vi.mock('lucide-react', async () => {
@@ -2,8 +2,9 @@ import React from 'react';
2
2
  import { flexRender, type Row, type Column } from '@tanstack/react-table';
3
3
  import { X, Check } from 'lucide-react';
4
4
 
5
- import { Button } from '../../Button/Button';
6
- import { Input } from '../../Input/Input';
5
+ import { Button } from '../../../Button/Button';
6
+ import { Input } from '../../../Input/Input';
7
+ import { Checkbox } from '../../../Checkbox/Checkbox';
7
8
  import {
8
9
  Select,
9
10
  SelectContent,
@@ -13,9 +14,10 @@ import {
13
14
  SelectGroup,
14
15
  SelectLabel,
15
16
  SelectSeparator,
16
- } from '../../Select/Select';
17
- import { createLogger } from '../../../utils/core/logger';
18
- import type { CellValue, DataRecord, DataTableAction, EditableColumnDef } from '../types';
17
+ } from '../../../Select/Select';
18
+ import { createLogger } from '../../../../utils/core/logger';
19
+ import { optionMatchesSearch } from '../../utils/selectFieldUtils';
20
+ import type { CellValue, DataRecord, DataTableAction, EditableColumnDef } from '../../types';
19
21
 
20
22
  interface EditableRowProps<TData extends DataRecord> {
21
23
  row: Row<TData>;
@@ -29,52 +31,28 @@ interface EditableRowProps<TData extends DataRecord> {
29
31
  hierarchical?: boolean;
30
32
  }
31
33
 
32
- // Component for select fields with searchable and creatable support
33
- function SelectEditField<TData extends DataRecord>({
34
- columnDef,
35
- accessorKey: _accessorKey,
36
- currentValue,
37
- placeholder,
38
- onChange,
39
- className,
40
- }: {
34
+ /** Syncs search input DOM value with search term and show-create state. No return value. */
35
+ function useSelectSearchInput<TData extends DataRecord>(params: {
36
+ isOpen: boolean;
37
+ isSearchable: boolean;
38
+ isCreatable: boolean;
41
39
  columnDef: EditableColumnDef<TData>;
42
- accessorKey: string;
43
- currentValue: CellValue;
44
- placeholder?: string;
45
- onChange: (value: CellValue) => void;
46
- className?: string;
47
- }) {
48
- const logger = createLogger('SelectEditField');
49
- // Determine if searchable - explicitly check for true to ensure visible search input appears
50
- // When selectSearchable is true or undefined, show the visible search input box
51
- // When selectSearchable is false, hide the search input (type-to-search still works via SelectContent internals)
52
- const isSearchable = columnDef.selectSearchable !== false;
53
- const isCreatable = columnDef.creatable === true;
54
- const selectRef = React.useRef<HTMLFieldSetElement>(null);
55
- const [searchTerm, setSearchTerm] = React.useState('');
56
- const [isOpen, setIsOpen] = React.useState(false);
57
- const [showCreateOption, setShowCreateOption] = React.useState(false);
40
+ selectRef: React.RefObject<HTMLFieldSetElement | null>;
41
+ setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
42
+ setShowCreateOption: React.Dispatch<React.SetStateAction<boolean>>;
43
+ }): void {
44
+ const { isOpen, isSearchable, isCreatable, columnDef, selectRef, setSearchTerm, setShowCreateOption } = params;
58
45
 
59
- // Monitor search input value via DOM events to detect when user types
60
46
  React.useEffect(() => {
61
47
  if (!isOpen || !isSearchable || !isCreatable) return;
62
-
63
- // Function to find and attach listener to search input
48
+
64
49
  const findAndAttachSearchInput = (): (() => void) | null => {
65
- // Try to find search input - check both within selectRef and document
66
- // SelectContent might be rendered outside the form element
67
50
  let searchInput: HTMLInputElement | null = null;
68
-
69
51
  if (selectRef.current) {
70
52
  searchInput = selectRef.current.querySelector<HTMLInputElement>('[data-testid="select-search-input"]');
71
53
  }
72
-
73
- // If not found in selectRef, try document (in case SelectContent is in a portal)
74
54
  if (!searchInput) {
75
- // Find the most recently opened select's search input
76
55
  const allSearchInputs = document.querySelectorAll<HTMLInputElement>('[data-testid="select-search-input"]');
77
- // Get the one that's visible (not hidden)
78
56
  for (const input of Array.from(allSearchInputs)) {
79
57
  const content = input.closest('[data-testid="select-content"]');
80
58
  if (content && content.getAttribute('aria-hidden') !== 'true') {
@@ -83,71 +61,27 @@ function SelectEditField<TData extends DataRecord>({
83
61
  }
84
62
  }
85
63
  }
86
-
87
64
  if (!searchInput) return null;
88
65
 
89
66
  const handleInput = (e: Event) => {
90
67
  const target = e.target as HTMLInputElement;
91
68
  const currentSearch = target.value;
92
69
  setSearchTerm(currentSearch);
93
-
94
- // Check if search doesn't match any option (including items in groups)
95
70
  if (currentSearch.trim()) {
96
71
  const searchLower = currentSearch.toLowerCase().trim();
97
-
98
- // Helper to check if an option matches
99
- // Use explicit union type instead of typeof to avoid Babel parsing issues
100
- type FieldOption =
101
- | { value: string | number; label: string }
102
- | { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
103
- | { type: 'separator' };
104
-
105
- const checkMatch = (opt: FieldOption): boolean => {
106
- // Simple option
107
- if ('value' in opt && !('type' in opt)) {
108
- return opt.label.toLowerCase().includes(searchLower);
109
- }
110
- // Group - check items within the group
111
- if ('type' in opt && opt.type === 'group') {
112
- return (opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some((item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower));
113
- }
114
- // Separator - doesn't match
115
- return false;
116
- };
117
-
118
- const hasMatch = (columnDef.fieldOptions || []).some(checkMatch);
72
+ const hasMatch = (columnDef.fieldOptions || []).some((opt) => optionMatchesSearch(opt, searchLower));
119
73
  setShowCreateOption(!hasMatch);
120
74
  } else {
121
75
  setShowCreateOption(false);
122
76
  }
123
77
  };
124
78
 
125
- // Check initial value in case user has already typed
126
79
  const initialValue = searchInput.value;
127
80
  if (initialValue) {
128
- const currentSearch = initialValue;
129
- setSearchTerm(currentSearch);
130
-
131
- // Check if search doesn't match any option (including items in groups)
132
- if (currentSearch.trim()) {
133
- const searchLower = currentSearch.toLowerCase().trim();
134
-
135
- type FieldOption =
136
- | { value: string | number; label: string }
137
- | { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
138
- | { type: 'separator' };
139
-
140
- const checkMatch = (opt: FieldOption): boolean => {
141
- if ('value' in opt && !('type' in opt)) {
142
- return opt.label.toLowerCase().includes(searchLower);
143
- }
144
- if ('type' in opt && opt.type === 'group') {
145
- return (opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some((item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower));
146
- }
147
- return false;
148
- };
149
-
150
- const hasMatch = (columnDef.fieldOptions || []).some(checkMatch);
81
+ setSearchTerm(initialValue);
82
+ if (initialValue.trim()) {
83
+ const searchLower = initialValue.toLowerCase().trim();
84
+ const hasMatch = (columnDef.fieldOptions || []).some((opt) => optionMatchesSearch(opt, searchLower));
151
85
  setShowCreateOption(!hasMatch);
152
86
  } else {
153
87
  setShowCreateOption(false);
@@ -155,30 +89,57 @@ function SelectEditField<TData extends DataRecord>({
155
89
  }
156
90
 
157
91
  searchInput.addEventListener('input', handleInput);
158
-
159
- return () => {
160
- searchInput?.removeEventListener('input', handleInput);
161
- };
92
+ return () => searchInput?.removeEventListener('input', handleInput);
162
93
  };
163
94
 
164
- // Try to find immediately
165
- const cleanup: (() => void) | null = findAndAttachSearchInput();
166
-
167
- // If not found, try again after a short delay (SelectContent might render asynchronously)
95
+ const cleanup = findAndAttachSearchInput();
168
96
  if (!cleanup) {
169
97
  let timeoutCleanup: (() => void) | null = null;
170
98
  const timeoutId = setTimeout(() => {
171
99
  timeoutCleanup = findAndAttachSearchInput();
172
100
  }, 50);
173
-
174
101
  return () => {
175
102
  clearTimeout(timeoutId);
176
103
  timeoutCleanup?.();
177
104
  };
178
105
  }
179
-
180
106
  return cleanup;
181
- }, [isOpen, isSearchable, isCreatable, columnDef]);
107
+ }, [isOpen, isSearchable, isCreatable, columnDef, selectRef, setSearchTerm, setShowCreateOption]);
108
+ }
109
+
110
+ // Component for select fields with searchable and creatable support
111
+ function SelectEditField<TData extends DataRecord>({
112
+ columnDef,
113
+ accessorKey: _accessorKey,
114
+ currentValue,
115
+ placeholder,
116
+ onChange,
117
+ className,
118
+ }: {
119
+ columnDef: EditableColumnDef<TData>;
120
+ accessorKey: string;
121
+ currentValue: CellValue;
122
+ placeholder?: string;
123
+ onChange: (value: CellValue) => void;
124
+ className?: string;
125
+ }) {
126
+ const logger = createLogger('SelectEditField');
127
+ const isSearchable = columnDef.selectSearchable !== false;
128
+ const isCreatable = columnDef.creatable === true;
129
+ const selectRef = React.useRef<HTMLFieldSetElement>(null);
130
+ const [searchTerm, setSearchTerm] = React.useState('');
131
+ const [isOpen, setIsOpen] = React.useState(false);
132
+ const [showCreateOption, setShowCreateOption] = React.useState(false);
133
+
134
+ useSelectSearchInput({
135
+ isOpen,
136
+ isSearchable,
137
+ isCreatable,
138
+ columnDef,
139
+ selectRef,
140
+ setSearchTerm,
141
+ setShowCreateOption,
142
+ });
182
143
 
183
144
  const handleCreateNew = React.useCallback(async () => {
184
145
  if (!isCreatable || !columnDef.onCreateNew || !searchTerm.trim()) return;
@@ -258,7 +219,7 @@ function SelectEditField<TData extends DataRecord>({
258
219
  <SelectItem
259
220
  key="__create_new__"
260
221
  value={`__create_new__${searchTerm}`}
261
- className="bg-main-100 font-medium border-t border-main-200"
222
+ className="bg-main-100 border-t border-main-200"
262
223
  >
263
224
  Create "{searchTerm}"
264
225
  </SelectItem>
@@ -279,7 +240,7 @@ const renderEditField = <TData extends DataRecord>(
279
240
  const columnDef = column.columnDef as EditableColumnDef<TData>;
280
241
 
281
242
  if (columnDef.editable === false) {
282
- return <span className="text-sm text-sec-600">{String(value ?? '')}</span>;
243
+ return <span>{String(value ?? '')}</span>;
283
244
  }
284
245
 
285
246
  if (columnDef.fieldType === 'select' && columnDef.fieldOptions) {
@@ -325,6 +286,27 @@ const renderEditField = <TData extends DataRecord>(
325
286
  );
326
287
  }
327
288
 
289
+ if (columnDef.fieldType === 'checkbox') {
290
+ const accessorKey = columnDef.editAccessorKey || column.id;
291
+ // Convert value to boolean - handle string "true"/"false", boolean, null, undefined
292
+ const rawValue = editingData[accessorKey] !== undefined && editingData[accessorKey] !== null
293
+ ? editingData[accessorKey]
294
+ : (value !== undefined && value !== null ? value : false);
295
+ const checked = rawValue === true || rawValue === 'true' || rawValue === 1 || rawValue === '1';
296
+
297
+ return (
298
+ <Checkbox
299
+ checked={checked}
300
+ onCheckedChange={(checkedValue) => {
301
+ // onCheckedChange can return boolean | 'indeterminate', convert to boolean
302
+ const booleanValue = checkedValue === true;
303
+ onChange({ [accessorKey]: booleanValue });
304
+ }}
305
+ aria-label={columnDef.header ? `Toggle ${columnDef.header}` : `Toggle ${column.id}`}
306
+ />
307
+ );
308
+ }
309
+
328
310
  return (
329
311
  <Input
330
312
  ref={inputRef}
@@ -379,7 +361,7 @@ export function EditableRow<TData extends DataRecord>({
379
361
  const isSystemColumn = cell.column.id === 'select' || cell.column.id === 'actions';
380
362
 
381
363
  return (
382
- <td key={cell.id} role="cell" className={cell.column.columnDef.meta?.align === 'right' ? 'text-right' : ''}>
364
+ <td key={cell.id} role="cell" className={`${cell.column.columnDef.meta?.align === 'right' ? 'text-right' : ''} ${isSystemColumn ? 'print:hidden' : ''}`}>
383
365
  {isSystemColumn ? (
384
366
  // System columns: render their normal cell content (checkbox for select, buttons for actions)
385
367
  cell.column.id === 'actions' ? (
@@ -421,7 +403,7 @@ export function EditableRow<TData extends DataRecord>({
421
403
  }
422
404
  })
423
405
  ) : (
424
- <span className="text-sm text-sec-600">{String(cell.getValue() ?? '')}</span>
406
+ <span>{String(cell.getValue() ?? '')}</span>
425
407
  );
426
408
  }
427
409
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file EmptyState Component Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Components/DataTable/Components/__tests__
4
+ * @module Components/DataTable/Components
5
5
  * @since 0.4.0
6
6
  *
7
7
  * Comprehensive test suite for EmptyState component following testing guidelines.
@@ -12,22 +12,16 @@ import React from 'react';
12
12
  import { render, screen } from '@testing-library/react';
13
13
  import userEvent from '@testing-library/user-event';
14
14
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
15
- import { EmptyState } from '../EmptyState';
15
+ import { EmptyState } from './EmptyState';
16
16
 
17
17
  // Mock lucide-react icons
18
18
  vi.mock('lucide-react', () => ({
19
- Database: ({ className }: { className?: string }) => (
20
- <div data-testid="lucide-database" className={className}>Database</div>
21
- ),
22
19
  Search: ({ className }: { className?: string }) => (
23
20
  <div data-testid="lucide-search" className={className}>Search</div>
24
21
  ),
25
22
  Plus: ({ className }: { className?: string }) => (
26
23
  <div data-testid="lucide-plus" className={className}>Plus</div>
27
24
  ),
28
- User: ({ className }: { className?: string }) => (
29
- <div data-testid="lucide-user" className={className}>User</div>
30
- ),
31
25
  }));
32
26
 
33
27
  // Mock Button component
@@ -54,7 +48,6 @@ describe('[component] EmptyState', () => {
54
48
 
55
49
  expect(screen.getByText('No data available')).toBeInTheDocument();
56
50
  expect(screen.getByText('Get started by adding your first entry')).toBeInTheDocument();
57
- expect(screen.getByTestId('lucide-database')).toBeInTheDocument();
58
51
  });
59
52
 
60
53
  it('renders with custom title', () => {
@@ -70,23 +63,6 @@ describe('[component] EmptyState', () => {
70
63
  expect(screen.getByText('Custom description')).toBeInTheDocument();
71
64
  expect(screen.queryByText('Get started by adding your first entry')).not.toBeInTheDocument();
72
65
  });
73
-
74
- it('renders with custom icon component', () => {
75
- const CustomIcon = ({ className }: { className?: string }) => (
76
- <div data-testid="custom-icon" className={className}>Custom</div>
77
- );
78
-
79
- render(<EmptyState icon={CustomIcon} />);
80
-
81
- expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
82
- expect(screen.queryByTestId('lucide-database')).not.toBeInTheDocument();
83
- });
84
-
85
- it('uses default Database icon when no icon provided', () => {
86
- render(<EmptyState />);
87
-
88
- expect(screen.getByTestId('lucide-database')).toBeInTheDocument();
89
- });
90
66
  });
91
67
 
92
68
  describe('Filtered State', () => {
@@ -294,15 +270,6 @@ describe('[component] EmptyState', () => {
294
270
  expect(container).toHaveAttribute('aria-live', 'polite');
295
271
  });
296
272
 
297
- it('marks icon as decorative with aria-hidden', () => {
298
- render(<EmptyState />);
299
-
300
- const icon = screen.getByTestId('lucide-database');
301
- // Icon is wrapped in a component that may not have aria-hidden directly
302
- // Check that it exists and is accessible
303
- expect(icon).toBeInTheDocument();
304
- });
305
-
306
273
  it('uses semantic heading for title', () => {
307
274
  render(<EmptyState title="Custom Title" />);
308
275
 
@@ -328,33 +295,6 @@ describe('[component] EmptyState', () => {
328
295
  });
329
296
  });
330
297
 
331
- describe('Icon Detection', () => {
332
- it('identifies default Database icon correctly', () => {
333
- render(<EmptyState />);
334
-
335
- const icon = screen.getByTestId('lucide-database');
336
- expect(icon).toBeInTheDocument();
337
- });
338
-
339
- it('identifies User icon correctly when provided', () => {
340
- const UserIcon = () => <div data-testid="lucide-user">User</div>;
341
-
342
- render(<EmptyState icon={UserIcon} />);
343
-
344
- const icon = screen.getByTestId('lucide-user');
345
- expect(icon).toBeInTheDocument();
346
- });
347
-
348
- it('handles custom icons gracefully', () => {
349
- const CustomIcon = () => <div data-testid="custom-icon">Custom</div>;
350
-
351
- render(<EmptyState icon={CustomIcon} />);
352
-
353
- expect(screen.getByTestId('custom-icon')).toBeInTheDocument();
354
- expect(screen.queryByTestId('lucide-database')).not.toBeInTheDocument();
355
- });
356
- });
357
-
358
298
  describe('Edge Cases', () => {
359
299
  it('handles empty title string', () => {
360
300
  render(<EmptyState title="" />);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { Database, Search, Plus, User } from 'lucide-react';
3
- import { Button } from '../../Button/Button';
4
- import { Alert, AlertTitle, AlertDescription } from '../../Alert/Alert';
2
+ import { Search, Plus } from 'lucide-react';
3
+ import { Button } from '../../../Button/Button';
4
+ import { Alert, AlertTitle, AlertDescription } from '../../../Alert/Alert';
5
5
 
6
6
  /**
7
7
  * Props for the EmptyState component.
@@ -9,7 +9,7 @@ import { Alert, AlertTitle, AlertDescription } from '../../Alert/Alert';
9
9
  interface EmptyStateProps {
10
10
  title?: string;
11
11
  description?: string;
12
- icon?: React.ComponentType<React.SVGProps<SVGSVGElement>>;
12
+ icon?: React.ComponentType<{ className?: string }>;
13
13
  action?: {
14
14
  label: string;
15
15
  onClick: () => void;
@@ -38,25 +38,17 @@ export function EmptyState({
38
38
  ? "Try adjusting your search or filter criteria"
39
39
  : "Get started by adding your first entry";
40
40
 
41
- // Use default icon only if no icon is provided
42
- const DisplayIcon = Icon || Database;
43
-
44
41
  return (
45
42
  <Alert
46
43
  role="status"
47
44
  aria-live="polite"
48
45
  className="grid place-items-center text-center max-w-lg mx-auto"
49
46
  >
50
- <DisplayIcon
51
- role="img"
52
- aria-hidden="true"
53
- className="size-12 text-muted-foreground mb-4"
54
- data-testid={DisplayIcon === Database ? 'lucide-database' : DisplayIcon === User ? 'lucide-user' : 'custom-icon'}
55
- />
56
- <AlertTitle className="text-lg font-semibold mb-2">
47
+ {Icon && <Icon className="size-8 mx-auto" aria-hidden />}
48
+ <AlertTitle>
57
49
  {title || defaultTitle}
58
50
  </AlertTitle>
59
- <AlertDescription className="text-sm text-muted-foreground mb-4 max-w-sm">
51
+ <AlertDescription>
60
52
  {description || defaultDescription}
61
53
  </AlertDescription>
62
54
 
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file Filter Row Component Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Components/DataTable/Components/__tests__
4
+ * @module Components/DataTable/Components
5
5
  * @since 0.4.0
6
6
  *
7
7
  * Comprehensive test suite for FilterRow component following testing guidelines.
@@ -12,11 +12,12 @@ import React from 'react';
12
12
  import { render, screen, renderHook } from '@testing-library/react';
13
13
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
14
14
  import { createColumnHelper, useReactTable, getCoreRowModel, getFilteredRowModel } from '@tanstack/react-table';
15
- import { FilterRow } from '../FilterRow';
15
+ import { FilterRow } from './FilterRow';
16
16
  import type { DataRecord } from '../../types';
17
17
 
18
- // Mock ColumnFilter component
19
- vi.mock('../ColumnFilter', () => ({
18
+ // Mock ColumnFilter so tests get predictable DOM (data-testid="column-filter").
19
+ // Path must match FilterRow's import; use same-dir path so Vite resolves the same module.
20
+ vi.mock('../shared/ColumnFilter', () => ({
20
21
  ColumnFilter: ({ column, filterType, options, placeholder }: any) => (
21
22
  <div
22
23
  data-testid="column-filter"
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { ColumnFilter } from './ColumnFilter';
2
+ import { ColumnFilter } from '../shared/ColumnFilter';
3
3
  import type { Column, Header, Table } from '@tanstack/react-table';
4
- import { getColumnHeaderText } from '../utils/columnUtils';
5
- import type { DataRecord, DataTableColumn } from '../types';
4
+ import { getColumnHeaderText } from '../../utils/columnUtils';
5
+ import type { DataRecord, DataTableColumn } from '../../types';
6
6
 
7
7
  /**
8
8
  * Props for the FilterRow component.
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file LoadingState Component Tests
3
3
  * @package @jmruthers/pace-core
4
- * @module Components/DataTable/Components/__tests__
4
+ * @module Components/DataTable/Components
5
5
  * @since 0.4.0
6
6
  *
7
7
  * Comprehensive test suite for LoadingState component following testing guidelines.
@@ -11,7 +11,7 @@
11
11
  import React from 'react';
12
12
  import { render, screen } from '@testing-library/react';
13
13
  import { describe, it, expect } from 'vitest';
14
- import { LoadingState } from '../LoadingState';
14
+ import { LoadingState } from './LoadingState';
15
15
 
16
16
  describe('[component] LoadingState', () => {
17
17
  describe('Rendering', () => {
@@ -63,18 +63,14 @@ describe('[component] LoadingState', () => {
63
63
 
64
64
  describe('Visual Presentation', () => {
65
65
  it('centers content visually', () => {
66
- const { container } = render(<LoadingState />);
67
-
68
- // Component uses grid place-items-center for centering (changed from p to div for semantic HTML)
69
- const containerElement = container.querySelector('div');
66
+ render(<LoadingState />);
67
+ const containerElement = screen.getByRole('region', { name: 'Loading' });
70
68
  expect(containerElement).toHaveClass('grid', 'place-items-center');
71
69
  });
72
70
 
73
71
  it('applies appropriate spacing', () => {
74
- const { container } = render(<LoadingState />);
75
-
76
- // Component uses div for layout (changed from p for semantic HTML)
77
- const containerElement = container.querySelector('div');
72
+ render(<LoadingState />);
73
+ const containerElement = screen.getByRole('region', { name: 'Loading' });
78
74
  expect(containerElement).toHaveClass('p-8');
79
75
  });
80
76
  });
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { LoadingSpinner } from '../../LoadingSpinner/LoadingSpinner';
2
+ import { LoadingSpinner } from '../../../LoadingSpinner/LoadingSpinner';
3
3
 
4
4
  /**
5
5
  * Loading state component for DataTable.
@@ -9,9 +9,9 @@ import { LoadingSpinner } from '../../LoadingSpinner/LoadingSpinner';
9
9
  */
10
10
  export function LoadingState() {
11
11
  return (
12
- <div className="grid place-items-center text-center p-8">
12
+ <section aria-label="Loading" className="grid place-items-center text-center p-8">
13
13
  <LoadingSpinner />
14
- <strong>Loading...</strong>
15
- </div>
14
+ <strong>Loading...</strong>
15
+ </section>
16
16
  );
17
17
  }