@jmruthers/pace-core 0.5.76 → 0.5.78
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 +8 -0
- package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-Df3IozMG.d.ts} +10 -118
- package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
- package/dist/{DataTable-4GAVPIEG.js → DataTable-ETGVF4Y5.js} +50 -13
- package/dist/{PublicLoadingSpinner-BiNER8F5.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +5 -2
- package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
- package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-P5SOJAQ6.js} +4 -5
- package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
- package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
- package/dist/{chunk-K34IM5CT.js → chunk-2OGV6IRV.js} +196 -626
- package/dist/chunk-2OGV6IRV.js.map +1 -0
- package/dist/{chunk-NTNILOBC.js → chunk-5BO3MI5Y.js} +4 -4
- package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
- package/dist/chunk-CVMVPYAL.js.map +1 -0
- package/dist/{chunk-URUTVZ7N.js → chunk-FL4ZCQLD.js} +2 -2
- package/dist/{chunk-LW7MMEAQ.js → chunk-FT2M4R4F.js} +2 -2
- package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
- package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
- package/dist/{chunk-KHJS6VIA.js → chunk-LRQ6RBJC.js} +157 -112
- package/dist/chunk-LRQ6RBJC.js.map +1 -0
- package/dist/{chunk-WN6XJWOS.js → chunk-MNJXXD6C.js} +274 -743
- package/dist/chunk-MNJXXD6C.js.map +1 -0
- package/dist/{chunk-KK73ZB4E.js → chunk-PTR5PMPE.js} +153 -132
- package/dist/chunk-PTR5PMPE.js.map +1 -0
- package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
- package/dist/chunk-Q7APDV6H.js.map +1 -0
- package/dist/{chunk-A4FUBC7B.js → chunk-QGVSOUJ2.js} +2 -4
- package/dist/{chunk-A4FUBC7B.js.map → chunk-QGVSOUJ2.js.map} +1 -1
- package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
- package/dist/chunk-S63MFSY6.js.map +1 -0
- package/dist/{chunk-AFGTSUAD.js → chunk-VSOKOFRF.js} +4 -4
- package/dist/chunk-WUXCWRL6.js +20 -0
- package/dist/chunk-WUXCWRL6.js.map +1 -0
- package/dist/{chunk-Y6TXWPJO.js → chunk-YVVGHRGI.js} +105 -31
- package/dist/chunk-YVVGHRGI.js.map +1 -0
- package/dist/{chunk-M5IWZRBT.js → chunk-ZMNXIJP4.js} +2187 -981
- package/dist/chunk-ZMNXIJP4.js.map +1 -0
- package/dist/components.d.ts +6 -6
- package/dist/components.js +14 -18
- package/dist/components.js.map +1 -1
- package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +8 -9
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +19 -27
- package/dist/index.js +21 -29
- package/dist/index.js.map +1 -1
- package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
- package/dist/providers.d.ts +7 -21
- package/dist/providers.js +3 -10
- package/dist/rbac/index.d.ts +71 -221
- package/dist/rbac/index.js +15 -16
- package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
- package/dist/types.d.ts +3 -3
- package/dist/types.js +61 -18
- package/dist/types.js.map +1 -1
- package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
- package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +52 -9
- package/dist/utils.js.map +1 -1
- package/docs/CONTENT_AUDIT_REPORT.md +253 -0
- package/docs/DOCUMENTATION_AUDIT.md +172 -0
- package/docs/README.md +142 -147
- package/docs/STYLE_GUIDE.md +37 -0
- package/docs/api/classes/ColumnFactory.md +17 -17
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +5 -5
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +8 -8
- package/docs/api/classes/RBACCache.md +35 -5
- package/docs/api/classes/RBACEngine.md +49 -20
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/ButtonProps.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/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +11 -0
- package/docs/api/interfaces/DataTableAction.md +65 -29
- package/docs/api/interfaces/DataTableColumn.md +36 -23
- package/docs/api/interfaces/DataTableProps.md +80 -38
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/FooterProps.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/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- 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 +7 -7
- 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 +16 -3
- 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/PermissionEnforcerProps.md +4 -4
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.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/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.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/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- 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/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +251 -269
- package/docs/api-reference/components.md +193 -0
- package/docs/api-reference/hooks.md +265 -0
- package/docs/api-reference/providers.md +6 -0
- package/docs/api-reference/types.md +6 -0
- package/docs/api-reference/utilities.md +207 -0
- package/docs/architecture/README.md +6 -0
- package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
- package/docs/architecture/rbac-security-architecture.md +258 -0
- package/docs/architecture/services.md +9 -1
- package/docs/best-practices/README.md +6 -0
- package/docs/best-practices/accessibility.md +6 -0
- package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
- package/docs/best-practices/deployment.md +6 -0
- package/docs/best-practices/performance.md +475 -2
- package/docs/best-practices/security.md +6 -0
- package/docs/best-practices/testing.md +6 -0
- package/docs/core-concepts/authentication.md +6 -0
- package/docs/core-concepts/events.md +6 -0
- package/docs/core-concepts/organisations.md +6 -0
- package/docs/core-concepts/permissions.md +6 -0
- package/docs/core-concepts/rbac-system.md +8 -0
- package/docs/documentation-index.md +121 -182
- package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
- package/docs/getting-started/documentation-index.md +40 -0
- package/docs/getting-started/examples/README.md +878 -35
- package/docs/{faq.md → getting-started/faq.md} +7 -1
- package/docs/getting-started/installation-guide.md +6 -0
- package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
- package/docs/implementation-guides/app-layout.md +6 -0
- package/docs/implementation-guides/authentication.md +1021 -0
- package/docs/implementation-guides/component-styling.md +6 -0
- package/docs/implementation-guides/data-tables.md +1264 -2076
- package/docs/implementation-guides/dynamic-colors.md +6 -0
- package/docs/implementation-guides/event-theming-summary.md +6 -0
- package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
- package/docs/implementation-guides/file-upload-storage.md +6 -0
- package/docs/implementation-guides/forms.md +6 -0
- package/docs/implementation-guides/inactivity-tracking.md +6 -0
- package/docs/implementation-guides/navigation.md +6 -0
- package/docs/implementation-guides/organisation-security.md +6 -0
- package/docs/implementation-guides/permission-enforcement.md +6 -0
- package/docs/implementation-guides/public-pages-advanced.md +6 -0
- package/docs/implementation-guides/public-pages.md +6 -0
- package/docs/migration/MIGRATION_GUIDE.md +827 -351
- package/docs/migration/README.md +7 -1
- package/docs/migration/organisation-context-timing-fix.md +6 -0
- package/docs/migration/rbac-migration.md +44 -1
- package/docs/migration/service-architecture.md +6 -0
- package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
- package/docs/migration/v0.4.16-css-first-approach.md +6 -0
- package/docs/migration/v0.4.17-source-path-fix.md +6 -0
- package/docs/rbac/README-rbac-rls-integration.md +6 -0
- package/docs/rbac/README.md +6 -0
- package/docs/rbac/advanced-patterns.md +6 -0
- package/docs/rbac/api-reference.md +7 -1
- package/docs/rbac/breaking-changes-v3.md +222 -0
- package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
- package/docs/rbac/examples.md +6 -0
- package/docs/rbac/getting-started.md +6 -0
- package/docs/rbac/migration-guide.md +260 -0
- package/docs/rbac/quick-start.md +70 -13
- package/docs/rbac/rbac-rls-integration.md +6 -0
- package/docs/rbac/super-admin-guide.md +6 -0
- package/docs/rbac/troubleshooting.md +6 -0
- package/docs/security/README.md +6 -0
- package/docs/security/checklist.md +6 -0
- package/docs/styles/README.md +7 -1
- package/docs/{usage.md → styles/usage.md} +6 -0
- package/docs/testing/README.md +6 -0
- package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
- package/docs/troubleshooting/README.md +387 -5
- package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
- package/docs/troubleshooting/common-issues.md +6 -0
- package/docs/troubleshooting/database-view-compatibility.md +6 -0
- package/docs/troubleshooting/organisation-context-setup.md +6 -0
- package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
- package/docs/troubleshooting/styling-issues.md +6 -0
- package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
- package/package.json +1 -1
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
- package/src/__tests__/helpers/test-providers.tsx +3 -53
- package/src/components/DataTable/DataTable.test.tsx +319 -0
- package/src/components/DataTable/DataTable.tsx +32 -11
- package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +31 -9
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
- package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
- package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +88 -104
- package/src/components/DataTable/components/DataTableCore.tsx +309 -337
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
- package/src/components/DataTable/components/DataTableModals.tsx +22 -1
- package/src/components/DataTable/components/EditableRow.tsx +69 -84
- package/src/components/DataTable/components/EmptyState.tsx +5 -1
- package/src/components/DataTable/components/ImportModal.tsx +65 -36
- package/src/components/DataTable/components/PaginationControls.tsx +40 -100
- package/src/components/DataTable/components/UnifiedTableBody.tsx +125 -148
- package/src/components/DataTable/context/DataTableContext.tsx +1 -1
- package/src/components/DataTable/core/ColumnFactory.ts +5 -0
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
- package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
- package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +1 -5
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
- package/src/components/DataTable/hooks/index.ts +7 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
- package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +71 -27
- package/src/components/DataTable/hooks/useDataTableState.ts +39 -11
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
- package/src/components/DataTable/hooks/useHierarchicalState.ts +15 -1
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
- package/src/components/DataTable/hooks/useTableColumns.ts +10 -7
- package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
- package/src/components/DataTable/index.ts +12 -3
- package/src/components/DataTable/types.ts +129 -9
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +159 -22
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +111 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +15 -29
- package/src/components/DataTable/utils/a11yUtils.ts +244 -0
- package/src/components/DataTable/utils/debugTools.ts +609 -0
- package/src/components/DataTable/utils/exportUtils.ts +114 -16
- package/src/components/DataTable/utils/flexibleImport.ts +202 -32
- package/src/components/DataTable/utils/hierarchicalUtils.ts +1 -1
- package/src/components/DataTable/utils/index.ts +2 -0
- package/src/components/DataTable/utils/paginationUtils.ts +350 -0
- package/src/components/DataTable/utils/rowUtils.ts +6 -5
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
- package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
- package/src/components/Select/Select.tsx +1 -0
- package/src/components/examples/PermissionExample.tsx +173 -0
- package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
- package/src/examples/PublicEventPage.tsx +274 -0
- package/src/examples/PublicPageApp.tsx +308 -0
- package/src/examples/PublicPageUsageExample.tsx +216 -0
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
- package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
- package/src/hooks/useOrganisationPermissions.test.ts +42 -18
- package/src/hooks/useOrganisationPermissions.ts +12 -6
- package/src/hooks/useOrganisationSecurity.test.ts +138 -85
- package/src/hooks/useOrganisationSecurity.ts +41 -10
- package/src/index.ts +0 -1
- package/src/providers/AuthProvider.simplified.tsx +880 -0
- package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
- package/src/providers/index.ts +0 -1
- package/src/providers/services/EventServiceProvider.tsx +19 -15
- package/src/providers/services/InactivityServiceProvider.tsx +19 -15
- package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
- package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
- package/src/rbac/adapters.tsx +26 -69
- package/src/rbac/api.test.ts +90 -27
- package/src/rbac/api.ts +61 -10
- package/src/rbac/audit.test.ts +33 -38
- package/src/rbac/audit.ts +21 -6
- package/src/rbac/cache.ts +33 -1
- package/src/rbac/components/NavigationGuard.tsx +11 -11
- package/src/rbac/components/NavigationProvider.test.tsx +11 -5
- package/src/rbac/components/NavigationProvider.tsx +37 -13
- package/src/rbac/components/PagePermissionGuard.tsx +111 -50
- package/src/rbac/components/PagePermissionProvider.tsx +5 -5
- package/src/rbac/components/PermissionEnforcer.tsx +11 -11
- package/src/rbac/components/RoleBasedRouter.tsx +5 -5
- package/src/rbac/components/SecureDataProvider.tsx +5 -5
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
- package/src/rbac/engine.test.simple.ts +19 -13
- package/src/rbac/engine.test.ts +1 -0
- package/src/rbac/engine.ts +330 -766
- package/src/rbac/errors.ts +156 -0
- package/src/rbac/hooks/usePermissions.ts +32 -10
- package/src/rbac/hooks/useRBAC.test.ts +126 -512
- package/src/rbac/hooks/useRBAC.ts +147 -193
- package/src/rbac/hooks/useResolvedScope.ts +12 -0
- package/src/rbac/index.ts +7 -4
- package/src/rbac/security.ts +109 -18
- package/src/rbac/types.ts +12 -1
- package/src/services/AuthService.ts +2 -15
- package/src/services/EventService.ts +43 -46
- package/src/services/OrganisationService.ts +51 -31
- package/src/services/__tests__/AuthService.test.ts +1 -1
- package/src/services/__tests__/EventService.test.ts +1 -1
- package/src/services/__tests__/OrganisationService.test.ts +1 -1
- package/src/services/base/BaseService.ts +8 -0
- package/src/styles/base.css +208 -0
- package/src/styles/semantic.css +24 -0
- package/src/types/database.generated.ts +7347 -0
- package/src/types/database.ts +20 -0
- package/src/utils/logger.ts +179 -0
- package/src/utils/organisationContext.ts +11 -4
- package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
- package/dist/appNameResolver-UURKN7NF.js +0 -22
- package/dist/audit-6TOCAMKO.js.map +0 -1
- package/dist/chunk-B2WTCLCV.js.map +0 -1
- package/dist/chunk-FGMFQSHX.js.map +0 -1
- package/dist/chunk-K34IM5CT.js.map +0 -1
- package/dist/chunk-KHJS6VIA.js.map +0 -1
- package/dist/chunk-KK73ZB4E.js.map +0 -1
- package/dist/chunk-M5IWZRBT.js.map +0 -1
- package/dist/chunk-ULBI5JGB.js +0 -109
- package/dist/chunk-ULBI5JGB.js.map +0 -1
- package/dist/chunk-WN6XJWOS.js.map +0 -1
- package/dist/chunk-XLZ7U46Z.js.map +0 -1
- package/dist/chunk-Y6TXWPJO.js.map +0 -1
- package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
- package/docs/TERMINOLOGY.md +0 -231
- package/docs/api/interfaces/RBACContextType.md +0 -468
- package/docs/api/interfaces/RBACProviderProps.md +0 -107
- package/docs/best-practices/performance-expansion.md +0 -473
- package/docs/breaking-changes.md +0 -179
- package/docs/consuming-app-example.md +0 -290
- package/docs/documentation-templates.md +0 -539
- package/docs/examples/navigation-menu-auth-fix.md +0 -344
- package/docs/getting-started/examples/basic-auth-app.md +0 -520
- package/docs/getting-started/examples/full-featured-app.md +0 -616
- package/docs/getting-started/quick-start.md +0 -376
- package/docs/implementation-guides/datatable-filtering.md +0 -313
- package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
- package/docs/implementation-guides/hierarchical-datatable.md +0 -850
- package/docs/implementation-guides/large-datasets.md +0 -281
- package/docs/implementation-guides/performance.md +0 -403
- package/docs/migration/quick-migration-guide.md +0 -320
- package/docs/migration-guide.md +0 -193
- package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
- package/docs/performance/README.md +0 -551
- package/docs/style-guide.md +0 -964
- package/docs/troubleshooting/authentication-issues.md +0 -334
- package/docs/troubleshooting/debugging.md +0 -1117
- package/docs/troubleshooting/migration.md +0 -918
- package/src/__tests__/hooks/usePermissions.test.ts +0 -261
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
- package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
- package/src/hooks/services/__tests__/useServiceHooks.test.tsx +0 -137
- package/src/hooks/services/usePermissions.ts +0 -70
- package/src/hooks/services/useRBACService.ts +0 -30
- package/src/hooks/usePermissionCheck.ts +0 -150
- package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
- package/src/providers/services/RBACServiceProvider.tsx +0 -79
- package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
- package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
- package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
- package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
- package/src/rbac/providers/RBACProvider.tsx +0 -645
- package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
- package/src/rbac/providers/index.ts +0 -11
- package/src/services/RBACService.ts +0 -522
- package/src/services/__tests__/RBACService.test.ts +0 -492
- package/src/services/interfaces/IRBACService.ts +0 -62
- package/src/utils/appNameResolver.test 2.ts +0 -494
- /package/dist/{DataTable-4GAVPIEG.js.map → DataTable-ETGVF4Y5.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-P5SOJAQ6.js.map} +0 -0
- /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
- /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
- /package/dist/{chunk-NTNILOBC.js.map → chunk-5BO3MI5Y.js.map} +0 -0
- /package/dist/{chunk-URUTVZ7N.js.map → chunk-FL4ZCQLD.js.map} +0 -0
- /package/dist/{chunk-LW7MMEAQ.js.map → chunk-FT2M4R4F.js.map} +0 -0
- /package/dist/{chunk-AFGTSUAD.js.map → chunk-VSOKOFRF.js.map} +0 -0
- /package/docs/{app.css.example → styles/app.css.example} +0 -0
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
# Quick Start - Build Your First App
|
|
2
|
-
|
|
3
|
-
> **🎯 Build Your First App** | [← Back to Documentation](../README.md) | [Installation Guide](./installation-guide.md) | [Examples](./examples/)
|
|
4
|
-
|
|
5
|
-
Build a complete PACE Core application with authentication, permissions, and a modern UI in under 10 minutes.
|
|
6
|
-
|
|
7
|
-
> **⏱️ Time to Complete**: ~10 minutes
|
|
8
|
-
> **Prerequisites**: Node.js 18+, npm/yarn/pnpm
|
|
9
|
-
> **Difficulty**: Beginner
|
|
10
|
-
|
|
11
|
-
## 🎯 What We'll Build
|
|
12
|
-
|
|
13
|
-
A complete meal management application featuring:
|
|
14
|
-
- ✅ **User Authentication** - Login/logout with Supabase
|
|
15
|
-
- ✅ **Role-Based Access Control** - Different permissions for different users
|
|
16
|
-
- ✅ **Interactive Data Tables** - CRUD operations with sorting, filtering, pagination
|
|
17
|
-
- ✅ **Form Validation** - Real-time validation with Zod schemas
|
|
18
|
-
- ✅ **Responsive Design** - Mobile-first with Tailwind CSS
|
|
19
|
-
- ✅ **Print Reports** - Generate PDF-ready reports
|
|
20
|
-
- ✅ **Modern UI** - Accessible, consistent component library
|
|
21
|
-
|
|
22
|
-
### Final Result Preview
|
|
23
|
-
|
|
24
|
-
Your app will have:
|
|
25
|
-
- A login page with proper authentication
|
|
26
|
-
- A dashboard with user-specific content
|
|
27
|
-
- A data table for managing meals with full CRUD operations
|
|
28
|
-
- Permission-based UI elements (admin-only features)
|
|
29
|
-
- Responsive design that works on all devices
|
|
30
|
-
|
|
31
|
-
## 🚀 Step-by-Step Implementation
|
|
32
|
-
|
|
33
|
-
### 1. Project Setup
|
|
34
|
-
|
|
35
|
-
If you don't have a project yet:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
# Using Vite (recommended)
|
|
39
|
-
npm create vite@latest meal-manager -- --template react-ts
|
|
40
|
-
cd meal-manager
|
|
41
|
-
|
|
42
|
-
# Or using Create React App (legacy)
|
|
43
|
-
# npx create-react-app meal-manager --template typescript
|
|
44
|
-
# cd meal-manager
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### 2. Install Dependencies
|
|
48
|
-
|
|
49
|
-
```bash
|
|
50
|
-
# Install pace-core and required peer dependencies
|
|
51
|
-
npm install @jmruthers/pace-core @tanstack/react-table @radix-ui/react-checkbox @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-label @radix-ui/react-slot lucide-react class-variance-authority clsx tailwind-merge
|
|
52
|
-
|
|
53
|
-
# Install Supabase and routing
|
|
54
|
-
npm install @supabase/supabase-js react-router-dom
|
|
55
|
-
|
|
56
|
-
# Install Tailwind CSS v4 and development dependencies
|
|
57
|
-
npm install -D @tailwindcss/vite tailwindcss@^4.0.0 @types/react @types/react-dom
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### 3. Configure Tailwind CSS v4 (CRITICAL)
|
|
61
|
-
|
|
62
|
-
**⚠️ CRITICAL**: pace-core requires Tailwind v4 with proper content scanning. Without this configuration, components will be unstyled.
|
|
63
|
-
|
|
64
|
-
Install Tailwind v4:
|
|
65
|
-
```bash
|
|
66
|
-
npm install -D @tailwindcss/vite tailwindcss@^4.0.0
|
|
67
|
-
# Remove old Tailwind v3 if installed
|
|
68
|
-
npm uninstall tailwindcss@^3.0.0
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**REQUIRED Vite Configuration** - You MUST include pace-core in content scanning:
|
|
72
|
-
|
|
73
|
-
```js
|
|
74
|
-
// vite.config.js
|
|
75
|
-
import { defineConfig } from 'vite'
|
|
76
|
-
import react from '@vitejs/plugin-react'
|
|
77
|
-
import tailwindcss from '@tailwindcss/vite'
|
|
78
|
-
|
|
79
|
-
export default defineConfig({
|
|
80
|
-
plugins: [
|
|
81
|
-
react(),
|
|
82
|
-
tailwindcss({
|
|
83
|
-
// CRITICAL: Include pace-core components for scanning
|
|
84
|
-
content: [
|
|
85
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
86
|
-
'./node_modules/@jmruthers/pace-core/**/*.{js,ts,jsx,tsx}'
|
|
87
|
-
]
|
|
88
|
-
})
|
|
89
|
-
],
|
|
90
|
-
})
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
**Why this is critical:**
|
|
94
|
-
- Pace-core components contain Tailwind classes that must be scanned
|
|
95
|
-
- Without proper content configuration, components will appear unstyled
|
|
96
|
-
- The UI will be severely compromised without this step
|
|
97
|
-
|
|
98
|
-
**No `tailwind.config.js` file needed** - pace-core handles all configuration via CSS imports.
|
|
99
|
-
|
|
100
|
-
### 4. Set Up Environment Variables
|
|
101
|
-
|
|
102
|
-
Create `.env.local`:
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
# Supabase Configuration
|
|
106
|
-
REACT_APP_SUPABASE_URL=https://your-project.supabase.co
|
|
107
|
-
REACT_APP_SUPABASE_ANON_KEY=your-anon-key-here
|
|
108
|
-
|
|
109
|
-
# ⚠️ CRITICAL: Use anon key, NOT service role key
|
|
110
|
-
# The anon key starts with: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
|
|
111
|
-
# The service role key has different permissions and can cause RPC timeouts
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### 5. Create Supabase Client
|
|
115
|
-
|
|
116
|
-
```typescript
|
|
117
|
-
// src/lib/supabase.ts
|
|
118
|
-
import { createClient } from '@supabase/supabase-js'
|
|
119
|
-
|
|
120
|
-
const supabaseUrl = process.env.REACT_APP_SUPABASE_URL!
|
|
121
|
-
const supabaseAnonKey = process.env.REACT_APP_SUPABASE_ANON_KEY!
|
|
122
|
-
|
|
123
|
-
if (!supabaseUrl || !supabaseAnonKey) {
|
|
124
|
-
throw new Error('Missing Supabase environment variables')
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### 6. Set Up App with Authentication
|
|
131
|
-
|
|
132
|
-
**CRITICAL**: UnifiedAuthProvider now requires inactivity timeout configuration:
|
|
133
|
-
|
|
134
|
-
```tsx
|
|
135
|
-
// src/main.tsx
|
|
136
|
-
import React from 'react'
|
|
137
|
-
import ReactDOM from 'react-dom/client'
|
|
138
|
-
import { BrowserRouter } from 'react-router-dom'
|
|
139
|
-
import {
|
|
140
|
-
UnifiedAuthProvider
|
|
141
|
-
} from '@jmruthers/pace-core'
|
|
142
|
-
import { supabase } from './lib/supabase'
|
|
143
|
-
import App from './App.tsx'
|
|
144
|
-
|
|
145
|
-
// CRITICAL: Import the CSS system - includes everything you need
|
|
146
|
-
import '@jmruthers/pace-core/src/styles/core.css'
|
|
147
|
-
|
|
148
|
-
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
149
|
-
<React.StrictMode>
|
|
150
|
-
<BrowserRouter>
|
|
151
|
-
<UnifiedAuthProvider
|
|
152
|
-
supabaseClient={supabase}
|
|
153
|
-
appName="meal-manager"
|
|
154
|
-
enableRBAC={true}
|
|
155
|
-
requireOrganisationContext={true}
|
|
156
|
-
idleTimeoutMs={30 * 60 * 1000} // 30 minutes - REQUIRED
|
|
157
|
-
warnBeforeMs={60 * 1000} // 60 seconds - REQUIRED
|
|
158
|
-
onIdleLogout={() => window.location.href = '/login'} // REQUIRED
|
|
159
|
-
>
|
|
160
|
-
<App />
|
|
161
|
-
</UnifiedAuthProvider>
|
|
162
|
-
</BrowserRouter>
|
|
163
|
-
</React.StrictMode>,
|
|
164
|
-
)
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
**That's it!** The core.css file includes:
|
|
168
|
-
- Complete color palettes (main, secondary, accent)
|
|
169
|
-
- All fonts (Georama, Open Sans, Reddit Mono)
|
|
170
|
-
- Base element styles and resets
|
|
171
|
-
- Tailwind v4 utility classes
|
|
172
|
-
- Component styling
|
|
173
|
-
|
|
174
|
-
Update your `index.html`:
|
|
175
|
-
```html
|
|
176
|
-
<!DOCTYPE html>
|
|
177
|
-
<html lang="en">
|
|
178
|
-
<head>
|
|
179
|
-
<meta charset="UTF-8" />
|
|
180
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
181
|
-
<title>Meal Manager</title>
|
|
182
|
-
</head>
|
|
183
|
-
<body class="appGradient">
|
|
184
|
-
<div id="root" class="grid grid-rows-[auto_1fr_auto] min-h-screen"></div>
|
|
185
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
186
|
-
</body>
|
|
187
|
-
</html>
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### 7. Create Login Page
|
|
191
|
-
|
|
192
|
-
```tsx
|
|
193
|
-
// src/pages/LoginPage.tsx
|
|
194
|
-
import { LoginForm } from '@jmruthers/pace-core';
|
|
195
|
-
import { useNavigate } from 'react-router-dom';
|
|
196
|
-
|
|
197
|
-
export function LoginPage() {
|
|
198
|
-
const navigate = useNavigate();
|
|
199
|
-
|
|
200
|
-
const handleLoginSuccess = () => {
|
|
201
|
-
navigate('/');
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
return (
|
|
205
|
-
<div className="min-h-screen flex items-center justify-center bg-sec-50">
|
|
206
|
-
<div className="max-w-md w-full space-y-8">
|
|
207
|
-
<div>
|
|
208
|
-
<h2 className="mt-6 text-center text-3xl font-extrabold text-sec-900">
|
|
209
|
-
Sign in to Meal Manager
|
|
210
|
-
</h2>
|
|
211
|
-
</div>
|
|
212
|
-
<LoginForm onLoginSuccess={handleLoginSuccess} />
|
|
213
|
-
</div>
|
|
214
|
-
</div>
|
|
215
|
-
);
|
|
216
|
-
}
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
### 9. Create App Layout
|
|
220
|
-
|
|
221
|
-
```tsx
|
|
222
|
-
// src/components/AppLayout.tsx
|
|
223
|
-
import { PaceAppLayout } from '@jmruthers/pace-core';
|
|
224
|
-
import { Outlet } from 'react-router-dom';
|
|
225
|
-
|
|
226
|
-
const navItems = [
|
|
227
|
-
{
|
|
228
|
-
title: 'Dashboard',
|
|
229
|
-
href: '/',
|
|
230
|
-
icon: 'HomeIcon'
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
title: 'Meals',
|
|
234
|
-
href: '/meals',
|
|
235
|
-
icon: 'UtensilsIcon'
|
|
236
|
-
}
|
|
237
|
-
];
|
|
238
|
-
|
|
239
|
-
export function AppLayout() {
|
|
240
|
-
return (
|
|
241
|
-
<PaceAppLayout
|
|
242
|
-
appName="Meal Manager"
|
|
243
|
-
navItems={navItems}
|
|
244
|
-
>
|
|
245
|
-
<Outlet />
|
|
246
|
-
</PaceAppLayout>
|
|
247
|
-
);
|
|
248
|
-
}
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
### 10. Create Dashboard Page
|
|
252
|
-
|
|
253
|
-
```tsx
|
|
254
|
-
// src/pages/DashboardPage.tsx
|
|
255
|
-
import { Card, CardHeader, CardTitle, CardContent } from '@jmruthers/pace-core';
|
|
256
|
-
|
|
257
|
-
export function DashboardPage() {
|
|
258
|
-
return (
|
|
259
|
-
<div className="p-6">
|
|
260
|
-
<h1 className="text-2xl font-bold mb-6">Dashboard</h1>
|
|
261
|
-
|
|
262
|
-
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
|
263
|
-
<Card>
|
|
264
|
-
<CardHeader>
|
|
265
|
-
<CardTitle>Total Meals</CardTitle>
|
|
266
|
-
</CardHeader>
|
|
267
|
-
<CardContent>
|
|
268
|
-
<p className="text-3xl font-bold">24</p>
|
|
269
|
-
</CardContent>
|
|
270
|
-
</Card>
|
|
271
|
-
|
|
272
|
-
<Card>
|
|
273
|
-
<CardHeader>
|
|
274
|
-
<CardTitle>This Week</CardTitle>
|
|
275
|
-
</CardHeader>
|
|
276
|
-
<CardContent>
|
|
277
|
-
<p className="text-3xl font-bold">7</p>
|
|
278
|
-
</CardContent>
|
|
279
|
-
</Card>
|
|
280
|
-
|
|
281
|
-
<Card>
|
|
282
|
-
<CardHeader>
|
|
283
|
-
<CardTitle>Categories</CardTitle>
|
|
284
|
-
</CardHeader>
|
|
285
|
-
<CardContent>
|
|
286
|
-
<p className="text-3xl font-bold">5</p>
|
|
287
|
-
</CardContent>
|
|
288
|
-
</Card>
|
|
289
|
-
</div>
|
|
290
|
-
</div>
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### 11. Create Meals Page with DataTable
|
|
296
|
-
|
|
297
|
-
```tsx
|
|
298
|
-
// src/pages/MealsPage.tsx
|
|
299
|
-
import { DataTable, type DataTableColumn } from '@jmruthers/pace-core';
|
|
300
|
-
import { useState } from 'react';
|
|
301
|
-
|
|
302
|
-
interface Meal {
|
|
303
|
-
id: string;
|
|
304
|
-
name: string;
|
|
305
|
-
category: string;
|
|
306
|
-
calories: number;
|
|
307
|
-
date: string;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const sampleMeals: Meal[] = [
|
|
311
|
-
{ id: '1', name: 'Grilled Chicken Salad', category: 'Healthy', calories: 350, date: '2024-01-15' },
|
|
312
|
-
{ id: '2', name: 'Pasta Carbonara', category: 'Italian', calories: 650, date: '2024-01-15' },
|
|
313
|
-
{ id: '3', name: 'Vegetable Stir Fry', category: 'Asian', calories: 280, date: '2024-01-14' },
|
|
314
|
-
];
|
|
315
|
-
|
|
316
|
-
const columns: DataTableColumn<Meal>[] = [
|
|
317
|
-
{
|
|
318
|
-
accessorKey: 'name',
|
|
319
|
-
header: 'Meal Name',
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
accessorKey: 'category',
|
|
323
|
-
header: 'Category',
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
accessorKey: 'calories',
|
|
327
|
-
header: 'Calories',
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
accessorKey: 'date',
|
|
331
|
-
header: 'Date',
|
|
332
|
-
},
|
|
333
|
-
];
|
|
334
|
-
|
|
335
|
-
export function MealsPage() {
|
|
336
|
-
const [meals] = useState<Meal[]>(sampleMeals);
|
|
337
|
-
|
|
338
|
-
return (
|
|
339
|
-
<div className="p-6">
|
|
340
|
-
<h1 className="text-2xl font-bold mb-6">Meals</h1>
|
|
341
|
-
|
|
342
|
-
<DataTable
|
|
343
|
-
data={meals}
|
|
344
|
-
columns={columns}
|
|
345
|
-
rbac={{ pageId: 'meals' }}
|
|
346
|
-
features={{
|
|
347
|
-
search: true,
|
|
348
|
-
pagination: true,
|
|
349
|
-
}}
|
|
350
|
-
/>
|
|
351
|
-
</div>
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
## 🎉 You're Done!
|
|
357
|
-
|
|
358
|
-
Your app now has:
|
|
359
|
-
- ✅ User authentication with Supabase
|
|
360
|
-
- ✅ Role-based access control
|
|
361
|
-
- ✅ Modern UI components
|
|
362
|
-
- ✅ Responsive layout
|
|
363
|
-
- ✅ Data table with sorting and pagination
|
|
364
|
-
|
|
365
|
-
## 🚀 Next Steps
|
|
366
|
-
|
|
367
|
-
- **[Core Concepts](../core-concepts/)** - Understand authentication, RBAC, and events
|
|
368
|
-
- **[Implementation Guides](../implementation-guides/)** - Learn advanced patterns
|
|
369
|
-
- **[API Reference](../api-reference/)** - Explore all available components and hooks
|
|
370
|
-
- **[Examples](./examples/)** - See complete working applications
|
|
371
|
-
|
|
372
|
-
## 🆘 Need Help?
|
|
373
|
-
|
|
374
|
-
- Check [Common Issues](../troubleshooting/common-issues.md)
|
|
375
|
-
- Review [Troubleshooting](../troubleshooting/) for debugging
|
|
376
|
-
- See [Best Practices](../best-practices/) for production patterns
|
|
@@ -1,313 +0,0 @@
|
|
|
1
|
-
# DataTable Filtering Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
The DataTable component supports multiple types of column filtering, including text, select dropdowns, number, and date filters. This guide explains how to configure each filter type and provides examples for common use cases.
|
|
6
|
-
|
|
7
|
-
## Filter Types
|
|
8
|
-
|
|
9
|
-
### 1. Text Filters (Default)
|
|
10
|
-
Text filters allow users to type and search for values in a column.
|
|
11
|
-
|
|
12
|
-
```typescript
|
|
13
|
-
const columns = [
|
|
14
|
-
{
|
|
15
|
-
id: 'name',
|
|
16
|
-
accessorKey: 'name',
|
|
17
|
-
header: 'Name',
|
|
18
|
-
enableColumnFilter: true,
|
|
19
|
-
// No filterType specified - defaults to 'text'
|
|
20
|
-
}
|
|
21
|
-
];
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
### 2. Select Filters
|
|
25
|
-
Select filters provide dropdown menus with predefined options, perfect for categorical data.
|
|
26
|
-
|
|
27
|
-
#### Method 1: Using `filterSelectOptions` (Recommended)
|
|
28
|
-
```typescript
|
|
29
|
-
const columns = [
|
|
30
|
-
{
|
|
31
|
-
id: 'meal_type',
|
|
32
|
-
accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
|
|
33
|
-
header: 'Type',
|
|
34
|
-
enableColumnFilter: true,
|
|
35
|
-
filterType: 'select',
|
|
36
|
-
filterSelectOptions: [
|
|
37
|
-
{ value: 'breakfast', label: 'Breakfast' },
|
|
38
|
-
{ value: 'lunch', label: 'Lunch' },
|
|
39
|
-
{ value: 'dinner', label: 'Dinner' },
|
|
40
|
-
{ value: 'morning_tea', label: 'Morning Tea' },
|
|
41
|
-
{ value: 'afternoon_tea', label: 'Afternoon Tea' },
|
|
42
|
-
{ value: 'pantry', label: 'Pantry' }
|
|
43
|
-
],
|
|
44
|
-
filterFn: (row, id, value) => {
|
|
45
|
-
return value.includes(row.original.mealtype?.mealtype_id);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
#### Method 2: Using `fieldOptions`
|
|
52
|
-
```typescript
|
|
53
|
-
const columns = [
|
|
54
|
-
{
|
|
55
|
-
id: 'status',
|
|
56
|
-
accessorKey: 'status',
|
|
57
|
-
header: 'Status',
|
|
58
|
-
enableColumnFilter: true,
|
|
59
|
-
filterType: 'select',
|
|
60
|
-
fieldOptions: [
|
|
61
|
-
{ value: 'active', label: 'Active' },
|
|
62
|
-
{ value: 'inactive', label: 'Inactive' },
|
|
63
|
-
{ value: 'pending', label: 'Pending' }
|
|
64
|
-
]
|
|
65
|
-
}
|
|
66
|
-
];
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
#### Method 3: Auto-detection
|
|
70
|
-
The DataTable automatically detects select filters when a column has limited unique values (≤10):
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
const columns = [
|
|
74
|
-
{
|
|
75
|
-
id: 'priority',
|
|
76
|
-
accessorKey: 'priority',
|
|
77
|
-
header: 'Priority',
|
|
78
|
-
enableColumnFilter: true,
|
|
79
|
-
// No filterType specified - will auto-detect as 'select' if ≤10 unique values
|
|
80
|
-
}
|
|
81
|
-
];
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### 3. Number Filters
|
|
85
|
-
Number filters provide numeric input with comparison operators.
|
|
86
|
-
|
|
87
|
-
```typescript
|
|
88
|
-
const columns = [
|
|
89
|
-
{
|
|
90
|
-
id: 'price',
|
|
91
|
-
accessorKey: 'price',
|
|
92
|
-
header: 'Price',
|
|
93
|
-
enableColumnFilter: true,
|
|
94
|
-
filterType: 'number'
|
|
95
|
-
}
|
|
96
|
-
];
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### 4. Date Filters
|
|
100
|
-
Date filters provide date picker inputs.
|
|
101
|
-
|
|
102
|
-
```typescript
|
|
103
|
-
const columns = [
|
|
104
|
-
{
|
|
105
|
-
id: 'created_date',
|
|
106
|
-
accessorKey: 'created_date',
|
|
107
|
-
header: 'Created Date',
|
|
108
|
-
enableColumnFilter: true,
|
|
109
|
-
filterType: 'date'
|
|
110
|
-
}
|
|
111
|
-
];
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
## Complete Example
|
|
115
|
-
|
|
116
|
-
Here's a complete example showing different filter types:
|
|
117
|
-
|
|
118
|
-
```typescript
|
|
119
|
-
import { DataTable } from '@jmruthers/pace-core';
|
|
120
|
-
|
|
121
|
-
function MealsTable() {
|
|
122
|
-
const meals = [
|
|
123
|
-
{
|
|
124
|
-
id: '1',
|
|
125
|
-
meal_code: '28py',
|
|
126
|
-
mealtype: { mealtype_id: 'breakfast', mealtype_name: 'Breakfast' },
|
|
127
|
-
meal_date: '2024-12-28',
|
|
128
|
-
price: 15.50
|
|
129
|
-
},
|
|
130
|
-
// ... more data
|
|
131
|
-
];
|
|
132
|
-
|
|
133
|
-
const mealTypes = [
|
|
134
|
-
{ mealtype_id: 'breakfast', mealtype_name: 'Breakfast' },
|
|
135
|
-
{ mealtype_id: 'lunch', mealtype_name: 'Lunch' },
|
|
136
|
-
{ mealtype_id: 'dinner', mealtype_name: 'Dinner' },
|
|
137
|
-
{ mealtype_id: 'morning_tea', mealtype_name: 'Morning Tea' },
|
|
138
|
-
{ mealtype_id: 'afternoon_tea', mealtype_name: 'Afternoon Tea' },
|
|
139
|
-
{ mealtype_id: 'pantry', mealtype_name: 'Pantry' }
|
|
140
|
-
];
|
|
141
|
-
|
|
142
|
-
const columns = [
|
|
143
|
-
{
|
|
144
|
-
id: 'meal_code',
|
|
145
|
-
accessorKey: 'meal_code',
|
|
146
|
-
header: 'Meal Code',
|
|
147
|
-
enableColumnFilter: true,
|
|
148
|
-
// Text filter (default)
|
|
149
|
-
},
|
|
150
|
-
{
|
|
151
|
-
id: 'meal_type',
|
|
152
|
-
accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
|
|
153
|
-
header: 'Type',
|
|
154
|
-
enableColumnFilter: true,
|
|
155
|
-
filterType: 'select',
|
|
156
|
-
filterSelectOptions: mealTypes.map(mt => ({
|
|
157
|
-
value: mt.mealtype_id,
|
|
158
|
-
label: mt.mealtype_name
|
|
159
|
-
})),
|
|
160
|
-
filterFn: (row, id, value) => {
|
|
161
|
-
return value.includes(row.original.mealtype?.mealtype_id);
|
|
162
|
-
}
|
|
163
|
-
},
|
|
164
|
-
{
|
|
165
|
-
id: 'meal_date',
|
|
166
|
-
accessorKey: 'meal_date',
|
|
167
|
-
header: 'Date',
|
|
168
|
-
enableColumnFilter: true,
|
|
169
|
-
filterType: 'date'
|
|
170
|
-
},
|
|
171
|
-
{
|
|
172
|
-
id: 'price',
|
|
173
|
-
accessorKey: 'price',
|
|
174
|
-
header: 'Price',
|
|
175
|
-
enableColumnFilter: true,
|
|
176
|
-
filterType: 'number'
|
|
177
|
-
}
|
|
178
|
-
];
|
|
179
|
-
|
|
180
|
-
return (
|
|
181
|
-
<DataTable
|
|
182
|
-
data={meals}
|
|
183
|
-
columns={columns}
|
|
184
|
-
features={{
|
|
185
|
-
filtering: true, // Enable filtering
|
|
186
|
-
search: true,
|
|
187
|
-
pagination: true,
|
|
188
|
-
sorting: true
|
|
189
|
-
}}
|
|
190
|
-
rbac={{
|
|
191
|
-
pageName: 'meals'
|
|
192
|
-
}}
|
|
193
|
-
/>
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## Filter Configuration Options
|
|
199
|
-
|
|
200
|
-
### Column Properties
|
|
201
|
-
|
|
202
|
-
| Property | Type | Description |
|
|
203
|
-
|----------|------|-------------|
|
|
204
|
-
| `enableColumnFilter` | `boolean` | Enable filtering for this column |
|
|
205
|
-
| `filterType` | `'text' \| 'select' \| 'number' \| 'date'` | Type of filter to render |
|
|
206
|
-
| `filterSelectOptions` | `Array<{value: string\|number, label: string}>` | Options for select filters |
|
|
207
|
-
| `fieldOptions` | `Array<{value: string\|number, label: string}>` | Alternative options for select filters |
|
|
208
|
-
| `filterFn` | `(row, id, value) => boolean` | Custom filter function |
|
|
209
|
-
|
|
210
|
-
### DataTable Features
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
features={{
|
|
214
|
-
filtering: true, // Enable column filtering
|
|
215
|
-
search: true, // Enable global search
|
|
216
|
-
showFilterRow: true, // Show filter row by default
|
|
217
|
-
}}
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
## Advanced Filtering
|
|
221
|
-
|
|
222
|
-
### Custom Filter Functions
|
|
223
|
-
|
|
224
|
-
For complex filtering logic, you can provide a custom `filterFn`:
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
{
|
|
228
|
-
id: 'meal_type',
|
|
229
|
-
accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
|
|
230
|
-
header: 'Type',
|
|
231
|
-
enableColumnFilter: true,
|
|
232
|
-
filterType: 'select',
|
|
233
|
-
filterSelectOptions: mealTypes.map(mt => ({
|
|
234
|
-
value: mt.mealtype_id,
|
|
235
|
-
label: mt.mealtype_name
|
|
236
|
-
})),
|
|
237
|
-
filterFn: (row, id, value) => {
|
|
238
|
-
// Custom logic: filter by mealtype_id but display mealtype_name
|
|
239
|
-
const mealtypeId = row.original.mealtype?.mealtype_id;
|
|
240
|
-
return value.includes(mealtypeId);
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Multiple Value Selection
|
|
246
|
-
|
|
247
|
-
Select filters support multiple value selection by default:
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// Users can select multiple meal types
|
|
251
|
-
filterSelectOptions: [
|
|
252
|
-
{ value: 'breakfast', label: 'Breakfast' },
|
|
253
|
-
{ value: 'lunch', label: 'Lunch' },
|
|
254
|
-
{ value: 'dinner', label: 'Dinner' }
|
|
255
|
-
]
|
|
256
|
-
// When user selects "Breakfast" and "Lunch",
|
|
257
|
-
// filterFn receives: ['breakfast', 'lunch']
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
## Troubleshooting
|
|
261
|
-
|
|
262
|
-
### Common Issues
|
|
263
|
-
|
|
264
|
-
1. **Select filter not showing dropdown:**
|
|
265
|
-
- Ensure `filterType: 'select'` is set
|
|
266
|
-
- Verify `filterSelectOptions` or `fieldOptions` is provided
|
|
267
|
-
- Check that `enableColumnFilter: true` is set
|
|
268
|
-
|
|
269
|
-
2. **Filter not working with foreign key data:**
|
|
270
|
-
- Use `accessorFn` to extract the display value
|
|
271
|
-
- Provide custom `filterFn` to match against the actual ID
|
|
272
|
-
- Ensure `filterSelectOptions` uses the ID values
|
|
273
|
-
|
|
274
|
-
3. **Auto-detection not working:**
|
|
275
|
-
- Ensure column has ≤10 unique values
|
|
276
|
-
- Check that values are not null/undefined
|
|
277
|
-
- Verify `enableColumnFilter: true` is set
|
|
278
|
-
|
|
279
|
-
### Debug Tips
|
|
280
|
-
|
|
281
|
-
Enable debug logging to see filter behavior:
|
|
282
|
-
|
|
283
|
-
```typescript
|
|
284
|
-
// In your app setup
|
|
285
|
-
<UnifiedAuthProvider
|
|
286
|
-
supabaseClient={supabase}
|
|
287
|
-
appName="your-app"
|
|
288
|
-
enableRBAC={true}
|
|
289
|
-
debug={true} // Enable debug logging
|
|
290
|
-
>
|
|
291
|
-
<YourApp />
|
|
292
|
-
</UnifiedAuthProvider>
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## Best Practices
|
|
296
|
-
|
|
297
|
-
1. **Use `filterSelectOptions` for predefined options** - More explicit and clear
|
|
298
|
-
2. **Provide meaningful labels** - Use human-readable labels, not IDs
|
|
299
|
-
3. **Use custom `filterFn` for foreign keys** - Match against IDs, display names
|
|
300
|
-
4. **Limit select options** - Keep dropdowns manageable (≤20 options)
|
|
301
|
-
5. **Test with real data** - Ensure filters work with actual data values
|
|
302
|
-
6. **Consider performance** - Large datasets may need server-side filtering
|
|
303
|
-
|
|
304
|
-
## Migration from Old Filtering
|
|
305
|
-
|
|
306
|
-
If you're upgrading from an older version:
|
|
307
|
-
|
|
308
|
-
1. **Replace `meta.filterOptions`** with `filterSelectOptions`
|
|
309
|
-
2. **Add `filterType: 'select'`** for explicit select filters
|
|
310
|
-
3. **Update `filterFn`** to work with new filter value format
|
|
311
|
-
4. **Test all filter combinations** to ensure they work correctly
|
|
312
|
-
|
|
313
|
-
This comprehensive filtering system provides a great user experience for data exploration and analysis.
|