@jmruthers/pace-core 0.5.193 → 0.6.2
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/CHANGELOG.md +62 -0
- package/README.md +7 -1
- package/cursor-rules/00-pace-core-compliance.mdc +299 -0
- package/cursor-rules/01-standards-compliance.mdc +244 -0
- package/cursor-rules/02-project-structure.mdc +200 -0
- package/cursor-rules/03-solid-principles.mdc +222 -0
- package/cursor-rules/04-testing-standards.mdc +268 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
- package/cursor-rules/06-code-quality.mdc +309 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
- package/cursor-rules/08-markup-quality.mdc +452 -0
- package/cursor-rules/CHANGELOG.md +119 -0
- package/cursor-rules/README.md +192 -0
- package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
- package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
- package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
- package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
- package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
- package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
- package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
- package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
- package/dist/chunk-24UVZUZG.js.map +1 -0
- package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
- package/dist/chunk-2UOI2FG5.js.map +1 -0
- package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
- package/dist/chunk-3XC4CPTD.js.map +1 -0
- package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
- package/dist/chunk-6J4GEEJR.js.map +1 -0
- package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
- package/dist/chunk-6SOIHG6Z.js.map +1 -0
- package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
- package/dist/chunk-EHMR7VYL.js.map +1 -0
- package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
- package/dist/chunk-F2IMUDXZ.js.map +1 -0
- package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
- package/dist/chunk-FFQEQTNW.js.map +1 -0
- package/dist/chunk-FMUCXFII.js +76 -0
- package/dist/chunk-FMUCXFII.js.map +1 -0
- package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
- package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
- package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
- package/dist/chunk-L4OXEN46.js.map +1 -0
- package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
- package/dist/chunk-M43Y4SSO.js.map +1 -0
- package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
- package/dist/chunk-MMZ7JXPU.js.map +1 -0
- package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
- package/dist/chunk-NECFR5MM.js.map +1 -0
- package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
- package/dist/chunk-SFZUDBL5.js.map +1 -0
- package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
- package/dist/chunk-XWQCNGTQ.js.map +1 -0
- package/dist/components.d.ts +6 -6
- package/dist/components.js +15 -12
- package/dist/components.js.map +1 -1
- package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
- package/dist/hooks.d.ts +59 -126
- package/dist/hooks.js +19 -28
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +63 -16
- package/dist/index.js +23 -24
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +21 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +146 -115
- package/dist/rbac/index.js +8 -11
- package/dist/theming/runtime.d.ts +1 -13
- package/dist/theming/runtime.js +1 -1
- package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
- package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
- package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
- package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
- package/dist/utils.d.ts +4 -5
- package/dist/utils.js +15 -15
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +7 -1
- package/docs/api/classes/ColumnFactory.md +8 -8
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +4 -4
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- package/docs/api/classes/SecureSupabaseClient.md +18 -15
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +9 -2
- package/docs/api/interfaces/ButtonProps.md +7 -4
- package/docs/api/interfaces/CalendarProps.md +8 -5
- package/docs/api/interfaces/CardProps.md +8 -5
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +24 -21
- package/docs/api/interfaces/DataTableColumn.md +31 -31
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
- package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- 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 +26 -23
- package/docs/api/interfaces/FooterProps.md +10 -8
- package/docs/api/interfaces/FormFieldProps.md +10 -10
- package/docs/api/interfaces/FormProps.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 +7 -4
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +14 -11
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +11 -11
- package/docs/api/interfaces/NavigationMenuProps.md +15 -15
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- 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 +30 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
- package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
- package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
- package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
- package/docs/api/interfaces/SetupIssue.md +1 -1
- 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/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +3 -3
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +4 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +14 -11
- package/docs/api/interfaces/UserMenuProps.md +8 -6
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +575 -634
- package/docs/architecture/database-schema-requirements.md +161 -0
- package/docs/core-concepts/rbac-system.md +3 -3
- package/docs/documentation-index.md +2 -4
- package/docs/getting-started/cursor-rules.md +263 -0
- package/docs/getting-started/installation-guide.md +6 -1
- package/docs/getting-started/quick-start.md +6 -1
- package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
- package/docs/migration/MIGRATION_GUIDE.md +6 -28
- package/docs/migration/README.md +52 -6
- package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
- package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
- package/docs/migration/database-changes-december-2025.md +3 -3
- package/docs/rbac/event-based-apps.md +1 -1
- package/docs/rbac/getting-started.md +1 -1
- package/docs/rbac/quick-start.md +1 -1
- package/docs/standards/README.md +40 -0
- package/docs/troubleshooting/migration.md +4 -4
- package/examples/PublicPages/PublicEventPage.tsx +1 -1
- package/package.json +12 -6
- package/scripts/audit/core/checks/accessibility.cjs +197 -0
- package/scripts/audit/core/checks/api-usage.cjs +191 -0
- package/scripts/audit/core/checks/bundle.cjs +142 -0
- package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
- package/scripts/audit/core/checks/config.cjs +54 -0
- package/scripts/audit/core/checks/coverage.cjs +84 -0
- package/scripts/audit/core/checks/dependencies.cjs +454 -0
- package/scripts/audit/core/checks/documentation.cjs +203 -0
- package/scripts/audit/core/checks/environment.cjs +128 -0
- package/scripts/audit/core/checks/error-handling.cjs +299 -0
- package/scripts/audit/core/checks/forms.cjs +172 -0
- package/scripts/audit/core/checks/heuristics.cjs +68 -0
- package/scripts/audit/core/checks/hooks.cjs +334 -0
- package/scripts/audit/core/checks/imports.cjs +244 -0
- package/scripts/audit/core/checks/performance.cjs +325 -0
- package/scripts/audit/core/checks/routes.cjs +117 -0
- package/scripts/audit/core/checks/state.cjs +130 -0
- package/scripts/audit/core/checks/structure.cjs +65 -0
- package/scripts/audit/core/checks/style.cjs +584 -0
- package/scripts/audit/core/checks/testing.cjs +122 -0
- package/scripts/audit/core/checks/typescript.cjs +61 -0
- package/scripts/audit/core/scanner.cjs +199 -0
- package/scripts/audit/core/utils.cjs +137 -0
- package/scripts/audit/index.cjs +223 -0
- package/scripts/audit/reporters/console.cjs +151 -0
- package/scripts/audit/reporters/json.cjs +54 -0
- package/scripts/audit/reporters/markdown.cjs +124 -0
- package/scripts/audit-consuming-app.cjs +86 -0
- package/scripts/build-docs/build-decision.js +240 -0
- package/scripts/build-docs/cache-utils.js +105 -0
- package/scripts/build-docs/content-normalization.js +150 -0
- package/scripts/build-docs/file-utils.js +105 -0
- package/scripts/build-docs/git-utils.js +86 -0
- package/scripts/build-docs/hash-utils.js +116 -0
- package/scripts/build-docs/typedoc-runner.js +220 -0
- package/scripts/build-docs-incremental.js +77 -913
- package/scripts/install-cursor-rules.cjs +236 -0
- package/scripts/utils/command-runner.js +16 -11
- package/scripts/validate-formats.js +61 -56
- package/scripts/validate-master.js +74 -69
- package/scripts/validate-pre-publish.js +70 -65
- package/src/__tests__/helpers/test-providers.tsx +1 -1
- package/src/__tests__/helpers/test-utils.tsx +1 -1
- package/src/__tests__/hooks/usePermissions.test.ts +2 -2
- package/src/components/Alert/Alert.test.tsx +12 -18
- package/src/components/Alert/Alert.tsx +5 -7
- package/src/components/Avatar/Avatar.test.tsx +4 -4
- package/src/components/Badge/Badge.tsx +16 -4
- package/src/components/Button/Button.tsx +27 -4
- package/src/components/Calendar/Calendar.tsx +9 -3
- package/src/components/Card/Card.tsx +4 -0
- package/src/components/Checkbox/Checkbox.test.tsx +12 -12
- package/src/components/Checkbox/Checkbox.tsx +2 -2
- package/src/components/DataTable/DataTable.test.tsx +57 -93
- package/src/components/DataTable/DataTable.tsx +40 -6
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
- package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
- package/src/components/DataTable/components/ActionButtons.tsx +10 -7
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
- package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
- package/src/components/DataTable/components/DataTableBody.tsx +8 -0
- package/src/components/DataTable/components/DataTableCore.tsx +200 -561
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
- package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
- package/src/components/DataTable/components/DataTableModals.tsx +9 -1
- package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
- package/src/components/DataTable/components/EditFields.tsx +307 -0
- package/src/components/DataTable/components/EditableRow.tsx +9 -1
- package/src/components/DataTable/components/EmptyState.tsx +10 -0
- package/src/components/DataTable/components/FilterRow.tsx +12 -0
- package/src/components/DataTable/components/GroupHeader.tsx +12 -0
- package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
- package/src/components/DataTable/components/ImportModal.tsx +7 -0
- package/src/components/DataTable/components/LoadingState.tsx +6 -0
- package/src/components/DataTable/components/PaginationControls.tsx +16 -1
- package/src/components/DataTable/components/RowComponent.tsx +391 -0
- package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
- package/src/components/DataTable/components/cellValueUtils.ts +40 -0
- package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
- package/src/components/DataTable/context/DataTableContext.tsx +50 -0
- package/src/components/DataTable/core/ColumnFactory.ts +31 -0
- package/src/components/DataTable/core/DataTableContext.tsx +32 -1
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
- package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
- package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
- package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
- package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
- package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
- package/src/components/DataTable/styles.ts +6 -6
- package/src/components/DataTable/types.ts +6 -10
- package/src/components/DataTable/utils/a11yUtils.ts +7 -0
- package/src/components/DataTable/utils/debugTools.ts +18 -113
- package/src/components/DataTable/utils/errorHandling.ts +12 -0
- package/src/components/DataTable/utils/exportUtils.ts +9 -0
- package/src/components/DataTable/utils/flexibleImport.ts +12 -48
- package/src/components/DataTable/utils/paginationUtils.ts +8 -0
- package/src/components/DataTable/utils/performanceUtils.ts +5 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
- package/src/components/Dialog/Dialog.tsx +8 -7
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
- package/src/components/ErrorBoundary/index.ts +27 -2
- package/src/components/EventSelector/EventSelector.tsx +4 -1
- package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
- package/src/components/FileDisplay/FileDisplay.tsx +32 -18
- package/src/components/FileUpload/FileUpload.tsx +22 -2
- package/src/components/Footer/Footer.test.tsx +16 -16
- package/src/components/Footer/Footer.tsx +15 -12
- package/src/components/Form/Form.test.tsx +36 -15
- package/src/components/Form/Form.tsx +31 -26
- package/src/components/Header/Header.tsx +22 -11
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
- package/src/components/Input/Input.test.tsx +2 -2
- package/src/components/Input/Input.tsx +36 -34
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +42 -42
- package/src/components/LoginForm/LoginForm.tsx +12 -8
- package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
- package/src/components/NavigationMenu/types.ts +56 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
- package/src/components/PaceAppLayout/README.md +1 -1
- package/src/components/PaceAppLayout/test-setup.tsx +1 -2
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
- package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
- package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
- package/src/components/Select/Select.tsx +95 -438
- package/src/components/Select/context.ts +23 -0
- package/src/components/Select/hooks/useSelectEvents.ts +87 -0
- package/src/components/Select/hooks/useSelectSearch.ts +91 -0
- package/src/components/Select/hooks/useSelectState.ts +104 -0
- package/src/components/Select/index.ts +9 -1
- package/src/components/Select/types.ts +123 -0
- package/src/components/Select/utils/text.ts +26 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
- package/src/components/Switch/Switch.tsx +4 -4
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +27 -29
- package/src/components/Toast/Toast.tsx +5 -1
- package/src/components/Tooltip/Tooltip.tsx +3 -3
- package/src/components/UserMenu/UserMenu.test.tsx +24 -11
- package/src/components/UserMenu/UserMenu.tsx +22 -19
- package/src/components/index.ts +2 -2
- package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
- package/src/hooks/__tests__/index.unit.test.ts +2 -5
- package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
- package/src/hooks/index.ts +1 -2
- package/src/hooks/public/usePublicEvent.ts +5 -1
- package/src/hooks/public/usePublicEventLogo.ts +5 -1
- package/src/hooks/public/usePublicFileDisplay.ts +4 -0
- package/src/hooks/public/usePublicRouteParams.ts +5 -1
- package/src/hooks/services/useAuth.ts +32 -0
- package/src/hooks/services/useCurrentEvent.ts +6 -0
- package/src/hooks/services/useCurrentOrganisation.ts +6 -0
- package/src/hooks/useDataTableState.ts +8 -18
- package/src/hooks/useDebounce.ts +9 -0
- package/src/hooks/useEventTheme.ts +6 -0
- package/src/hooks/useFileDisplay.ts +4 -0
- package/src/hooks/useFileReference.ts +25 -7
- package/src/hooks/useFileUrl.ts +11 -1
- package/src/hooks/useFocusManagement.ts +16 -2
- package/src/hooks/useFocusTrap.ts +7 -4
- package/src/hooks/useFormDialog.ts +8 -7
- package/src/hooks/useInactivityTracker.ts +4 -1
- package/src/hooks/useKeyboardShortcuts.ts +4 -0
- package/src/hooks/useOrganisationPermissions.ts +4 -0
- package/src/hooks/useOrganisationSecurity.ts +4 -0
- package/src/hooks/usePerformanceMonitor.ts +4 -0
- package/src/hooks/usePermissionCache.ts +8 -1
- package/src/hooks/useQueryCache.ts +12 -1
- package/src/hooks/useSessionRestoration.ts +4 -0
- package/src/hooks/useStorage.ts +4 -0
- package/src/hooks/useToast.ts +3 -3
- package/src/index.ts +2 -1
- package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
- package/src/providers/services/AuthServiceProvider.tsx +18 -0
- package/src/providers/services/EventServiceProvider.tsx +18 -0
- package/src/providers/services/InactivityServiceProvider.tsx +18 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
- package/src/rbac/adapters.tsx +14 -5
- package/src/rbac/api.ts +100 -67
- package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
- package/src/rbac/components/NavigationGuard.tsx +1 -1
- package/src/rbac/components/NavigationProvider.tsx +5 -2
- package/src/rbac/components/PagePermissionGuard.tsx +158 -18
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +1 -1
- package/src/rbac/components/RoleBasedRouter.tsx +6 -2
- package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
- package/src/rbac/components/SecureDataProvider.tsx +21 -6
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
- package/src/rbac/engine.ts +38 -14
- package/src/rbac/hooks/permissions/index.ts +7 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
- package/src/rbac/hooks/permissions/useCan.ts +347 -0
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
- package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
- package/src/rbac/hooks/useCan.test.ts +71 -64
- package/src/rbac/hooks/usePermissions.ts +14 -995
- package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
- package/src/rbac/hooks/useResourcePermissions.ts +14 -4
- package/src/rbac/hooks/useSecureSupabase.ts +33 -13
- package/src/rbac/permissions.ts +0 -30
- package/src/rbac/secureClient.ts +212 -61
- package/src/rbac/types.ts +8 -0
- package/src/theming/__tests__/parseEventColours.test.ts +6 -9
- package/src/theming/parseEventColours.ts +5 -19
- package/src/types/vitest-globals.d.ts +51 -26
- package/src/utils/__mocks__/supabaseMock.ts +1 -3
- package/src/utils/__tests__/formatting.unit.test.ts +4 -4
- package/src/utils/__tests__/index.unit.test.ts +2 -2
- package/src/utils/audit/audit.ts +0 -3
- package/src/utils/core/cn.ts +1 -1
- package/src/utils/file-reference/index.ts +53 -1
- package/src/utils/formatting/formatting.ts +8 -18
- package/src/utils/index.ts +0 -1
- package/src/utils/security/secureDataAccess.test.ts +31 -20
- package/src/utils/security/secureDataAccess.ts +4 -3
- package/dist/chunk-6C4YBBJM.js +0 -628
- package/dist/chunk-6C4YBBJM.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js 2.map +0 -1
- package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
- package/dist/chunk-7EQTDTTJ.js.map +0 -1
- package/dist/chunk-7FLMSG37.js 2.map +0 -1
- package/dist/chunk-7FLMSG37.js.map +0 -1
- package/dist/chunk-BC4IJKSL.js.map +0 -1
- package/dist/chunk-E3SPN4VZ.js +0 -12917
- package/dist/chunk-E3SPN4VZ.js.map +0 -1
- package/dist/chunk-E66EQZE6 5.js +0 -37
- package/dist/chunk-E66EQZE6.js 2.map +0 -1
- package/dist/chunk-HWIIPPNI.js.map +0 -1
- package/dist/chunk-I7PSE6JW 5.js +0 -191
- package/dist/chunk-I7PSE6JW.js 2.map +0 -1
- package/dist/chunk-I7PSE6JW.js.map +0 -1
- package/dist/chunk-IIELH4DL.js.map +0 -1
- package/dist/chunk-KNC55RTG.js 5.map +0 -1
- package/dist/chunk-KNC55RTG.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js 5.map +0 -1
- package/dist/chunk-LFNCN2SP.js +0 -412
- package/dist/chunk-LFNCN2SP.js 2.map +0 -1
- package/dist/chunk-LFNCN2SP.js.map +0 -1
- package/dist/chunk-LMC26NLJ 2.js +0 -84
- package/dist/chunk-NOAYCWCX.js +0 -4993
- package/dist/chunk-NOAYCWCX.js.map +0 -1
- package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
- package/dist/chunk-QWWZ5CAQ.js.map +0 -1
- package/dist/chunk-QXHPKYJV 3.js +0 -113
- package/dist/chunk-R77UEZ4E.js +0 -68
- package/dist/chunk-R77UEZ4E.js.map +0 -1
- package/dist/chunk-SQGMNID3.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
- package/dist/chunk-XNXXZ43G.js.map +0 -1
- package/dist/chunk-ZSAAAMVR 6.js +0 -25
- package/dist/components.js 5.map +0 -1
- package/dist/styles/index 2.js +0 -12
- package/dist/styles/index.js 5.map +0 -1
- package/dist/theming/runtime 5.js +0 -19
- package/dist/theming/runtime.js 5.map +0 -1
- package/docs/api/classes/ErrorBoundary.md +0 -144
- package/docs/migration/quick-migration-guide.md +0 -356
- package/docs/migration/service-architecture.md +0 -281
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
- package/src/hooks/useSecureDataAccess.test.ts +0 -559
- package/src/hooks/useSecureDataAccess.ts +0 -666
- /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
- /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
- /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
- /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
- /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
- /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
- /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/index.ts +0 -0
|
@@ -38,7 +38,7 @@ const mockSupabase = {
|
|
|
38
38
|
const mockFile = new File(['test content'], 'test.txt', { type: 'text/plain' });
|
|
39
39
|
|
|
40
40
|
describe('useStorage Hook', () => {
|
|
41
|
-
const
|
|
41
|
+
const baseProps = {
|
|
42
42
|
supabase: mockSupabase,
|
|
43
43
|
appName: 'test-app',
|
|
44
44
|
orgId: 'test-org',
|
|
@@ -46,7 +46,7 @@ describe('useStorage Hook', () => {
|
|
|
46
46
|
|
|
47
47
|
describe('Initial State', () => {
|
|
48
48
|
it('should initialize with correct default values', () => {
|
|
49
|
-
const { result } = renderHook(() => useStorage(
|
|
49
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
50
50
|
|
|
51
51
|
expect(result.current.isUploading).toBe(false);
|
|
52
52
|
expect(result.current.uploadError).toBe(null);
|
|
@@ -58,7 +58,7 @@ describe('useStorage Hook', () => {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
it('should provide all required functions', () => {
|
|
61
|
-
const { result } = renderHook(() => useStorage(
|
|
61
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
62
62
|
|
|
63
63
|
expect(typeof result.current.uploadFile).toBe('function');
|
|
64
64
|
expect(typeof result.current.getPublicUrl).toBe('function');
|
|
@@ -106,7 +106,7 @@ describe('useStorage Hook', () => {
|
|
|
106
106
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
107
107
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
108
108
|
|
|
109
|
-
const { result } = renderHook(() => useStorage(
|
|
109
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
110
110
|
|
|
111
111
|
let uploadResult: any;
|
|
112
112
|
await act(async () => {
|
|
@@ -132,7 +132,7 @@ describe('useStorage Hook', () => {
|
|
|
132
132
|
|
|
133
133
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
134
134
|
|
|
135
|
-
const { result } = renderHook(() => useStorage(
|
|
135
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
136
136
|
|
|
137
137
|
let uploadResult: any;
|
|
138
138
|
await act(async () => {
|
|
@@ -153,7 +153,7 @@ describe('useStorage Hook', () => {
|
|
|
153
153
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
154
154
|
vi.mocked(listFiles).mockResolvedValue({ files: [], totalCount: 0, hasMore: false });
|
|
155
155
|
|
|
156
|
-
const { result } = renderHook(() => useStorage(
|
|
156
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
157
157
|
|
|
158
158
|
const customOptions = {
|
|
159
159
|
isPublic: true,
|
|
@@ -179,7 +179,7 @@ describe('useStorage Hook', () => {
|
|
|
179
179
|
it('should handle upload exception', async () => {
|
|
180
180
|
vi.mocked(uploadFile).mockRejectedValue(new Error('Network error'));
|
|
181
181
|
|
|
182
|
-
const { result } = renderHook(() => useStorage(
|
|
182
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
183
183
|
|
|
184
184
|
let uploadResult: any;
|
|
185
185
|
await act(async () => {
|
|
@@ -197,7 +197,7 @@ describe('useStorage Hook', () => {
|
|
|
197
197
|
it('should handle upload exception with non-Error object', async () => {
|
|
198
198
|
vi.mocked(uploadFile).mockRejectedValue('String error');
|
|
199
199
|
|
|
200
|
-
const { result } = renderHook(() => useStorage(
|
|
200
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
201
201
|
|
|
202
202
|
let uploadResult: any;
|
|
203
203
|
await act(async () => {
|
|
@@ -217,7 +217,7 @@ describe('useStorage Hook', () => {
|
|
|
217
217
|
const mockUrl = 'https://example.com/public/test-file.txt';
|
|
218
218
|
vi.mocked(getPublicUrl).mockReturnValue(mockUrl);
|
|
219
219
|
|
|
220
|
-
const { result } = renderHook(() => useStorage(
|
|
220
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
221
221
|
|
|
222
222
|
const url = result.current.getPublicUrl('test-org/public/test-file.txt');
|
|
223
223
|
|
|
@@ -229,7 +229,7 @@ describe('useStorage Hook', () => {
|
|
|
229
229
|
const mockUrl = 'https://example.com/public/test-file.txt';
|
|
230
230
|
vi.mocked(getPublicUrl).mockReturnValue(mockUrl);
|
|
231
231
|
|
|
232
|
-
const { result } = renderHook(() => useStorage(
|
|
232
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
233
233
|
|
|
234
234
|
const url = result.current.getFileUrl('test-org/public/test-file.txt');
|
|
235
235
|
|
|
@@ -245,7 +245,7 @@ describe('useStorage Hook', () => {
|
|
|
245
245
|
|
|
246
246
|
vi.mocked(getSignedUrl).mockResolvedValue(mockSignedUrl);
|
|
247
247
|
|
|
248
|
-
const { result } = renderHook(() => useStorage(
|
|
248
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
249
249
|
|
|
250
250
|
let signedUrl: string | null = null;
|
|
251
251
|
await act(async () => {
|
|
@@ -263,7 +263,7 @@ describe('useStorage Hook', () => {
|
|
|
263
263
|
it('should handle signed URL failure', async () => {
|
|
264
264
|
vi.mocked(getSignedUrl).mockRejectedValue(new Error('Signing failed'));
|
|
265
265
|
|
|
266
|
-
const { result } = renderHook(() => useStorage(
|
|
266
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
267
267
|
|
|
268
268
|
let signedUrl: string | null = null;
|
|
269
269
|
await act(async () => {
|
|
@@ -276,7 +276,7 @@ describe('useStorage Hook', () => {
|
|
|
276
276
|
it('should handle signed URL with null result', async () => {
|
|
277
277
|
vi.mocked(getSignedUrl).mockResolvedValue(null);
|
|
278
278
|
|
|
279
|
-
const { result } = renderHook(() => useStorage(
|
|
279
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
280
280
|
|
|
281
281
|
let signedUrl: string | null = null;
|
|
282
282
|
await act(async () => {
|
|
@@ -295,7 +295,7 @@ describe('useStorage Hook', () => {
|
|
|
295
295
|
vi.mocked(deleteFile).mockResolvedValue(mockDeleteResult);
|
|
296
296
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
297
297
|
|
|
298
|
-
const { result } = renderHook(() => useStorage(
|
|
298
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
299
299
|
|
|
300
300
|
let deleteResult: any;
|
|
301
301
|
await act(async () => {
|
|
@@ -311,7 +311,7 @@ describe('useStorage Hook', () => {
|
|
|
311
311
|
|
|
312
312
|
vi.mocked(deleteFile).mockResolvedValue(mockDeleteResult);
|
|
313
313
|
|
|
314
|
-
const { result } = renderHook(() => useStorage(
|
|
314
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
315
315
|
|
|
316
316
|
let deleteResult: any;
|
|
317
317
|
await act(async () => {
|
|
@@ -324,7 +324,7 @@ describe('useStorage Hook', () => {
|
|
|
324
324
|
it('should handle delete file exception', async () => {
|
|
325
325
|
vi.mocked(deleteFile).mockRejectedValue(new Error('Network error'));
|
|
326
326
|
|
|
327
|
-
const { result } = renderHook(() => useStorage(
|
|
327
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
328
328
|
|
|
329
329
|
let deleteResult: any;
|
|
330
330
|
await act(async () => {
|
|
@@ -344,7 +344,7 @@ describe('useStorage Hook', () => {
|
|
|
344
344
|
vi.mocked(archiveFile).mockResolvedValue(mockArchiveResult);
|
|
345
345
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
346
346
|
|
|
347
|
-
const { result } = renderHook(() => useStorage(
|
|
347
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
348
348
|
|
|
349
349
|
let archiveResult: any;
|
|
350
350
|
await act(async () => {
|
|
@@ -363,7 +363,7 @@ describe('useStorage Hook', () => {
|
|
|
363
363
|
|
|
364
364
|
vi.mocked(archiveFile).mockResolvedValue(mockArchiveResult);
|
|
365
365
|
|
|
366
|
-
const { result } = renderHook(() => useStorage(
|
|
366
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
367
367
|
|
|
368
368
|
let archiveResult: any;
|
|
369
369
|
await act(async () => {
|
|
@@ -376,7 +376,7 @@ describe('useStorage Hook', () => {
|
|
|
376
376
|
it('should handle archive file exception', async () => {
|
|
377
377
|
vi.mocked(archiveFile).mockRejectedValue(new Error('Network error'));
|
|
378
378
|
|
|
379
|
-
const { result } = renderHook(() => useStorage(
|
|
379
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
380
380
|
|
|
381
381
|
let archiveResult: any;
|
|
382
382
|
await act(async () => {
|
|
@@ -417,7 +417,7 @@ describe('useStorage Hook', () => {
|
|
|
417
417
|
|
|
418
418
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
419
419
|
|
|
420
|
-
const { result } = renderHook(() => useStorage(
|
|
420
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
421
421
|
|
|
422
422
|
let listResult: any;
|
|
423
423
|
await act(async () => {
|
|
@@ -439,7 +439,7 @@ describe('useStorage Hook', () => {
|
|
|
439
439
|
|
|
440
440
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
441
441
|
|
|
442
|
-
const { result } = renderHook(() => useStorage(
|
|
442
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
443
443
|
|
|
444
444
|
const customOptions = {
|
|
445
445
|
pathPrefix: 'documents',
|
|
@@ -465,7 +465,7 @@ describe('useStorage Hook', () => {
|
|
|
465
465
|
it('should handle list files failure', async () => {
|
|
466
466
|
vi.mocked(listFiles).mockRejectedValue(new Error('List failed'));
|
|
467
467
|
|
|
468
|
-
const { result } = renderHook(() => useStorage(
|
|
468
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
469
469
|
|
|
470
470
|
let listResult: any;
|
|
471
471
|
await act(async () => {
|
|
@@ -481,7 +481,7 @@ describe('useStorage Hook', () => {
|
|
|
481
481
|
it('should handle list files exception with non-Error object', async () => {
|
|
482
482
|
vi.mocked(listFiles).mockRejectedValue('String error');
|
|
483
483
|
|
|
484
|
-
const { result } = renderHook(() => useStorage(
|
|
484
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
485
485
|
|
|
486
486
|
let listResult: any;
|
|
487
487
|
await act(async () => {
|
|
@@ -497,7 +497,7 @@ describe('useStorage Hook', () => {
|
|
|
497
497
|
|
|
498
498
|
vi.mocked(listFiles).mockResolvedValue(mockListResult);
|
|
499
499
|
|
|
500
|
-
const { result } = renderHook(() => useStorage(
|
|
500
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
501
501
|
|
|
502
502
|
await act(async () => {
|
|
503
503
|
await result.current.refreshFiles();
|
|
@@ -519,7 +519,7 @@ describe('useStorage Hook', () => {
|
|
|
519
519
|
|
|
520
520
|
vi.mocked(uploadFile).mockReturnValue(uploadPromise);
|
|
521
521
|
|
|
522
|
-
const { result } = renderHook(() => useStorage(
|
|
522
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
523
523
|
|
|
524
524
|
expect(result.current.isUploading).toBe(false);
|
|
525
525
|
|
|
@@ -545,7 +545,7 @@ describe('useStorage Hook', () => {
|
|
|
545
545
|
|
|
546
546
|
vi.mocked(listFiles).mockReturnValue(listPromise);
|
|
547
547
|
|
|
548
|
-
const { result } = renderHook(() => useStorage(
|
|
548
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
549
549
|
|
|
550
550
|
expect(result.current.isListing).toBe(false);
|
|
551
551
|
|
|
@@ -566,13 +566,13 @@ describe('useStorage Hook', () => {
|
|
|
566
566
|
|
|
567
567
|
describe('Aliases', () => {
|
|
568
568
|
it('should provide isLoading alias for isListing', () => {
|
|
569
|
-
const { result } = renderHook(() => useStorage(
|
|
569
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
570
570
|
|
|
571
571
|
expect(result.current.isLoading).toBe(result.current.isListing);
|
|
572
572
|
});
|
|
573
573
|
|
|
574
574
|
it('should provide error alias for listError', () => {
|
|
575
|
-
const { result } = renderHook(() => useStorage(
|
|
575
|
+
const { result } = renderHook(() => useStorage(baseProps));
|
|
576
576
|
|
|
577
577
|
expect(result.current.error).toBe(result.current.listError);
|
|
578
578
|
});
|
|
@@ -580,7 +580,7 @@ describe('useStorage Hook', () => {
|
|
|
580
580
|
});
|
|
581
581
|
|
|
582
582
|
describe('useFileUpload Hook', () => {
|
|
583
|
-
const
|
|
583
|
+
const baseProps = {
|
|
584
584
|
supabase: mockSupabase,
|
|
585
585
|
appName: 'test-app',
|
|
586
586
|
orgId: 'test-org',
|
|
@@ -588,7 +588,7 @@ describe('useFileUpload Hook', () => {
|
|
|
588
588
|
|
|
589
589
|
describe('Initial State', () => {
|
|
590
590
|
it('should initialize with correct default values', () => {
|
|
591
|
-
const { result } = renderHook(() => useFileUpload(
|
|
591
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
592
592
|
|
|
593
593
|
expect(result.current.uploadProgress).toBe(0);
|
|
594
594
|
expect(result.current.isUploading).toBe(false);
|
|
@@ -605,7 +605,7 @@ describe('useFileUpload Hook', () => {
|
|
|
605
605
|
|
|
606
606
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
607
607
|
|
|
608
|
-
const { result } = renderHook(() => useFileUpload(
|
|
608
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
609
609
|
|
|
610
610
|
let uploadResult: any;
|
|
611
611
|
await act(async () => {
|
|
@@ -628,7 +628,7 @@ describe('useFileUpload Hook', () => {
|
|
|
628
628
|
|
|
629
629
|
vi.mocked(uploadFile).mockReturnValue(uploadPromise);
|
|
630
630
|
|
|
631
|
-
const { result } = renderHook(() => useFileUpload(
|
|
631
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
632
632
|
|
|
633
633
|
act(() => {
|
|
634
634
|
result.current.uploadWithProgress(mockFile);
|
|
@@ -670,7 +670,7 @@ describe('useFileUpload Hook', () => {
|
|
|
670
670
|
|
|
671
671
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
672
672
|
|
|
673
|
-
const { result } = renderHook(() => useFileUpload(
|
|
673
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
674
674
|
|
|
675
675
|
let uploadResult: any;
|
|
676
676
|
await act(async () => {
|
|
@@ -686,7 +686,7 @@ describe('useFileUpload Hook', () => {
|
|
|
686
686
|
it('should handle upload exception', async () => {
|
|
687
687
|
vi.mocked(uploadFile).mockRejectedValue(new Error('Network error'));
|
|
688
688
|
|
|
689
|
-
const { result } = renderHook(() => useFileUpload(
|
|
689
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
690
690
|
|
|
691
691
|
let uploadResult: any;
|
|
692
692
|
await act(async () => {
|
|
@@ -707,7 +707,7 @@ describe('useFileUpload Hook', () => {
|
|
|
707
707
|
|
|
708
708
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
709
709
|
|
|
710
|
-
const { result } = renderHook(() => useFileUpload(
|
|
710
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
711
711
|
|
|
712
712
|
await act(async () => {
|
|
713
713
|
await result.current.uploadWithProgress(mockFile);
|
|
@@ -729,7 +729,7 @@ describe('useFileUpload Hook', () => {
|
|
|
729
729
|
|
|
730
730
|
vi.mocked(uploadFile).mockResolvedValue(mockUploadResult);
|
|
731
731
|
|
|
732
|
-
const { result } = renderHook(() => useFileUpload(
|
|
732
|
+
const { result } = renderHook(() => useFileUpload(baseProps));
|
|
733
733
|
|
|
734
734
|
const customOptions = {
|
|
735
735
|
isPublic: true,
|
package/src/hooks/index.ts
CHANGED
|
@@ -33,9 +33,8 @@ export type { UseAddressAutocompleteOptions, UseAddressAutocompleteReturn } from
|
|
|
33
33
|
|
|
34
34
|
// === ORGANISATION HOOKS ===
|
|
35
35
|
export { useOrganisationPermissions } from './useOrganisationPermissions';
|
|
36
|
-
|
|
36
|
+
// useSecureDataAccess has been removed - use useSecureSupabase from @jmruthers/pace-core/rbac instead
|
|
37
37
|
export type { UseOrganisationPermissionsReturn } from './useOrganisationPermissions';
|
|
38
|
-
export type { SecureDataAccessReturn } from './useSecureDataAccess';
|
|
39
38
|
export { useOrganisationSecurity } from './useOrganisationSecurity';
|
|
40
39
|
export type { OrganisationSecurityHook } from './useOrganisationSecurity';
|
|
41
40
|
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
* - Error boundary integration
|
|
55
55
|
*
|
|
56
56
|
* @dependencies
|
|
57
|
-
* - React
|
|
57
|
+
* - React 19+ - Hooks and effects
|
|
58
58
|
* - @supabase/supabase-js - Database integration
|
|
59
59
|
* - Event types - Type definitions
|
|
60
60
|
*/
|
|
@@ -70,6 +70,10 @@ import { logger } from '../../utils/core/logger';
|
|
|
70
70
|
// Simple in-memory cache for public data
|
|
71
71
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Return value of the usePublicEvent hook.
|
|
75
|
+
* Provides event data, loading state, error, and refetch function.
|
|
76
|
+
*/
|
|
73
77
|
export interface UsePublicEventReturn {
|
|
74
78
|
/** The event data, null if not loaded or not found */
|
|
75
79
|
event: Event | null;
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
* - Lazy loading support
|
|
60
60
|
*
|
|
61
61
|
* @dependencies
|
|
62
|
-
* - React
|
|
62
|
+
* - React 19+ - Hooks and effects
|
|
63
63
|
* - @supabase/supabase-js - Storage integration
|
|
64
64
|
* - Event types - Type definitions
|
|
65
65
|
*/
|
|
@@ -74,6 +74,10 @@ const log = createLogger('usePublicEventLogo');
|
|
|
74
74
|
// Simple in-memory cache for public data
|
|
75
75
|
const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Return value of the usePublicEventLogo hook.
|
|
79
|
+
* Provides logo URL, fallback text, loading state, error, and refetch function.
|
|
80
|
+
*/
|
|
77
81
|
export interface UsePublicEventLogoReturn {
|
|
78
82
|
/** The logo URL if available, null if not found or error */
|
|
79
83
|
logoUrl: string | null;
|
|
@@ -46,6 +46,10 @@ import { logger } from '../../utils/core/logger';
|
|
|
46
46
|
// Simple in-memory cache for public file data
|
|
47
47
|
const publicFileCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
|
|
48
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Return value of the usePublicFileDisplay hook.
|
|
51
|
+
* Provides file URLs, references, loading state, error, and refetch function.
|
|
52
|
+
*/
|
|
49
53
|
export interface UsePublicFileDisplayReturn {
|
|
50
54
|
/** Single file URL if category is provided and file found, null otherwise */
|
|
51
55
|
fileUrl: string | null;
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
* - Caching integration
|
|
52
52
|
*
|
|
53
53
|
* @dependencies
|
|
54
|
-
* - React
|
|
54
|
+
* - React 19+ - Hooks and effects
|
|
55
55
|
* - React Router - URL parameter extraction
|
|
56
56
|
* - Event types - Type definitions
|
|
57
57
|
*/
|
|
@@ -61,6 +61,10 @@ import { useParams, useLocation } from 'react-router-dom';
|
|
|
61
61
|
import type { Event } from '../../types/event';
|
|
62
62
|
import { usePublicEvent } from './usePublicEvent';
|
|
63
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Return value of the usePublicRouteParams hook.
|
|
66
|
+
* Provides event code, event ID, event data, loading state, error, and refetch function.
|
|
67
|
+
*/
|
|
64
68
|
export interface UsePublicRouteParamsReturn {
|
|
65
69
|
/** The event code from the URL */
|
|
66
70
|
eventCode: string | null;
|
|
@@ -11,23 +11,55 @@
|
|
|
11
11
|
import { useAuthService } from './useAuthService';
|
|
12
12
|
import { type User, type Session, type SupabaseClient, AuthError } from '@supabase/supabase-js';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Authentication state and methods returned by the useAuth hook.
|
|
16
|
+
*/
|
|
14
17
|
export interface AuthState {
|
|
18
|
+
/** Current authenticated user, or null if not authenticated */
|
|
15
19
|
user: User | null;
|
|
20
|
+
/** Current session, or null if not authenticated */
|
|
16
21
|
session: Session | null;
|
|
22
|
+
/** Whether the user is currently authenticated */
|
|
17
23
|
isAuthenticated: boolean;
|
|
24
|
+
/** Whether authentication state is currently loading */
|
|
18
25
|
authLoading: boolean;
|
|
26
|
+
/** Any authentication error that occurred, or null */
|
|
19
27
|
authError: AuthError | null;
|
|
28
|
+
/** Supabase client instance, or null if not available */
|
|
20
29
|
supabase: SupabaseClient | null;
|
|
21
30
|
|
|
22
31
|
// Auth methods
|
|
32
|
+
/** Sign in with email and optional password */
|
|
23
33
|
signIn: (email: string, password?: string) => Promise<{ error: AuthError | null }>;
|
|
34
|
+
/** Sign up with email and password */
|
|
24
35
|
signUp: (email: string, password: string) => Promise<{ error: AuthError | null }>;
|
|
36
|
+
/** Sign out the current user */
|
|
25
37
|
signOut: () => Promise<{ error: AuthError | null }>;
|
|
38
|
+
/** Request a password reset email */
|
|
26
39
|
resetPassword: (email: string) => Promise<{ error: AuthError | null }>;
|
|
40
|
+
/** Update the current user's password */
|
|
27
41
|
updatePassword: (password: string) => Promise<{ error: AuthError | null }>;
|
|
42
|
+
/** Refresh the current session */
|
|
28
43
|
refreshSession: () => Promise<{ error: AuthError | null }>;
|
|
29
44
|
}
|
|
30
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Convenience hook for authentication.
|
|
48
|
+
* Returns the auth state and methods needed by components.
|
|
49
|
+
*
|
|
50
|
+
* @returns Authentication state and methods
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```tsx
|
|
54
|
+
* const { user, isAuthenticated, signIn, signOut } = useAuth();
|
|
55
|
+
*
|
|
56
|
+
* if (!isAuthenticated) {
|
|
57
|
+
* return <LoginForm onSignIn={signIn} />;
|
|
58
|
+
* }
|
|
59
|
+
*
|
|
60
|
+
* return <Dashboard user={user} onSignOut={signOut} />;
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
31
63
|
export function useAuth(): AuthState {
|
|
32
64
|
const authService = useAuthService();
|
|
33
65
|
|
|
@@ -22,6 +22,12 @@ export interface CurrentEventState {
|
|
|
22
22
|
refreshEvents: () => Promise<void>;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Convenience hook for accessing current event state.
|
|
27
|
+
* Returns event state and methods needed by components.
|
|
28
|
+
*
|
|
29
|
+
* @returns Current event state including events, selected event, loading state, and methods
|
|
30
|
+
*/
|
|
25
31
|
export function useCurrentEvent(): CurrentEventState {
|
|
26
32
|
const eventService = useEventService();
|
|
27
33
|
|
|
@@ -30,6 +30,12 @@ export interface CurrentOrganisationState {
|
|
|
30
30
|
getPrimaryOrganisation: () => Organisation | null;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Convenience hook for accessing current organisation state.
|
|
35
|
+
* Returns organisation state and methods needed by components.
|
|
36
|
+
*
|
|
37
|
+
* @returns Current organisation state including selected organisation, organisations, memberships, and methods
|
|
38
|
+
*/
|
|
33
39
|
export function useCurrentOrganisation(): CurrentOrganisationState {
|
|
34
40
|
const organisationService = useOrganisationService();
|
|
35
41
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @description Hook for managing DataTable state
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { useState, useCallback
|
|
6
|
+
import { useState, useCallback } from 'react';
|
|
7
7
|
import type { SortingState, ColumnFiltersState, ExpandedState } from '@tanstack/react-table';
|
|
8
8
|
|
|
9
9
|
export interface DataTableState {
|
|
@@ -63,24 +63,14 @@ export function useDataTableState(options: UseDataTableStateOptions) {
|
|
|
63
63
|
setSelectedRows([]);
|
|
64
64
|
}, [initialPageSize]);
|
|
65
65
|
|
|
66
|
-
// Computed values
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
return data.slice(start, end);
|
|
71
|
-
}, [data, pageIndex, pageSize]);
|
|
66
|
+
// Computed values - React Compiler handles memoization automatically
|
|
67
|
+
const start = pageIndex * pageSize;
|
|
68
|
+
const end = start + pageSize;
|
|
69
|
+
const paginatedData = data.slice(start, end);
|
|
72
70
|
|
|
73
|
-
const totalPages =
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const hasNextPage = useMemo(() => {
|
|
78
|
-
return pageIndex < totalPages - 1;
|
|
79
|
-
}, [pageIndex, totalPages]);
|
|
80
|
-
|
|
81
|
-
const hasPreviousPage = useMemo(() => {
|
|
82
|
-
return pageIndex > 0;
|
|
83
|
-
}, [pageIndex]);
|
|
71
|
+
const totalPages = Math.ceil(data.length / pageSize);
|
|
72
|
+
const hasNextPage = pageIndex < totalPages - 1;
|
|
73
|
+
const hasPreviousPage = pageIndex > 0;
|
|
84
74
|
|
|
85
75
|
return {
|
|
86
76
|
state: {
|
package/src/hooks/useDebounce.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
|
|
2
2
|
import { useState, useEffect } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Hook for debouncing a value.
|
|
6
|
+
* Returns a debounced version of the value that only updates after the specified delay.
|
|
7
|
+
*
|
|
8
|
+
* @template T - The type of the value to debounce
|
|
9
|
+
* @param value - The value to debounce
|
|
10
|
+
* @param delay - The delay in milliseconds
|
|
11
|
+
* @returns The debounced value
|
|
12
|
+
*/
|
|
4
13
|
export function useDebounce<T>(value: T, delay: number): T {
|
|
5
14
|
const [debouncedValue, setDebouncedValue] = useState<T>(value);
|
|
6
15
|
|
|
@@ -92,6 +92,12 @@ const log = createLogger('useEventTheme');
|
|
|
92
92
|
* }
|
|
93
93
|
* ```
|
|
94
94
|
*/
|
|
95
|
+
/**
|
|
96
|
+
* Hook that automatically applies event-specific theming.
|
|
97
|
+
* Works in authenticated mode (via EventProvider) or public page mode (via event prop).
|
|
98
|
+
*
|
|
99
|
+
* @param event - Optional event object for public page mode. If not provided, uses EventProvider context.
|
|
100
|
+
*/
|
|
95
101
|
export function useEventTheme(event?: Event | null): void {
|
|
96
102
|
const location = useLocation();
|
|
97
103
|
|
|
@@ -71,6 +71,10 @@ function cleanupCache() {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Return value of the useFileDisplay hook.
|
|
76
|
+
* Provides file URLs, references, loading state, error, and refetch function.
|
|
77
|
+
*/
|
|
74
78
|
export interface UseFileDisplayReturn {
|
|
75
79
|
/** Single file URL if category is provided and file found, null otherwise */
|
|
76
80
|
fileUrl: string | null;
|
|
@@ -59,6 +59,13 @@ const urlRefreshManager = {
|
|
|
59
59
|
}
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Hook for managing file references.
|
|
64
|
+
* Provides file upload, retrieval, and URL generation functionality.
|
|
65
|
+
*
|
|
66
|
+
* @param supabase - Supabase client instance
|
|
67
|
+
* @returns File reference service with upload, get, and URL methods
|
|
68
|
+
*/
|
|
62
69
|
export function useFileReference(supabase: SupabaseClient) {
|
|
63
70
|
const [isLoading, setIsLoading] = useState(false);
|
|
64
71
|
const [error, setError] = useState<string | null>(null);
|
|
@@ -385,13 +392,18 @@ export function useFileReferenceById(
|
|
|
385
392
|
}
|
|
386
393
|
|
|
387
394
|
const loadUrl = async () => {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
+
try {
|
|
396
|
+
const service = createFileReferenceService(supabase);
|
|
397
|
+
const url = await service.getFileUrl(
|
|
398
|
+
fileReference.table_name,
|
|
399
|
+
fileReference.record_id,
|
|
400
|
+
organisationId
|
|
401
|
+
);
|
|
402
|
+
setFileUrl(url);
|
|
403
|
+
} catch (error) {
|
|
404
|
+
// Silently fail - component will handle missing URL
|
|
405
|
+
setFileUrl(null);
|
|
406
|
+
}
|
|
395
407
|
};
|
|
396
408
|
|
|
397
409
|
loadUrl();
|
|
@@ -478,6 +490,9 @@ export type UseFileReferenceOptions = {
|
|
|
478
490
|
organisation_id: string;
|
|
479
491
|
};
|
|
480
492
|
|
|
493
|
+
/**
|
|
494
|
+
* Return value of the useFileReference hook.
|
|
495
|
+
*/
|
|
481
496
|
export type UseFileReferenceReturn = {
|
|
482
497
|
isLoading: boolean;
|
|
483
498
|
error: string | null;
|
|
@@ -492,6 +507,9 @@ export type UseFileReferenceReturn = {
|
|
|
492
507
|
clearError: () => void;
|
|
493
508
|
};
|
|
494
509
|
|
|
510
|
+
/**
|
|
511
|
+
* Return value of the useFileReferenceForRecord hook.
|
|
512
|
+
*/
|
|
495
513
|
export type UseFileReferenceForRecordReturn = {
|
|
496
514
|
isLoading: boolean;
|
|
497
515
|
error: string | null;
|
package/src/hooks/useFileUrl.ts
CHANGED
|
@@ -15,11 +15,14 @@ import { createLogger } from '../utils/core/logger';
|
|
|
15
15
|
|
|
16
16
|
const log = createLogger('useFileUrl');
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Options for the useFileUrl hook.
|
|
20
|
+
*/
|
|
18
21
|
export interface UseFileUrlOptions {
|
|
19
22
|
/** Organisation ID for signed URL generation */
|
|
20
23
|
organisation_id: string | undefined;
|
|
21
24
|
/** Supabase client instance */
|
|
22
|
-
supabase: SupabaseClient;
|
|
25
|
+
supabase: SupabaseClient | null;
|
|
23
26
|
/** Whether to auto-load URLs on mount */
|
|
24
27
|
autoLoad?: boolean;
|
|
25
28
|
}
|
|
@@ -63,6 +66,13 @@ export function useFileUrl(
|
|
|
63
66
|
return;
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
if (!supabase) {
|
|
70
|
+
setUrl(null);
|
|
71
|
+
setIsLoading(false);
|
|
72
|
+
setError(new Error('Supabase client is required for URL generation'));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
66
76
|
// Skip if already loading or URL already exists for this file
|
|
67
77
|
if (isLoading || (url && fileReferenceIdRef.current === fileReference.id)) {
|
|
68
78
|
return;
|