@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
|
@@ -11,6 +11,10 @@ import { flexRender, type Table as TanStackTable, type Cell, type Row } from '@t
|
|
|
11
11
|
import { cn } from '../../../utils/core/cn';
|
|
12
12
|
import type { DataRecord } from '../types';
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Props for the VirtualizedDataTable component.
|
|
16
|
+
* @template TData - The type of data records in the table
|
|
17
|
+
*/
|
|
14
18
|
export interface VirtualizedDataTableProps<TData extends DataRecord> {
|
|
15
19
|
table: TanStackTable<TData>;
|
|
16
20
|
height?: number;
|
|
@@ -42,8 +46,8 @@ MemoizedCell.displayName = 'MemoizedCell';
|
|
|
42
46
|
/**
|
|
43
47
|
* Memoized row component for performance
|
|
44
48
|
*/
|
|
45
|
-
const MemoizedRow = memo(
|
|
46
|
-
row: Row<
|
|
49
|
+
const MemoizedRow = memo(({ row, style }: {
|
|
50
|
+
row: Row<DataRecord>;
|
|
47
51
|
style: React.CSSProperties;
|
|
48
52
|
}) => {
|
|
49
53
|
return (
|
|
@@ -228,7 +232,7 @@ export function VirtualizedDataTable<TData extends DataRecord>({
|
|
|
228
232
|
return (
|
|
229
233
|
<MemoizedRow
|
|
230
234
|
key={row.id}
|
|
231
|
-
row={row}
|
|
235
|
+
row={row as unknown as Row<DataRecord>}
|
|
232
236
|
style={{
|
|
233
237
|
position: 'absolute',
|
|
234
238
|
top: 0,
|
|
@@ -284,6 +288,14 @@ export interface EnhancedVirtualizedDataTableProps<TData extends DataRecord>
|
|
|
284
288
|
getRowId?: (row: TData) => string;
|
|
285
289
|
}
|
|
286
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Enhanced virtualized DataTable component.
|
|
293
|
+
* Provides virtual scrolling for large datasets with performance optimizations.
|
|
294
|
+
*
|
|
295
|
+
* @template TData - The type of data records in the table
|
|
296
|
+
* @param props - Virtualized table configuration
|
|
297
|
+
* @returns The rendered virtualized table
|
|
298
|
+
*/
|
|
287
299
|
export function EnhancedVirtualizedDataTable<TData extends DataRecord>({
|
|
288
300
|
table,
|
|
289
301
|
height = 400,
|
|
@@ -472,7 +484,7 @@ export function EnhancedVirtualizedDataTable<TData extends DataRecord>({
|
|
|
472
484
|
return (
|
|
473
485
|
<MemoizedRow
|
|
474
486
|
key={row.id}
|
|
475
|
-
row={row}
|
|
487
|
+
row={row as unknown as Row<DataRecord>}
|
|
476
488
|
style={{
|
|
477
489
|
position: 'absolute',
|
|
478
490
|
top: 0,
|
|
@@ -407,7 +407,7 @@ describe('[component] AccessDeniedPage', () => {
|
|
|
407
407
|
it('has proper semantic structure', () => {
|
|
408
408
|
render(<AccessDeniedPage resource="users" />);
|
|
409
409
|
|
|
410
|
-
const heading = screen.getByRole('heading', { level:
|
|
410
|
+
const heading = screen.getByRole('heading', { level: 3 });
|
|
411
411
|
expect(heading).toHaveTextContent('Access Denied');
|
|
412
412
|
});
|
|
413
413
|
|
|
@@ -471,7 +471,9 @@ describe('[component] AccessDeniedPage', () => {
|
|
|
471
471
|
const { container } = render(<AccessDeniedPage resource="users" />);
|
|
472
472
|
|
|
473
473
|
const mainContainer = container.firstChild;
|
|
474
|
-
|
|
474
|
+
// AccessDeniedPage uses Card component, which has its own layout classes
|
|
475
|
+
expect(mainContainer).toBeInTheDocument();
|
|
476
|
+
expect(mainContainer).toHaveClass('max-w-md', 'w-full', 'text-center');
|
|
475
477
|
});
|
|
476
478
|
|
|
477
479
|
it('renders Card component', async () => {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { CellValue, DataRecord } from '../types';
|
|
2
|
+
|
|
3
|
+
const isCellValue = (value: unknown): value is CellValue => {
|
|
4
|
+
if (value === null || value === undefined) {
|
|
5
|
+
return true;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (value instanceof Date) {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const valueType = typeof value;
|
|
13
|
+
return valueType === 'string' || valueType === 'number' || valueType === 'boolean';
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Converts a data record to a cell value record.
|
|
18
|
+
* Filters and converts values to valid cell values (string, number, boolean, Date, null, undefined).
|
|
19
|
+
*
|
|
20
|
+
* @template TData - The type of data records
|
|
21
|
+
* @param row - The data record to convert
|
|
22
|
+
* @returns A record with cell-compatible values
|
|
23
|
+
*/
|
|
24
|
+
export const toCellValueRecord = <TData extends DataRecord>(row: TData): Record<string, CellValue> => {
|
|
25
|
+
if (typeof row !== 'object' || row === null) {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return Object.entries(row).reduce<Record<string, CellValue>>((accumulator, [key, entryValue]) => {
|
|
30
|
+
if (isCellValue(entryValue)) {
|
|
31
|
+
accumulator[key] = entryValue;
|
|
32
|
+
} else if (entryValue && typeof entryValue === 'object' && 'toString' in entryValue) {
|
|
33
|
+
accumulator[key] = String(entryValue) as CellValue;
|
|
34
|
+
} else {
|
|
35
|
+
accumulator[key] = entryValue as CellValue;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return accumulator;
|
|
39
|
+
}, {});
|
|
40
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
import type { UseKeyboardNavigationReturn } from '../../hooks/useKeyboardNavigation';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook for managing focus when the import modal opens/closes.
|
|
6
|
+
* Stores and restores focus to maintain keyboard navigation flow.
|
|
7
|
+
*
|
|
8
|
+
* @param isImportOpen - Whether the import modal is currently open
|
|
9
|
+
* @param keyboardNavigation - Keyboard navigation utilities
|
|
10
|
+
* @returns Object with last focused element reference
|
|
11
|
+
*/
|
|
12
|
+
export function useImportModalFocus(isImportOpen: boolean, keyboardNavigation: UseKeyboardNavigationReturn) {
|
|
13
|
+
const lastFocusedElementRef = useRef<HTMLElement | null>(null);
|
|
14
|
+
const wasImportModalOpenRef = useRef(false);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (isImportOpen) {
|
|
18
|
+
wasImportModalOpenRef.current = true;
|
|
19
|
+
keyboardNavigation.storeFocus();
|
|
20
|
+
if (document.activeElement instanceof HTMLElement) {
|
|
21
|
+
lastFocusedElementRef.current = document.activeElement;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}, [isImportOpen, keyboardNavigation]);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (isImportOpen) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!wasImportModalOpenRef.current) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
wasImportModalOpenRef.current = false;
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
const storedElement = lastFocusedElementRef.current;
|
|
38
|
+
lastFocusedElementRef.current = null;
|
|
39
|
+
|
|
40
|
+
const elementToRestore = storedElement?.isConnected
|
|
41
|
+
? storedElement
|
|
42
|
+
: document.querySelector<HTMLElement>('[data-restore-target="datatable-import-button"]');
|
|
43
|
+
|
|
44
|
+
if (elementToRestore && typeof elementToRestore.focus === 'function') {
|
|
45
|
+
elementToRestore.focus();
|
|
46
|
+
} else {
|
|
47
|
+
keyboardNavigation.restoreFocus();
|
|
48
|
+
}
|
|
49
|
+
}, 100);
|
|
50
|
+
}, [isImportOpen, keyboardNavigation]);
|
|
51
|
+
|
|
52
|
+
return { lastFocusedElementRef };
|
|
53
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { UseDataTablePermissionsReturn } from '../../hooks/useDataTablePermissions';
|
|
3
|
+
import type { createLogger } from '../../../../utils/core/logger';
|
|
4
|
+
|
|
5
|
+
interface PermissionTrackingParams {
|
|
6
|
+
permissions: UseDataTablePermissionsReturn['permissions'];
|
|
7
|
+
effectivePageId?: string;
|
|
8
|
+
logger: ReturnType<typeof createLogger>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Result of permission tracking hook.
|
|
13
|
+
* Provides timing information and loading state for permission checks.
|
|
14
|
+
*/
|
|
15
|
+
export interface PermissionTrackingResult {
|
|
16
|
+
permissionElapsed: number;
|
|
17
|
+
shouldAllowRenderAfterTimeout: boolean;
|
|
18
|
+
isPermissionLoading: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook for tracking permission check performance.
|
|
23
|
+
* Monitors permission loading times and provides warnings for slow checks.
|
|
24
|
+
*
|
|
25
|
+
* @param params - Permission tracking configuration
|
|
26
|
+
* @returns Permission tracking results including elapsed time and loading state
|
|
27
|
+
*/
|
|
28
|
+
export function usePermissionTracking({
|
|
29
|
+
permissions,
|
|
30
|
+
effectivePageId,
|
|
31
|
+
logger,
|
|
32
|
+
}: PermissionTrackingParams): PermissionTrackingResult {
|
|
33
|
+
const permissionCheckStartTime = React.useRef<number | null>(null);
|
|
34
|
+
const permissionTimeoutId = React.useRef<NodeJS.Timeout | null>(null);
|
|
35
|
+
const permissionWarningTimeoutId = React.useRef<NodeJS.Timeout | null>(null);
|
|
36
|
+
const hasStartedTracking = React.useRef<boolean>(false);
|
|
37
|
+
const [permissionSlowWarning, setPermissionSlowWarning] = React.useState(false);
|
|
38
|
+
|
|
39
|
+
React.useEffect(() => {
|
|
40
|
+
if (permissions.canRead.isLoading && !hasStartedTracking.current) {
|
|
41
|
+
hasStartedTracking.current = true;
|
|
42
|
+
permissionCheckStartTime.current = Date.now();
|
|
43
|
+
logger.debug('DataTable: Permission check started', {
|
|
44
|
+
pageId: effectivePageId,
|
|
45
|
+
timestamp: permissionCheckStartTime.current,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
if (permissionWarningTimeoutId.current) {
|
|
49
|
+
clearTimeout(permissionWarningTimeoutId.current);
|
|
50
|
+
}
|
|
51
|
+
if (permissionTimeoutId.current) {
|
|
52
|
+
clearTimeout(permissionTimeoutId.current);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
permissionWarningTimeoutId.current = setTimeout(() => {
|
|
56
|
+
const elapsed = permissionCheckStartTime.current ? Date.now() - permissionCheckStartTime.current : 0;
|
|
57
|
+
logger.warn('DataTable: Permission check taking longer than expected (>2s)', {
|
|
58
|
+
pageId: effectivePageId,
|
|
59
|
+
elapsedMs: elapsed,
|
|
60
|
+
diagnostic: 'Permission checks should complete in <1s. This may indicate slow database queries or network issues.',
|
|
61
|
+
});
|
|
62
|
+
setPermissionSlowWarning(true);
|
|
63
|
+
}, 2000);
|
|
64
|
+
|
|
65
|
+
permissionTimeoutId.current = setTimeout(() => {
|
|
66
|
+
const elapsed = permissionCheckStartTime.current ? Date.now() - permissionCheckStartTime.current : 0;
|
|
67
|
+
logger.warn('DataTable: Permission check taking longer than expected (>5s)', {
|
|
68
|
+
pageId: effectivePageId,
|
|
69
|
+
elapsedMs: elapsed,
|
|
70
|
+
permissionState: {
|
|
71
|
+
isLoading: permissions.canRead.isLoading,
|
|
72
|
+
can: permissions.canRead.can,
|
|
73
|
+
error: permissions.canRead.error?.message,
|
|
74
|
+
},
|
|
75
|
+
diagnostic: 'This may indicate slow database queries or network issues. Check scope resolution and permission check performance.',
|
|
76
|
+
});
|
|
77
|
+
}, 5000);
|
|
78
|
+
} else if (!permissions.canRead.isLoading && hasStartedTracking.current) {
|
|
79
|
+
if (permissionCheckStartTime.current) {
|
|
80
|
+
const elapsed = Date.now() - permissionCheckStartTime.current;
|
|
81
|
+
if (elapsed > 1000) {
|
|
82
|
+
logger.warn('DataTable: Permission check took longer than expected', {
|
|
83
|
+
pageId: effectivePageId,
|
|
84
|
+
elapsedMs: elapsed,
|
|
85
|
+
can: permissions.canRead.can,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
permissionCheckStartTime.current = null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
hasStartedTracking.current = false;
|
|
92
|
+
|
|
93
|
+
if (permissionWarningTimeoutId.current) {
|
|
94
|
+
clearTimeout(permissionWarningTimeoutId.current);
|
|
95
|
+
permissionWarningTimeoutId.current = null;
|
|
96
|
+
}
|
|
97
|
+
if (permissionTimeoutId.current) {
|
|
98
|
+
clearTimeout(permissionTimeoutId.current);
|
|
99
|
+
permissionTimeoutId.current = null;
|
|
100
|
+
}
|
|
101
|
+
setPermissionSlowWarning(false);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return () => {
|
|
105
|
+
if (permissionWarningTimeoutId.current) {
|
|
106
|
+
clearTimeout(permissionWarningTimeoutId.current);
|
|
107
|
+
}
|
|
108
|
+
if (permissionTimeoutId.current) {
|
|
109
|
+
clearTimeout(permissionTimeoutId.current);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
}, [permissions.canRead.isLoading, effectivePageId, logger, permissions.canRead.can, permissions.canRead.error]);
|
|
113
|
+
|
|
114
|
+
const permissionElapsed = permissionCheckStartTime.current ? Date.now() - permissionCheckStartTime.current : 0;
|
|
115
|
+
const shouldAllowRenderAfterTimeout = permissionElapsed > 3000;
|
|
116
|
+
|
|
117
|
+
if (permissionSlowWarning) {
|
|
118
|
+
// state is only used for logging; keep hook returning derived values
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
permissionElapsed,
|
|
123
|
+
shouldAllowRenderAfterTimeout,
|
|
124
|
+
isPermissionLoading: permissions.canRead.isLoading && !shouldAllowRenderAfterTimeout,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -20,6 +20,12 @@ import type {
|
|
|
20
20
|
// CONTEXT INTERFACE
|
|
21
21
|
// ============================================================================
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* Context value interface for DataTable.
|
|
25
|
+
* Provides state, actions, computed values, and utility functions.
|
|
26
|
+
*
|
|
27
|
+
* @template TData - The type of data records in the table
|
|
28
|
+
*/
|
|
23
29
|
export interface DataTableContextValue<TData extends DataRecord> {
|
|
24
30
|
state: DataTableState<TData>;
|
|
25
31
|
actions: ReturnType<typeof useDataTableStateHook<TData>>['actions'];
|
|
@@ -37,11 +43,23 @@ const DataTableContext = createContext<DataTableContextValue<DataRecord> | null>
|
|
|
37
43
|
// PROVIDER COMPONENT
|
|
38
44
|
// ============================================================================
|
|
39
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Props for the DataTableProvider component.
|
|
48
|
+
* @template TData - The type of data records in the table
|
|
49
|
+
*/
|
|
40
50
|
export interface DataTableProviderProps<TData extends DataRecord> {
|
|
41
51
|
children: React.ReactNode;
|
|
42
52
|
options?: UseDataTableStateOptions<TData>;
|
|
43
53
|
}
|
|
44
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Context provider component for DataTable.
|
|
57
|
+
* Provides state management and actions to child components.
|
|
58
|
+
*
|
|
59
|
+
* @template TData - The type of data records in the table
|
|
60
|
+
* @param props - Provider configuration
|
|
61
|
+
* @returns The context provider
|
|
62
|
+
*/
|
|
45
63
|
export function DataTableProvider<TData extends DataRecord>({
|
|
46
64
|
children,
|
|
47
65
|
options = {}
|
|
@@ -66,6 +84,14 @@ export function DataTableProvider<TData extends DataRecord>({
|
|
|
66
84
|
// HOOKS
|
|
67
85
|
// ============================================================================
|
|
68
86
|
|
|
87
|
+
/**
|
|
88
|
+
* Hook to access DataTable context.
|
|
89
|
+
* Must be used within a DataTableProvider.
|
|
90
|
+
*
|
|
91
|
+
* @template TData - The type of data records in the table
|
|
92
|
+
* @returns DataTable context value
|
|
93
|
+
* @throws Error if used outside DataTableProvider
|
|
94
|
+
*/
|
|
69
95
|
export function useDataTableContext<TData extends DataRecord>(): DataTableContextValue<TData> {
|
|
70
96
|
const context = useContext(DataTableContext);
|
|
71
97
|
|
|
@@ -76,21 +102,45 @@ export function useDataTableContext<TData extends DataRecord>(): DataTableContex
|
|
|
76
102
|
return context as DataTableContextValue<TData>;
|
|
77
103
|
}
|
|
78
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Hook to access DataTable state from context.
|
|
107
|
+
*
|
|
108
|
+
* @template TData - The type of data records in the table
|
|
109
|
+
* @returns Current table state
|
|
110
|
+
*/
|
|
79
111
|
export function useDataTableState<TData extends DataRecord>() {
|
|
80
112
|
const { state } = useDataTableContext<TData>();
|
|
81
113
|
return state;
|
|
82
114
|
}
|
|
83
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Hook to access DataTable actions from context.
|
|
118
|
+
*
|
|
119
|
+
* @template TData - The type of data records in the table
|
|
120
|
+
* @returns Table state actions
|
|
121
|
+
*/
|
|
84
122
|
export function useDataTableActions<TData extends DataRecord>() {
|
|
85
123
|
const { actions } = useDataTableContext<TData>();
|
|
86
124
|
return actions;
|
|
87
125
|
}
|
|
88
126
|
|
|
127
|
+
/**
|
|
128
|
+
* Hook to access DataTable computed values from context.
|
|
129
|
+
*
|
|
130
|
+
* @template TData - The type of data records in the table
|
|
131
|
+
* @returns Computed table values
|
|
132
|
+
*/
|
|
89
133
|
export function useDataTableComputed<TData extends DataRecord>() {
|
|
90
134
|
const { computed } = useDataTableContext<TData>();
|
|
91
135
|
return computed;
|
|
92
136
|
}
|
|
93
137
|
|
|
138
|
+
/**
|
|
139
|
+
* Hook to access the clear filters function from context.
|
|
140
|
+
*
|
|
141
|
+
* @template TData - The type of data records in the table
|
|
142
|
+
* @returns Function to clear all table filters
|
|
143
|
+
*/
|
|
94
144
|
export function useDataTableClearFilters<TData extends DataRecord>() {
|
|
95
145
|
const { clearFilters } = useDataTableContext<TData>();
|
|
96
146
|
return clearFilters;
|
|
@@ -12,6 +12,9 @@ import type { DataRecord, DataTableAction } from '../types';
|
|
|
12
12
|
// COLUMN OPTIONS INTERFACES
|
|
13
13
|
// ============================================================================
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Options for text column configuration.
|
|
17
|
+
*/
|
|
15
18
|
export interface TextColumnOptions {
|
|
16
19
|
label?: string;
|
|
17
20
|
sortable?: boolean;
|
|
@@ -25,20 +28,36 @@ export interface TextColumnOptions {
|
|
|
25
28
|
maxSize?: number;
|
|
26
29
|
}
|
|
27
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Options for number column configuration.
|
|
33
|
+
* Extends TextColumnOptions with number-specific formatting.
|
|
34
|
+
*/
|
|
28
35
|
export interface NumberColumnOptions extends TextColumnOptions {
|
|
29
36
|
format?: (value: number) => string;
|
|
30
37
|
}
|
|
31
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Options for date column configuration.
|
|
41
|
+
* Extends TextColumnOptions with date-specific formatting and locale options.
|
|
42
|
+
*/
|
|
32
43
|
export interface DateColumnOptions extends TextColumnOptions {
|
|
33
44
|
format?: (date: Date) => string;
|
|
34
45
|
locale?: string;
|
|
35
46
|
dateOptions?: Intl.DateTimeFormatOptions;
|
|
36
47
|
}
|
|
37
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Options for boolean column configuration.
|
|
51
|
+
* Extends TextColumnOptions with boolean-specific rendering.
|
|
52
|
+
*/
|
|
38
53
|
export interface BooleanColumnOptions extends Omit<TextColumnOptions, 'render'> {
|
|
39
54
|
render?: (value: boolean) => React.ReactNode;
|
|
40
55
|
}
|
|
41
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Options for action column configuration.
|
|
59
|
+
* Defines how action buttons are rendered in table rows.
|
|
60
|
+
*/
|
|
42
61
|
export interface ActionColumnOptions {
|
|
43
62
|
header?: string;
|
|
44
63
|
render?: (row: DataRecord, actions: DataTableAction<DataRecord>[]) => React.ReactNode;
|
|
@@ -51,6 +70,12 @@ export interface ActionColumnOptions {
|
|
|
51
70
|
};
|
|
52
71
|
}
|
|
53
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Options for custom column configuration.
|
|
75
|
+
* Allows full control over column rendering and behavior.
|
|
76
|
+
*
|
|
77
|
+
* @template TData - The type of data records in the table
|
|
78
|
+
*/
|
|
54
79
|
export interface CustomColumnOptions<TData extends DataRecord> {
|
|
55
80
|
header?: string;
|
|
56
81
|
cell?: (info: unknown) => React.ReactNode;
|
|
@@ -64,6 +89,12 @@ export interface CustomColumnOptions<TData extends DataRecord> {
|
|
|
64
89
|
maxSize?: number;
|
|
65
90
|
}
|
|
66
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Column configuration interface.
|
|
94
|
+
* Defines the structure for creating columns programmatically.
|
|
95
|
+
*
|
|
96
|
+
* @template TData - The type of data records in the table
|
|
97
|
+
*/
|
|
67
98
|
export interface ColumnConfig<TData extends DataRecord> {
|
|
68
99
|
key: keyof TData | string;
|
|
69
100
|
type: 'text' | 'number' | 'date' | 'boolean' | 'custom';
|
|
@@ -27,7 +27,8 @@ import { LocalDataAdapter } from './LocalDataAdapter';
|
|
|
27
27
|
const DataTableContext = createContext<IDataTableContext<DataRecord> | null>(null);
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
|
-
*
|
|
30
|
+
* Props for the DataTableProvider component.
|
|
31
|
+
* @template TData - The type of data records in the table
|
|
31
32
|
*/
|
|
32
33
|
export interface DataTableProviderProps<TData extends DataRecord> {
|
|
33
34
|
children: React.ReactNode;
|
|
@@ -159,26 +160,56 @@ export function useDataTableContext<TData extends DataRecord = DataRecord>(): ID
|
|
|
159
160
|
/**
|
|
160
161
|
* Hook to use specific managers
|
|
161
162
|
*/
|
|
163
|
+
/**
|
|
164
|
+
* Hook to access DataTable data manager.
|
|
165
|
+
*
|
|
166
|
+
* @template TData - The type of data records in the table
|
|
167
|
+
* @returns Data manager instance
|
|
168
|
+
*/
|
|
162
169
|
export function useDataManager<TData extends DataRecord = DataRecord>() {
|
|
163
170
|
const context = useDataTableContext<TData>();
|
|
164
171
|
return context.dataManager;
|
|
165
172
|
}
|
|
166
173
|
|
|
174
|
+
/**
|
|
175
|
+
* Hook to access DataTable column manager.
|
|
176
|
+
*
|
|
177
|
+
* @template TData - The type of data records in the table
|
|
178
|
+
* @returns Column manager instance
|
|
179
|
+
*/
|
|
167
180
|
export function useColumnManager<TData extends DataRecord = DataRecord>() {
|
|
168
181
|
const context = useDataTableContext<TData>();
|
|
169
182
|
return context.columnManager;
|
|
170
183
|
}
|
|
171
184
|
|
|
185
|
+
/**
|
|
186
|
+
* Hook to access DataTable action manager.
|
|
187
|
+
*
|
|
188
|
+
* @template TData - The type of data records in the table
|
|
189
|
+
* @returns Action manager instance
|
|
190
|
+
*/
|
|
172
191
|
export function useActionManager<TData extends DataRecord = DataRecord>() {
|
|
173
192
|
const context = useDataTableContext<TData>();
|
|
174
193
|
return context.actionManager;
|
|
175
194
|
}
|
|
176
195
|
|
|
196
|
+
/**
|
|
197
|
+
* Hook to access DataTable state manager.
|
|
198
|
+
*
|
|
199
|
+
* @template TData - The type of data records in the table
|
|
200
|
+
* @returns State manager instance
|
|
201
|
+
*/
|
|
177
202
|
export function useStateManager<TData extends DataRecord = DataRecord>() {
|
|
178
203
|
const context = useDataTableContext<TData>();
|
|
179
204
|
return context.stateManager;
|
|
180
205
|
}
|
|
181
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Hook to access DataTable plugin registry.
|
|
209
|
+
*
|
|
210
|
+
* @template TData - The type of data records in the table
|
|
211
|
+
* @returns Plugin registry instance
|
|
212
|
+
*/
|
|
182
213
|
export function usePluginRegistry<TData extends DataRecord = DataRecord>() {
|
|
183
214
|
const context = useDataTableContext<TData>();
|
|
184
215
|
return context.pluginRegistry;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from 'react';
|
|
2
2
|
import { createLogger } from '../../../utils/core/logger';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Props for the useColumnOrderPersistence hook.
|
|
6
|
+
*/
|
|
4
7
|
interface UseColumnOrderPersistenceProps {
|
|
5
8
|
tableId?: string;
|
|
6
9
|
defaultOrder?: string[];
|
|
@@ -8,6 +11,13 @@ interface UseColumnOrderPersistenceProps {
|
|
|
8
11
|
storageKey?: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Hook for persisting column order in localStorage.
|
|
16
|
+
* Saves and restores column order across page reloads.
|
|
17
|
+
*
|
|
18
|
+
* @param props - Column order persistence configuration
|
|
19
|
+
* @returns Column order state and update function
|
|
20
|
+
*/
|
|
11
21
|
export function useColumnOrderPersistence({
|
|
12
22
|
tableId,
|
|
13
23
|
defaultOrder = [],
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { useState, useCallback, useMemo, useEffect } from 'react';
|
|
2
2
|
import type { Column } from '@tanstack/react-table';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Props for the useColumnReordering hook.
|
|
6
|
+
* @template TData - The type of data records in the table
|
|
7
|
+
*/
|
|
4
8
|
interface UseColumnReorderingProps<TData> {
|
|
5
9
|
columns: Column<TData, unknown>[];
|
|
6
10
|
onColumnOrderChange?: (columnOrder: string[]) => void;
|
|
@@ -11,6 +15,14 @@ interface UseColumnReorderingProps<TData> {
|
|
|
11
15
|
onColumnOrderUpdate?: (columnOrder: string[]) => void;
|
|
12
16
|
}
|
|
13
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Hook for managing column reordering in DataTable.
|
|
20
|
+
* Provides functions to move columns and persist order changes.
|
|
21
|
+
*
|
|
22
|
+
* @template TData - The type of data records in the table
|
|
23
|
+
* @param props - Column reordering configuration
|
|
24
|
+
* @returns Column order state and reordering functions
|
|
25
|
+
*/
|
|
14
26
|
export function useColumnReordering<TData>({
|
|
15
27
|
columns,
|
|
16
28
|
onColumnOrderChange,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { useState, useEffect, useCallback } from 'react';
|
|
2
2
|
import { createLogger } from '../../../utils/core/logger';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Props for the useColumnVisibilityPersistence hook.
|
|
6
|
+
*/
|
|
4
7
|
interface UseColumnVisibilityPersistenceProps {
|
|
5
8
|
tableId?: string;
|
|
6
9
|
defaultVisibility?: Record<string, boolean>;
|
|
@@ -8,6 +11,13 @@ interface UseColumnVisibilityPersistenceProps {
|
|
|
8
11
|
storageKey?: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Hook for persisting column visibility in localStorage.
|
|
16
|
+
* Saves and restores column visibility state across page reloads.
|
|
17
|
+
*
|
|
18
|
+
* @param props - Column visibility persistence configuration
|
|
19
|
+
* @returns Column visibility state and update function
|
|
20
|
+
*/
|
|
11
21
|
export function useColumnVisibilityPersistence({
|
|
12
22
|
tableId,
|
|
13
23
|
defaultVisibility = {},
|
|
@@ -21,6 +21,10 @@ import type {
|
|
|
21
21
|
} from '../types';
|
|
22
22
|
import type { SortingState } from '@tanstack/react-table';
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Parameters for the useDataTableDataPipeline hook.
|
|
26
|
+
* @template TData - The type of data records in the table
|
|
27
|
+
*/
|
|
24
28
|
export interface UseDataTableDataPipelineParams<TData extends DataRecord> {
|
|
25
29
|
data: TData[];
|
|
26
30
|
features: NormalizedDataTableFeatureConfig;
|
|
@@ -30,6 +34,10 @@ export interface UseDataTableDataPipelineParams<TData extends DataRecord> {
|
|
|
30
34
|
serverData: ServerSideResponse<TData> | null;
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Return value of the useDataTableDataPipeline hook.
|
|
39
|
+
* @template TData - The type of data records in the table
|
|
40
|
+
*/
|
|
33
41
|
export interface UseDataTableDataPipelineResult<TData extends DataRecord> {
|
|
34
42
|
finalTableData: TData[];
|
|
35
43
|
dataCount: number;
|
|
@@ -37,6 +45,14 @@ export interface UseDataTableDataPipelineResult<TData extends DataRecord> {
|
|
|
37
45
|
hierarchicalValidation: { isValid: boolean; errors: string[] };
|
|
38
46
|
}
|
|
39
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Hook that encapsulates hierarchical validation, sorting, and data source resolution.
|
|
50
|
+
* Processes table data through the data pipeline before rendering.
|
|
51
|
+
*
|
|
52
|
+
* @template TData - The type of data records in the table
|
|
53
|
+
* @param params - Data pipeline configuration
|
|
54
|
+
* @returns Processed table data and pipeline state
|
|
55
|
+
*/
|
|
40
56
|
export function useDataTableDataPipeline<TData extends DataRecord>({
|
|
41
57
|
data,
|
|
42
58
|
features,
|