@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,66 +1,21 @@
1
- import React, { useState, useEffect, useCallback, useRef, useContext, useMemo } from 'react';
2
- import { FileText, ExternalLink } from 'lucide-react';
1
+ import React, { useState, useEffect, useContext } from 'react';
3
2
  import type { SupabaseClient } from '@supabase/supabase-js';
4
3
  import type { Database } from '../../types/database';
5
4
  import { FileReference, FileCategory } from '../../types/file-reference';
6
- import { usePublicFileDisplay } from '../../hooks/public/usePublicFileDisplay';
7
- import { useFileDisplay } from '../../hooks/useFileDisplay';
5
+ import { usePublicFileDisplay } from './usePublicFileDisplay';
6
+ import { useFileDisplay } from './useFileDisplay';
8
7
  import { useFileUrl } from '../../hooks/useFileUrl';
9
8
  import { PublicPageContext } from '../PublicLayout/PublicPageContext';
10
9
  import { useIsPublicPage } from '../PublicLayout/usePublicPageContext';
11
10
  import { useUnifiedAuth } from '../../providers/services/UnifiedAuthProvider';
12
- import { Dialog, DialogContent, DialogHeader, DialogBody, DialogFooter } from '../Dialog/Dialog';
13
- import { Button } from '../Button/Button';
14
- import { LoadingSpinner } from '../LoadingSpinner/LoadingSpinner';
11
+ import { FileDisplayContent } from './FileDisplayContent';
12
+ import { getFallbackClasses } from './fallbackUtils';
15
13
  import { logger } from '../../utils/core/logger';
16
14
 
