@jmruthers/pace-core 0.5.191 → 0.6.1
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 +29 -0
- package/README.md +7 -1
- package/cursor-rules/00-pace-core-compliance.mdc +372 -0
- package/cursor-rules/01-standards-compliance.mdc +275 -0
- package/cursor-rules/02-project-structure.mdc +200 -0
- package/cursor-rules/03-solid-principles.mdc +341 -0
- package/cursor-rules/04-testing-standards.mdc +315 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
- package/cursor-rules/06-code-quality.mdc +392 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +309 -0
- package/cursor-rules/CHANGELOG.md +101 -0
- package/cursor-rules/README.md +191 -0
- package/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
- package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-CH1U5Tpy.d.ts} +1 -1
- package/dist/{DataTable-WKRZD47S.js → DataTable-DQ7RSOHE.js} +8 -7
- package/dist/{PublicPageProvider-ULXC_u6U.d.ts → PublicPageProvider-ce4xlHYA.d.ts} +37 -156
- package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
- package/dist/{UnifiedAuthProvider-FTSG5XH7.js → UnifiedAuthProvider-ATAP5UTR.js} +3 -3
- package/dist/{api-IHKALJZD.js → api-N774RPUA.js} +2 -2
- package/dist/{chunk-6C4YBBJM.js → chunk-3QRJFVBR.js} +1 -1
- package/dist/chunk-3QRJFVBR.js.map +1 -0
- package/dist/{chunk-OETXORNB.js → chunk-3XTALGJF.js} +211 -136
- package/dist/chunk-3XTALGJF.js.map +1 -0
- package/dist/{chunk-6TQDD426.js → chunk-4N5C5XZU.js} +47 -228
- package/dist/chunk-4N5C5XZU.js.map +1 -0
- package/dist/{chunk-LOMZXPSN.js → chunk-4ZC4GX36.js} +47 -74
- package/dist/chunk-4ZC4GX36.js.map +1 -0
- package/dist/{chunk-6LTQQAT6.js → chunk-BYFSK72L.js} +357 -158
- package/dist/chunk-BYFSK72L.js.map +1 -0
- package/dist/{chunk-XYXSXPUK.js → chunk-EXUD6RNJ.js} +50 -10
- package/dist/chunk-EXUD6RNJ.js.map +1 -0
- package/dist/{chunk-VKB2CO4Z.js → chunk-GLK6VM3F.js} +244 -249
- package/dist/chunk-GLK6VM3F.js.map +1 -0
- package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
- package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
- package/dist/{chunk-XNYQOL3Z.js → chunk-JBKQ3SAO.js} +9 -18
- package/dist/chunk-JBKQ3SAO.js.map +1 -0
- package/dist/{chunk-ROXMHMY2.js → chunk-KNC55RTG.js} +13 -3
- package/dist/{chunk-ROXMHMY2.js.map → chunk-KNC55RTG.js.map} +1 -1
- package/dist/{chunk-QWWZ5CAQ.js → chunk-LXQLPRQ2.js} +2 -2
- package/dist/{chunk-ULHIJK66.js → chunk-T33XF5ZC.js} +255 -140
- package/dist/chunk-T33XF5ZC.js.map +1 -0
- package/dist/{chunk-VRGWKHDB.js → chunk-XM25TVIE.js} +100 -33
- package/dist/chunk-XM25TVIE.js.map +1 -0
- package/dist/components.d.ts +4 -4
- package/dist/components.js +9 -9
- package/dist/hooks.d.ts +6 -6
- package/dist/hooks.js +20 -25
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +18 -21
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +2 -20
- package/dist/rbac/index.js +7 -9
- package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-BJAlWfuJ.d.ts} +3 -3
- package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +3 -3
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +2 -2
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +10 -10
- 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 +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +24 -11
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
- 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 +4 -4
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +2 -2
- 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 +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +194 -209
- package/docs/getting-started/cursor-rules.md +262 -0
- package/docs/getting-started/installation-guide.md +6 -1
- package/docs/getting-started/quick-start.md +6 -1
- package/docs/migration/MIGRATION_GUIDE.md +4 -4
- package/docs/migration/REACT_19_MIGRATION.md +227 -0
- package/docs/migration/database-changes-december-2025.md +2 -1
- package/docs/rbac/event-based-apps.md +124 -6
- package/docs/standards/README.md +39 -0
- package/docs/troubleshooting/migration.md +4 -4
- package/examples/PublicPages/PublicEventPage.tsx +1 -1
- package/package.json +11 -6
- package/scripts/audit-consuming-app.cjs +961 -0
- package/scripts/check-pace-core-compliance.cjs +315 -61
- package/scripts/install-cursor-rules.cjs +236 -0
- package/src/__tests__/helpers/test-providers.tsx +1 -1
- package/src/__tests__/helpers/test-utils.tsx +1 -1
- package/src/__tests__/rls-policies.test.ts +3 -1
- package/src/components/Badge/Badge.tsx +2 -4
- package/src/components/Button/Button.tsx +5 -4
- package/src/components/Calendar/Calendar.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +57 -93
- package/src/components/DataTable/DataTable.tsx +2 -2
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
- package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +88 -16
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
- package/src/components/DataTable/components/AccessDeniedPage.tsx +1 -1
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +4 -7
- package/src/components/DataTable/components/DataTableModals.tsx +1 -1
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +86 -17
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
- package/src/components/DataTable/hooks/useColumnReordering.ts +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
- package/src/components/Dialog/Dialog.tsx +6 -5
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
- package/src/components/EventSelector/EventSelector.tsx +1 -1
- package/src/components/FileDisplay/FileDisplay.test.tsx +4 -3
- package/src/components/FileDisplay/FileDisplay.tsx +16 -4
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +36 -15
- package/src/components/Form/Form.tsx +30 -26
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
- package/src/components/Input/Input.tsx +28 -30
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +42 -42
- package/src/components/LoginForm/LoginForm.tsx +8 -8
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -11
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -1
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +75 -52
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +98 -69
- package/src/components/PaceAppLayout/README.md +1 -1
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -8
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
- package/src/components/PasswordChange/PasswordChangeForm.tsx +1 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
- package/src/components/PublicLayout/PublicPageLayout.tsx +1 -1
- package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
- package/src/components/Select/Select.tsx +33 -22
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +27 -29
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/UserMenu/UserMenu.tsx +1 -1
- package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +14 -7
- package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
- package/src/hooks/public/usePublicEvent.ts +1 -1
- package/src/hooks/public/usePublicEventLogo.ts +1 -1
- package/src/hooks/public/usePublicRouteParams.ts +1 -1
- package/src/hooks/services/useAuthService.ts +21 -3
- package/src/hooks/services/useEventService.ts +21 -3
- package/src/hooks/services/useInactivityService.ts +21 -3
- package/src/hooks/services/useOrganisationService.ts +21 -3
- package/src/hooks/useDataTableState.ts +8 -18
- package/src/hooks/useFileDisplay.ts +10 -17
- package/src/hooks/useFocusManagement.ts +2 -2
- package/src/hooks/useFocusTrap.ts +4 -4
- package/src/hooks/useFormDialog.ts +8 -7
- package/src/hooks/useInactivityTracker.ts +1 -1
- package/src/hooks/usePermissionCache.ts +1 -1
- package/src/hooks/useSecureDataAccess.test.ts +16 -9
- package/src/hooks/useSecureDataAccess.ts +22 -6
- package/src/hooks/useToast.ts +2 -2
- package/src/providers/__tests__/OrganisationProvider.test.tsx +57 -13
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
- package/src/providers/services/EventServiceProvider.tsx +0 -8
- package/src/providers/services/UnifiedAuthProvider.tsx +196 -46
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +13 -3
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +34 -40
- package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
- package/src/rbac/adapters.tsx +3 -22
- package/src/rbac/api.test.ts +2 -2
- package/src/rbac/api.ts +7 -1
- package/src/rbac/components/EnhancedNavigationMenu.tsx +3 -16
- package/src/rbac/components/NavigationGuard.tsx +2 -11
- package/src/rbac/components/NavigationProvider.tsx +1 -2
- package/src/rbac/components/PagePermissionGuard.tsx +1 -1
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +46 -13
- package/src/rbac/components/RoleBasedRouter.tsx +1 -1
- package/src/rbac/components/SecureDataProvider.tsx +1 -2
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
- package/src/rbac/engine.ts +14 -2
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/usePermissions.ts +51 -11
- package/src/rbac/hooks/useRBAC.ts +3 -13
- package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
- package/src/rbac/hooks/useResolvedScope.ts +58 -33
- package/src/rbac/hooks/useSecureSupabase.ts +4 -9
- package/src/rbac/secureClient.ts +43 -0
- package/src/services/EventService.ts +4 -57
- package/src/services/InactivityService.ts +127 -34
- package/src/services/OrganisationService.ts +68 -10
- package/src/utils/security/secureDataAccess.test.ts +31 -20
- package/src/utils/security/secureDataAccess.ts +4 -3
- package/dist/chunk-6C4YBBJM.js.map +0 -1
- package/dist/chunk-6LTQQAT6.js.map +0 -1
- package/dist/chunk-6TQDD426.js.map +0 -1
- package/dist/chunk-LOMZXPSN.js.map +0 -1
- package/dist/chunk-OETXORNB.js.map +0 -1
- package/dist/chunk-ULHIJK66.js.map +0 -1
- package/dist/chunk-VKB2CO4Z.js.map +0 -1
- package/dist/chunk-VRGWKHDB.js.map +0 -1
- package/dist/chunk-XNYQOL3Z.js.map +0 -1
- package/dist/chunk-XYXSXPUK.js.map +0 -1
- package/scripts/check-pace-core-compliance.js +0 -512
- package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
- package/src/utils/context/superAdminOverride.ts +0 -58
- /package/dist/{DataTable-WKRZD47S.js.map → DataTable-DQ7RSOHE.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-FTSG5XH7.js.map → UnifiedAuthProvider-ATAP5UTR.js.map} +0 -0
- /package/dist/{api-IHKALJZD.js.map → api-N774RPUA.js.map} +0 -0
- /package/dist/{chunk-QWWZ5CAQ.js.map → chunk-LXQLPRQ2.js.map} +0 -0
- /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
- /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/index.ts +0 -0
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Enforce testing framework consistency and standards for consuming apps
|
|
3
|
+
globs: ["**/*.{test,spec}.{ts,tsx}"]
|
|
4
|
+
alwaysApply: true
|
|
5
|
+
paceCoreVersion: "0.5.x"
|
|
6
|
+
rulesVersion: "2025-01-15"
|
|
7
|
+
---
|
|
8
|
+
# Testing Standards Guide
|
|
9
|
+
|
|
10
|
+
This guide ensures consistent, high-quality testing across consuming apps in the PACE suite.
|
|
11
|
+
|
|
12
|
+
## MUST: Meet Coverage Requirements
|
|
13
|
+
|
|
14
|
+
**MUST achieve minimum coverage:**
|
|
15
|
+
- ≥90% coverage for utils & hooks
|
|
16
|
+
- ≥70% coverage for components
|
|
17
|
+
|
|
18
|
+
**Verify coverage:**
|
|
19
|
+
```bash
|
|
20
|
+
npm run test:coverage
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## MUST: Use React Testing Library
|
|
24
|
+
|
|
25
|
+
**MUST use React Testing Library + userEvent for all component tests.**
|
|
26
|
+
|
|
27
|
+
```tsx
|
|
28
|
+
// ✅ CORRECT - React Testing Library
|
|
29
|
+
import { render, screen } from '@testing-library/react';
|
|
30
|
+
import userEvent from '@testing-library/user-event';
|
|
31
|
+
import { Button } from '@jmruthers/pace-core';
|
|
32
|
+
|
|
33
|
+
test('button clicks work', async () => {
|
|
34
|
+
const user = userEvent.setup();
|
|
35
|
+
const handleClick = vi.fn();
|
|
36
|
+
|
|
37
|
+
render(<Button onClick={handleClick}>Click me</Button>);
|
|
38
|
+
|
|
39
|
+
await user.click(screen.getByRole('button', { name: /click me/i }));
|
|
40
|
+
|
|
41
|
+
expect(handleClick).toHaveBeenCalledTimes(1);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// ❌ WRONG - Enzyme or other testing libraries
|
|
45
|
+
import { shallow } from 'enzyme';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## MUST: Colocate Tests
|
|
49
|
+
|
|
50
|
+
**Tests MUST be colocated with source files:**
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
src/
|
|
54
|
+
├── components/
|
|
55
|
+
│ └── EventCard/
|
|
56
|
+
│ ├── EventCard.tsx
|
|
57
|
+
│ └── EventCard.test.tsx
|
|
58
|
+
├── hooks/
|
|
59
|
+
│ ├── useEventData.ts
|
|
60
|
+
│ └── useEventData.test.ts
|
|
61
|
+
└── utils/
|
|
62
|
+
├── formatEvent.ts
|
|
63
|
+
└── formatEvent.test.ts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## MUST: Use Vitest
|
|
67
|
+
|
|
68
|
+
**MUST use Vitest for all testing:**
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
// vitest.config.ts
|
|
72
|
+
import { defineConfig } from 'vitest/config';
|
|
73
|
+
|
|
74
|
+
export default defineConfig({
|
|
75
|
+
test: {
|
|
76
|
+
environment: 'jsdom',
|
|
77
|
+
setupFiles: ['./vitest.setup.ts'],
|
|
78
|
+
coverage: {
|
|
79
|
+
provider: 'v8',
|
|
80
|
+
reporter: ['text', 'json', 'html'],
|
|
81
|
+
thresholds: {
|
|
82
|
+
lines: 80,
|
|
83
|
+
functions: 80,
|
|
84
|
+
branches: 80,
|
|
85
|
+
statements: 80,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## MUST: Test User Behavior, Not Implementation
|
|
93
|
+
|
|
94
|
+
**Tests MUST focus on what users see and do:**
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
// ❌ WRONG - Testing implementation
|
|
98
|
+
test('calls setState', () => {
|
|
99
|
+
const component = render(<Counter />);
|
|
100
|
+
expect(component.state.count).toBe(0);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// ✅ CORRECT - Testing user behavior
|
|
104
|
+
test('displays count and increments on button click', async () => {
|
|
105
|
+
const user = userEvent.setup();
|
|
106
|
+
render(<Counter />);
|
|
107
|
+
|
|
108
|
+
expect(screen.getByText('Count: 0')).toBeInTheDocument();
|
|
109
|
+
|
|
110
|
+
await user.click(screen.getByRole('button', { name: /increment/i }));
|
|
111
|
+
|
|
112
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
113
|
+
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## MUST: Use Accessible Queries
|
|
117
|
+
|
|
118
|
+
**MUST prefer accessible queries (byRole, byLabelText, etc.):**
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
// ✅ CORRECT - Accessible queries
|
|
122
|
+
screen.getByRole('button', { name: /submit/i });
|
|
123
|
+
screen.getByLabelText(/email address/i);
|
|
124
|
+
screen.getByText(/welcome/i);
|
|
125
|
+
|
|
126
|
+
// ❌ AVOID - Non-accessible queries (use as last resort)
|
|
127
|
+
screen.getByTestId('submit-button');
|
|
128
|
+
screen.getByClassName('btn-primary');
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## SHOULD: Test Critical Paths
|
|
132
|
+
|
|
133
|
+
**SHOULD test:**
|
|
134
|
+
- User workflows and interactions
|
|
135
|
+
- Error handling and edge cases
|
|
136
|
+
- Form validation
|
|
137
|
+
- Permission checks (RBAC)
|
|
138
|
+
- Data loading states
|
|
139
|
+
- Error states
|
|
140
|
+
|
|
141
|
+
## SHOULD: Use Descriptive Test Names
|
|
142
|
+
|
|
143
|
+
**Test names SHOULD describe behavior:**
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
// ❌ WRONG - Vague
|
|
147
|
+
test('button works', () => { ... });
|
|
148
|
+
|
|
149
|
+
// ✅ CORRECT - Descriptive
|
|
150
|
+
test('increments counter when increment button is clicked', () => { ... });
|
|
151
|
+
test('displays error message when API call fails', () => { ... });
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## SHOULD: Group Related Tests
|
|
155
|
+
|
|
156
|
+
**SHOULD use `describe` blocks to group related tests:**
|
|
157
|
+
|
|
158
|
+
```tsx
|
|
159
|
+
describe('EventCard', () => {
|
|
160
|
+
describe('rendering', () => {
|
|
161
|
+
test('displays event title', () => { ... });
|
|
162
|
+
test('displays event date', () => { ... });
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe('interactions', () => {
|
|
166
|
+
test('calls onEdit when edit button clicked', () => { ... });
|
|
167
|
+
test('calls onDelete when delete button clicked', () => { ... });
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## MUST: Avoid Unnecessary Mocks
|
|
173
|
+
|
|
174
|
+
**MUST NOT mock unless necessary:**
|
|
175
|
+
|
|
176
|
+
```tsx
|
|
177
|
+
// ❌ WRONG - Unnecessary mock
|
|
178
|
+
const mockFetch = vi.fn();
|
|
179
|
+
global.fetch = mockFetch;
|
|
180
|
+
|
|
181
|
+
// ✅ CORRECT - Use real implementation or MSW
|
|
182
|
+
import { server } from './mocks/server';
|
|
183
|
+
import { rest } from 'msw';
|
|
184
|
+
|
|
185
|
+
server.use(
|
|
186
|
+
rest.get('/api/events', (req, res, ctx) => {
|
|
187
|
+
return res(ctx.json([{ id: '1', name: 'Event' }]));
|
|
188
|
+
})
|
|
189
|
+
);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## MUST: Test Async Code Properly
|
|
193
|
+
|
|
194
|
+
**MUST handle async operations correctly:**
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
// ✅ CORRECT - Async testing
|
|
198
|
+
test('loads and displays events', async () => {
|
|
199
|
+
render(<EventList />);
|
|
200
|
+
|
|
201
|
+
expect(screen.getByText(/loading/i)).toBeInTheDocument();
|
|
202
|
+
|
|
203
|
+
await waitFor(() => {
|
|
204
|
+
expect(screen.getByText('Event 1')).toBeInTheDocument();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
expect(screen.queryByText(/loading/i)).not.toBeInTheDocument();
|
|
208
|
+
});
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## MUST: Clean Up After Tests
|
|
212
|
+
|
|
213
|
+
**MUST clean up resources:**
|
|
214
|
+
|
|
215
|
+
```tsx
|
|
216
|
+
// ✅ CORRECT - Cleanup
|
|
217
|
+
afterEach(() => {
|
|
218
|
+
cleanup();
|
|
219
|
+
vi.clearAllMocks();
|
|
220
|
+
});
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## SHOULD: Use Test Utilities
|
|
224
|
+
|
|
225
|
+
**SHOULD create reusable test utilities:**
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
// test-utils.tsx
|
|
229
|
+
import { render } from '@testing-library/react';
|
|
230
|
+
import { UnifiedAuthProvider } from '@jmruthers/pace-core';
|
|
231
|
+
|
|
232
|
+
export function renderWithProviders(ui: React.ReactElement) {
|
|
233
|
+
return render(
|
|
234
|
+
<UnifiedAuthProvider supabaseClient={mockSupabase} appName="Test App">
|
|
235
|
+
{ui}
|
|
236
|
+
</UnifiedAuthProvider>
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// Usage
|
|
241
|
+
test('component works with providers', () => {
|
|
242
|
+
renderWithProviders(<MyComponent />);
|
|
243
|
+
// ...
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## MUST: Include Timeout Parameters
|
|
248
|
+
|
|
249
|
+
**Tests MUST include timeout parameters to prevent hanging:**
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
// ✅ CORRECT - With timeout
|
|
253
|
+
test('async operation completes', async () => {
|
|
254
|
+
await waitFor(
|
|
255
|
+
() => expect(screen.getByText('Loaded')).toBeInTheDocument(),
|
|
256
|
+
{ timeout: 5000 }
|
|
257
|
+
);
|
|
258
|
+
}, { timeout: 10000 });
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Testing Checklist
|
|
262
|
+
|
|
263
|
+
Before committing tests, verify:
|
|
264
|
+
- [ ] Coverage meets requirements (≥90% utils, ≥70% components)
|
|
265
|
+
- [ ] Using React Testing Library + userEvent
|
|
266
|
+
- [ ] Tests are colocated with source files
|
|
267
|
+
- [ ] Testing user behavior, not implementation
|
|
268
|
+
- [ ] Using accessible queries (byRole, byLabelText)
|
|
269
|
+
- [ ] Test names are descriptive
|
|
270
|
+
- [ ] Related tests grouped with describe
|
|
271
|
+
- [ ] No unnecessary mocks
|
|
272
|
+
- [ ] Async code tested properly
|
|
273
|
+
- [ ] Cleanup after tests
|
|
274
|
+
- [ ] Timeout parameters included
|
|
275
|
+
|
|
276
|
+
## Test Structure Template
|
|
277
|
+
|
|
278
|
+
```tsx
|
|
279
|
+
import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
280
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
281
|
+
import userEvent from '@testing-library/user-event';
|
|
282
|
+
import { ComponentName } from './ComponentName';
|
|
283
|
+
|
|
284
|
+
describe('ComponentName', () => {
|
|
285
|
+
beforeEach(() => {
|
|
286
|
+
// Setup
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
afterEach(() => {
|
|
290
|
+
// Cleanup
|
|
291
|
+
vi.clearAllMocks();
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
describe('rendering', () => {
|
|
295
|
+
test('renders correctly', () => {
|
|
296
|
+
render(<ComponentName />);
|
|
297
|
+
// Assertions
|
|
298
|
+
});
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
describe('interactions', () => {
|
|
302
|
+
test('handles user interaction', async () => {
|
|
303
|
+
const user = userEvent.setup();
|
|
304
|
+
render(<ComponentName />);
|
|
305
|
+
// Test interaction
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Reference
|
|
312
|
+
|
|
313
|
+
- React Testing Library: https://testing-library.com/react
|
|
314
|
+
- Vitest: https://vitest.dev
|
|
315
|
+
- Testing Standards: See `06-testing-and-docs-standard.md` in pace-core docs
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Standardized templates for bug reports and feature requests for pace-core
|
|
3
|
+
globs: []
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
paceCoreVersion: "0.5.x"
|
|
6
|
+
rulesVersion: "2025-01-15"
|
|
7
|
+
---
|
|
8
|
+
# Bug Reports and Feature Requests Guide
|
|
9
|
+
|
|
10
|
+
This guide provides standardized templates for reporting bugs and requesting features in pace-core. This is a reference guide - Cursor will use this for context when helping with issue reporting.
|
|
11
|
+
|
|
12
|
+
## Identifying Issues
|
|
13
|
+
|
|
14
|
+
### Is This a pace-core Issue?
|
|
15
|
+
|
|
16
|
+
**Before reporting, determine if the issue is in pace-core or your consuming app:**
|
|
17
|
+
|
|
18
|
+
1. **Check pace-core documentation** - Is the behavior documented?
|
|
19
|
+
2. **Check pace-core source** - Can you find the relevant code?
|
|
20
|
+
3. **Test in isolation** - Can you reproduce with minimal pace-core usage?
|
|
21
|
+
4. **Check similar issues** - Has this been reported before?
|
|
22
|
+
|
|
23
|
+
**If the issue is in your consuming app:**
|
|
24
|
+
- Fix it locally
|
|
25
|
+
- Don't file a pace-core issue
|
|
26
|
+
|
|
27
|
+
**If the issue is in pace-core:**
|
|
28
|
+
- Use the templates below to file an issue
|
|
29
|
+
|
|
30
|
+
## Bug Report Template
|
|
31
|
+
|
|
32
|
+
### Required Information
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
## Bug Description
|
|
36
|
+
[Clear, concise description of the bug]
|
|
37
|
+
|
|
38
|
+
## Expected Behavior
|
|
39
|
+
[What should happen]
|
|
40
|
+
|
|
41
|
+
## Actual Behavior
|
|
42
|
+
[What actually happens]
|
|
43
|
+
|
|
44
|
+
## Steps to Reproduce
|
|
45
|
+
1. [First step]
|
|
46
|
+
2. [Second step]
|
|
47
|
+
3. [Third step]
|
|
48
|
+
...
|
|
49
|
+
|
|
50
|
+
## Minimal Reproduction
|
|
51
|
+
[Link to minimal reproduction or code snippet]
|
|
52
|
+
|
|
53
|
+
## Environment
|
|
54
|
+
- pace-core version: [e.g., 0.5.193]
|
|
55
|
+
- React version: [e.g., 19.2.3]
|
|
56
|
+
- Node version: [e.g., 20.10.0]
|
|
57
|
+
- Browser: [e.g., Chrome 120]
|
|
58
|
+
- OS: [e.g., macOS 14.2]
|
|
59
|
+
|
|
60
|
+
## Code Example
|
|
61
|
+
\`\`\`tsx
|
|
62
|
+
// Minimal code that reproduces the issue
|
|
63
|
+
import { Component } from '@jmruthers/pace-core';
|
|
64
|
+
|
|
65
|
+
function App() {
|
|
66
|
+
return <Component />;
|
|
67
|
+
}
|
|
68
|
+
\`\`\`
|
|
69
|
+
|
|
70
|
+
## Error Messages
|
|
71
|
+
[Any error messages or console output]
|
|
72
|
+
|
|
73
|
+
## Additional Context
|
|
74
|
+
[Screenshots, videos, or other relevant information]
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Example Bug Report
|
|
78
|
+
|
|
79
|
+
```markdown
|
|
80
|
+
## Bug Description
|
|
81
|
+
DataTable component throws error when `rbac` prop is missing, but error message is unclear.
|
|
82
|
+
|
|
83
|
+
## Expected Behavior
|
|
84
|
+
DataTable should either:
|
|
85
|
+
1. Work without rbac prop (if not required), OR
|
|
86
|
+
2. Show clear error message explaining rbac is required
|
|
87
|
+
|
|
88
|
+
## Actual Behavior
|
|
89
|
+
DataTable throws: "Cannot read property 'pageId' of undefined" with no context about missing rbac prop.
|
|
90
|
+
|
|
91
|
+
## Steps to Reproduce
|
|
92
|
+
1. Import DataTable from pace-core
|
|
93
|
+
2. Use DataTable without rbac prop
|
|
94
|
+
3. See error in console
|
|
95
|
+
|
|
96
|
+
## Minimal Reproduction
|
|
97
|
+
\`\`\`tsx
|
|
98
|
+
import { DataTable } from '@jmruthers/pace-core';
|
|
99
|
+
|
|
100
|
+
function App() {
|
|
101
|
+
return (
|
|
102
|
+
<DataTable
|
|
103
|
+
data={[]}
|
|
104
|
+
columns={[]}
|
|
105
|
+
// Missing rbac prop
|
|
106
|
+
/>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
\`\`\`
|
|
110
|
+
|
|
111
|
+
## Environment
|
|
112
|
+
- pace-core version: 0.5.193
|
|
113
|
+
- React version: 19.2.3
|
|
114
|
+
- Node version: 20.10.0
|
|
115
|
+
- Browser: Chrome 120
|
|
116
|
+
- OS: macOS 14.2
|
|
117
|
+
|
|
118
|
+
## Error Messages
|
|
119
|
+
```
|
|
120
|
+
Uncaught TypeError: Cannot read property 'pageId' of undefined
|
|
121
|
+
at DataTable (DataTable.tsx:123)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Additional Context
|
|
125
|
+
The error occurs immediately on render. The documentation mentions rbac is required, but the error doesn't reference this.
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Feature Request Template
|
|
129
|
+
|
|
130
|
+
### Required Information
|
|
131
|
+
|
|
132
|
+
```markdown
|
|
133
|
+
## Feature Description
|
|
134
|
+
[Clear, concise description of the feature]
|
|
135
|
+
|
|
136
|
+
## Problem Statement
|
|
137
|
+
[What problem does this solve? Why is it needed?]
|
|
138
|
+
|
|
139
|
+
## Proposed Solution
|
|
140
|
+
[How should this work? What would the API look like?]
|
|
141
|
+
|
|
142
|
+
## Use Case
|
|
143
|
+
[Real-world scenario where this would be useful]
|
|
144
|
+
|
|
145
|
+
## Alternatives Considered
|
|
146
|
+
[Other approaches you've considered]
|
|
147
|
+
|
|
148
|
+
## Code Example
|
|
149
|
+
\`\`\`tsx
|
|
150
|
+
// How you would use this feature
|
|
151
|
+
import { NewFeature } from '@jmruthers/pace-core';
|
|
152
|
+
|
|
153
|
+
function App() {
|
|
154
|
+
return <NewFeature prop="value" />;
|
|
155
|
+
}
|
|
156
|
+
\`\`\`
|
|
157
|
+
|
|
158
|
+
## Additional Context
|
|
159
|
+
[Screenshots, mockups, or other relevant information]
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Example Feature Request
|
|
163
|
+
|
|
164
|
+
```markdown
|
|
165
|
+
## Feature Description
|
|
166
|
+
Add `onRowDoubleClick` prop to DataTable component for double-click row interactions.
|
|
167
|
+
|
|
168
|
+
## Problem Statement
|
|
169
|
+
Currently, DataTable only supports single-click row selection. Many users expect double-click to open/edit a row, which is a common pattern in data tables.
|
|
170
|
+
|
|
171
|
+
## Proposed Solution
|
|
172
|
+
Add optional `onRowDoubleClick` callback prop:
|
|
173
|
+
- Fires when user double-clicks a row
|
|
174
|
+
- Receives row data and event
|
|
175
|
+
- Works alongside existing selection behavior
|
|
176
|
+
|
|
177
|
+
## Use Case
|
|
178
|
+
In an event management app, users want to double-click an event row to open the event details modal, while single-click selects the row for bulk operations.
|
|
179
|
+
|
|
180
|
+
## Alternatives Considered
|
|
181
|
+
1. Using `onRowClick` and detecting double-clicks - but this conflicts with selection
|
|
182
|
+
2. Custom row component - but this loses DataTable features
|
|
183
|
+
3. External double-click handler - but this is less integrated
|
|
184
|
+
|
|
185
|
+
## Code Example
|
|
186
|
+
\`\`\`tsx
|
|
187
|
+
import { DataTable } from '@jmruthers/pace-core';
|
|
188
|
+
|
|
189
|
+
function EventList() {
|
|
190
|
+
const handleRowDoubleClick = (row: Event) => {
|
|
191
|
+
openEventDetails(row.id);
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return (
|
|
195
|
+
<DataTable
|
|
196
|
+
data={events}
|
|
197
|
+
columns={columns}
|
|
198
|
+
rbac={{ pageName: 'events' }}
|
|
199
|
+
onRowDoubleClick={handleRowDoubleClick}
|
|
200
|
+
/>
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
\`\`\`
|
|
204
|
+
|
|
205
|
+
## Additional Context
|
|
206
|
+
This is a common pattern in enterprise data tables. Many similar libraries support this.
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## Where to File Issues
|
|
210
|
+
|
|
211
|
+
**File issues in the pace-core repository:**
|
|
212
|
+
- GitHub Issues: [Repository URL]
|
|
213
|
+
- Include all required information from templates
|
|
214
|
+
- Use appropriate labels if available
|
|
215
|
+
|
|
216
|
+
## Before Filing
|
|
217
|
+
|
|
218
|
+
**Check:**
|
|
219
|
+
- [ ] Issue hasn't been reported already
|
|
220
|
+
- [ ] You're using the latest pace-core version
|
|
221
|
+
- [ ] Issue is actually in pace-core (not your app)
|
|
222
|
+
- [ ] You've checked documentation
|
|
223
|
+
- [ ] You have a minimal reproduction
|
|
224
|
+
- [ ] You've included all required information
|
|
225
|
+
|
|
226
|
+
## After Filing
|
|
227
|
+
|
|
228
|
+
**Be prepared to:**
|
|
229
|
+
- Provide additional information if requested
|
|
230
|
+
- Test fixes in development versions
|
|
231
|
+
- Verify the fix works in your app
|
|
232
|
+
- Close the issue if resolved
|
|
233
|
+
|
|
234
|
+
## Tips for Effective Reports
|
|
235
|
+
|
|
236
|
+
1. **Be specific** - Vague descriptions waste time
|
|
237
|
+
2. **Include reproduction** - Minimal code that shows the issue
|
|
238
|
+
3. **Check existing issues** - Don't duplicate reports
|
|
239
|
+
4. **Be patient** - Maintainers are volunteers
|
|
240
|
+
5. **Be respectful** - Constructive feedback helps
|
|
241
|
+
|
|
242
|
+
## Reference
|
|
243
|
+
|
|
244
|
+
- pace-core Documentation: `packages/core/docs/`
|
|
245
|
+
- pace-core Source: `packages/core/src/`
|
|
246
|
+
- GitHub Issues: [Repository URL]
|