@jmruthers/pace-core 0.5.135 → 0.5.137
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.
- package/dist/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
- package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
- package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
- package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
- package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
- package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
- package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
- package/dist/{chunk-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
- package/dist/chunk-22WKWKRX.js.map +1 -0
- package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
- package/dist/chunk-4C7EXCAR.js.map +1 -0
- package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
- package/dist/chunk-56XJ3TU6.js.map +1 -0
- package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
- package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
- package/dist/chunk-7QCC6MCP.js.map +1 -0
- package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
- package/dist/chunk-ANBQRTPX.js.map +1 -0
- package/dist/{chunk-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
- package/dist/chunk-BCIBECNB.js.map +1 -0
- package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
- package/dist/chunk-BESYRHQM.js.map +1 -0
- package/dist/chunk-BJPBT3CU.js +21 -0
- package/dist/chunk-BJPBT3CU.js.map +1 -0
- package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
- package/dist/chunk-BLCXZEYF.js.map +1 -0
- package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
- package/dist/chunk-BVYWGZVV.js.map +1 -0
- package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
- package/dist/chunk-ERISIBYU.js.map +1 -0
- package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
- package/dist/chunk-FMUCXFII.js.map +1 -0
- package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
- package/dist/chunk-HAWZXGR2.js.map +1 -0
- package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
- package/dist/chunk-JISYG63F.js +70 -0
- package/dist/chunk-JISYG63F.js.map +1 -0
- package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
- package/dist/chunk-KYRHUBIU.js.map +1 -0
- package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
- package/dist/chunk-LS353YLY.js.map +1 -0
- package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
- package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
- package/dist/chunk-OWAG3GSU.js +58 -0
- package/dist/chunk-OWAG3GSU.js.map +1 -0
- package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
- package/dist/chunk-Q5QRDWKI.js.map +1 -0
- package/dist/chunk-S5OFRT4M.js +94 -0
- package/dist/chunk-S5OFRT4M.js.map +1 -0
- package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
- package/dist/chunk-SBVILCCA.js.map +1 -0
- package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
- package/dist/chunk-T6JN6LH6.js.map +1 -0
- package/dist/chunk-XDNLUEXI.js +138 -0
- package/dist/chunk-XDNLUEXI.js.map +1 -0
- package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
- package/dist/chunk-YCWDTTUK.js.map +1 -0
- package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
- package/dist/chunk-ZZ2SS7NI.js.map +1 -0
- package/dist/components.d.ts +7 -287
- package/dist/components.js +27 -157
- package/dist/components.js.map +1 -1
- package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
- package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +21 -16
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +101 -9
- package/dist/index.js +44 -31
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/rbac/index.js +12 -12
- package/dist/schema-DTDZQe2u.d.ts +28 -0
- package/dist/styles/index.js +2 -1
- package/dist/theming/runtime.d.ts +2 -19
- package/dist/theming/runtime.js +2 -1
- package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
- package/dist/types.d.ts +153 -4
- package/dist/types.js +51 -16
- package/dist/types.js.map +1 -1
- package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
- package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
- package/dist/utils.d.ts +221 -173
- package/dist/utils.js +185 -225
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +24 -115
- package/dist/validation.js +19 -474
- package/dist/validation.js.map +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +6 -6
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +6 -6
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +7 -7
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/BadgeProps.md +27 -0
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +29 -4
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +18 -18
- package/docs/api/interfaces/DataTableColumn.md +61 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +152 -0
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +15 -15
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- package/docs/api/interfaces/NavigationGuardProps.md +10 -10
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +7 -7
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
- package/docs/api/interfaces/PageAccessRecord.md +8 -8
- package/docs/api/interfaces/PagePermissionContextType.md +8 -8
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
- package/docs/api/interfaces/PaletteData.md +4 -4
- package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
- package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
- package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +10 -10
- package/docs/api/interfaces/RouteConfig.md +10 -10
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
- package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +591 -220
- package/docs/api-reference/components.md +106 -26
- package/docs/architecture/README.md +0 -3
- package/docs/implementation-guides/data-tables.md +277 -13
- package/docs/implementation-guides/forms.md +1 -16
- package/docs/implementation-guides/permission-enforcement.md +8 -2
- package/docs/styles/README.md +0 -2
- package/examples/README.md +30 -14
- package/examples/STRUCTURE.md +125 -0
- package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
- package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
- package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
- package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
- package/examples/components 2/DataTable/index.ts +13 -0
- package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
- package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
- package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
- package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
- package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
- package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
- package/examples/components 2/Dialog/index.ts +15 -0
- package/examples/components 2/index.ts +11 -0
- package/examples/features/index.ts +12 -0
- package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
- package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
- package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
- package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
- package/examples/features/public-pages/index.ts +14 -0
- package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
- package/examples/features/rbac/EventBasedApp.tsx +239 -0
- package/examples/features/rbac/PermissionExample.tsx +151 -0
- package/examples/features/rbac/index.ts +13 -0
- package/examples/index.ts +11 -3
- package/package.json +30 -19
- package/src/__tests__/TEST_STANDARD.md +92 -0
- package/src/components/Alert/Alert.tsx +1 -1
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Badge/Badge.test.tsx +314 -0
- package/src/components/Badge/Badge.tsx +304 -0
- package/src/components/Badge/index.ts +3 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/Checkbox/Checkbox.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +1 -1
- package/src/components/DataTable/DataTable.tsx +1 -30
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
- package/src/components/DataTable/__tests__/styles.test.ts +3 -3
- package/src/components/DataTable/components/ActionButtons.tsx +0 -15
- package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
- package/src/components/DataTable/components/DataTableBody.tsx +461 -0
- package/src/components/DataTable/components/DataTableCore.tsx +4 -185
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
- package/src/components/DataTable/components/DataTableModals.tsx +1 -27
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/FilterRow.tsx +9 -3
- package/src/components/DataTable/components/ImportModal.tsx +2 -14
- package/src/components/DataTable/components/PaginationControls.tsx +2 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
- package/src/components/DataTable/core/ActionManager.ts +235 -0
- package/src/components/DataTable/core/ColumnManager.ts +205 -0
- package/src/components/DataTable/core/DataManager.ts +188 -0
- package/src/components/DataTable/core/DataTableContext.tsx +181 -0
- package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
- package/src/components/DataTable/core/PluginRegistry.ts +229 -0
- package/src/components/DataTable/core/StateManager.ts +311 -0
- package/src/components/DataTable/core/interfaces.ts +338 -0
- package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
- package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
- package/src/components/DataTable/index.ts +4 -0
- package/src/components/DataTable/styles.ts +28 -7
- package/src/components/DataTable/types.ts +13 -0
- package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
- package/src/components/DataTable/utils/columnUtils.ts +40 -0
- package/src/components/DataTable/utils/debugTools.ts +609 -0
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +1 -11
- package/src/components/DataTable/utils/index.ts +2 -0
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
- package/src/components/EventSelector/EventSelector.tsx +3 -2
- package/src/components/FileDisplay/FileDisplay.tsx +2 -36
- package/src/components/FileUpload/FileUpload.test.tsx +2 -2
- package/src/components/FileUpload/FileUpload.tsx +2 -2
- package/src/components/Footer/Footer.test.tsx +1 -1
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +5 -510
- package/src/components/Form/Form.tsx +1 -1
- package/src/components/Form/FormField.tsx +1 -1
- package/src/components/Form/index.ts +0 -12
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/Input/Input.tsx +1 -1
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +1 -1
- package/src/components/LoginForm/LoginForm.tsx +1 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
- package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
- package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
- package/src/components/PasswordReset/index.ts +0 -2
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
- package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
- package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
- package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
- package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
- package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
- package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
- package/src/components/PublicLayout/index.ts +4 -2
- package/src/components/Select/Select.test.tsx +1 -1
- package/src/components/Select/Select.tsx +21 -9
- package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
- package/src/components/SessionRestorationLoader/index.ts +3 -0
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Table/__tests__/Table.test.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/index.ts +7 -10
- package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
- package/src/hooks/public/usePublicEvent.ts +7 -6
- package/src/hooks/public/usePublicEventLogo.ts +7 -4
- package/src/hooks/public/usePublicFileDisplay.ts +6 -150
- package/src/hooks/useComponentPerformance.ts +4 -1
- package/src/hooks/useDataTablePerformance.ts +4 -3
- package/src/hooks/useEventTheme.test.ts +18 -5
- package/src/hooks/useEventTheme.ts +4 -1
- package/src/hooks/useEvents.ts +2 -0
- package/src/hooks/useFileDisplay.ts +9 -8
- package/src/hooks/useFileReference.ts +4 -1
- package/src/hooks/useFileUrl.ts +4 -1
- package/src/hooks/useInactivityTracker.ts +5 -4
- package/src/hooks/useOrganisationSecurity.test.ts +33 -12
- package/src/hooks/useOrganisationSecurity.ts +8 -7
- package/src/hooks/usePerformanceMonitor.ts +6 -3
- package/src/hooks/usePermissionCache.ts +13 -6
- package/src/hooks/useSecureDataAccess.test.ts +2 -2
- package/src/hooks/useSecureDataAccess.ts +9 -8
- package/src/hooks/useSessionRestoration.ts +4 -1
- package/src/hooks/useStorage.ts +4 -1
- package/src/index.ts +20 -7
- package/src/providers/services/AuthServiceProvider.tsx +3 -2
- package/src/providers/services/EventServiceProvider.tsx +2 -1
- package/src/providers/services/InactivityServiceProvider.tsx +2 -1
- package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
- package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
- package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
- package/src/rbac/api.ts +5 -2
- package/src/rbac/audit-enhanced.ts +6 -6
- package/src/rbac/audit.test.ts +60 -38
- package/src/rbac/audit.ts +8 -8
- package/src/rbac/cache-invalidation.ts +7 -4
- package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
- package/src/rbac/components/NavigationGuard.tsx +7 -3
- package/src/rbac/components/NavigationProvider.tsx +6 -3
- package/src/rbac/components/PagePermissionGuard.tsx +28 -16
- package/src/rbac/components/PagePermissionProvider.tsx +4 -1
- package/src/rbac/components/PermissionEnforcer.tsx +9 -3
- package/src/rbac/components/RoleBasedRouter.tsx +3 -1
- package/src/rbac/components/SecureDataProvider.tsx +7 -3
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
- package/src/rbac/engine.ts +15 -7
- package/src/rbac/hooks/usePermissions.ts +7 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
- package/src/rbac/hooks/useResolvedScope.ts +10 -7
- package/src/rbac/permissions.ts +5 -2
- package/src/rbac/security.test.ts +27 -16
- package/src/rbac/security.ts +5 -4
- package/src/services/AuthService.ts +22 -21
- package/src/services/EventService.ts +12 -12
- package/src/services/InactivityService.ts +5 -4
- package/src/services/OrganisationService.ts +26 -25
- package/src/services/__tests__/AuthService.test.ts +51 -19
- package/src/services/__tests__/EventService.test.ts +37 -5
- package/src/services/__tests__/InactivityService.test.ts +38 -4
- package/src/services/__tests__/OrganisationService.test.ts +3 -8
- package/src/services/base/BaseService.ts +3 -1
- package/src/styles/core.css +3 -0
- package/src/theming/__tests__/runtime.test.ts +21 -12
- package/src/theming/parseEventColours.ts +5 -19
- package/src/theming/runtime.ts +8 -4
- package/src/types/validation.ts +2 -29
- package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
- package/src/utils/__tests__/audit.unit.test.ts +1 -1
- package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
- package/src/utils/__tests__/cn.unit.test.ts +1 -1
- package/src/utils/__tests__/debugLogger.test.ts +1 -1
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/formatting.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
- package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
- package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
- package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
- package/src/utils/__tests__/security.unit.test.ts +40 -18
- package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
- package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
- package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
- package/src/utils/app/appConfig.ts +47 -0
- package/src/utils/app/appIdResolver.test.ts +497 -0
- package/src/utils/app/appIdResolver.ts +133 -0
- package/src/utils/app/appNameResolver.simple.test.ts +212 -0
- package/src/utils/app/appNameResolver.test.ts +121 -0
- package/src/utils/app/appNameResolver.ts +195 -0
- package/src/utils/audit/audit.ts +127 -0
- package/src/utils/context/organisationContext.test.ts +322 -0
- package/src/utils/context/organisationContext.ts +156 -0
- package/src/utils/context/sessionTracking.ts +125 -0
- package/src/utils/core/cn.ts +7 -0
- package/src/utils/core/debugLogger.ts +67 -0
- package/src/utils/core/logger.ts +181 -0
- package/src/utils/device/deviceFingerprint.ts +215 -0
- package/src/utils/dynamic/dynamicUtils.ts +105 -0
- package/src/utils/dynamic/lazyLoad.tsx +44 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
- package/src/utils/file-reference/index.ts +501 -0
- package/src/utils/formatting/formatDate.test.ts +237 -0
- package/src/utils/formatting/formatting.ts +133 -0
- package/src/utils/index.ts +39 -54
- package/src/utils/performance/bundleAnalysis.ts +129 -0
- package/src/utils/performance/performanceBenchmark.ts +64 -0
- package/src/utils/performance/performanceBudgets.ts +110 -0
- package/src/utils/permissions/permissionTypes.ts +37 -0
- package/src/utils/permissions/permissionUtils.test.ts +393 -0
- package/src/utils/permissions/permissionUtils.ts +34 -0
- package/src/utils/security/auth-utils.ts +96 -0
- package/src/utils/security/secureDataAccess.test.ts +711 -0
- package/src/utils/security/secureDataAccess.ts +377 -0
- package/src/utils/security/secureErrors.ts +82 -0
- package/src/utils/security/secureStorage.ts +244 -0
- package/src/utils/security/security.ts +159 -0
- package/src/utils/security/securityMonitor.ts +45 -0
- package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
- package/src/utils/storage/helpers.ts +15 -8
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
- package/src/{validation → utils/validation}/csrf.ts +1 -1
- package/src/utils/validation/htmlSanitization.ts +184 -0
- package/src/utils/validation/index.ts +79 -0
- package/src/utils/validation/sanitization.ts +333 -0
- package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
- package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
- package/src/utils/validation/validation.ts +111 -0
- package/src/utils/validation/validationUtils.ts +123 -0
- package/src/validation/index.ts +3 -34
- package/dist/chunk-24MKLB7U.js +0 -81
- package/dist/chunk-24MKLB7U.js.map +0 -1
- package/dist/chunk-3CG5L6RN.js.map +0 -1
- package/dist/chunk-3DBFLLLU.js.map +0 -1
- package/dist/chunk-5F3NDPJV.js.map +0 -1
- package/dist/chunk-66C4BSAY.js.map +0 -1
- package/dist/chunk-BDZUMRBD.js +0 -87
- package/dist/chunk-BDZUMRBD.js.map +0 -1
- package/dist/chunk-BYXRHAIF.js.map +0 -1
- package/dist/chunk-CDQ3PX7L.js +0 -18
- package/dist/chunk-CDQ3PX7L.js.map +0 -1
- package/dist/chunk-CQZU6TFE.js.map +0 -1
- package/dist/chunk-F64FFPOZ.js.map +0 -1
- package/dist/chunk-GEVIB2UB.js.map +0 -1
- package/dist/chunk-GKHF54DI.js.map +0 -1
- package/dist/chunk-GVDR7WNV.js.map +0 -1
- package/dist/chunk-HMNOSGVA.js.map +0 -1
- package/dist/chunk-JCQZ6LA7.js.map +0 -1
- package/dist/chunk-M6DDYFUD.js.map +0 -1
- package/dist/chunk-O3NWNXDY.js.map +0 -1
- package/dist/chunk-PYUXFQJ3.js.map +0 -1
- package/dist/chunk-UJI6WSMD.js.map +0 -1
- package/dist/chunk-VZ5OR6HD.js.map +0 -1
- package/dist/chunk-WP5I5GLN.js.map +0 -1
- package/dist/chunk-ZYZCRSBD.js.map +0 -1
- package/dist/validation-DnhrNMju.d.ts +0 -159
- package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
- package/src/validation/__tests__/common.unit.test.ts +0 -101
- package/src/validation/__tests__/csrf.unit.test.ts +0 -365
- package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
- package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
- package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
- package/src/validation/__tests__/user.unit.test.ts +0 -440
- package/src/validation/sanitization.ts +0 -96
- /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
- /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
- /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
- /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
- /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
- /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
- /package/src/{validation → utils/validation}/common.ts +0 -0
- /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
- /package/src/{validation → utils/validation}/user.ts +0 -0
|
@@ -16,7 +16,7 @@ let mockPerformanceNowValue = 0;
|
|
|
16
16
|
const mockPerformanceNow = vi.fn(() => mockPerformanceNowValue);
|
|
17
17
|
|
|
18
18
|
// Mock performanceBudgetMonitor
|
|
19
|
-
vi.mock('../../utils/performanceBudgets', () => ({
|
|
19
|
+
vi.mock('../../utils/performance/performanceBudgets', () => ({
|
|
20
20
|
performanceBudgetMonitor: {
|
|
21
21
|
measure: vi.fn(() => ({
|
|
22
22
|
passed: true,
|
|
@@ -30,7 +30,21 @@ vi.mock('../../utils/performanceBudgets', () => ({
|
|
|
30
30
|
},
|
|
31
31
|
}));
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// Mock the Logger module
|
|
34
|
+
vi.mock('../../utils/core/logger', () => {
|
|
35
|
+
const mockLoggerInstance = {
|
|
36
|
+
warn: vi.fn(),
|
|
37
|
+
};
|
|
38
|
+
return {
|
|
39
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Get the mock instance after mock is set up
|
|
44
|
+
import { createLogger as createLoggerImport } from '../../utils/core/logger';
|
|
45
|
+
const getMockLogger = () => createLoggerImport('test');
|
|
46
|
+
|
|
47
|
+
import { performanceBudgetMonitor } from '../../utils/performance/performanceBudgets';
|
|
34
48
|
|
|
35
49
|
// Mock window.performance
|
|
36
50
|
Object.defineProperty(window, 'performance', {
|
|
@@ -458,7 +472,7 @@ describe('usePerformanceMonitor', () => {
|
|
|
458
472
|
});
|
|
459
473
|
|
|
460
474
|
it('logs warning when budget is exceeded in development', () => {
|
|
461
|
-
|
|
475
|
+
vi.clearAllMocks();
|
|
462
476
|
|
|
463
477
|
vi.mocked(performanceBudgetMonitor.measure).mockReturnValue({
|
|
464
478
|
passed: false,
|
|
@@ -492,11 +506,10 @@ describe('usePerformanceMonitor', () => {
|
|
|
492
506
|
result2.current.endMeasurement();
|
|
493
507
|
});
|
|
494
508
|
|
|
495
|
-
|
|
509
|
+
const logger = getMockLogger();
|
|
510
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
496
511
|
expect.stringContaining('Performance budget exceeded')
|
|
497
512
|
);
|
|
498
|
-
|
|
499
|
-
consoleWarnSpy.mockRestore();
|
|
500
513
|
});
|
|
501
514
|
});
|
|
502
515
|
|
|
@@ -15,6 +15,20 @@ vi.mock('../../rbac/api', async () => {
|
|
|
15
15
|
};
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
// Mock logger
|
|
19
|
+
vi.mock('../../utils/core/logger', () => {
|
|
20
|
+
const mockLoggerInstance = {
|
|
21
|
+
debug: vi.fn(),
|
|
22
|
+
info: vi.fn(),
|
|
23
|
+
warn: vi.fn(),
|
|
24
|
+
error: vi.fn(),
|
|
25
|
+
};
|
|
26
|
+
return {
|
|
27
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
28
|
+
logger: mockLoggerInstance,
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
|
|
18
32
|
// Mock useOrganisations hook (required by usePermissionCache)
|
|
19
33
|
const mockOrganisationContext = {
|
|
20
34
|
selectedOrganisation: {
|
|
@@ -115,7 +129,7 @@ describe('usePermissionCache - Simple Tests', () => {
|
|
|
115
129
|
});
|
|
116
130
|
|
|
117
131
|
it('should handle permission check errors gracefully', async () => {
|
|
118
|
-
const
|
|
132
|
+
const { logger } = await import('../../utils/core/logger');
|
|
119
133
|
mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
|
|
120
134
|
|
|
121
135
|
mockUseRBAC.mockReturnValue({
|
|
@@ -130,9 +144,8 @@ describe('usePermissionCache - Simple Tests', () => {
|
|
|
130
144
|
const permission = await result.current.checkPermission('read', 'dashboard');
|
|
131
145
|
|
|
132
146
|
expect(permission).toBe(false);
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
consoleSpy.mockRestore();
|
|
147
|
+
// Verify error was logged using logger
|
|
148
|
+
expect(logger.error).toHaveBeenCalled();
|
|
136
149
|
});
|
|
137
150
|
|
|
138
151
|
it('should provide debug information', () => {
|
|
@@ -26,6 +26,20 @@ vi.mock('../../rbac/api', async () => {
|
|
|
26
26
|
};
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
// Mock logger
|
|
30
|
+
vi.mock('../../utils/core/logger', () => {
|
|
31
|
+
const mockLoggerInstance = {
|
|
32
|
+
debug: vi.fn(),
|
|
33
|
+
info: vi.fn(),
|
|
34
|
+
warn: vi.fn(),
|
|
35
|
+
error: vi.fn(),
|
|
36
|
+
};
|
|
37
|
+
return {
|
|
38
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
39
|
+
logger: mockLoggerInstance,
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
|
|
29
43
|
// Mock useOrganisations hook (required by usePermissionCache)
|
|
30
44
|
const mockOrganisationContext = {
|
|
31
45
|
selectedOrganisation: {
|
|
@@ -184,7 +198,7 @@ describe('usePermissionCache', () => {
|
|
|
184
198
|
});
|
|
185
199
|
|
|
186
200
|
it('handles permission check errors gracefully', async () => {
|
|
187
|
-
const
|
|
201
|
+
const { logger } = await import('../../utils/core/logger');
|
|
188
202
|
mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
|
|
189
203
|
|
|
190
204
|
mockUseRBAC.mockReturnValue({
|
|
@@ -199,9 +213,8 @@ describe('usePermissionCache', () => {
|
|
|
199
213
|
const permission = await result.current.checkPermission('read', 'dashboard');
|
|
200
214
|
|
|
201
215
|
expect(permission).toBe(false);
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
consoleSpy.mockRestore();
|
|
216
|
+
// Verify error was logged using logger
|
|
217
|
+
expect(logger.error).toHaveBeenCalled();
|
|
205
218
|
});
|
|
206
219
|
});
|
|
207
220
|
|
|
@@ -41,7 +41,21 @@ vi.mock('@supabase/supabase-js', () => ({
|
|
|
41
41
|
const originalEnv = import.meta.env;
|
|
42
42
|
|
|
43
43
|
describe('usePublicEvent - Simple Tests', () => {
|
|
44
|
+
let originalMode: string | undefined;
|
|
45
|
+
|
|
44
46
|
beforeEach(() => {
|
|
47
|
+
// Ensure logger is enabled by setting MODE to development
|
|
48
|
+
originalMode = import.meta.env.MODE;
|
|
49
|
+
(import.meta.env as any).MODE = 'development';
|
|
50
|
+
|
|
51
|
+
import('../../utils/core/logger').then(({ Logger, LogLevel }) => {
|
|
52
|
+
Logger.configure({
|
|
53
|
+
level: LogLevel.DEBUG,
|
|
54
|
+
includeTimestamp: false,
|
|
55
|
+
includeComponent: true,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
45
59
|
vi.clearAllMocks();
|
|
46
60
|
clearPublicEventCache();
|
|
47
61
|
|
|
@@ -62,6 +76,10 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
62
76
|
});
|
|
63
77
|
|
|
64
78
|
afterEach(() => {
|
|
79
|
+
// Restore original mode
|
|
80
|
+
if (originalMode !== undefined) {
|
|
81
|
+
(import.meta.env as any).MODE = originalMode;
|
|
82
|
+
}
|
|
65
83
|
vi.clearAllMocks();
|
|
66
84
|
clearPublicEventCache();
|
|
67
85
|
Object.defineProperty(import.meta, 'env', {
|
|
@@ -623,7 +641,7 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
623
641
|
expect(result.current.error).toEqual(new Error('Event not found'));
|
|
624
642
|
});
|
|
625
643
|
|
|
626
|
-
it('handles missing Supabase environment variables', () => {
|
|
644
|
+
it('handles missing Supabase environment variables', async () => {
|
|
627
645
|
// Mock usePublicPageContext to return null environment
|
|
628
646
|
vi.mocked(usePublicPageContext).mockReturnValue({
|
|
629
647
|
environment: {
|
|
@@ -638,20 +656,22 @@ describe('usePublicEvent - Simple Tests', () => {
|
|
|
638
656
|
writable: true
|
|
639
657
|
});
|
|
640
658
|
|
|
641
|
-
const
|
|
659
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
642
660
|
|
|
643
661
|
const { result } = renderHook(() => usePublicEvent('test-event'));
|
|
644
662
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
663
|
+
await waitFor(() => {
|
|
664
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
665
|
+
expect.stringContaining('[WARN] [usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.')
|
|
666
|
+
);
|
|
667
|
+
}, { timeout: 2000 });
|
|
648
668
|
|
|
649
669
|
// Should still initialize but with error
|
|
650
670
|
expect(result.current.isLoading).toBe(false);
|
|
651
671
|
expect(result.current.error).toBeInstanceOf(Error);
|
|
652
672
|
expect(result.current.error?.message).toContain('Invalid event code or Supabase client not available');
|
|
653
673
|
|
|
654
|
-
|
|
674
|
+
consoleWarnSpy.mockRestore();
|
|
655
675
|
});
|
|
656
676
|
|
|
657
677
|
it('handles server-side rendering (window undefined)', () => {
|
|
@@ -26,6 +26,16 @@ vi.mock('../../utils/storage/helpers', () => ({
|
|
|
26
26
|
getPublicUrl: vi.fn((supabase: any, path: string) => `https://example.com/${path}`)
|
|
27
27
|
}));
|
|
28
28
|
|
|
29
|
+
// Mock logger
|
|
30
|
+
vi.mock('../../utils/core/logger', () => ({
|
|
31
|
+
logger: {
|
|
32
|
+
debug: vi.fn(),
|
|
33
|
+
info: vi.fn(),
|
|
34
|
+
warn: vi.fn(),
|
|
35
|
+
error: vi.fn(),
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
|
|
29
39
|
import { getPublicUrl } from '../../utils/storage/helpers';
|
|
30
40
|
|
|
31
41
|
describe('usePublicFileDisplay Hook', () => {
|
|
@@ -618,7 +628,7 @@ describe('usePublicFileDisplay Hook', () => {
|
|
|
618
628
|
});
|
|
619
629
|
|
|
620
630
|
it('validates UUID format for organisation_id', async () => {
|
|
621
|
-
const
|
|
631
|
+
const { logger } = await import('../../utils/core/logger');
|
|
622
632
|
|
|
623
633
|
(mockSupabase.rpc as any).mockResolvedValue({
|
|
624
634
|
data: [],
|
|
@@ -638,12 +648,12 @@ describe('usePublicFileDisplay Hook', () => {
|
|
|
638
648
|
{ timeout: 2000 }
|
|
639
649
|
);
|
|
640
650
|
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
'
|
|
651
|
+
// Verify warning was logged using logger
|
|
652
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
653
|
+
'usePublicFileDisplay',
|
|
654
|
+
'Invalid organisationId format (not a valid UUID)',
|
|
655
|
+
{ organisation_id: 'invalid-uuid' }
|
|
644
656
|
);
|
|
645
|
-
|
|
646
|
-
consoleSpy.mockRestore();
|
|
647
657
|
});
|
|
648
658
|
});
|
|
649
659
|
|
|
@@ -18,7 +18,7 @@ vi.mock('../../hooks/useOrganisations', () => ({
|
|
|
18
18
|
useOrganisations: vi.fn(),
|
|
19
19
|
}));
|
|
20
20
|
|
|
21
|
-
vi.mock('../../utils/organisationContext', () => ({
|
|
21
|
+
vi.mock('../../utils/context/organisationContext', () => ({
|
|
22
22
|
setOrganisationContext: vi.fn().mockResolvedValue(undefined),
|
|
23
23
|
}));
|
|
24
24
|
|
|
@@ -621,8 +621,8 @@ describe('useSecureDataAccess', () => {
|
|
|
621
621
|
organisation_id: 'org-123'
|
|
622
622
|
})
|
|
623
623
|
);
|
|
624
|
-
// Verify RPC was called correctly
|
|
625
|
-
expect(mockSupabase.rpc).
|
|
624
|
+
// Verify RPC was called correctly (may be called multiple times due to React strict mode or other effects)
|
|
625
|
+
expect(mockSupabase.rpc).toHaveBeenCalled();
|
|
626
626
|
|
|
627
627
|
consoleSpy.mockRestore();
|
|
628
628
|
});
|
|
@@ -14,6 +14,20 @@ import { useSessionRestoration } from '../useSessionRestoration';
|
|
|
14
14
|
import { AuthServiceContext } from '../../providers/services/AuthServiceProvider';
|
|
15
15
|
import type { SessionRestorationState } from '../../types/auth';
|
|
16
16
|
|
|
17
|
+
// Mock the Logger module
|
|
18
|
+
vi.mock('../../utils/core/logger', () => {
|
|
19
|
+
const mockLoggerInstance = {
|
|
20
|
+
warn: vi.fn(),
|
|
21
|
+
};
|
|
22
|
+
return {
|
|
23
|
+
createLogger: vi.fn(() => mockLoggerInstance),
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Get the mock instance after mock is set up
|
|
28
|
+
import { createLogger } from '../../utils/core/logger';
|
|
29
|
+
const getMockLogger = () => createLogger('test');
|
|
30
|
+
|
|
17
31
|
const SESSION_RESTORATION_TIMEOUT_MS = 5000;
|
|
18
32
|
|
|
19
33
|
describe('useSessionRestoration', () => {
|
|
@@ -30,7 +44,6 @@ describe('useSessionRestoration', () => {
|
|
|
30
44
|
beforeEach(() => {
|
|
31
45
|
vi.clearAllMocks();
|
|
32
46
|
vi.useFakeTimers();
|
|
33
|
-
vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
34
47
|
|
|
35
48
|
mockContext = {
|
|
36
49
|
sessionRestoration: {
|
|
@@ -128,8 +141,9 @@ describe('useSessionRestoration', () => {
|
|
|
128
141
|
// With fake timers, the timeout should fire immediately
|
|
129
142
|
expect(result.current.hasTimedOut).toBe(true);
|
|
130
143
|
|
|
131
|
-
|
|
132
|
-
|
|
144
|
+
const logger = getMockLogger();
|
|
145
|
+
expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
|
|
146
|
+
'Session restoration timed out'
|
|
133
147
|
);
|
|
134
148
|
});
|
|
135
149
|
|
|
@@ -64,6 +64,7 @@ import { createClient } from '@supabase/supabase-js';
|
|
|
64
64
|
import type { Event } from '../../types/unified';
|
|
65
65
|
import type { Database } from '../../types/database';
|
|
66
66
|
import { usePublicPageContext } from '../../components/PublicLayout/PublicPageProvider';
|
|
67
|
+
import { logger } from '../../utils/core/logger';
|
|
67
68
|
|
|
68
69
|
// Simple in-memory cache for public data
|
|
69
70
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
@@ -127,7 +128,7 @@ export function usePublicEvent(
|
|
|
127
128
|
if (typeof window === 'undefined') return null;
|
|
128
129
|
|
|
129
130
|
if (!environment.supabaseUrl || !environment.supabaseKey) {
|
|
130
|
-
|
|
131
|
+
logger.warn('usePublicEvent', 'Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');
|
|
131
132
|
return null;
|
|
132
133
|
}
|
|
133
134
|
|
|
@@ -141,7 +142,7 @@ export function usePublicEvent(
|
|
|
141
142
|
await (supabase as any).from('information_schema.routines').select('routine_name').limit(1);
|
|
142
143
|
} catch (error) {
|
|
143
144
|
// Ignore errors, this is just an attempt to refresh cache
|
|
144
|
-
|
|
145
|
+
logger.debug('usePublicEvent', 'Schema cache refresh attempt failed:', error);
|
|
145
146
|
}
|
|
146
147
|
}, [supabase]);
|
|
147
148
|
|
|
@@ -184,7 +185,7 @@ export function usePublicEvent(
|
|
|
184
185
|
if (rpcError.message?.includes('Could not find the function') ||
|
|
185
186
|
rpcError.message?.includes('does not exist') ||
|
|
186
187
|
rpcError.message?.includes('schema cache')) {
|
|
187
|
-
|
|
188
|
+
logger.warn('usePublicEvent', 'RPC function not found or schema cache issue, attempting refresh:', rpcError.message);
|
|
188
189
|
|
|
189
190
|
// Try to refresh schema cache first
|
|
190
191
|
await refreshSchemaCache();
|
|
@@ -204,7 +205,7 @@ export function usePublicEvent(
|
|
|
204
205
|
throw new Error('RPC still failing after cache refresh');
|
|
205
206
|
}
|
|
206
207
|
} catch (retryError) {
|
|
207
|
-
|
|
208
|
+
logger.warn('usePublicEvent', 'RPC still failing after cache refresh, falling back to direct table access');
|
|
208
209
|
|
|
209
210
|
// Fallback: Direct table access with public RLS policy
|
|
210
211
|
const tableResponse2 = await (supabase as any)
|
|
@@ -281,7 +282,7 @@ export function usePublicEvent(
|
|
|
281
282
|
}
|
|
282
283
|
} catch (rpcError) {
|
|
283
284
|
// If RPC call fails for any reason (including schema cache issues), try direct table access
|
|
284
|
-
|
|
285
|
+
logger.warn('usePublicEvent', 'RPC call failed, falling back to direct table access:', rpcError);
|
|
285
286
|
|
|
286
287
|
const tableResponse = await (supabase as any)
|
|
287
288
|
.from('event')
|
|
@@ -372,7 +373,7 @@ export function usePublicEvent(
|
|
|
372
373
|
}
|
|
373
374
|
|
|
374
375
|
} catch (err) {
|
|
375
|
-
|
|
376
|
+
logger.error('usePublicEvent', 'Error fetching event:', err);
|
|
376
377
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
377
378
|
setError(error);
|
|
378
379
|
setEvent(null);
|
|
@@ -67,6 +67,9 @@
|
|
|
67
67
|
import { useState, useEffect, useCallback, useMemo } from 'react';
|
|
68
68
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
69
69
|
import type { Database } from '../../types/database';
|
|
70
|
+
import { createLogger } from '../../utils/core/logger';
|
|
71
|
+
|
|
72
|
+
const log = createLogger('usePublicEventLogo');
|
|
70
73
|
|
|
71
74
|
// Simple in-memory cache for public data
|
|
72
75
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
@@ -155,7 +158,7 @@ export function usePublicEventLogo(
|
|
|
155
158
|
// Validate UUID format for organisationId to prevent database errors
|
|
156
159
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
157
160
|
if (!uuidRegex.test(organisationId)) {
|
|
158
|
-
|
|
161
|
+
log.warn('Invalid organisationId format (not a valid UUID):', organisationId);
|
|
159
162
|
// Don't return early - let the database handle the validation
|
|
160
163
|
// This allows for more graceful error handling
|
|
161
164
|
}
|
|
@@ -198,12 +201,12 @@ export function usePublicEventLogo(
|
|
|
198
201
|
try {
|
|
199
202
|
const response = await fetch(logoUrl, { method: 'HEAD' });
|
|
200
203
|
if (!response.ok) {
|
|
201
|
-
|
|
204
|
+
log.warn('Logo URL not accessible:', logoUrl);
|
|
202
205
|
setLogoUrl(null);
|
|
203
206
|
return;
|
|
204
207
|
}
|
|
205
208
|
} catch (fetchError) {
|
|
206
|
-
|
|
209
|
+
log.warn('Error validating logo URL:', fetchError);
|
|
207
210
|
setLogoUrl(null);
|
|
208
211
|
return;
|
|
209
212
|
}
|
|
@@ -221,7 +224,7 @@ export function usePublicEventLogo(
|
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
} catch (err) {
|
|
224
|
-
|
|
227
|
+
log.error('Error fetching logo:', err);
|
|
225
228
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
226
229
|
setError(error);
|
|
227
230
|
setLogoUrl(null);
|
|
@@ -36,11 +36,12 @@
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
-
import { useState, useEffect, useCallback
|
|
39
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
40
40
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
41
41
|
import type { Database } from '../../types/database';
|
|
42
42
|
import { FileReference, FileCategory } from '../../types/file-reference';
|
|
43
43
|
import { getPublicUrl } from '../../utils/storage/helpers';
|
|
44
|
+
import { logger } from '../../utils/core/logger';
|
|
44
45
|
|
|
45
46
|
// Simple in-memory cache for public file data
|
|
46
47
|
const publicFileCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
@@ -121,7 +122,7 @@ export function usePublicFileDisplay(
|
|
|
121
122
|
// Validate UUID format for organisationId to prevent database errors
|
|
122
123
|
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
123
124
|
if (!uuidRegex.test(organisation_id)) {
|
|
124
|
-
|
|
125
|
+
logger.warn('usePublicFileDisplay', 'Invalid organisationId format (not a valid UUID)', { organisation_id });
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
// Check cache first
|
|
@@ -158,53 +159,11 @@ export function usePublicFileDisplay(
|
|
|
158
159
|
p_organisation_id: organisation_id
|
|
159
160
|
};
|
|
160
161
|
|
|
161
|
-
// Step 1: Log RPC call parameters with full context
|
|
162
|
-
console.log('[usePublicFileDisplay] RPC Call Parameters:', {
|
|
163
|
-
function: 'data_file_reference_by_category_list',
|
|
164
|
-
parameters: rpcParams,
|
|
165
|
-
supabaseClient: {
|
|
166
|
-
available: !!supabase,
|
|
167
|
-
hasAuth: !!supabase?.auth
|
|
168
|
-
},
|
|
169
|
-
context: 'public_page_anonymous_user',
|
|
170
|
-
note: 'Public pages use anonymous Supabase client (no user session)'
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
console.log('[usePublicFileDisplay] Using RPC function for category filtering:', {
|
|
174
|
-
table_name,
|
|
175
|
-
record_id,
|
|
176
|
-
category,
|
|
177
|
-
organisation_id
|
|
178
|
-
});
|
|
179
|
-
|
|
180
162
|
const { data, error: rpcError } = await (supabase as any)
|
|
181
163
|
.rpc('data_file_reference_by_category_list', rpcParams);
|
|
182
164
|
|
|
183
|
-
// Step 2: Log RPC response immediately after call
|
|
184
|
-
console.log('[usePublicFileDisplay] RPC Response:', {
|
|
185
|
-
function: 'data_file_reference_by_category_list',
|
|
186
|
-
dataType: Array.isArray(data) ? 'array' : typeof data,
|
|
187
|
-
dataLength: Array.isArray(data) ? data.length : (data ? 1 : 0),
|
|
188
|
-
dataIsNull: data === null,
|
|
189
|
-
dataIsUndefined: data === undefined,
|
|
190
|
-
dataIsEmpty: Array.isArray(data) ? data.length === 0 : !data,
|
|
191
|
-
firstItem: Array.isArray(data) && data.length > 0 ? {
|
|
192
|
-
id: data[0].id,
|
|
193
|
-
file_path: data[0].file_path,
|
|
194
|
-
is_public: data[0].is_public,
|
|
195
|
-
has_metadata: !!data[0].file_metadata,
|
|
196
|
-
category_in_metadata: data[0].file_metadata?.category
|
|
197
|
-
} : null,
|
|
198
|
-
error: rpcError ? {
|
|
199
|
-
message: rpcError.message,
|
|
200
|
-
code: rpcError.code,
|
|
201
|
-
details: rpcError.details,
|
|
202
|
-
hint: rpcError.hint
|
|
203
|
-
} : null
|
|
204
|
-
});
|
|
205
|
-
|
|
206
165
|
if (rpcError) {
|
|
207
|
-
|
|
166
|
+
logger.error('usePublicFileDisplay', 'RPC function error', {
|
|
208
167
|
function: 'data_file_reference_by_category_list',
|
|
209
168
|
table_name,
|
|
210
169
|
record_id,
|
|
@@ -224,28 +183,6 @@ export function usePublicFileDisplay(
|
|
|
224
183
|
if (!data || data.length === 0) {
|
|
225
184
|
files = [];
|
|
226
185
|
} else {
|
|
227
|
-
// Step 3: Log data transformation - analyze files before filtering
|
|
228
|
-
const totalFilesFromRPC = data.length;
|
|
229
|
-
const filesWithIsPublic = data.filter((item: any) => item.is_public === true).length;
|
|
230
|
-
const filesWithIsPublicFalse = data.filter((item: any) => item.is_public === false).length;
|
|
231
|
-
const filesWithIsPublicNull = data.filter((item: any) => item.is_public === null || item.is_public === undefined).length;
|
|
232
|
-
const filesWithValidStructure = data.filter((item: any) => item.id && item.file_path && item.file_metadata).length;
|
|
233
|
-
|
|
234
|
-
console.log('[usePublicFileDisplay] RPC Data Analysis (before filtering):', {
|
|
235
|
-
totalFilesFromRPC,
|
|
236
|
-
filesWithIsPublicTrue: filesWithIsPublic,
|
|
237
|
-
filesWithIsPublicFalse,
|
|
238
|
-
filesWithIsPublicNull,
|
|
239
|
-
filesWithValidStructure,
|
|
240
|
-
sampleItems: data.slice(0, 2).map((item: any) => ({
|
|
241
|
-
id: item.id,
|
|
242
|
-
is_public: item.is_public,
|
|
243
|
-
has_id: !!item.id,
|
|
244
|
-
has_file_path: !!item.file_path,
|
|
245
|
-
has_metadata: !!item.file_metadata
|
|
246
|
-
}))
|
|
247
|
-
});
|
|
248
|
-
|
|
249
186
|
// Construct file reference objects from RPC response
|
|
250
187
|
// This avoids RLS issues - the RPC already validated permissions and filtered public files
|
|
251
188
|
files = data
|
|
@@ -268,18 +205,6 @@ export function usePublicFileDisplay(
|
|
|
268
205
|
updated_at: item.created_at || new Date().toISOString()
|
|
269
206
|
};
|
|
270
207
|
});
|
|
271
|
-
|
|
272
|
-
// Step 3: Log after filtering
|
|
273
|
-
console.log('[usePublicFileDisplay] Data Transformation (after filtering):', {
|
|
274
|
-
filesBeforeFilter: totalFilesFromRPC,
|
|
275
|
-
filesAfterFilter: files.length,
|
|
276
|
-
constructedFileReferences: files.map(f => ({
|
|
277
|
-
id: f.id,
|
|
278
|
-
file_path: f.file_path,
|
|
279
|
-
organisation_id: f.organisation_id,
|
|
280
|
-
is_public: f.is_public
|
|
281
|
-
}))
|
|
282
|
-
});
|
|
283
208
|
}
|
|
284
209
|
} else {
|
|
285
210
|
// Multiple files mode - use RPC to get all files
|
|
@@ -291,7 +216,7 @@ export function usePublicFileDisplay(
|
|
|
291
216
|
});
|
|
292
217
|
|
|
293
218
|
if (rpcError) {
|
|
294
|
-
|
|
219
|
+
logger.error('usePublicFileDisplay', 'RPC function error', {
|
|
295
220
|
function: 'data_file_reference_list',
|
|
296
221
|
table_name,
|
|
297
222
|
record_id,
|
|
@@ -327,75 +252,6 @@ export function usePublicFileDisplay(
|
|
|
327
252
|
const publicFiles = files.filter((f: any) => f.is_public === true);
|
|
328
253
|
|
|
329
254
|
if (publicFiles.length === 0) {
|
|
330
|
-
console.log('[usePublicFileDisplay] No public files found:', {
|
|
331
|
-
table_name,
|
|
332
|
-
record_id,
|
|
333
|
-
category,
|
|
334
|
-
organisation_id,
|
|
335
|
-
totalFilesFound: files.length,
|
|
336
|
-
note: 'This is expected if no public files exist. Fallback UI will be shown if showFallback is enabled.'
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
// Step 5: Add database query verification (for debugging only)
|
|
340
|
-
// This helps determine if files exist but RPC is filtering them out
|
|
341
|
-
try {
|
|
342
|
-
console.log('[usePublicFileDisplay] Database Query Verification (debugging):', {
|
|
343
|
-
note: 'Performing direct query to verify if files exist in database',
|
|
344
|
-
table_name,
|
|
345
|
-
record_id,
|
|
346
|
-
organisation_id,
|
|
347
|
-
category
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
// Direct query to check if any files exist (regardless of is_public)
|
|
351
|
-
const { data: directQueryData, error: directQueryError } = await supabase
|
|
352
|
-
.from('file_references')
|
|
353
|
-
.select('id, file_path, file_metadata, is_public, organisation_id')
|
|
354
|
-
.eq('table_name', table_name)
|
|
355
|
-
.eq('record_id', record_id)
|
|
356
|
-
.eq('organisation_id', organisation_id);
|
|
357
|
-
|
|
358
|
-
if (directQueryError) {
|
|
359
|
-
console.warn('[usePublicFileDisplay] Direct query error (RLS may be blocking):', {
|
|
360
|
-
error: directQueryError.message,
|
|
361
|
-
code: directQueryError.code,
|
|
362
|
-
hint: 'This is expected if RLS policies block anonymous access to file_references table'
|
|
363
|
-
});
|
|
364
|
-
} else {
|
|
365
|
-
const totalFilesInDB = directQueryData?.length || 0;
|
|
366
|
-
const publicFilesInDB = directQueryData?.filter((f: any) => f.is_public === true).length || 0;
|
|
367
|
-
const privateFilesInDB = directQueryData?.filter((f: any) => f.is_public === false).length || 0;
|
|
368
|
-
const filesWithCategory = category ? directQueryData?.filter((f: any) =>
|
|
369
|
-
f.file_metadata?.category === category
|
|
370
|
-
).length || 0 : totalFilesInDB;
|
|
371
|
-
|
|
372
|
-
console.log('[usePublicFileDisplay] Database Query Results:', {
|
|
373
|
-
totalFilesInDB,
|
|
374
|
-
publicFilesInDB,
|
|
375
|
-
privateFilesInDB,
|
|
376
|
-
filesWithCategory: category ? filesWithCategory : 'N/A (no category filter)',
|
|
377
|
-
filesWithMatchingCategoryAndPublic: category ? directQueryData?.filter((f: any) =>
|
|
378
|
-
f.is_public === true && f.file_metadata?.category === category
|
|
379
|
-
).length || 0 : 'N/A',
|
|
380
|
-
sampleFiles: directQueryData?.slice(0, 2).map((f: any) => ({
|
|
381
|
-
id: f.id,
|
|
382
|
-
is_public: f.is_public,
|
|
383
|
-
category: f.file_metadata?.category,
|
|
384
|
-
organisation_id: f.organisation_id
|
|
385
|
-
})) || [],
|
|
386
|
-
conclusion: totalFilesInDB === 0
|
|
387
|
-
? 'No files exist in database for this record'
|
|
388
|
-
: publicFilesInDB === 0
|
|
389
|
-
? 'Files exist but none are marked as public (is_public = true)'
|
|
390
|
-
: filesWithCategory === 0 && category
|
|
391
|
-
? `Files exist but none match category "${category}"`
|
|
392
|
-
: 'Files exist and should be accessible - RPC function may be filtering them out'
|
|
393
|
-
});
|
|
394
|
-
}
|
|
395
|
-
} catch (debugError) {
|
|
396
|
-
console.warn('[usePublicFileDisplay] Database verification query failed:', debugError);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
255
|
setFileUrl(null);
|
|
400
256
|
setFileReference(null);
|
|
401
257
|
setFileReferences([]);
|
|
@@ -477,7 +333,7 @@ export function usePublicFileDisplay(
|
|
|
477
333
|
}
|
|
478
334
|
|
|
479
335
|
} catch (err) {
|
|
480
|
-
|
|
336
|
+
logger.error('usePublicFileDisplay', 'Error fetching files', {
|
|
481
337
|
table_name,
|
|
482
338
|
record_id,
|
|
483
339
|
organisation_id,
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
|
+
import { createLogger } from '../utils/core/logger';
|
|
4
|
+
|
|
5
|
+
const log = createLogger('useComponentPerformance');
|
|
3
6
|
|
|
4
7
|
interface PerformanceConfig {
|
|
5
8
|
componentName: string;
|
|
@@ -23,7 +26,7 @@ export function useComponentPerformance({
|
|
|
23
26
|
renderCount.current += 1;
|
|
24
27
|
|
|
25
28
|
if (renderCount.current > 1 && renderTime > threshold) {
|
|
26
|
-
|
|
29
|
+
log.warn(
|
|
27
30
|
`Performance warning: ${componentName} rendered in ${renderTime.toFixed(2)}ms ` +
|
|
28
31
|
`(render #${renderCount.current}). Consider optimizing.`
|
|
29
32
|
);
|