17
- /**
18
- * Size classes for fallback display
19
- */
20
- const fallbackSizeClasses = {
21
- xs: 'size-4 text-xs',
22
- sm: 'size-6 text-sm',
23
- md: 'size-8 text-base',
24
- lg: 'size-12 text-lg',
25
- xl: 'size-16 text-xl',
26
- '2xl': 'size-20 text-2xl'
27
- };
28
-
29
- /**
30
- * Base classes for fallback display
31
- */
32
- const fallbackBaseClasses = 'size-full grid place-items-center text-center text-sec-600 font-semibold';
33
-
34
- /**
35
- * Helper function to compute fallback classes for a given size
36
- */
37
- function getFallbackClasses(size: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' = 'md'): string {
38
- const sizeClass = fallbackSizeClasses[size];
39
- return `${fallbackBaseClasses} ${sizeClass}`.trim();
40
- }
41
-
42
- /**
43
- * Default fallback text generator - extracts initials from file name
44
- */
45
- function defaultGenerateFallbackText(fileName?: string): string {
46
- if (!fileName) return 'FL';
47
-
48
- // Extract initials from file name (without extension)
49
- const baseName = fileName.replace(/\.[^/.]+$/, '');
50
- const words = baseName.split(/[\s\-_]+/);
51
-
52
- if (words.length === 0) return 'FL';
53
-
54
- return words
55
- .map(word => word.charAt(0).toUpperCase())
56
- .join('')
57
- .substring(0, 3); // Max 3 characters
58
- }
59
-
60
15
  export interface FileDisplayProps {
61
16
  table_name: string;
62
17
  record_id: string;
63
- /**
18
+ /**
64
19
  * Optional organisation ID. When not provided (undefined), the component will automatically
65
20
  * search for files in both user-scoped (organisation_id = null) and organisation-scoped contexts.
66
21
  * If both types of files exist, organisation-scoped files are preferred.
@@ -89,9 +44,9 @@ export interface FileDisplayProps {
89
44
  fallbackSourceText?: string;
90
45
  /** Size variant for fallback display (only applies when showFallback is true) */
91
46
  fallbackSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
92
- /**
93
- * Enable children rendering in displayOnly mode. When true, uses standard display path
94
- * (with children support) even if showDelete is false. The delete button will only appear
47
+ /**
48
+ * Enable children rendering in displayOnly mode. When true, uses standard display path
49
+ * (with children support) even if showDelete is false. The delete button will only appear
95
50
  * if showDelete is also true.
96
51
  */
97
52
  enableChildren?: boolean;
@@ -99,540 +54,6 @@ export interface FileDisplayProps {
99
54
  showMetadata?: boolean;
100
55
  }
101
56
 
102
- // Shared rendering logic for file display
103
- interface FileDisplayContentProps {
104
- isLoading: boolean;
105
- error: string | Error | null;
106
- fileUrl: string | null;
107
- fileReference: FileReference | null;
108
- fileReferences: FileReference[];
109
- fileUrls: Map<string, string>;
110
- fileCount: number;
111
- category: FileCategory | undefined;
112
- displayOnly: boolean;
113
- showDelete: boolean;
114
- className: string;
115
- imgClassName?: string;
116
- children?: React.ReactNode;
117
- onDelete?: () => Promise<void>;
118
- clearError?: () => void;
119
- organisation_id: string | undefined;
120
- loadingComponent?: React.ComponentType;
121
- errorComponent?: React.ComponentType<{ error: Error | string | null; retry?: () => void }>;
122
- showFallback?: boolean;
123
- generateFallbackText?: (fileName?: string) => string;
124
- fallbackText?: string;
125
- fallbackSourceText?: string;
126
- fallbackSize?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
127
- enableChildren?: boolean;
128
- showMetadata?: boolean;
129
- }
130
-
131
- const FileDisplayContent = React.memo(function FileDisplayContent({
132
- isLoading,
133
- error,
134
- fileUrl,
135
- fileReference,
136
- fileReferences,
137
- fileUrls,
138
- fileCount,
139
- category,
140
- displayOnly,
141
- showDelete,
142
- className,
143
- imgClassName,
144
- children,
145
- onDelete,
146
- clearError,
147
- organisation_id: _organisation_id,
148
- loadingComponent: LoadingComponent,
149
- errorComponent: ErrorComponent,
150
- showFallback = false,
151
- generateFallbackText = defaultGenerateFallbackText,
152
- fallbackText,
153
- fallbackSourceText,
154
- fallbackSize = 'md',
155
- enableChildren = false,
156
- showMetadata = true
157
- }: FileDisplayContentProps) {
158
- const [imageError, setImageError] = useState(false);
159
- const [internalFileUrls, setInternalFileUrls] = useState<Map<string, string>>(new Map(fileUrls));
160
- const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
161
- const fileReferencesRef = useRef<FileReference[]>([]);
162
- const imgRef = useRef<HTMLImageElement | null>(null);
163
- const currentSrcRef = useRef<string | null>(null);
164
- const isImageLoadingRef = useRef(false);
165
-
166
- // Stabilize fileUrl to prevent unnecessary image reloads
167
- // This prevents NS_BINDING_ABORTED errors when the component re-renders
168
- const stableFileUrl = useMemo(() => fileUrl, [fileUrl]);
169
-
170
- // Track when image starts loading to prevent cancellation
171
- const handleImageLoadStart = useCallback(() => {
172
- isImageLoadingRef.current = true;
173
- if (stableFileUrl) {
174
- currentSrcRef.current = stableFileUrl;
175
- }
176
- }, [stableFileUrl]);
177
-
178
- // Track when image finishes loading
179
- const handleImageLoad = useCallback(() => {
180
- isImageLoadingRef.current = false;
181
- if (stableFileUrl) {
182
- currentSrcRef.current = stableFileUrl;
183
- }
184
- }, [stableFileUrl]);
185
-
186
- // Compute fallback text
187
- const computedFallbackText = useMemo(() => {
188
- if (fallbackText) return fallbackText;
189
- // Use fallbackSourceText if provided, otherwise fall back to filename
190
- const sourceText = fallbackSourceText ?? fileReference?.file_metadata?.fileName;
191
- return generateFallbackText(sourceText);
192
- }, [fallbackText, fallbackSourceText, fileReference, generateFallbackText]);
193
-
194
- // Compute fallback classes
195
- const fallbackClasses = useMemo(() => {
196
- return getFallbackClasses(fallbackSize);
197
- }, [fallbackSize]);
198
-
199
- // Sync fileUrls prop with internal state
200
- // Track file references to detect when they change and sync URLs
201
- useEffect(() => {
202
- const currentIds = fileReferences.map(f => f.id).join(',');
203
- const prevIds = fileReferencesRef.current.map(f => f.id).join(',');
204
-
205
- if (currentIds !== prevIds) {
206
- fileReferencesRef.current = fileReferences;
207
- // Reset internal URLs when file references change, then immediately sync from props
208
- setInternalFileUrls(new Map(fileUrls));
209
- } else {
210
- // If file references haven't changed, just sync URLs
211
- setInternalFileUrls(new Map(fileUrls));
212
- }
213
- }, [fileReferences, fileUrls]);
214
-
215
- const handleDeleteClick = () => {
216
- setDeleteDialogOpen(true);
217
- };
218
-
219
- const handleDeleteConfirm = async () => {
220
- setDeleteDialogOpen(false);
221
- try {
222
- if (onDelete) {
223
- await onDelete();
224
- }
225
- setImageError(false);
226
- } catch (_error) {
227
- // Error handling is delegated to onDelete callback
228
- setImageError(false);
229
- }
230
- };
231
-
232
- const handleImageError = () => {
233
- setImageError(true);
234
- };
235
-
236
- const getFileIcon = (fileType: string) => {
237
- if (fileType.startsWith('image/')) return '🖼️';
238
- if (fileType.startsWith('video/')) return '🎥';
239
- if (fileType.startsWith('audio/')) return '🎵';
240
- if (fileType.includes('pdf')) return '📄';
241
- if (fileType.includes('word')) return '📝';
242
- if (fileType.includes('excel') || fileType.includes('spreadsheet')) return '📊';
243
- if (fileType.includes('powerpoint') || fileType.includes('presentation')) return '📊';
244
- return '📁';
245
- };
246
-
247
- const formatFileSize = (bytes: number) => {
248
- if (bytes === 0) return '0 Bytes';
249
- const k = 1024;
250
- const sizes = ['Bytes', 'KB', 'MB', 'GB'];
251
- const i = Math.floor(Math.log(bytes) / Math.log(k));
252
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
253
- };
254
-
255
- // Check for errors first - errors should be shown even if fileCount is 0
256
- if (error) {
257
- if (ErrorComponent) {
258
- return <ErrorComponent error={error} retry={clearError} />;
259
- }
260
-
261
- // Show fallback if enabled
262
- if (showFallback) {
263
- return (
264
- <figure className={className} title="File unavailable">
265
- <p className={fallbackClasses}>
266
- {computedFallbackText}
267
- </p>
268
- </figure>
269
- );
270
- }
271
-
272
- return (
273
- <figure className={className} title="Error">
274
- <p className={getFallbackClasses(fallbackSize || 'md')}>
275
- Error loading file: {error instanceof Error ? error.message : String(error)}
276
- </p>
277
- {clearError && (
278
- <Button
279
- onClick={clearError}
280
- className="mt-2"
281
- aria-label="Retry loading file"
282
- >
283
- Try again
284
- </Button>
285
- )}
286
- </figure>
287
- );
288
- }
289
-
290
- // Show fallback immediately if enabled and we have no files (even during loading)
291
- // This provides better UX by showing fallback UI instead of a spinner when we know there are no files
292
- if (fileCount === 0 && !isLoading) {
293
- // Show fallback if enabled
294
- if (showFallback) {
295
- return (
296
- <figure className={className} title="No file">
297
- <p className={fallbackClasses}>
298
- {computedFallbackText}
299
- </p>
300
- {children}
301
- </figure>
302
- );
303
- }
304
-
305
- return (
306
- <figure className={`text-sec-500 text-center p-4 ${className}`}>
307
- <p>No files found</p>
308
- {children}
309
- </figure>
310
- );
311
- }
312
-
313
- // During loading, show fallback if enabled (better UX than spinner for empty states)
314
- if (isLoading && showFallback && fileCount === 0) {
315
- return (
316
- <figure className={className} title="Loading...">
317
- <p className={fallbackClasses}>
318
- {computedFallbackText}
319
- </p>
320
- {children}
321
- </figure>
322
- );
323
- }
324
-
325
- if (isLoading) {
326
- if (LoadingComponent) {
327
- return <LoadingComponent />;
328
- }
329
- return (
330
- <figure className={className} title="Loading">
331
- <div className="flex items-center justify-center p-4">
332
- <LoadingSpinner />
333
- </div>
334
- </figure>
335
- );
336
- }
337
-
338
- // Single file display (when category or displayOnly is specified)
339
- if ((category || displayOnly) && fileReference) {
340
- const isImage = fileReference.file_metadata.fileType?.startsWith('image/');
341
-
342
- // Simplified image-only display when displayOnly is true and it's an image
343
- // Only use simplified path if enableChildren is not explicitly enabled
344
- if (displayOnly && isImage && !showDelete && !enableChildren) {
345
- // Show fallback if image error occurred and fallback is enabled
346
- if (imageError && showFallback) {
347
- return (
348
- <figure className={className} title={fileReference.file_metadata.fileName || 'File'}>
349
- <p className={fallbackClasses}>
350
- {computedFallbackText}
351
- </p>
352
- </figure>
353
- );
354
- }
355
-
356
- // Show loading skeleton if URL is not available yet
357
- if (!stableFileUrl) {
358
- return (
359
- <figure className={className || "max-w-full h-48"} title="Loading">
360
- <p className={fallbackClasses}>
361
- <LoadingSpinner />
362
- </p>
363
- </figure>
364
- );
365
- }
366
-
367
- return (
368
- <figure className={className || ""}>
369
- <img
370
- ref={imgRef}
371
- key={fileReference.id}
372
- src={stableFileUrl || undefined}
373
- alt={fileReference.file_metadata.fileName || 'File'}
374
- className={imgClassName || "object-cover size-full"}
375
- onError={handleImageError}
376
- onLoadStart={handleImageLoadStart}
377
- onLoad={handleImageLoad}
378
- loading="lazy"
379
- />
380
- </figure>
381
- );
382
- }
383
-
384
- // Document link display when displayOnly is true and file is not an image
385
- // Render non-image files as clickable links that open in a new tab
386
- if (displayOnly && !isImage && stableFileUrl && fileReference && !showDelete) {
387
- const fileName = fileReference.file_metadata?.fileName || 'Document';
388
- const ariaLabel = `Open ${fileName} in new tab`;
389
-
390
- return (
391
- <figure className={className}>
392
- <a
393
- href={stableFileUrl || undefined}
394
- target="_blank"
395
- rel="noopener noreferrer"
396
- aria-label={ariaLabel}
397
- className="flex items-center gap-2 p-3 bg-sec-50 border border-sec-200 rounded-lg hover:bg-sec-100 transition-colors text-main-600 hover:text-main-700 focus:outline-none focus:ring-2 focus:ring-main-500 focus:ring-offset-2"
398
- >
399
- <FileText className="size-5 shrink-0" aria-hidden="true" />
400
- <span className="flex-1 font-medium truncate">
401
- {fileName}
402
- </span>
403
- <ExternalLink className="size-5 shrink-0" aria-hidden="true" />
404
- </a>
405
- {showMetadata && (
406
- <figcaption>
407
- <p>{fileName}</p>
408
- {fileReference.file_metadata.fileSize && (
409
- <p>{formatFileSize(fileReference.file_metadata.fileSize)} • {fileReference.file_metadata.fileType}</p>
410
- )}
411
- </figcaption>
412
- )}
413
- </figure>
414
- );
415
- }
416
-
417
- // Standard single file display with wrapper
418
- // For displayOnly mode, if fallback is enabled and there's no URL or image error, show fallback instead of folder icon
419
- if (displayOnly && showFallback && (!stableFileUrl || imageError || !isImage)) {
420
- return (
421
- <figure className={className} title={fileReference.file_metadata.fileName || 'File'}>
422
- <p className={fallbackClasses}>
423
- {computedFallbackText}
424
- </p>
425
- </figure>
426
- );
427
- }
428
-
429
- return (
430
- <figure className={`relative ${className}`}>
431
- {isImage && stableFileUrl && !imageError ? (
432
- <>
433
- <img
434
- key={fileReference.id}
435
- src={stableFileUrl}
436
- alt={fileReference.file_metadata.fileName || 'File'}
437
- className={imgClassName || "object-cover size-full"}
438
- onError={handleImageError}
439
- loading="lazy"
440
- />
441
- {showDelete && (
442
- <>
443
- <Button
444
- variant="destructive"
445
- size="icon"
446
- onClick={handleDeleteClick}
447
- className="absolute top-2 right-2"
448
- title="Delete file"
449
- aria-label="Delete file"
450
- >
451
- ×
452
- </Button>
453
- <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
454
- <DialogContent size="sm" title="Confirm Delete">
455
- <DialogHeader>
456
- <h2>Confirm Delete</h2>
457
- </DialogHeader>
458
- <DialogBody>
459
- <p>Are you sure you want to delete this file? This action cannot be undone.</p>
460
- </DialogBody>
461
- <DialogFooter>
462
- <Button variant="outline" onClick={() => setDeleteDialogOpen(false)}>
463
- Cancel
464
- </Button>
465
- <Button variant="destructive" onClick={handleDeleteConfirm}>
466
- Delete
467
- </Button>
468
- </DialogFooter>
469
- </DialogContent>
470
- </Dialog>
471
- </>
472
- )}
473
- {children}
474
- {showMetadata && (
475
- <figcaption>
476
- <p>{fileReference.file_metadata.fileName || 'Unknown file'}</p>
477
- {(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && (
478
- <p>
479
- {fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize)}
480
- {fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && ' • '}
481
- {fileReference.file_metadata.fileType}
482
- </p>
483
- )}
484
- </figcaption>
485
- )}
486
- </>
487
- ) : isImage && imageError && showFallback ? (
488
- // Show fallback when image fails to load and fallback is enabled
489
- <>
490
- <p className={fallbackClasses} title={fileReference.file_metadata.fileName || 'File'}>
491
- {computedFallbackText}
492
- </p>
493
- {children}
494
- {showMetadata && (
495
- <figcaption>
496
- <p>{fileReference.file_metadata.fileName || 'Unknown file'}</p>
497
- {(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && (
498
- <p>
499
- {fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize)}
500
- {fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && ' • '}
501
- {fileReference.file_metadata.fileType}
502
- </p>
503
- )}
504
- </figcaption>
505
- )}
506
- </>
507
- ) : (
508
- <>
509
- <div className="flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200">
510
- <span className="text-2xl">
511
- {getFileIcon(fileReference.file_metadata.fileType || '')}
512
- </span>
513
- {showDelete && (
514
- <>
515
- <Button
516
- variant="destructive"
517
- size="icon"
518
- onClick={handleDeleteClick}
519
- className="ml-auto"
520
- title="Delete file"
521
- aria-label="Delete file"
522
- >
523
- ×
524
- </Button>
525
- <Dialog open={deleteDialogOpen} onOpenChange={setDeleteDialogOpen}>
526
- <DialogContent size="sm" title="Confirm Delete">
527
- <DialogHeader>
528
- <h2>Confirm Delete</h2>
529
- </DialogHeader>
530
- <DialogBody>
531
- <p>Are you sure you want to delete this file? This action cannot be undone.</p>
532
- </DialogBody>
533
- <DialogFooter>
534
- <Button variant="outline" onClick={() => setDeleteDialogOpen(false)}>
535
- Cancel
536
- </Button>
537
- <Button variant="destructive" onClick={handleDeleteConfirm}>
538
- Delete
539
- </Button>
540
- </DialogFooter>
541
- </DialogContent>
542
- </Dialog>
543
- </>
544
- )}
545
- </div>
546
- {children}
547
- {showMetadata && (
548
- <figcaption>
549
- <p>{fileReference.file_metadata.fileName || 'Unknown file'}</p>
550
- {(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && (
551
- <p>
552
- {fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize)}
553
- {fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && ' • '}
554
- {fileReference.file_metadata.fileType}
555
- </p>
556
- )}
557
- </figcaption>
558
- )}
559
- </>
560
- )}
561
- </figure>
562
- );
563
- }
564
-
565
- // Multiple files display
566
- return (
567
- <figure className={`space-y-2 ${className}`}>
568
- {fileReferences.map((fileRef) => {
569
- const isImage = fileRef.file_metadata.fileType?.startsWith('image/');
570
- const fileUrl = internalFileUrls.get(fileRef.id) || null;
571
- const canDownload = !isImage && fileUrl;
572
-
573
- return (
574
- <figure key={fileRef.id} className="flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200">
575
- {isImage && fileUrl ? (
576
- <img
577
- key={fileRef.id}
578
- src={fileUrl || undefined}
579
- alt={fileRef.file_metadata.fileName || 'File'}
580
- className={imgClassName || "object-cover size-full"}
581
- onError={handleImageError}
582
- loading="lazy"
583
- />
584
- ) : (
585
- <span className="text-2xl">
586
- {getFileIcon(fileRef.file_metadata.fileType || '')}
587
- </span>
588
- )}
589
- {showMetadata && (
590
- <figcaption className="flex-1 min-w-0">
591
- <p className="font-medium text-sec-900 truncate">
592
- {fileRef.file_metadata.fileName || 'Unknown file'}
593
- </p>
594
- {(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType || fileRef.file_metadata.category) && (
595
- <p className="text-sm text-sec-500">
596
- {fileRef.file_metadata.fileSize && formatFileSize(fileRef.file_metadata.fileSize)}
597
- {fileRef.file_metadata.fileSize && fileRef.file_metadata.fileType && ' • '}
598
- {fileRef.file_metadata.fileType}
599
- {(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType) && fileRef.file_metadata.category && ' • '}
600
- {fileRef.file_metadata.category}
601
- </p>
602
- )}
603
- </figcaption>
604
- )}
605
- <div className="flex items-center space-x-2">
606
- {canDownload && (
607
- <a
608
- href={fileRef.file_path}
609
- download={fileRef.file_metadata.fileName || 'download'}
610
- className="text-main-500 hover:text-main-700 p-1"
611
- title="Download file"
612
- >
613
-
614
- </a>
615
- )}
616
- {showDelete && onDelete && (
617
- <Button
618
- variant="destructive"
619
- size="icon"
620
- onClick={handleDeleteClick}
621
- title="Delete file"
622
- aria-label="Delete file"
623
- >
624
- ×
625
- </Button>
626
- )}
627
- </div>
628
- </figure>
629
- );
630
- })}
631
- {children}
632
- </figure>
633
- );
634
- });
635
-
636
57
  /**
637
58
  * Internal component for public page context
638
59
  * Uses PublicPageContext to get Supabase client
@@ -657,14 +78,9 @@ function FileDisplayPublic({
657
78
  enableChildren,
658
79
  showMetadata
659
80
  }: FileDisplayProps) {
660
- // Call all hooks unconditionally at the top level
661
- // Hooks must be called in the same order on every render
662
81
  const publicPageContext = useContext(PublicPageContext);
663
82
  const supabase = publicPageContext?.supabase ?? null;
664
83
 
665
- // Call hook unconditionally - if supabase is null, the hook will handle it
666
- // Use a dummy supabase client if null to satisfy type requirements
667
- // The hook should handle null gracefully, but TypeScript requires a valid type
668
84
  const {
669
85
  fileUrl,
670
86
  fileReference,
@@ -678,12 +94,10 @@ function FileDisplayPublic({
678
94
  record_id,
679
95
  organisation_id,
680
96
  category,
681
- { supabase: supabase as unknown as SupabaseClient<Database> } // Type assertion needed due to type mismatch between contexts
97
+ { supabase: supabase as unknown as SupabaseClient<Database> }
682
98
  );
683
99
 
684
- // Early return after all hooks have been called
685
100
  if (!supabase) {
686
- // If fallback is enabled, show fallback UI instead of error
687
101
  if (showFallback) {
688
102
  return (
689
103
  <FileDisplayContent
@@ -714,8 +128,6 @@ function FileDisplayPublic({
714
128
  />
715
129
  );
716
130
  }
717
-
718
- // Only show error if fallback is not enabled
719
131
  return (
720
132
  <figure className={className} title="Error">
721
133
  <p className={getFallbackClasses(fallbackSize || 'md')}>
@@ -725,7 +137,6 @@ function FileDisplayPublic({
725
137
  );
726
138
  }
727
139
 
728
- // Log errors for debugging public file display issues
729
140
  if (error) {
730
141
  logger.error('FileDisplayPublic', 'Error fetching file', {
731
142
  table_name,
@@ -737,28 +148,23 @@ function FileDisplayPublic({
737
148
  });
738
149
  }
739
150
 
740
- // Public context doesn't support delete operations
741
151
  const handleDelete = async () => {
742
152
  // Delete operations are not available in public context for security reasons
743
153
  };
744
154
 
745
- // Handle displayOnly mode: select first file (prefer images) from all files
746
155
  let finalFileReference = fileReference;
747
156
  let finalFileUrl = fileUrl;
748
157
  let finalFileReferences = fileReferences;
749
158
  let finalFileCount = fileCount;
750
159
 
751
160
  if (displayOnly && !category && fileReferences.length > 0) {
752
- // Prefer image files
753
- const imageFiles = fileReferences.filter(f =>
161
+ const imageFiles = fileReferences.filter(f =>
754
162
  f.file_metadata.fileType?.startsWith('image/')
755
163
  );
756
164
  const targetFile = imageFiles.length > 0 ? imageFiles[0] : fileReferences[0];
757
165
  finalFileReference = targetFile;
758
166
  finalFileReferences = [targetFile];
759
167
  finalFileCount = 1;
760
-
761
- // Get URL for target file from fileUrls map
762
168
  finalFileUrl = fileUrls.get(targetFile.id) || null;
763
169
  }
764
170
 
@@ -773,7 +179,7 @@ function FileDisplayPublic({
773
179
  fileCount={finalFileCount}
774
180
  category={category}
775
181
  displayOnly={displayOnly}
776
- showDelete={false} // Never show delete in public context
182
+ showDelete={false}
777
183
  className={className}
778
184
  imgClassName={imgClassName}
779
185
  children={children}
@@ -817,11 +223,9 @@ function FileDisplayAuthenticated({
817
223
  showMetadata
818
224
  }: FileDisplayProps) {
819
225
  const { supabase } = useUnifiedAuth();
226
+ const [displayOnlyFileReference, setDisplayOnlyFileReference] =
227
+ useState<FileReference | null>(null);
820
228
 
821
- // Consolidated state for displayOnly mode - must be before early return
822
- const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState<FileReference | null>(null);
823
-
824
- // Call hooks before any early returns - hooks must handle null supabase gracefully
825
229
  const {
826
230
  fileUrl,
827
231
  fileReference,
@@ -831,16 +235,13 @@ function FileDisplayAuthenticated({
831
235
  isLoading,
832
236
  error,
833
237
  refetch
834
- } = useFileDisplay(
835
- table_name,
836
- record_id,
837
- organisation_id,
838
- category,
839
- { supabase: supabase || null }
840
- );
841
-
842
- // Use fileUrls map if available, otherwise use useFileUrl hook
843
- const displayOnlyFileUrlFromMap = displayOnlyFileReference ? fileUrls.get(displayOnlyFileReference.id) : null;
238
+ } = useFileDisplay(table_name, record_id, organisation_id, category, {
239
+ supabase: supabase || null
240
+ });
241
+
242
+ const displayOnlyFileUrlFromMap = displayOnlyFileReference
243
+ ? fileUrls.get(displayOnlyFileReference.id)
244
+ : null;
844
245
  const displayOnlyFileUrlHook = useFileUrl(
845
246
  displayOnlyFileReference && !displayOnlyFileUrlFromMap ? displayOnlyFileReference : null,
846
247
  {
@@ -851,23 +252,18 @@ function FileDisplayAuthenticated({
851
252
  );
852
253
  const displayOnlyFileUrl = displayOnlyFileUrlFromMap || displayOnlyFileUrlHook.url;
853
254
 
854
- // Handle displayOnly mode: select first file (prefer images) from all files
855
255
  useEffect(() => {
856
256
  if (displayOnly && !category && fileReferences.length > 0) {
857
- // Prefer image files
858
- const imageFiles = fileReferences.filter(f =>
257
+ const imageFiles = fileReferences.filter(f =>
859
258
  f.file_metadata.fileType?.startsWith('image/')
860
259
  );
861
260
  const targetFile = imageFiles.length > 0 ? imageFiles[0] : fileReferences[0];
862
261
  setDisplayOnlyFileReference(targetFile);
863
- // URL generation is handled by useFileUrl hook or fileUrls map
864
262
  } else {
865
- // Clear displayOnly files when not in displayOnly mode or when category is specified
866
263
  setDisplayOnlyFileReference(null);
867
264
  }
868
265
  }, [displayOnly, category, fileReferences, fileUrls]);
869
266
 
870
- // Early return check after all hooks are called
871
267
  if (!supabase) {
872
268
  return (
873
269
  <figure className={className} title="Error">
@@ -878,12 +274,10 @@ function FileDisplayAuthenticated({
878
274
  );
879
275
  }
880
276
 
881
- // Delete operation - implementation pending
882
277
  const handleDelete = async () => {
883
278
  // TODO: Implement delete via FileReferenceService when delete functionality is needed
884
279
  };
885
280
 
886
- // Determine final file reference and URL based on mode
887
281
  let finalFileReference = fileReference;
888
282
  let finalFileUrl = fileUrl;
889
283
  let finalFileReferences = fileReferences;
@@ -892,12 +286,10 @@ function FileDisplayAuthenticated({
892
286
  let finalError = error;
893
287
 
894
288
  if (displayOnly && !category) {
895
- // DisplayOnly mode: use state-managed file reference and URL
896
289
  finalFileReference = displayOnlyFileReference;
897
290
  finalFileUrl = displayOnlyFileUrl;
898
291
  finalFileReferences = displayOnlyFileReference ? [displayOnlyFileReference] : [];
899
292
  finalFileCount = displayOnlyFileReference ? 1 : 0;
900
- // Include URL loading state in overall loading state
901
293
  if (!displayOnlyFileUrlFromMap) {
902
294
  finalIsLoading = isLoading || displayOnlyFileUrlHook.isLoading;
903
295
  finalError = error || displayOnlyFileUrlHook.error;
@@ -935,30 +327,10 @@ function FileDisplayAuthenticated({
935
327
  );
936
328
  }
937
329
 
938
- /**
939
- * Component for displaying file references with context-awareness
940
- *
941
- * This component is context-aware and automatically detects whether it's being used
942
- * in a public or authenticated context. It fetches and displays files from storage.
943
- *
944
- * The component automatically detects context and uses:
945
- * - PublicPageProvider context for public pages
946
- * - UnifiedAuthProvider context for authenticated pages
947
- *
948
- * @param props - File display configuration
949
- * @param props.displayOnly - Display only a single file instead of all files. Uses first file (prefers images) from all files, without category filtering. When true:
950
- * - **Image files**: Renders a simplified image-only display without metadata or wrapper divs
951
- * - **Non-image files** (PDFs, Word docs, Excel files, etc.): Renders as clickable links that open in a new tab with document icon, filename, and external link icon. Links include proper security attributes (`rel="noopener noreferrer"`) and accessibility features (ARIA labels, keyboard navigation, visible focus states)
952
- * - If `showDelete={true}`, uses standard wrapper behavior instead of simplified display
953
- * @param props.category - Optional category filter. When specified, only displays files matching this category and uses single file display variant.
954
- * @returns React element with file display
955
- */
956
330
  /**
957
331
  * File display component.
958
332
  * Renders files from the file reference system with support for previews, downloads, and public/private access.
959
- *
960
- * @param props - File display configuration
961
- * @returns The rendered file display
333
+ * Context-aware: uses PublicPageProvider for public pages and UnifiedAuthProvider for authenticated pages.
962
334
  */
963
335
  export function FileDisplay({
964
336
  table_name,
@@ -980,10 +352,8 @@ export function FileDisplay({
980
352
  enableChildren,
981
353
  showMetadata
982
354
  }: FileDisplayProps) {
983
- // Check which context we're in and route to the appropriate component
984
355
  const isPublicPage = useIsPublicPage();
985
-
986
- // If we're in a public page context, use the public component
356
+
987
357
  if (isPublicPage) {
988
358
  return (
989
359
  <FileDisplayPublic
@@ -1009,8 +379,6 @@ export function FileDisplay({
1009
379
  );
1010
380
  }
1011
381
 
1012
- // Otherwise, use the authenticated component
1013
- // It will show an error if not in UnifiedAuthProvider
1014
382
  return (
1015
383
  <FileDisplayAuthenticated
1016
384
  table_name={table_name}