@jmruthers/pace-core 0.6.1 → 0.6.3
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 +88 -10
- package/cursor-rules/00-pace-core-compliance.mdc +46 -87
- package/cursor-rules/01-standards-compliance.mdc +16 -47
- package/cursor-rules/02-project-structure.mdc +4 -4
- package/cursor-rules/03-solid-principles.mdc +45 -164
- package/cursor-rules/04-testing-standards.mdc +22 -69
- package/cursor-rules/05-bug-reports-and-features.mdc +2 -2
- package/cursor-rules/06-code-quality.mdc +42 -125
- package/cursor-rules/07-tech-stack-compliance.mdc +33 -128
- package/cursor-rules/08-markup-quality.mdc +452 -0
- package/cursor-rules/CHANGELOG.md +18 -0
- package/cursor-rules/README.md +2 -1
- package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-Cb34EQs3.d.ts} +63 -1
- package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
- package/dist/{DataTable-DQ7RSOHE.js → DataTable-THFPBKTP.js} +12 -10
- package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DEMpysFR.d.ts} +394 -171
- package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +30 -8
- package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
- package/dist/{api-N774RPUA.js → api-IAGWF3ZG.js} +10 -10
- package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
- package/dist/{chunk-JBKQ3SAO.js → chunk-2T2IG7T7.js} +107 -57
- package/dist/chunk-2T2IG7T7.js.map +1 -0
- package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
- package/dist/chunk-6SOIHG6Z.js.map +1 -0
- package/dist/{chunk-3XTALGJF.js → chunk-6Z7LTB3D.js} +69 -240
- package/dist/chunk-6Z7LTB3D.js.map +1 -0
- package/dist/{chunk-4ZC4GX36.js → chunk-CNCQDFLN.js} +199 -46
- package/dist/chunk-CNCQDFLN.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-BYFSK72L.js → chunk-DWUBLJJM.js} +361 -187
- package/dist/chunk-DWUBLJJM.js.map +1 -0
- package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
- 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-4N5C5XZU.js → chunk-HFZBI76P.js} +4 -4
- package/dist/chunk-HFZBI76P.js.map +1 -0
- package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
- package/dist/chunk-L4OXEN46.js.map +1 -0
- package/dist/{chunk-R77UEZ4E.js → chunk-M43Y4SSO.js} +1 -1
- package/dist/chunk-M43Y4SSO.js.map +1 -0
- package/dist/{chunk-I7PSE6JW.js → chunk-M7MPQISP.js} +3 -76
- package/dist/chunk-M7MPQISP.js.map +1 -0
- package/dist/chunk-PQBSKX33.js +7793 -0
- package/dist/chunk-PQBSKX33.js.map +1 -0
- package/dist/chunk-QRPVRXYT.js +226 -0
- package/dist/chunk-QRPVRXYT.js.map +1 -0
- package/dist/{chunk-KNC55RTG.js → chunk-RWEBCB47.js} +194 -416
- package/dist/chunk-RWEBCB47.js.map +1 -0
- package/dist/{chunk-XM25TVIE.js → chunk-YDQHOZNA.js} +843 -388
- package/dist/chunk-YDQHOZNA.js.map +1 -0
- package/dist/{chunk-GLK6VM3F.js → chunk-ZNIWI3UC.js} +739 -737
- package/dist/chunk-ZNIWI3UC.js.map +1 -0
- package/dist/components.d.ts +5 -5
- package/dist/components.js +18 -16
- package/dist/components.js.map +1 -1
- package/dist/contextValidator-3JNZKUTX.js +9 -0
- package/dist/contextValidator-3JNZKUTX.js.map +1 -0
- package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
- package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
- package/dist/hooks.d.ts +55 -122
- package/dist/hooks.js +10 -13
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +60 -13
- package/dist/index.js +30 -25
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +21 -3
- package/dist/providers.js +4 -3
- package/dist/rbac/index.d.ts +210 -139
- package/dist/rbac/index.js +17 -13
- package/dist/styles/index.js +1 -1
- package/dist/theming/runtime.d.ts +1 -13
- package/dist/theming/runtime.js +2 -2
- 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/types.js +1 -1
- package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +38 -17
- package/dist/utils.d.ts +4 -5
- package/dist/utils.js +17 -19
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +21 -17
- package/docs/api/modules.md +4191 -2967
- package/docs/architecture/database-schema-requirements.md +161 -0
- package/docs/components/context-selector.md +126 -0
- package/docs/core-concepts/rbac-system.md +3 -3
- package/docs/documentation-index.md +2 -4
- package/docs/getting-started/cursor-rules.md +2 -1
- package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
- package/docs/migration/MIGRATION_GUIDE.md +2 -24
- package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
- package/docs/migration/README.md +52 -6
- package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
- package/docs/migration/database-changes-december-2025.md +3 -3
- package/docs/pace-mint-fix-auto-selection.md +218 -0
- package/docs/pace-mint-rbac-setup.md +391 -0
- 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/rbac/secure-client-protection.md +330 -0
- package/docs/standards/README.md +1 -0
- package/package.json +4 -3
- 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} +784 -685
- 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 +985 -0
- package/scripts/audit/core/checks/documentation.cjs +268 -0
- package/scripts/audit/core/checks/environment.cjs +116 -0
- package/scripts/audit/core/checks/error-handling.cjs +340 -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 +61 -936
- 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/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__/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 +14 -0
- package/src/components/Button/Button.tsx +22 -0
- package/src/components/Calendar/Calendar.tsx +8 -2
- 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/ContextSelector/ContextSelector.tsx +384 -0
- package/src/components/ContextSelector/index.ts +3 -0
- package/src/components/DataTable/DataTable.tsx +38 -4
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
- package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
- package/src/components/DataTable/components/ActionButtons.tsx +10 -7
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
- 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 +196 -554
- 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 +8 -0
- 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 +8 -0
- 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 +63 -851
- 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/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 +12 -0
- 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 +127 -33
- package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
- 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/Dialog/Dialog.tsx +31 -3
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
- package/src/components/ErrorBoundary/index.ts +27 -2
- package/src/components/FileDisplay/FileDisplay.tsx +74 -28
- package/src/components/FileUpload/FileUpload.tsx +22 -2
- package/src/components/Footer/Footer.test.tsx +16 -16
- package/src/components/Footer/Footer.tsx +14 -11
- package/src/components/Form/Form.tsx +1 -0
- package/src/components/Header/Header.test.tsx +43 -73
- package/src/components/Header/Header.tsx +59 -49
- package/src/components/Input/Input.test.tsx +2 -2
- package/src/components/Input/Input.tsx +8 -4
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
- package/src/components/LoginForm/LoginForm.tsx +4 -0
- package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
- package/src/components/NavigationMenu/types.ts +56 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +13 -11
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +167 -44
- package/src/components/PaceAppLayout/README.md +14 -17
- package/src/components/PaceAppLayout/test-setup.tsx +3 -4
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
- package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
- package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
- package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
- package/src/components/Select/Select.tsx +80 -434
- 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 +4 -5
- package/src/components/Switch/Switch.tsx +4 -4
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/components/Toast/Toast.tsx +4 -0
- package/src/components/Tooltip/Tooltip.tsx +2 -2
- package/src/components/UserMenu/UserMenu.test.tsx +24 -11
- package/src/components/UserMenu/UserMenu.tsx +21 -18
- package/src/components/index.ts +7 -7
- package/src/eslint-rules/pace-core-compliance.cjs +106 -0
- package/src/hooks/__tests__/index.unit.test.ts +2 -5
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
- package/src/hooks/index.ts +1 -2
- package/src/hooks/public/usePublicEvent.ts +4 -0
- package/src/hooks/public/usePublicEventLogo.ts +4 -0
- package/src/hooks/public/usePublicFileDisplay.ts +4 -0
- package/src/hooks/public/usePublicRouteParams.ts +4 -0
- 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/useAppConfig.ts +15 -30
- package/src/hooks/useDebounce.ts +9 -0
- package/src/hooks/useEventTheme.ts +6 -0
- package/src/hooks/useFileDisplay.ts +81 -50
- package/src/hooks/useFileReference.ts +25 -7
- package/src/hooks/useFileUrl.ts +11 -1
- package/src/hooks/useFocusManagement.ts +14 -0
- package/src/hooks/useFocusTrap.ts +3 -0
- package/src/hooks/useInactivityTracker.ts +3 -0
- 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 +7 -0
- 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 +1 -1
- package/src/index.ts +6 -6
- package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
- package/src/providers/services/AuthServiceProvider.tsx +35 -7
- package/src/providers/services/EventServiceProvider.tsx +51 -5
- package/src/providers/services/InactivityServiceProvider.tsx +18 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +126 -134
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
- package/src/rbac/adapters.tsx +12 -3
- package/src/rbac/api.test.ts +59 -51
- package/src/rbac/api.ts +246 -167
- package/src/rbac/components/NavigationProvider.tsx +4 -1
- package/src/rbac/components/PagePermissionGuard.tsx +185 -17
- package/src/rbac/components/RoleBasedRouter.tsx +5 -1
- package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
- package/src/rbac/components/SecureDataProvider.tsx +20 -5
- 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/__tests__/useSecureSupabase.test.ts +32 -21
- 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 +377 -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 +64 -66
- package/src/rbac/hooks/usePermissions.ts +14 -995
- package/src/rbac/hooks/useRBAC.test.ts +1 -5
- package/src/rbac/hooks/useRBAC.ts +36 -37
- package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
- package/src/rbac/hooks/useResolvedScope.ts +35 -40
- package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
- package/src/rbac/hooks/useResourcePermissions.ts +14 -4
- package/src/rbac/hooks/useSecureSupabase.ts +27 -7
- package/src/rbac/index.ts +7 -0
- package/src/rbac/permissions.ts +0 -30
- package/src/rbac/secureClient.test.ts +22 -18
- package/src/rbac/secureClient.ts +294 -68
- package/src/rbac/security.ts +0 -17
- package/src/rbac/types.ts +9 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
- package/src/rbac/utils/clientSecurity.ts +93 -0
- package/src/rbac/utils/contextValidator.ts +77 -168
- package/src/services/AuthService.ts +39 -7
- package/src/services/EventService.ts +186 -54
- package/src/services/OrganisationService.ts +81 -14
- package/src/services/__tests__/EventService.test.ts +1 -2
- package/src/services/base/BaseService.ts +3 -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/dynamic/dynamicUtils.ts +7 -4
- 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/dist/chunk-3QRJFVBR.js.map +0 -1
- package/dist/chunk-3XTALGJF.js.map +0 -1
- package/dist/chunk-4N5C5XZU.js.map +0 -1
- package/dist/chunk-4ZC4GX36.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-BYFSK72L.js.map +0 -1
- package/dist/chunk-EXUD6RNJ.js +0 -451
- package/dist/chunk-EXUD6RNJ.js.map +0 -1
- package/dist/chunk-GLK6VM3F.js.map +0 -1
- package/dist/chunk-I7PSE6JW.js.map +0 -1
- package/dist/chunk-JBKQ3SAO.js.map +0 -1
- package/dist/chunk-KNC55RTG.js.map +0 -1
- package/dist/chunk-LXQLPRQ2.js.map +0 -1
- package/dist/chunk-R77UEZ4E.js.map +0 -1
- package/dist/chunk-SQGMNID3.js.map +0 -1
- package/dist/chunk-T33XF5ZC.js +0 -12922
- package/dist/chunk-T33XF5ZC.js.map +0 -1
- package/dist/chunk-XM25TVIE.js.map +0 -1
- package/docs/api/classes/ColumnFactory.md +0 -243
- package/docs/api/classes/ErrorBoundary.md +0 -144
- package/docs/api/classes/InvalidScopeError.md +0 -73
- package/docs/api/classes/Logger.md +0 -178
- package/docs/api/classes/MissingUserContextError.md +0 -66
- package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
- package/docs/api/classes/PermissionDeniedError.md +0 -73
- package/docs/api/classes/RBACAuditManager.md +0 -297
- package/docs/api/classes/RBACCache.md +0 -322
- package/docs/api/classes/RBACEngine.md +0 -171
- package/docs/api/classes/RBACError.md +0 -76
- package/docs/api/classes/RBACNotInitializedError.md +0 -66
- package/docs/api/classes/SecureSupabaseClient.md +0 -160
- package/docs/api/classes/StorageUtils.md +0 -328
- package/docs/api/enums/FileCategory.md +0 -184
- package/docs/api/enums/LogLevel.md +0 -54
- package/docs/api/enums/RBACErrorCode.md +0 -228
- package/docs/api/enums/RPCFunction.md +0 -118
- package/docs/api/interfaces/AddressFieldProps.md +0 -241
- package/docs/api/interfaces/AddressFieldRef.md +0 -94
- package/docs/api/interfaces/AggregateConfig.md +0 -43
- package/docs/api/interfaces/AutocompleteOptions.md +0 -75
- package/docs/api/interfaces/AvatarProps.md +0 -128
- package/docs/api/interfaces/BadgeProps.md +0 -27
- package/docs/api/interfaces/ButtonProps.md +0 -53
- package/docs/api/interfaces/CalendarProps.md +0 -70
- package/docs/api/interfaces/CardProps.md +0 -66
- package/docs/api/interfaces/ColorPalette.md +0 -7
- package/docs/api/interfaces/ColorShade.md +0 -66
- package/docs/api/interfaces/ComplianceResult.md +0 -30
- package/docs/api/interfaces/DataAccessRecord.md +0 -96
- package/docs/api/interfaces/DataRecord.md +0 -11
- package/docs/api/interfaces/DataTableAction.md +0 -249
- package/docs/api/interfaces/DataTableColumn.md +0 -504
- package/docs/api/interfaces/DataTableProps.md +0 -625
- package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
- package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
- package/docs/api/interfaces/DatabaseIssue.md +0 -41
- package/docs/api/interfaces/EmptyStateConfig.md +0 -61
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
- package/docs/api/interfaces/EventAppRoleData.md +0 -71
- package/docs/api/interfaces/ExportColumn.md +0 -90
- package/docs/api/interfaces/ExportOptions.md +0 -126
- package/docs/api/interfaces/FileDisplayProps.md +0 -249
- package/docs/api/interfaces/FileMetadata.md +0 -129
- package/docs/api/interfaces/FileReference.md +0 -118
- package/docs/api/interfaces/FileSizeLimits.md +0 -7
- package/docs/api/interfaces/FileUploadOptions.md +0 -139
- package/docs/api/interfaces/FileUploadProps.md +0 -293
- package/docs/api/interfaces/FooterProps.md +0 -105
- package/docs/api/interfaces/FormFieldProps.md +0 -166
- package/docs/api/interfaces/FormProps.md +0 -113
- package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
- package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
- package/docs/api/interfaces/InputProps.md +0 -53
- package/docs/api/interfaces/LabelProps.md +0 -107
- package/docs/api/interfaces/LoggerConfig.md +0 -62
- package/docs/api/interfaces/LoginFormProps.md +0 -184
- package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
- package/docs/api/interfaces/NavigationContextType.md +0 -164
- package/docs/api/interfaces/NavigationGuardProps.md +0 -139
- package/docs/api/interfaces/NavigationItem.md +0 -120
- package/docs/api/interfaces/NavigationMenuProps.md +0 -221
- package/docs/api/interfaces/NavigationProviderProps.md +0 -117
- package/docs/api/interfaces/Organisation.md +0 -140
- package/docs/api/interfaces/OrganisationContextType.md +0 -388
- package/docs/api/interfaces/OrganisationMembership.md +0 -140
- package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
- package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
- package/docs/api/interfaces/PaceAppLayoutProps.md +0 -406
- package/docs/api/interfaces/PaceLoginPageProps.md +0 -47
- package/docs/api/interfaces/PageAccessRecord.md +0 -85
- package/docs/api/interfaces/PagePermissionContextType.md +0 -140
- package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
- package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
- package/docs/api/interfaces/PaletteData.md +0 -41
- package/docs/api/interfaces/ParsedAddress.md +0 -120
- package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
- package/docs/api/interfaces/ProgressProps.md +0 -42
- package/docs/api/interfaces/ProtectedRouteProps.md +0 -97
- package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
- package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
- package/docs/api/interfaces/PublicPageLayoutProps.md +0 -198
- package/docs/api/interfaces/QuickFix.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
- package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
- package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
- package/docs/api/interfaces/RBACConfig.md +0 -133
- package/docs/api/interfaces/RBACContext.md +0 -52
- package/docs/api/interfaces/RBACLogger.md +0 -112
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
- package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
- package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
- package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
- package/docs/api/interfaces/RBACResult.md +0 -58
- package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
- package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
- package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
- package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
- package/docs/api/interfaces/RBACRolesListParams.md +0 -52
- package/docs/api/interfaces/RBACRolesListResult.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
- package/docs/api/interfaces/ResourcePermissions.md +0 -155
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
- package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
- package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
- package/docs/api/interfaces/RoleManagementResult.md +0 -52
- package/docs/api/interfaces/RouteAccessRecord.md +0 -107
- package/docs/api/interfaces/RouteConfig.md +0 -134
- package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
- package/docs/api/interfaces/SecureDataContextType.md +0 -168
- package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
- package/docs/api/interfaces/SetupIssue.md +0 -41
- package/docs/api/interfaces/StorageConfig.md +0 -41
- package/docs/api/interfaces/StorageFileInfo.md +0 -74
- package/docs/api/interfaces/StorageFileMetadata.md +0 -151
- package/docs/api/interfaces/StorageListOptions.md +0 -99
- package/docs/api/interfaces/StorageListResult.md +0 -41
- package/docs/api/interfaces/StorageUploadOptions.md +0 -101
- package/docs/api/interfaces/StorageUploadResult.md +0 -63
- package/docs/api/interfaces/StorageUrlOptions.md +0 -60
- package/docs/api/interfaces/StyleImport.md +0 -19
- package/docs/api/interfaces/SwitchProps.md +0 -34
- package/docs/api/interfaces/TabsContentProps.md +0 -9
- package/docs/api/interfaces/TabsListProps.md +0 -9
- package/docs/api/interfaces/TabsProps.md +0 -9
- package/docs/api/interfaces/TabsTriggerProps.md +0 -50
- package/docs/api/interfaces/TextareaProps.md +0 -53
- package/docs/api/interfaces/ToastActionElement.md +0 -9
- package/docs/api/interfaces/ToastProps.md +0 -9
- package/docs/api/interfaces/UnifiedAuthContextType.md +0 -820
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -171
- package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
- package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -136
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
- package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
- package/docs/api/interfaces/UsePublicEventReturn.md +0 -68
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -120
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -94
- package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
- package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
- package/docs/api/interfaces/UserEventAccess.md +0 -118
- package/docs/api/interfaces/UserMenuProps.md +0 -86
- package/docs/api/interfaces/UserProfile.md +0 -63
- package/docs/migration/quick-migration-guide.md +0 -356
- package/docs/migration/service-architecture.md +0 -281
- package/src/components/EventSelector/EventSelector.test.tsx +0 -720
- package/src/components/EventSelector/EventSelector.tsx +0 -420
- package/src/components/EventSelector/index.ts +0 -3
- package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -324
- package/src/components/OrganisationSelector/index.ts +0 -9
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
- package/src/hooks/useSecureDataAccess.test.ts +0 -559
- package/src/hooks/useSecureDataAccess.ts +0 -681
- /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-THFPBKTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
- /package/dist/{api-N774RPUA.js.map → api-IAGWF3ZG.js.map} +0 -0
- /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.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/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
* ```
|
|
35
35
|
*/
|
|
36
36
|
|
|
37
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
37
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
38
38
|
import type { SupabaseClient } from '@supabase/supabase-js';
|
|
39
39
|
import { FileReference, FileCategory } from '../types/file-reference';
|
|
40
40
|
import { getPublicUrl, getSignedUrl, generateFileUrlsBatch } from '../utils/storage/helpers';
|
|
@@ -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;
|
|
@@ -134,14 +138,25 @@ export function useFileDisplay(
|
|
|
134
138
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
135
139
|
const [error, setError] = useState<Error | null>(null);
|
|
136
140
|
|
|
141
|
+
// Ref to track if component is mounted and effect is active
|
|
142
|
+
// This prevents state updates from stale async operations
|
|
143
|
+
const isMountedRef = useRef(true);
|
|
144
|
+
|
|
145
|
+
// Helper to safely set state only if component is still mounted
|
|
146
|
+
const safeSetState = <T,>(setter: (value: T) => void, value: T) => {
|
|
147
|
+
if (isMountedRef.current) {
|
|
148
|
+
setter(value);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
|
|
137
152
|
const fetchFiles = useCallback(async (): Promise<void> => {
|
|
138
153
|
if (!table_name || !record_id || !supabase) {
|
|
139
|
-
setFileUrl
|
|
140
|
-
setFileReference
|
|
141
|
-
setFileReferences
|
|
142
|
-
setFileUrls
|
|
143
|
-
setFileCount
|
|
144
|
-
setIsLoading
|
|
154
|
+
safeSetState(setFileUrl, null);
|
|
155
|
+
safeSetState(setFileReference, null);
|
|
156
|
+
safeSetState(setFileReferences, []);
|
|
157
|
+
safeSetState(setFileUrls, new Map());
|
|
158
|
+
safeSetState(setFileCount, 0);
|
|
159
|
+
safeSetState(setIsLoading, false);
|
|
145
160
|
return;
|
|
146
161
|
}
|
|
147
162
|
|
|
@@ -173,13 +188,13 @@ export function useFileDisplay(
|
|
|
173
188
|
expiresIn: 3600
|
|
174
189
|
});
|
|
175
190
|
const regeneratedUrl = signedUrlResult?.url || null;
|
|
176
|
-
setFileUrl
|
|
177
|
-
setFileReference
|
|
178
|
-
setFileReferences
|
|
179
|
-
setFileUrls
|
|
180
|
-
setFileCount
|
|
181
|
-
setIsLoading
|
|
182
|
-
setError
|
|
191
|
+
safeSetState(setFileUrl, regeneratedUrl);
|
|
192
|
+
safeSetState(setFileReference, cachedData.fileReference);
|
|
193
|
+
safeSetState(setFileReferences, cachedData.fileReferences || []);
|
|
194
|
+
safeSetState(setFileUrls, cachedData.fileUrls || new Map());
|
|
195
|
+
safeSetState(setFileCount, cachedData.fileCount || 0);
|
|
196
|
+
safeSetState(setIsLoading, false);
|
|
197
|
+
safeSetState(setError, null);
|
|
183
198
|
return;
|
|
184
199
|
} catch (err) {
|
|
185
200
|
// If signed URL regeneration fails, fall through to normal fetch
|
|
@@ -188,20 +203,20 @@ export function useFileDisplay(
|
|
|
188
203
|
}
|
|
189
204
|
|
|
190
205
|
// Normal cache hit for public files or files with URLs
|
|
191
|
-
setFileUrl
|
|
192
|
-
setFileReference
|
|
193
|
-
setFileReferences
|
|
194
|
-
setFileUrls
|
|
195
|
-
setFileCount
|
|
196
|
-
setIsLoading
|
|
197
|
-
setError
|
|
206
|
+
safeSetState(setFileUrl, cachedData.fileUrl || null);
|
|
207
|
+
safeSetState(setFileReference, cachedData.fileReference || null);
|
|
208
|
+
safeSetState(setFileReferences, cachedData.fileReferences || []);
|
|
209
|
+
safeSetState(setFileUrls, cachedData.fileUrls || new Map());
|
|
210
|
+
safeSetState(setFileCount, cachedData.fileCount || 0);
|
|
211
|
+
safeSetState(setIsLoading, false);
|
|
212
|
+
safeSetState(setError, null);
|
|
198
213
|
return;
|
|
199
214
|
}
|
|
200
215
|
}
|
|
201
216
|
|
|
202
217
|
try {
|
|
203
|
-
setIsLoading
|
|
204
|
-
setError
|
|
218
|
+
safeSetState(setIsLoading, true);
|
|
219
|
+
safeSetState(setError, null);
|
|
205
220
|
|
|
206
221
|
const service = createFileReferenceService(supabase);
|
|
207
222
|
let files: FileReference[] = [];
|
|
@@ -481,11 +496,11 @@ export function useFileDisplay(
|
|
|
481
496
|
}
|
|
482
497
|
|
|
483
498
|
if (files.length === 0) {
|
|
484
|
-
setFileUrl
|
|
485
|
-
setFileReference
|
|
486
|
-
setFileReferences
|
|
487
|
-
setFileUrls
|
|
488
|
-
setFileCount
|
|
499
|
+
safeSetState(setFileUrl, null);
|
|
500
|
+
safeSetState(setFileReference, null);
|
|
501
|
+
safeSetState(setFileReferences, []);
|
|
502
|
+
safeSetState(setFileUrls, new Map());
|
|
503
|
+
safeSetState(setFileCount, 0);
|
|
489
504
|
|
|
490
505
|
// Cache empty result
|
|
491
506
|
if (enableCache) {
|
|
@@ -499,14 +514,14 @@ export function useFileDisplay(
|
|
|
499
514
|
return;
|
|
500
515
|
}
|
|
501
516
|
|
|
502
|
-
setFileReferences
|
|
503
|
-
setFileCount
|
|
517
|
+
safeSetState(setFileReferences, files);
|
|
518
|
+
safeSetState(setFileCount, files.length);
|
|
504
519
|
|
|
505
520
|
if (category && files.length > 0) {
|
|
506
521
|
// Single file mode - get first file
|
|
507
522
|
const firstFile = files[0];
|
|
508
523
|
// Removed verbose debug logs - only log on errors
|
|
509
|
-
setFileReference
|
|
524
|
+
safeSetState(setFileReference, firstFile);
|
|
510
525
|
|
|
511
526
|
// Generate URL based on file visibility
|
|
512
527
|
let url: string | null = null;
|
|
@@ -529,7 +544,7 @@ export function useFileDisplay(
|
|
|
529
544
|
});
|
|
530
545
|
}
|
|
531
546
|
}
|
|
532
|
-
setFileUrl
|
|
547
|
+
safeSetState(setFileUrl, url);
|
|
533
548
|
} else {
|
|
534
549
|
// Multiple files mode - generate URLs for all files in batch
|
|
535
550
|
const urlMap = await generateFileUrlsBatch(supabase, files, {
|
|
@@ -538,9 +553,9 @@ export function useFileDisplay(
|
|
|
538
553
|
userId: organisation_id ? undefined : record_id,
|
|
539
554
|
expiresIn: 3600
|
|
540
555
|
});
|
|
541
|
-
setFileUrls
|
|
542
|
-
setFileReference
|
|
543
|
-
setFileUrl
|
|
556
|
+
safeSetState(setFileUrls, urlMap);
|
|
557
|
+
safeSetState(setFileReference, null);
|
|
558
|
+
safeSetState(setFileUrl, null);
|
|
544
559
|
}
|
|
545
560
|
|
|
546
561
|
// Cache the result
|
|
@@ -584,30 +599,46 @@ export function useFileDisplay(
|
|
|
584
599
|
} catch (err) {
|
|
585
600
|
logger.error('useFileDisplay', 'Error fetching files:', err);
|
|
586
601
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
587
|
-
setError
|
|
588
|
-
setFileUrl
|
|
589
|
-
setFileReference
|
|
590
|
-
setFileReferences
|
|
591
|
-
setFileUrls
|
|
592
|
-
setFileCount
|
|
602
|
+
safeSetState(setError, error);
|
|
603
|
+
safeSetState(setFileUrl, null);
|
|
604
|
+
safeSetState(setFileReference, null);
|
|
605
|
+
safeSetState(setFileReferences, []);
|
|
606
|
+
safeSetState(setFileUrls, new Map());
|
|
607
|
+
safeSetState(setFileCount, 0);
|
|
593
608
|
} finally {
|
|
594
|
-
setIsLoading
|
|
609
|
+
safeSetState(setIsLoading, false);
|
|
595
610
|
}
|
|
596
611
|
}, [table_name, record_id, organisation_id, category, supabase, cacheTtl, enableCache]);
|
|
597
612
|
|
|
598
613
|
// Fetch files when parameters change
|
|
599
614
|
useEffect(() => {
|
|
615
|
+
// Mark as mounted when effect runs
|
|
616
|
+
isMountedRef.current = true;
|
|
617
|
+
|
|
600
618
|
if (table_name && record_id && supabase) {
|
|
601
|
-
fetchFiles
|
|
619
|
+
// Call fetchFiles - it will check isMountedRef before setting state
|
|
620
|
+
fetchFiles().catch((err) => {
|
|
621
|
+
// Only set error if component is still mounted
|
|
622
|
+
if (isMountedRef.current) {
|
|
623
|
+
safeSetState(setError, err instanceof Error ? err : new Error('Unknown error'));
|
|
624
|
+
}
|
|
625
|
+
});
|
|
602
626
|
} else {
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
627
|
+
// Only update state if component is still mounted
|
|
628
|
+
safeSetState(setFileUrl, null);
|
|
629
|
+
safeSetState(setFileReference, null);
|
|
630
|
+
safeSetState(setFileReferences, []);
|
|
631
|
+
safeSetState(setFileUrls, new Map());
|
|
632
|
+
safeSetState(setFileCount, 0);
|
|
633
|
+
safeSetState(setIsLoading, false);
|
|
634
|
+
safeSetState(setError, null);
|
|
610
635
|
}
|
|
636
|
+
|
|
637
|
+
// Cleanup: mark as unmounted when dependencies change or component unmounts
|
|
638
|
+
// This prevents state updates from stale requests
|
|
639
|
+
return () => {
|
|
640
|
+
isMountedRef.current = false;
|
|
641
|
+
};
|
|
611
642
|
// fetchFiles is memoized; we only need to re-run when parameters change
|
|
612
643
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
613
644
|
}, [table_name, record_id, organisation_id, supabase]);
|
|
@@ -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;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
import { useRef, useCallback, useEffect } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Options for the useFocusManagement hook.
|
|
6
|
+
*/
|
|
4
7
|
export interface FocusManagementOptions {
|
|
5
8
|
trapFocus?: boolean;
|
|
6
9
|
autoFocus?: boolean;
|
|
@@ -10,6 +13,10 @@ export interface FocusManagementOptions {
|
|
|
10
13
|
onFocusLast?: () => void;
|
|
11
14
|
}
|
|
12
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Return value of the useFocusManagement hook.
|
|
18
|
+
* Provides focus management utilities for accessible components.
|
|
19
|
+
*/
|
|
13
20
|
export interface FocusManagementReturn {
|
|
14
21
|
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
15
22
|
focusRef: React.RefObject<HTMLElement | null>;
|
|
@@ -22,6 +29,13 @@ export interface FocusManagementReturn {
|
|
|
22
29
|
handleEscape: (callback: () => void) => () => void;
|
|
23
30
|
}
|
|
24
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Hook for managing focus in accessible components.
|
|
34
|
+
* Provides focus trapping, restoration, and navigation utilities.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Focus management configuration
|
|
37
|
+
* @returns Focus management utilities and refs
|
|
38
|
+
*/
|
|
25
39
|
export function useFocusManagement(options: FocusManagementOptions = {}): FocusManagementReturn {
|
|
26
40
|
const {
|
|
27
41
|
trapFocus = false,
|
|
@@ -55,6 +55,9 @@
|
|
|
55
55
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
56
56
|
import { logger } from '../utils/core/logger';
|
|
57
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Options for the useInactivityTracker hook.
|
|
60
|
+
*/
|
|
58
61
|
export interface UseInactivityTrackerOptions {
|
|
59
62
|
/** Timeout in milliseconds before user is considered idle (default: 30 minutes) */
|
|
60
63
|
idleTimeoutMs?: number;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { useEffect, useCallback } from 'react';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Keyboard shortcut definition.
|
|
5
|
+
* Defines a key combination and its handler function.
|
|
6
|
+
*/
|
|
3
7
|
export interface KeyboardShortcut {
|
|
4
8
|
/** Key combination (e.g., 'Escape', 'Enter', 'ArrowDown', 'ctrl+s') */
|
|
5
9
|
key: string;
|
|
@@ -50,6 +50,10 @@ import { useOrganisations } from './useOrganisations';
|
|
|
50
50
|
import { useOrganisationSecurity } from './useOrganisationSecurity';
|
|
51
51
|
import type { OrganisationRole, OrganisationPermission } from '../types/organisation';
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Return value of the useOrganisationPermissions hook.
|
|
55
|
+
* Provides organisation-specific permissions and role information.
|
|
56
|
+
*/
|
|
53
57
|
export interface UseOrganisationPermissionsReturn {
|
|
54
58
|
/** User's role in the organisation */
|
|
55
59
|
userRole: OrganisationRole | 'no_access';
|
|
@@ -16,6 +16,10 @@ import type { OrganisationSecurityError, SuperAdminContext } from '../types/orga
|
|
|
16
16
|
import type { Permission } from '../rbac/types';
|
|
17
17
|
import { logger } from '../utils/core/logger';
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Organisation security hook interface.
|
|
21
|
+
* Provides security utilities for organisation access validation and super admin functionality.
|
|
22
|
+
*/
|
|
19
23
|
export interface OrganisationSecurityHook {
|
|
20
24
|
// Super admin context
|
|
21
25
|
superAdminContext: SuperAdminContext;
|
|
@@ -5,6 +5,10 @@ import { createLogger } from '../utils/core/logger';
|
|
|
5
5
|
|
|
6
6
|
const log = createLogger('usePerformanceMonitor');
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Performance metrics interface.
|
|
10
|
+
* Represents performance measurement data for components or operations.
|
|
11
|
+
*/
|
|
8
12
|
export interface PerformanceMetrics {
|
|
9
13
|
renderTime: number;
|
|
10
14
|
componentName: string;
|
|
@@ -103,6 +103,13 @@ const DEFAULT_CONFIG: CacheConfig = {
|
|
|
103
103
|
enableAuditTrail: true
|
|
104
104
|
};
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Hook for centralized permission caching.
|
|
108
|
+
* Provides intelligent caching with automatic invalidation for permission checks.
|
|
109
|
+
*
|
|
110
|
+
* @param config - Optional cache configuration
|
|
111
|
+
* @returns Permission cache utilities including check functions and debug info
|
|
112
|
+
*/
|
|
106
113
|
export function usePermissionCache(config: Partial<CacheConfig> = {}) {
|
|
107
114
|
const mergedConfig = useMemo(() => ({ ...DEFAULT_CONFIG, ...config }), [config]);
|
|
108
115
|
|
|
@@ -127,6 +127,13 @@ export interface UseQueryCacheReturn {
|
|
|
127
127
|
* );
|
|
128
128
|
* ```
|
|
129
129
|
*/
|
|
130
|
+
/**
|
|
131
|
+
* Hook for in-memory query result caching.
|
|
132
|
+
* Provides caching for frequently accessed data to eliminate duplicate queries.
|
|
133
|
+
*
|
|
134
|
+
* @param supabase - Optional Supabase client instance
|
|
135
|
+
* @returns Query cache utilities including get, invalidate, and clear functions
|
|
136
|
+
*/
|
|
130
137
|
export function useQueryCache(supabase?: SupabaseClient<Database>): UseQueryCacheReturn {
|
|
131
138
|
const getCachedQuery = useCallback(async <T,>(
|
|
132
139
|
table: string,
|
|
@@ -218,7 +225,11 @@ export function useQueryCache(supabase?: SupabaseClient<Database>): UseQueryCach
|
|
|
218
225
|
/**
|
|
219
226
|
* Pre-configured cache helpers for common queries
|
|
220
227
|
*/
|
|
221
|
-
export const queryCacheHelpers
|
|
228
|
+
export const queryCacheHelpers: {
|
|
229
|
+
pacePersonByUserId: <T>(supabase: SupabaseClient<Database>, userId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
230
|
+
paceMemberByPersonId: <T>(supabase: SupabaseClient<Database>, personId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
231
|
+
rbacAppPagesByAppId: <T>(supabase: SupabaseClient<Database>, appId: string, fetchFn: () => Promise<T>) => Promise<T>;
|
|
232
|
+
} = {
|
|
222
233
|
/**
|
|
223
234
|
* Cache core_person queries by user_id
|
|
224
235
|
* TTL: 5 minutes
|
|
@@ -18,6 +18,10 @@ const log = createLogger('useSessionRestoration');
|
|
|
18
18
|
|
|
19
19
|
const SESSION_RESTORATION_TIMEOUT_MS = 5000;
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Return value of the useSessionRestoration hook.
|
|
23
|
+
* Extends SessionRestorationState with timeout information.
|
|
24
|
+
*/
|
|
21
25
|
export interface UseSessionRestorationResult extends SessionRestorationState {
|
|
22
26
|
/** Indicates whether the restoration process exceeded the timeout window */
|
|
23
27
|
hasTimedOut: boolean;
|
package/src/hooks/useStorage.ts
CHANGED
|
@@ -27,6 +27,10 @@ export interface UseStorageOptions {
|
|
|
27
27
|
orgId: string;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Return value of the useStorage hook.
|
|
32
|
+
* Provides storage operations including upload, URL generation, file management, and listing.
|
|
33
|
+
*/
|
|
30
34
|
export interface UseStorageReturn {
|
|
31
35
|
// Upload
|
|
32
36
|
uploadFile: (file: File, options?: Partial<StorageUploadOptions>) => Promise<StorageUploadResult>;
|
package/src/hooks/useToast.ts
CHANGED
|
@@ -71,7 +71,7 @@ const listeners: Array<(state: State) => void> = []
|
|
|
71
71
|
/**
|
|
72
72
|
* Reset the toast state and clear all timeouts
|
|
73
73
|
*/
|
|
74
|
-
export function reset() {
|
|
74
|
+
export function reset(): void {
|
|
75
75
|
memoryState = { toasts: [] }
|
|
76
76
|
toastTimeouts.forEach((timeout) => clearTimeout(timeout))
|
|
77
77
|
toastTimeouts.clear()
|
package/src/index.ts
CHANGED
|
@@ -224,16 +224,16 @@ export { ProtectedRoute } from './components/ProtectedRoute/ProtectedRoute';
|
|
|
224
224
|
export type { ProtectedRouteProps } from './components/ProtectedRoute/ProtectedRoute';
|
|
225
225
|
|
|
226
226
|
// UTILITY COMPONENTS
|
|
227
|
-
export { ErrorBoundary } from './components/ErrorBoundary
|
|
227
|
+
export { ErrorBoundary, ErrorBoundaryProvider } from './components/ErrorBoundary';
|
|
228
|
+
export type { ErrorBoundaryProps, ErrorBoundaryState, ErrorBoundaryProviderProps, GlobalErrorHandler } from './components/ErrorBoundary';
|
|
228
229
|
export { LoadingSpinner } from './components/LoadingSpinner/LoadingSpinner';
|
|
229
230
|
export { SessionRestorationLoader } from './components/SessionRestorationLoader/SessionRestorationLoader';
|
|
230
231
|
export type { SessionRestorationLoaderProps } from './components/SessionRestorationLoader/SessionRestorationLoader';
|
|
231
232
|
|
|
232
|
-
//
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
export { OrganisationSelector } from './components/OrganisationSelector/OrganisationSelector';
|
|
233
|
+
// CONTEXT SELECTION
|
|
234
|
+
// Unified context selector (shows all accessible orgs and events)
|
|
235
|
+
export { ContextSelector } from './components/ContextSelector/ContextSelector';
|
|
236
|
+
export type { ContextSelectorProps } from './components/ContextSelector/ContextSelector';
|
|
237
237
|
export { useOrganisationPermissions } from './hooks/useOrganisationPermissions';
|
|
238
238
|
export { useOrganisationSecurity } from './hooks/useOrganisationSecurity';
|
|
239
239
|
export { createSecureDataAccess } from './utils/security/secureDataAccess';
|