@jmruthers/pace-core 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -10
- package/cursor-rules/00-pace-core-compliance.mdc +18 -91
- 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-BPvc3Ka0.d.ts} +54 -0
- package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
- package/dist/{DataTable-DQ7RSOHE.js → DataTable-TPTKCX4D.js} +10 -9
- package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +356 -111
- package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
- package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
- package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
- package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
- package/dist/chunk-24UVZUZG.js.map +1 -0
- package/dist/{chunk-4N5C5XZU.js → chunk-2UOI2FG5.js} +4 -4
- package/dist/chunk-2UOI2FG5.js.map +1 -0
- package/dist/{chunk-T33XF5ZC.js → chunk-3XC4CPTD.js} +4317 -3963
- package/dist/chunk-3XC4CPTD.js.map +1 -0
- package/dist/{chunk-4ZC4GX36.js → chunk-6J4GEEJR.js} +172 -45
- package/dist/chunk-6J4GEEJR.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-BYFSK72L.js → chunk-EHMR7VYL.js} +4 -4
- package/dist/chunk-EHMR7VYL.js.map +1 -0
- package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
- package/dist/chunk-F2IMUDXZ.js.map +1 -0
- package/dist/{chunk-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-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-3XTALGJF.js → chunk-MMZ7JXPU.js} +60 -223
- package/dist/chunk-MMZ7JXPU.js.map +1 -0
- package/dist/{chunk-GLK6VM3F.js → chunk-NECFR5MM.js} +254 -170
- package/dist/chunk-NECFR5MM.js.map +1 -0
- package/dist/{chunk-JBKQ3SAO.js → chunk-SFZUDBL5.js} +40 -4
- package/dist/chunk-SFZUDBL5.js.map +1 -0
- package/dist/{chunk-XM25TVIE.js → chunk-XWQCNGTQ.js} +724 -363
- package/dist/chunk-XWQCNGTQ.js.map +1 -0
- package/dist/components.d.ts +5 -5
- package/dist/components.js +14 -11
- package/dist/components.js.map +1 -1
- package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
- package/dist/hooks.d.ts +55 -122
- package/dist/hooks.js +8 -12
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +60 -13
- package/dist/index.js +19 -19
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +21 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +145 -114
- package/dist/rbac/index.js +8 -11
- package/dist/theming/runtime.d.ts +1 -13
- package/dist/theming/runtime.js +1 -1
- package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
- package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
- package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +31 -1
- package/dist/utils.d.ts +4 -5
- package/dist/utils.js +14 -14
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +7 -1
- package/docs/api/classes/ColumnFactory.md +8 -8
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +4 -4
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- package/docs/api/classes/SecureSupabaseClient.md +18 -15
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +9 -2
- package/docs/api/interfaces/ButtonProps.md +7 -4
- package/docs/api/interfaces/CalendarProps.md +8 -5
- package/docs/api/interfaces/CardProps.md +8 -5
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +24 -21
- package/docs/api/interfaces/DataTableColumn.md +31 -31
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
- package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +26 -23
- package/docs/api/interfaces/FooterProps.md +10 -8
- package/docs/api/interfaces/FormFieldProps.md +10 -10
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +7 -4
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +14 -11
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +11 -11
- package/docs/api/interfaces/NavigationMenuProps.md +15 -15
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
- package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
- package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
- package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +3 -3
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +4 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +14 -11
- package/docs/api/interfaces/UserMenuProps.md +8 -6
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +575 -634
- package/docs/architecture/database-schema-requirements.md +161 -0
- package/docs/core-concepts/rbac-system.md +3 -3
- package/docs/documentation-index.md +2 -4
- package/docs/getting-started/cursor-rules.md +2 -1
- package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
- package/docs/migration/MIGRATION_GUIDE.md +2 -24
- 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/rbac/event-based-apps.md +1 -1
- package/docs/rbac/getting-started.md +1 -1
- package/docs/rbac/quick-start.md +1 -1
- package/docs/standards/README.md +1 -0
- package/package.json +2 -1
- 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} +714 -687
- package/scripts/audit/core/checks/config.cjs +54 -0
- package/scripts/audit/core/checks/coverage.cjs +84 -0
- package/scripts/audit/core/checks/dependencies.cjs +454 -0
- package/scripts/audit/core/checks/documentation.cjs +203 -0
- package/scripts/audit/core/checks/environment.cjs +128 -0
- package/scripts/audit/core/checks/error-handling.cjs +299 -0
- package/scripts/audit/core/checks/forms.cjs +172 -0
- package/scripts/audit/core/checks/heuristics.cjs +68 -0
- package/scripts/audit/core/checks/hooks.cjs +334 -0
- package/scripts/audit/core/checks/imports.cjs +244 -0
- package/scripts/audit/core/checks/performance.cjs +325 -0
- package/scripts/audit/core/checks/routes.cjs +117 -0
- package/scripts/audit/core/checks/state.cjs +130 -0
- package/scripts/audit/core/checks/structure.cjs +65 -0
- package/scripts/audit/core/checks/style.cjs +584 -0
- package/scripts/audit/core/checks/testing.cjs +122 -0
- package/scripts/audit/core/checks/typescript.cjs +61 -0
- package/scripts/audit/core/scanner.cjs +199 -0
- package/scripts/audit/core/utils.cjs +137 -0
- package/scripts/audit/index.cjs +223 -0
- package/scripts/audit/reporters/console.cjs +151 -0
- package/scripts/audit/reporters/json.cjs +54 -0
- package/scripts/audit/reporters/markdown.cjs +124 -0
- package/scripts/audit-consuming-app.cjs +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/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 +61 -849
- 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 +124 -32
- package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
- package/src/components/DataTable/hooks/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 +2 -2
- 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/EventSelector/EventSelector.tsx +3 -0
- package/src/components/FileDisplay/FileDisplay.tsx +32 -18
- package/src/components/FileUpload/FileUpload.tsx +22 -2
- package/src/components/Footer/Footer.test.tsx +16 -16
- package/src/components/Footer/Footer.tsx +14 -11
- package/src/components/Form/Form.tsx +1 -0
- package/src/components/Header/Header.tsx +21 -10
- 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/OrganisationSelector/OrganisationSelector.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +4 -2
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +32 -11
- package/src/components/PaceAppLayout/test-setup.tsx +1 -2
- 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 +2 -2
- package/src/hooks/__tests__/index.unit.test.ts +2 -5
- 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/useDebounce.ts +9 -0
- package/src/hooks/useEventTheme.ts +6 -0
- package/src/hooks/useFileDisplay.ts +4 -0
- package/src/hooks/useFileReference.ts +25 -7
- package/src/hooks/useFileUrl.ts +11 -1
- package/src/hooks/useFocusManagement.ts +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 +2 -1
- package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
- package/src/providers/services/AuthServiceProvider.tsx +18 -0
- package/src/providers/services/EventServiceProvider.tsx +18 -0
- package/src/providers/services/InactivityServiceProvider.tsx +18 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +36 -0
- 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 +2 -2
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
- package/src/rbac/adapters.tsx +14 -5
- package/src/rbac/api.ts +100 -67
- package/src/rbac/components/NavigationProvider.tsx +4 -1
- package/src/rbac/components/PagePermissionGuard.tsx +157 -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/permissions/index.ts +7 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
- package/src/rbac/hooks/permissions/useCan.ts +347 -0
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
- package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
- package/src/rbac/hooks/useCan.test.ts +71 -64
- package/src/rbac/hooks/usePermissions.ts +14 -995
- package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
- package/src/rbac/hooks/useResourcePermissions.ts +14 -4
- package/src/rbac/hooks/useSecureSupabase.ts +33 -13
- package/src/rbac/permissions.ts +0 -30
- package/src/rbac/secureClient.ts +200 -61
- package/src/rbac/types.ts +8 -0
- package/src/theming/__tests__/parseEventColours.test.ts +6 -9
- package/src/theming/parseEventColours.ts +5 -19
- package/src/types/vitest-globals.d.ts +51 -26
- package/src/utils/__mocks__/supabaseMock.ts +1 -3
- package/src/utils/__tests__/formatting.unit.test.ts +4 -4
- package/src/utils/__tests__/index.unit.test.ts +2 -2
- package/src/utils/audit/audit.ts +0 -3
- package/src/utils/core/cn.ts +1 -1
- package/src/utils/file-reference/index.ts +53 -1
- package/src/utils/formatting/formatting.ts +8 -18
- package/src/utils/index.ts +0 -1
- package/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-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.map +0 -1
- package/dist/chunk-XM25TVIE.js.map +0 -1
- package/docs/api/classes/ErrorBoundary.md +0 -144
- package/docs/migration/quick-migration-guide.md +0 -356
- package/docs/migration/service-architecture.md +0 -281
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
- package/src/hooks/useSecureDataAccess.test.ts +0 -559
- package/src/hooks/useSecureDataAccess.ts +0 -681
- /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-TPTKCX4D.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
- /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
- /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
- /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
- /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
- /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { type Column } from '@tanstack/react-table';
|
|
3
|
+
import { Input } from '../../Input/Input';
|
|
4
|
+
import {
|
|
5
|
+
Select,
|
|
6
|
+
SelectContent,
|
|
7
|
+
SelectGroup,
|
|
8
|
+
SelectItem,
|
|
9
|
+
SelectLabel,
|
|
10
|
+
SelectSeparator,
|
|
11
|
+
SelectTrigger,
|
|
12
|
+
SelectValue,
|
|
13
|
+
} from '../../Select/Select';
|
|
14
|
+
import { createLogger } from '../../../utils/core/logger';
|
|
15
|
+
import type { CellValue, DataRecord, EditableColumnDef } from '../types';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Component for select fields with searchable and creatable support
|
|
19
|
+
*/
|
|
20
|
+
export function SelectEditField<TData extends DataRecord>({
|
|
21
|
+
columnDef,
|
|
22
|
+
accessorKey,
|
|
23
|
+
currentValue,
|
|
24
|
+
placeholder,
|
|
25
|
+
onChange,
|
|
26
|
+
}: {
|
|
27
|
+
columnDef: EditableColumnDef<TData>;
|
|
28
|
+
accessorKey: string;
|
|
29
|
+
currentValue: CellValue;
|
|
30
|
+
placeholder?: string;
|
|
31
|
+
onChange: (value: CellValue) => void;
|
|
32
|
+
}) {
|
|
33
|
+
const logger = createLogger('SelectEditField');
|
|
34
|
+
const isSearchable = columnDef.selectSearchable !== false;
|
|
35
|
+
const isCreatable = columnDef.creatable === true;
|
|
36
|
+
const selectRef = React.useRef<HTMLFormElement>(null);
|
|
37
|
+
const [searchTerm, setSearchTerm] = React.useState('');
|
|
38
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
39
|
+
const [showCreateOption, setShowCreateOption] = React.useState(false);
|
|
40
|
+
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (!isOpen || !isSearchable || !isCreatable || !columnDef.onCreateNew) {
|
|
43
|
+
if (!isOpen || !isCreatable || !columnDef.onCreateNew) {
|
|
44
|
+
setShowCreateOption(false);
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const findAndAttachSearchInput = (): (() => void) | null => {
|
|
50
|
+
let searchInput: HTMLInputElement | null = null;
|
|
51
|
+
|
|
52
|
+
if (selectRef.current) {
|
|
53
|
+
searchInput = selectRef.current.querySelector<HTMLInputElement>('[data-testid="select-search-input"]');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!searchInput) {
|
|
57
|
+
const allSearchInputs = document.querySelectorAll<HTMLInputElement>('[data-testid="select-search-input"]');
|
|
58
|
+
for (const input of Array.from(allSearchInputs)) {
|
|
59
|
+
const content = input.closest('[data-testid="select-content"]');
|
|
60
|
+
if (content && content.getAttribute('aria-hidden') !== 'true') {
|
|
61
|
+
searchInput = input;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (!searchInput) return null;
|
|
68
|
+
|
|
69
|
+
const handleInput = (e: Event) => {
|
|
70
|
+
const target = e.target as HTMLInputElement;
|
|
71
|
+
const currentSearch = target.value;
|
|
72
|
+
setSearchTerm(currentSearch);
|
|
73
|
+
|
|
74
|
+
if (currentSearch.trim()) {
|
|
75
|
+
const searchLower = currentSearch.toLowerCase().trim();
|
|
76
|
+
|
|
77
|
+
type FieldOption =
|
|
78
|
+
| { value: string | number; label: string }
|
|
79
|
+
| { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
|
|
80
|
+
| { type: 'separator' };
|
|
81
|
+
|
|
82
|
+
const checkMatch = (opt: FieldOption): boolean => {
|
|
83
|
+
if ('value' in opt && !('type' in opt)) {
|
|
84
|
+
return opt.label.toLowerCase().includes(searchLower);
|
|
85
|
+
}
|
|
86
|
+
if ('type' in opt && opt.type === 'group') {
|
|
87
|
+
return (
|
|
88
|
+
(opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some(
|
|
89
|
+
(item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower)
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const shouldShow = isCreatable && !!columnDef.onCreateNew;
|
|
97
|
+
|
|
98
|
+
setShowCreateOption(shouldShow);
|
|
99
|
+
} else {
|
|
100
|
+
setShowCreateOption(false);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const initialValue = searchInput.value;
|
|
105
|
+
if (initialValue) {
|
|
106
|
+
const currentSearch = initialValue;
|
|
107
|
+
setSearchTerm(currentSearch);
|
|
108
|
+
|
|
109
|
+
if (currentSearch.trim()) {
|
|
110
|
+
const searchLower = currentSearch.toLowerCase().trim();
|
|
111
|
+
|
|
112
|
+
type FieldOption =
|
|
113
|
+
| { value: string | number; label: string }
|
|
114
|
+
| { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
|
|
115
|
+
| { type: 'separator' };
|
|
116
|
+
|
|
117
|
+
const checkMatch = (opt: FieldOption): boolean => {
|
|
118
|
+
if ('value' in opt && !('type' in opt)) {
|
|
119
|
+
return opt.label.toLowerCase().includes(searchLower);
|
|
120
|
+
}
|
|
121
|
+
if ('type' in opt && opt.type === 'group') {
|
|
122
|
+
return (
|
|
123
|
+
(opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some(
|
|
124
|
+
(item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower)
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const shouldShow = isCreatable && !!columnDef.onCreateNew;
|
|
132
|
+
setShowCreateOption(shouldShow);
|
|
133
|
+
} else {
|
|
134
|
+
setShowCreateOption(false);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
searchInput.addEventListener('input', handleInput);
|
|
139
|
+
|
|
140
|
+
return () => {
|
|
141
|
+
searchInput?.removeEventListener('input', handleInput);
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
let cleanup: (() => void) | null = findAndAttachSearchInput();
|
|
146
|
+
|
|
147
|
+
if (!cleanup) {
|
|
148
|
+
let timeoutCleanup: (() => void) | null = null;
|
|
149
|
+
const timeoutId = setTimeout(() => {
|
|
150
|
+
timeoutCleanup = findAndAttachSearchInput();
|
|
151
|
+
}, 50);
|
|
152
|
+
|
|
153
|
+
return () => {
|
|
154
|
+
clearTimeout(timeoutId);
|
|
155
|
+
timeoutCleanup?.();
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return cleanup;
|
|
160
|
+
}, [isOpen, isSearchable, isCreatable, columnDef.fieldOptions, columnDef.onCreateNew]);
|
|
161
|
+
|
|
162
|
+
const handleCreateNew = React.useCallback(async () => {
|
|
163
|
+
if (!isCreatable || !columnDef.onCreateNew || !searchTerm.trim()) return;
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
const newValue = await columnDef.onCreateNew(searchTerm.trim());
|
|
167
|
+
onChange(newValue);
|
|
168
|
+
setSearchTerm('');
|
|
169
|
+
setShowCreateOption(false);
|
|
170
|
+
} catch (error) {
|
|
171
|
+
logger.error('Error creating new item:', error);
|
|
172
|
+
}
|
|
173
|
+
}, [isCreatable, columnDef.onCreateNew, searchTerm, onChange, logger]);
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<Select
|
|
177
|
+
ref={selectRef}
|
|
178
|
+
value={String(currentValue)}
|
|
179
|
+
onValueChange={(newValue) => {
|
|
180
|
+
if (newValue.startsWith('__create_new__')) {
|
|
181
|
+
handleCreateNew();
|
|
182
|
+
} else {
|
|
183
|
+
onChange(newValue as CellValue);
|
|
184
|
+
}
|
|
185
|
+
}}
|
|
186
|
+
onOpenChange={(open) => {
|
|
187
|
+
setIsOpen(open);
|
|
188
|
+
if (!open) {
|
|
189
|
+
setSearchTerm('');
|
|
190
|
+
setShowCreateOption(false);
|
|
191
|
+
}
|
|
192
|
+
}}
|
|
193
|
+
>
|
|
194
|
+
<SelectTrigger className="h-8">
|
|
195
|
+
<SelectValue placeholder={placeholder || `Select ${columnDef.header || 'option'}...`} />
|
|
196
|
+
</SelectTrigger>
|
|
197
|
+
<SelectContent
|
|
198
|
+
searchable={Boolean(isSearchable)}
|
|
199
|
+
searchPlaceholder={`Search ${columnDef.header || 'options'}...`}
|
|
200
|
+
maxHeight={columnDef.selectMaxHeight}
|
|
201
|
+
className={columnDef.selectContentClassName}
|
|
202
|
+
style={columnDef.selectContentStyle}
|
|
203
|
+
>
|
|
204
|
+
{columnDef.fieldOptions?.map((option, index) => {
|
|
205
|
+
if ('value' in option && !('type' in option)) {
|
|
206
|
+
return (
|
|
207
|
+
<SelectItem key={`${option.value}-${index}`} value={String(option.value)}>
|
|
208
|
+
{option.label}
|
|
209
|
+
</SelectItem>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if ('type' in option && option.type === 'separator') {
|
|
214
|
+
return <SelectSeparator key={`separator-${index}`} />;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if ('type' in option && option.type === 'group') {
|
|
218
|
+
const groupOption = option as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> };
|
|
219
|
+
return (
|
|
220
|
+
<SelectGroup key={`group-${groupOption.label}-${index}`}>
|
|
221
|
+
<SelectLabel>{groupOption.label}</SelectLabel>
|
|
222
|
+
{groupOption.items.map((item: { value: string | number; label: string }) => (
|
|
223
|
+
<SelectItem key={`${item.value}-${index}`} value={String(item.value)}>
|
|
224
|
+
{item.label}
|
|
225
|
+
</SelectItem>
|
|
226
|
+
))}
|
|
227
|
+
</SelectGroup>
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return null;
|
|
232
|
+
})}
|
|
233
|
+
{showCreateOption && isCreatable && searchTerm.trim() && columnDef.onCreateNew && (
|
|
234
|
+
<SelectItem key="__create_new__" value={`__create_new__${searchTerm}`} className="bg-main-100 font-medium border-t border-main-200">
|
|
235
|
+
Create "{searchTerm}"
|
|
236
|
+
</SelectItem>
|
|
237
|
+
)}
|
|
238
|
+
</SelectContent>
|
|
239
|
+
</Select>
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Helper function to render the appropriate input type based on column configuration
|
|
245
|
+
*/
|
|
246
|
+
export const renderEditField = <TData extends DataRecord>(
|
|
247
|
+
column: Column<TData, unknown>,
|
|
248
|
+
value: CellValue,
|
|
249
|
+
onChange: (value: CellValue | Record<string, CellValue>) => void,
|
|
250
|
+
editingData: Record<string, CellValue> = {},
|
|
251
|
+
placeholder?: string
|
|
252
|
+
): React.ReactElement => {
|
|
253
|
+
const columnDef = column.columnDef as EditableColumnDef<TData>;
|
|
254
|
+
|
|
255
|
+
if (columnDef.editable === false) {
|
|
256
|
+
return <span className="text-sm text-sec-600">{String(value ?? '')}</span>;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (columnDef.fieldType === 'select' && columnDef.fieldOptions) {
|
|
260
|
+
const accessorKey = columnDef.editAccessorKey || column.id;
|
|
261
|
+
const currentValue = editingData[accessorKey] ?? value ?? '';
|
|
262
|
+
|
|
263
|
+
return (
|
|
264
|
+
<SelectEditField
|
|
265
|
+
columnDef={columnDef}
|
|
266
|
+
accessorKey={accessorKey}
|
|
267
|
+
currentValue={currentValue}
|
|
268
|
+
placeholder={placeholder}
|
|
269
|
+
onChange={(newValue) => onChange({ [accessorKey]: newValue })}
|
|
270
|
+
/>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (columnDef.fieldType === 'number') {
|
|
275
|
+
const hideSpinners = columnDef.hideNumberSpinners !== false;
|
|
276
|
+
return (
|
|
277
|
+
<Input
|
|
278
|
+
type="number"
|
|
279
|
+
value={String(value ?? '')}
|
|
280
|
+
onChange={(e) => onChange(e.target.value as unknown as CellValue)}
|
|
281
|
+
placeholder={placeholder || `Enter ${columnDef.header || column.id}...`}
|
|
282
|
+
className={`h-8 ${hideSpinners ? 'datatable-number-no-spinners' : ''}`}
|
|
283
|
+
/>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (columnDef.fieldType === 'date') {
|
|
288
|
+
return (
|
|
289
|
+
<Input
|
|
290
|
+
type="date"
|
|
291
|
+
value={String(value ?? '')}
|
|
292
|
+
onChange={(e) => onChange(e.target.value as unknown as CellValue)}
|
|
293
|
+
className="h-8"
|
|
294
|
+
/>
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<Input
|
|
300
|
+
type="text"
|
|
301
|
+
value={String(value ?? '')}
|
|
302
|
+
onChange={(e) => onChange(e.target.value as unknown as CellValue)}
|
|
303
|
+
placeholder={placeholder || `Enter ${columnDef.header || column.id}...`}
|
|
304
|
+
className="h-8"
|
|
305
|
+
/>
|
|
306
|
+
);
|
|
307
|
+
};
|
|
@@ -337,6 +337,14 @@ const renderEditField = <TData extends DataRecord>(
|
|
|
337
337
|
);
|
|
338
338
|
};
|
|
339
339
|
|
|
340
|
+
/**
|
|
341
|
+
* Editable row component for DataTable.
|
|
342
|
+
* Renders a row in edit mode with input fields for each editable column.
|
|
343
|
+
*
|
|
344
|
+
* @template TData - The type of data records in the table
|
|
345
|
+
* @param props - Editable row configuration
|
|
346
|
+
* @returns The rendered editable row
|
|
347
|
+
*/
|
|
340
348
|
export function EditableRow<TData extends DataRecord>({
|
|
341
349
|
row,
|
|
342
350
|
editingData,
|
|
@@ -2,6 +2,9 @@ import React from 'react';
|
|
|
2
2
|
import { Database, Search, Plus, User } from 'lucide-react';
|
|
3
3
|
import { Button } from '../../Button/Button';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Props for the EmptyState component.
|
|
7
|
+
*/
|
|
5
8
|
interface EmptyStateProps {
|
|
6
9
|
title?: string;
|
|
7
10
|
description?: string;
|
|
@@ -14,6 +17,13 @@ interface EmptyStateProps {
|
|
|
14
17
|
onClearFilters?: () => void;
|
|
15
18
|
}
|
|
16
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Empty state component for DataTable.
|
|
22
|
+
* Displays a message when the table has no data or no filtered results.
|
|
23
|
+
*
|
|
24
|
+
* @param props - Empty state configuration
|
|
25
|
+
* @returns The rendered empty state UI
|
|
26
|
+
*/
|
|
17
27
|
export function EmptyState({
|
|
18
28
|
title,
|
|
19
29
|
description,
|
|
@@ -5,11 +5,23 @@ import { getColumnHeaderText } from '../utils/columnUtils';
|
|
|
5
5
|
import type { Column } from '@tanstack/react-table';
|
|
6
6
|
import type { DataRecord } from '../types';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Props for the FilterRow component.
|
|
10
|
+
* @template TData - The type of data records in the table
|
|
11
|
+
*/
|
|
8
12
|
interface FilterRowProps<TData> {
|
|
9
13
|
table: Table<TData>;
|
|
10
14
|
visibleColumns: Header<TData, unknown>[];
|
|
11
15
|
}
|
|
12
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Filter row component for DataTable.
|
|
19
|
+
* Renders filter inputs for each visible column.
|
|
20
|
+
*
|
|
21
|
+
* @template TData - The type of data records in the table
|
|
22
|
+
* @param props - Filter row configuration
|
|
23
|
+
* @returns The rendered filter row
|
|
24
|
+
*/
|
|
13
25
|
export function FilterRow<TData>({ table, visibleColumns }: FilterRowProps<TData>) {
|
|
14
26
|
const { getState } = table;
|
|
15
27
|
const { columnFilters } = getState();
|
|
@@ -3,6 +3,10 @@ import { Row } from '@tanstack/react-table';
|
|
|
3
3
|
import { Button } from '../../Button/Button';
|
|
4
4
|
import { ChevronDown, ChevronRight } from 'lucide-react';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Props for the GroupHeader component.
|
|
8
|
+
* @template TData - The type of data records in the table
|
|
9
|
+
*/
|
|
6
10
|
interface GroupHeaderProps<TData> {
|
|
7
11
|
row: Row<TData>;
|
|
8
12
|
groupByColumn: string;
|
|
@@ -11,6 +15,14 @@ interface GroupHeaderProps<TData> {
|
|
|
11
15
|
subRowsCount: number;
|
|
12
16
|
}
|
|
13
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Group header component for DataTable.
|
|
20
|
+
* Displays the group label and toggle button for expanding/collapsing grouped rows.
|
|
21
|
+
*
|
|
22
|
+
* @template TData - The type of data records in the table
|
|
23
|
+
* @param props - Group header configuration
|
|
24
|
+
* @returns The rendered group header
|
|
25
|
+
*/
|
|
14
26
|
export function GroupHeader<TData>({
|
|
15
27
|
row,
|
|
16
28
|
groupByColumn,
|
|
@@ -10,6 +10,10 @@ import {
|
|
|
10
10
|
import { Group } from 'lucide-react';
|
|
11
11
|
import type { DataTableColumn, DataRecord, SimpleColumn } from '../types';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Props for the GroupingDropdown component.
|
|
15
|
+
* @template TData - The type of data records in the table
|
|
16
|
+
*/
|
|
13
17
|
interface GroupingDropdownProps<TData extends DataRecord = DataRecord> {
|
|
14
18
|
columns: (DataTableColumn<TData> | SimpleColumn<TData>)[];
|
|
15
19
|
currentGroupBy: string | null;
|
|
@@ -17,6 +21,14 @@ interface GroupingDropdownProps<TData extends DataRecord = DataRecord> {
|
|
|
17
21
|
className?: string;
|
|
18
22
|
}
|
|
19
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Dropdown component for selecting grouping column in DataTable.
|
|
26
|
+
* Allows users to group table rows by a specific column.
|
|
27
|
+
*
|
|
28
|
+
* @template TData - The type of data records in the table
|
|
29
|
+
* @param props - Grouping dropdown configuration
|
|
30
|
+
* @returns The rendered grouping dropdown
|
|
31
|
+
*/
|
|
20
32
|
export function GroupingDropdown<TData extends DataRecord>({
|
|
21
33
|
columns,
|
|
22
34
|
currentGroupBy,
|
|
@@ -108,6 +108,13 @@ interface ImportModalProps {
|
|
|
108
108
|
* />
|
|
109
109
|
* ```
|
|
110
110
|
*/
|
|
111
|
+
/**
|
|
112
|
+
* Import modal component for DataTable.
|
|
113
|
+
* Provides CSV file upload, preview, and import functionality.
|
|
114
|
+
*
|
|
115
|
+
* @param props - Import modal configuration
|
|
116
|
+
* @returns The rendered import modal dialog
|
|
117
|
+
*/
|
|
111
118
|
export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportModalProps) {
|
|
112
119
|
const logger = createLogger('ImportModal');
|
|
113
120
|
const [file, setFile] = useState<File | null>(null);
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Loading state component for DataTable.
|
|
5
|
+
* Displays a loading spinner and message while data is being fetched.
|
|
6
|
+
*
|
|
7
|
+
* @returns The rendered loading state UI
|
|
8
|
+
*/
|
|
3
9
|
export function LoadingState() {
|
|
4
10
|
return (
|
|
5
11
|
<div className="p-8 text-center">
|
|
@@ -16,6 +16,10 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
|
|
|
16
16
|
import { getPaginationBinding, getPageSizeOptions } from '../utils/paginationUtils';
|
|
17
17
|
import type { PaginationMode, ServerSideResponse, DataRecord } from '../types';
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Props for the PaginationControls component.
|
|
21
|
+
* @template TData - The type of data records in the table
|
|
22
|
+
*/
|
|
19
23
|
interface PaginationControlsProps<TData extends DataRecord> {
|
|
20
24
|
table: Table<TData>;
|
|
21
25
|
pageSizeOptions?: number[];
|
|
@@ -28,6 +32,14 @@ interface PaginationControlsProps<TData extends DataRecord> {
|
|
|
28
32
|
totalCount?: number;
|
|
29
33
|
}
|
|
30
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Pagination controls component for DataTable.
|
|
37
|
+
* Provides page navigation, page size selection, and performance information.
|
|
38
|
+
*
|
|
39
|
+
* @template TData - The type of data records in the table
|
|
40
|
+
* @param props - Pagination configuration
|
|
41
|
+
* @returns The rendered pagination controls
|
|
42
|
+
*/
|
|
31
43
|
export function PaginationControls<TData extends DataRecord>({
|
|
32
44
|
table,
|
|
33
45
|
pageSizeOptions = [10, 20, 30, 40, 50],
|
|
@@ -253,8 +265,10 @@ export function EnhancedPaginationControls<TData extends DataRecord>({
|
|
|
253
265
|
<>
|
|
254
266
|
{/* Jump to Page */}
|
|
255
267
|
<form onSubmit={handleJumpToPage} className="flex items-center space-x-2">
|
|
256
|
-
<
|
|
268
|
+
<label htmlFor="jump-to-page-input" className="sr-only">Jump to page</label>
|
|
269
|
+
<span aria-hidden="true">Jump to page:</span>
|
|
257
270
|
<input
|
|
271
|
+
id="jump-to-page-input"
|
|
258
272
|
type="number"
|
|
259
273
|
min="1"
|
|
260
274
|
max={pageCount}
|
|
@@ -262,6 +276,7 @@ export function EnhancedPaginationControls<TData extends DataRecord>({
|
|
|
262
276
|
onChange={(e) => setJumpToPage(e.target.value)}
|
|
263
277
|
className="w-16 h-6 px-2 border rounded text-xs datatable-number-no-spinners"
|
|
264
278
|
placeholder="1"
|
|
279
|
+
aria-label="Page number"
|
|
265
280
|
/>
|
|
266
281
|
<Button type="submit" size="sm" variant="outline" className="h-6 px-2 text-xs">
|
|
267
282
|
Go
|