@jmruthers/pace-core 0.5.126 → 0.5.128
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/dist/{DataTable-6FN7XDXA.js → DataTable-3Z5HLOWF.js} +6 -6
- package/dist/{PublicLoadingSpinner-CaoRbHvJ.d.ts → PublicLoadingSpinner-CUAnTvcg.d.ts} +41 -21
- package/dist/{UnifiedAuthProvider-6C47WIML.js → UnifiedAuthProvider-CQDZRJIS.js} +3 -3
- package/dist/{chunk-QXGLU2O5.js → chunk-27MGXDD6.js} +282 -147
- package/dist/chunk-27MGXDD6.js.map +1 -0
- package/dist/{chunk-ZBLK676C.js → chunk-3CG5L6RN.js} +1 -19
- package/dist/chunk-3CG5L6RN.js.map +1 -0
- package/dist/{chunk-35ZDPMBM.js → chunk-BYXRHAIF.js} +3 -3
- package/dist/{chunk-IJOZZOGT.js → chunk-CQZU6TFE.js} +5 -5
- package/dist/{chunk-C43QIDN3.js → chunk-CTJRBUX2.js} +2 -2
- package/dist/{chunk-R4CRQUJJ.js → chunk-ENE3AB75.js} +463 -453
- package/dist/chunk-ENE3AB75.js.map +1 -0
- package/dist/{chunk-ESJTIADP.js → chunk-F64FFPOZ.js} +5 -15
- package/dist/{chunk-ESJTIADP.js.map → chunk-F64FFPOZ.js.map} +1 -1
- package/dist/{chunk-4MXVZVNS.js → chunk-TGIY2AR2.js} +2 -2
- package/dist/{chunk-XN6GWKMV.js → chunk-VZ5OR6HD.js} +161 -14
- package/dist/chunk-VZ5OR6HD.js.map +1 -0
- package/dist/{chunk-QWNJCQXZ.js → chunk-ZV77RZMU.js} +2 -2
- package/dist/{chunk-NZGLXZGP.js → chunk-ZYZCRSBD.js} +3 -54
- package/dist/chunk-ZYZCRSBD.js.map +1 -0
- package/dist/components.d.ts +1 -1
- package/dist/components.js +9 -9
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +12 -12
- package/dist/providers.js +2 -2
- package/dist/rbac/index.js +7 -7
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +1 -1
- 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/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- 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 +1 -1
- 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 +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/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.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/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/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +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 +27 -27
- 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 +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- 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 +10 -62
- 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/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/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 +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.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 +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayReturn.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 +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +53 -28
- package/docs/api-reference/components.md +24 -0
- package/docs/api-reference/types.md +28 -0
- package/docs/architecture/rpc-function-standards.md +39 -5
- package/docs/implementation-guides/data-tables.md +55 -10
- package/docs/implementation-guides/permission-enforcement.md +4 -0
- package/docs/rbac/super-admin-guide.md +43 -5
- package/package.json +1 -1
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/DataTable/__tests__/DataTable.export.test.tsx +702 -0
- package/src/components/DataTable/components/DataTableCore.tsx +55 -36
- package/src/components/DataTable/components/ImportModal.tsx +134 -2
- package/src/components/DataTable/index.ts +3 -1
- package/src/components/DataTable/types.ts +68 -0
- package/src/components/Dialog/Dialog.tsx +0 -13
- package/src/components/FileDisplay/FileDisplay.tsx +76 -0
- package/src/components/Header/Header.tsx +5 -0
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +72 -50
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +81 -1
- package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
- package/src/components/PublicLayout/PublicPageHeader.tsx +69 -128
- package/src/components/PublicLayout/PublicPageLayout.tsx +4 -4
- package/src/components/PublicLayout/PublicPageProvider.tsx +12 -3
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +3 -18
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +3 -1
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +11 -5
- package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +8 -7
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +41 -46
- package/src/hooks/public/usePublicFileDisplay.ts +176 -7
- package/src/hooks/public/usePublicRouteParams.ts +0 -12
- package/src/hooks/useAppConfig.ts +15 -6
- package/src/hooks/usePermissionCache.test.ts +12 -4
- package/src/hooks/usePermissionCache.ts +3 -19
- package/src/hooks/useSecureDataAccess.ts +0 -63
- package/src/services/EventService.ts +0 -19
- package/dist/chunk-NZGLXZGP.js.map +0 -1
- package/dist/chunk-QXGLU2O5.js.map +0 -1
- package/dist/chunk-R4CRQUJJ.js.map +0 -1
- package/dist/chunk-XN6GWKMV.js.map +0 -1
- package/dist/chunk-ZBLK676C.js.map +0 -1
- /package/dist/{DataTable-6FN7XDXA.js.map → DataTable-3Z5HLOWF.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-6C47WIML.js.map → UnifiedAuthProvider-CQDZRJIS.js.map} +0 -0
- /package/dist/{chunk-35ZDPMBM.js.map → chunk-BYXRHAIF.js.map} +0 -0
- /package/dist/{chunk-IJOZZOGT.js.map → chunk-CQZU6TFE.js.map} +0 -0
- /package/dist/{chunk-C43QIDN3.js.map → chunk-CTJRBUX2.js.map} +0 -0
- /package/dist/{chunk-4MXVZVNS.js.map → chunk-TGIY2AR2.js.map} +0 -0
- /package/dist/{chunk-QWNJCQXZ.js.map → chunk-ZV77RZMU.js.map} +0 -0
package/docs/api/modules.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
[@jmruthers/pace-core - v0.5.
|
|
1
|
+
[@jmruthers/pace-core - v0.5.128](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.128
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -1558,7 +1558,7 @@ JSX.Element - The dialog footer container using semantic <footer> element
|
|
|
1558
1558
|
|
|
1559
1559
|
#### Defined in
|
|
1560
1560
|
|
|
1561
|
-
[packages/core/src/components/Dialog/Dialog.tsx:
|
|
1561
|
+
[packages/core/src/components/Dialog/Dialog.tsx:677](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Dialog/Dialog.tsx#L677)
|
|
1562
1562
|
|
|
1563
1563
|
___
|
|
1564
1564
|
|
|
@@ -1578,7 +1578,7 @@ ___
|
|
|
1578
1578
|
|
|
1579
1579
|
#### Defined in
|
|
1580
1580
|
|
|
1581
|
-
[packages/core/src/components/Dialog/Dialog.tsx:
|
|
1581
|
+
[packages/core/src/components/Dialog/Dialog.tsx:694](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Dialog/Dialog.tsx#L694)
|
|
1582
1582
|
|
|
1583
1583
|
___
|
|
1584
1584
|
|
|
@@ -1598,7 +1598,7 @@ ___
|
|
|
1598
1598
|
|
|
1599
1599
|
#### Defined in
|
|
1600
1600
|
|
|
1601
|
-
[packages/core/src/components/Dialog/Dialog.tsx:
|
|
1601
|
+
[packages/core/src/components/Dialog/Dialog.tsx:729](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Dialog/Dialog.tsx#L729)
|
|
1602
1602
|
|
|
1603
1603
|
___
|
|
1604
1604
|
|
|
@@ -1668,7 +1668,7 @@ React element with file display
|
|
|
1668
1668
|
|
|
1669
1669
|
#### Defined in
|
|
1670
1670
|
|
|
1671
|
-
[packages/core/src/components/FileDisplay/FileDisplay.tsx:
|
|
1671
|
+
[packages/core/src/components/FileDisplay/FileDisplay.tsx:803](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/FileDisplay/FileDisplay.tsx#L803)
|
|
1672
1672
|
|
|
1673
1673
|
___
|
|
1674
1674
|
|
|
@@ -1767,6 +1767,11 @@ and customizable branding support.
|
|
|
1767
1767
|
A flexible header component that supports various configurations including custom logos,
|
|
1768
1768
|
navigation menus, user authentication, event selection, and custom actions.
|
|
1769
1769
|
|
|
1770
|
+
**Logo Display:** When used via PaceAppLayout, the logo URL is automatically constructed
|
|
1771
|
+
from the appName prop as `/${appName.toLowerCase()}_logo_wide.svg`. The appName should
|
|
1772
|
+
come from an APP_NAME constant declared in your App.tsx file to ensure consistency across
|
|
1773
|
+
authenticated and public pages.
|
|
1774
|
+
|
|
1770
1775
|
Features:
|
|
1771
1776
|
- Customizable logo (URL or custom component)
|
|
1772
1777
|
- Clickable logo that automatically routes to dashboard (configurable via logoHref)
|
|
@@ -1872,7 +1877,7 @@ function MinimalHeader() {
|
|
|
1872
1877
|
|
|
1873
1878
|
#### Defined in
|
|
1874
1879
|
|
|
1875
|
-
[packages/core/src/components/Header/Header.tsx:
|
|
1880
|
+
[packages/core/src/components/Header/Header.tsx:234](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Header/Header.tsx#L234)
|
|
1876
1881
|
|
|
1877
1882
|
___
|
|
1878
1883
|
|
|
@@ -2304,6 +2309,17 @@ This component is designed to work with React Router's nested routing pattern us
|
|
|
2304
2309
|
Outlet to render child routes. It provides integrated authentication, navigation,
|
|
2305
2310
|
and user management functionality.
|
|
2306
2311
|
|
|
2312
|
+
**Super Admin Access:** When `enforcePermissions={true}`, PaceAppLayout automatically
|
|
2313
|
+
checks if the user is a super admin before enforcing permissions. Super admins bypass
|
|
2314
|
+
all permission checks and can access any route without violations. The component extracts
|
|
2315
|
+
base page names from route paths (e.g., `/organisation/scouts-victoria` → `"organisation"`)
|
|
2316
|
+
for permission checking, which can be overridden using `pageIdMapping`.
|
|
2317
|
+
|
|
2318
|
+
**Important:** The appName prop should use an APP_NAME constant declared in your App.tsx
|
|
2319
|
+
file. This ensures consistency with public pages (via PublicPageProvider) which should
|
|
2320
|
+
also receive the same APP_NAME constant. The logo URL is automatically constructed as
|
|
2321
|
+
`/${appName.toLowerCase()}_logo_wide.svg` from the public folder.
|
|
2322
|
+
|
|
2307
2323
|
Features:
|
|
2308
2324
|
- React Router v6 integration with nested routing
|
|
2309
2325
|
- Unified authentication integration
|
|
@@ -2315,6 +2331,7 @@ Features:
|
|
|
2315
2331
|
- Layout-level permission enforcement
|
|
2316
2332
|
- Permission-based navigation filtering
|
|
2317
2333
|
- Automatic page permission validation
|
|
2334
|
+
- Super admin bypass (super admins automatically bypass all permission checks)
|
|
2318
2335
|
|
|
2319
2336
|
#### Parameters
|
|
2320
2337
|
|
|
@@ -2334,17 +2351,20 @@ Basic React Router setup with permission enforcement (RECOMMENDED):
|
|
|
2334
2351
|
```tsx
|
|
2335
2352
|
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
|
|
2336
2353
|
import { UnifiedAuthProvider } from '@jmruthers/pace-core/providers';
|
|
2337
|
-
import { PaceAppLayout, PaceLoginPage } from '@jmruthers/pace-core';
|
|
2354
|
+
import { PaceAppLayout, PaceLoginPage, PublicPageApp } from '@jmruthers/pace-core';
|
|
2355
|
+
|
|
2356
|
+
const APP_NAME = 'CORE';
|
|
2338
2357
|
|
|
2339
2358
|
function App() {
|
|
2340
2359
|
return (
|
|
2341
|
-
<UnifiedAuthProvider supabaseClient={supabase} appName=
|
|
2360
|
+
<UnifiedAuthProvider supabaseClient={supabase} appName={APP_NAME}>
|
|
2342
2361
|
<Router>
|
|
2343
2362
|
<Routes>
|
|
2344
|
-
<Route path="/login" element={<PaceLoginPage appName=
|
|
2363
|
+
<Route path="/login" element={<PaceLoginPage appName={APP_NAME} />} />
|
|
2364
|
+
<Route path="/events/*" element={<PublicPageApp appName={APP_NAME} />} />
|
|
2345
2365
|
<Route path="/" element={
|
|
2346
2366
|
<PaceAppLayout
|
|
2347
|
-
appName=
|
|
2367
|
+
appName={APP_NAME}
|
|
2348
2368
|
enforcePermissions={true}
|
|
2349
2369
|
defaultPermission="read"
|
|
2350
2370
|
/>
|
|
@@ -2442,7 +2462,7 @@ function AdminApp() {
|
|
|
2442
2462
|
|
|
2443
2463
|
#### Defined in
|
|
2444
2464
|
|
|
2445
|
-
[packages/core/src/components/PaceAppLayout/PaceAppLayout.tsx:
|
|
2465
|
+
[packages/core/src/components/PaceAppLayout/PaceAppLayout.tsx:344](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PaceAppLayout/PaceAppLayout.tsx#L344)
|
|
2446
2466
|
|
|
2447
2467
|
___
|
|
2448
2468
|
|
|
@@ -2823,14 +2843,18 @@ Header component for public pages with event-specific branding
|
|
|
2823
2843
|
This component displays the app logo, event logo, and event information
|
|
2824
2844
|
in a clean, accessible layout suitable for public pages.
|
|
2825
2845
|
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2846
|
+
The app logo is automatically generated from the appName using the pattern:
|
|
2847
|
+
`/{appName.toLowerCase()}_logo_wide.svg` from the public folder.
|
|
2848
|
+
|
|
2849
|
+
**Important:** The appName is obtained from PublicPageProvider context, which should
|
|
2850
|
+
receive the APP_NAME constant from your App.tsx file. This ensures consistency with
|
|
2851
|
+
authenticated pages that use the same APP_NAME constant.
|
|
2831
2852
|
|
|
2832
|
-
|
|
2833
|
-
|
|
2853
|
+
**Event Logo Requirements:**
|
|
2854
|
+
- Event logo files must be marked as `is_public = true` in the `file_references` table
|
|
2855
|
+
- The RPC function `data_file_reference_by_category_list` must be accessible to the anonymous/public role
|
|
2856
|
+
- Storage bucket must allow public read access for logo files
|
|
2857
|
+
- If no public logo is available, a fallback UI with event initials will be displayed
|
|
2834
2858
|
|
|
2835
2859
|
#### Parameters
|
|
2836
2860
|
|
|
@@ -2846,7 +2870,7 @@ React element with public page header
|
|
|
2846
2870
|
|
|
2847
2871
|
#### Defined in
|
|
2848
2872
|
|
|
2849
|
-
[packages/core/src/components/PublicLayout/PublicPageHeader.tsx:
|
|
2873
|
+
[packages/core/src/components/PublicLayout/PublicPageHeader.tsx:103](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageHeader.tsx#L103)
|
|
2850
2874
|
|
|
2851
2875
|
___
|
|
2852
2876
|
|
|
@@ -2922,6 +2946,7 @@ This provider:
|
|
|
2922
2946
|
- Provides environment variables for public data access
|
|
2923
2947
|
- Includes error boundary for graceful error handling
|
|
2924
2948
|
- Is completely separate from the main app context
|
|
2949
|
+
- Provides appName for consistent logo display
|
|
2925
2950
|
|
|
2926
2951
|
#### Parameters
|
|
2927
2952
|
|
|
@@ -2935,7 +2960,7 @@ This provider:
|
|
|
2935
2960
|
|
|
2936
2961
|
#### Defined in
|
|
2937
2962
|
|
|
2938
|
-
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:
|
|
2963
|
+
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:70](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageProvider.tsx#L70)
|
|
2939
2964
|
|
|
2940
2965
|
___
|
|
2941
2966
|
|
|
@@ -2953,7 +2978,7 @@ Public page context with environment variables
|
|
|
2953
2978
|
|
|
2954
2979
|
#### Defined in
|
|
2955
2980
|
|
|
2956
|
-
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:
|
|
2981
|
+
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:128](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageProvider.tsx#L128)
|
|
2957
2982
|
|
|
2958
2983
|
___
|
|
2959
2984
|
|
|
@@ -2971,7 +2996,7 @@ True if we're in a public page context
|
|
|
2971
2996
|
|
|
2972
2997
|
#### Defined in
|
|
2973
2998
|
|
|
2974
|
-
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:
|
|
2999
|
+
[packages/core/src/components/PublicLayout/PublicPageProvider.tsx:143](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageProvider.tsx#L143)
|
|
2975
3000
|
|
|
2976
3001
|
___
|
|
2977
3002
|
|
|
@@ -3858,7 +3883,7 @@ Useful for testing or when you need to force refresh all data
|
|
|
3858
3883
|
|
|
3859
3884
|
#### Defined in
|
|
3860
3885
|
|
|
3861
|
-
[packages/core/src/hooks/public/usePublicFileDisplay.ts:
|
|
3886
|
+
[packages/core/src/hooks/public/usePublicFileDisplay.ts:542](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicFileDisplay.ts#L542)
|
|
3862
3887
|
|
|
3863
3888
|
___
|
|
3864
3889
|
|
|
@@ -3879,7 +3904,7 @@ Get cache statistics for debugging
|
|
|
3879
3904
|
|
|
3880
3905
|
#### Defined in
|
|
3881
3906
|
|
|
3882
|
-
[packages/core/src/hooks/public/usePublicFileDisplay.ts:
|
|
3907
|
+
[packages/core/src/hooks/public/usePublicFileDisplay.ts:553](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicFileDisplay.ts#L553)
|
|
3883
3908
|
|
|
3884
3909
|
___
|
|
3885
3910
|
|
|
@@ -3935,7 +3960,7 @@ Useful when you only need the event code and will fetch data separately
|
|
|
3935
3960
|
|
|
3936
3961
|
#### Defined in
|
|
3937
3962
|
|
|
3938
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
3963
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:212](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L212)
|
|
3939
3964
|
|
|
3940
3965
|
___
|
|
3941
3966
|
|
|
@@ -3958,7 +3983,7 @@ Utility function to generate public route paths
|
|
|
3958
3983
|
|
|
3959
3984
|
#### Defined in
|
|
3960
3985
|
|
|
3961
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
3986
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:248](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L248)
|
|
3962
3987
|
|
|
3963
3988
|
___
|
|
3964
3989
|
|
|
@@ -3981,7 +4006,7 @@ Supports 2-50 character event codes
|
|
|
3981
4006
|
|
|
3982
4007
|
#### Defined in
|
|
3983
4008
|
|
|
3984
|
-
[packages/core/src/hooks/public/usePublicRouteParams.ts:
|
|
4009
|
+
[packages/core/src/hooks/public/usePublicRouteParams.ts:263](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L263)
|
|
3985
4010
|
|
|
3986
4011
|
___
|
|
3987
4012
|
|
|
@@ -123,6 +123,12 @@ interface DataTableProps<TData extends DataRecord> {
|
|
|
123
123
|
onDeleteRow?: (row: TData) => void;
|
|
124
124
|
onCreateRow?: (data: Partial<TData>) => void;
|
|
125
125
|
onImport?: (data: TData[]) => void | Promise<void>;
|
|
126
|
+
/**
|
|
127
|
+
* Custom export handler - allows full control over export columns and filename
|
|
128
|
+
* Receives ExportOptions with tableRows, allColumns, visibleColumns, and more
|
|
129
|
+
* If not provided, defaults to exporting all visible columns
|
|
130
|
+
*/
|
|
131
|
+
onExport?: (options: ExportOptions<TData>) => void | Promise<void>;
|
|
126
132
|
onDeleteSelected?: (selectedRows: Record<string, boolean>) => void;
|
|
127
133
|
|
|
128
134
|
// Performance
|
|
@@ -276,6 +282,24 @@ const columns: DataTableColumn<User>[] = [
|
|
|
276
282
|
onEditRow={handleEdit}
|
|
277
283
|
onDeleteRow={handleDelete}
|
|
278
284
|
onCreateRow={handleCreate}
|
|
285
|
+
onExport={async (options) => {
|
|
286
|
+
// Custom export with specific columns
|
|
287
|
+
const exportColumns = options.allColumns
|
|
288
|
+
.filter(col => ['name', 'email'].includes(col.accessorKey || ''))
|
|
289
|
+
.map(col => ({
|
|
290
|
+
header: col.header || col.accessorKey,
|
|
291
|
+
id: col.id || col.accessorKey,
|
|
292
|
+
accessorKey: col.accessorKey,
|
|
293
|
+
accessorFn: 'accessorFn' in col ? col.accessorFn : undefined,
|
|
294
|
+
}));
|
|
295
|
+
|
|
296
|
+
await exportToCSVWithTableRows(
|
|
297
|
+
options.tableRows,
|
|
298
|
+
exportColumns,
|
|
299
|
+
options.columnIdToTableColumn,
|
|
300
|
+
'users-export.csv'
|
|
301
|
+
);
|
|
302
|
+
}}
|
|
279
303
|
/>
|
|
280
304
|
```
|
|
281
305
|
|
|
@@ -334,6 +334,33 @@ interface ButtonProps {
|
|
|
334
334
|
}
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
+
### ExportOptions
|
|
338
|
+
|
|
339
|
+
Options provided to the `onExport` handler for custom export functionality.
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
interface ExportOptions<TData extends DataRecord> {
|
|
343
|
+
/** Filtered table rows with getValue() method for proper accessorFn evaluation */
|
|
344
|
+
tableRows: Array<{
|
|
345
|
+
original: TData;
|
|
346
|
+
getValue: (columnId: string) => any;
|
|
347
|
+
id: string;
|
|
348
|
+
}>;
|
|
349
|
+
/** All column definitions passed to the DataTable */
|
|
350
|
+
allColumns: DataTableColumn<TData>[];
|
|
351
|
+
/** Currently visible columns in the table */
|
|
352
|
+
visibleColumns: DataTableColumn<TData>[];
|
|
353
|
+
/** Mapping of column IDs to TanStack table column instances (for getValue() calls) */
|
|
354
|
+
columnIdToTableColumn: Map<string, any>;
|
|
355
|
+
/** Raw data array (unfiltered) */
|
|
356
|
+
data: TData[];
|
|
357
|
+
/** Default filename generated from table title */
|
|
358
|
+
filename: string;
|
|
359
|
+
/** TanStack table instance for advanced operations */
|
|
360
|
+
table: any;
|
|
361
|
+
}
|
|
362
|
+
```
|
|
363
|
+
|
|
337
364
|
### DataTableProps
|
|
338
365
|
|
|
339
366
|
Props for the DataTable component.
|
|
@@ -948,6 +975,7 @@ export type {
|
|
|
948
975
|
// UI Components
|
|
949
976
|
ButtonProps,
|
|
950
977
|
DataTableProps,
|
|
978
|
+
ExportOptions,
|
|
951
979
|
ColumnDef,
|
|
952
980
|
PaginationConfig,
|
|
953
981
|
SortingConfig,
|
|
@@ -75,8 +75,9 @@ get_cake_meals -- Wrong: wrong prefix order
|
|
|
75
75
|
|
|
76
76
|
```sql
|
|
77
77
|
CREATE OR REPLACE FUNCTION public.<family>_<domain>_<verb>(
|
|
78
|
-
p_param1
|
|
79
|
-
p_param2
|
|
78
|
+
p_param1 TEXT, -- ⚠️ Use TEXT for strings, NOT CHARACTER VARYING
|
|
79
|
+
p_param2 INTEGER DEFAULT NULL, -- Use INTEGER, DOUBLE PRECISION, SMALLINT for numbers
|
|
80
|
+
p_param3 BOOLEAN DEFAULT NULL, -- Use BOOLEAN for boolean values
|
|
80
81
|
p_user_id UUID DEFAULT auth.uid(),
|
|
81
82
|
p_organisation_id UUID DEFAULT NULL
|
|
82
83
|
)
|
|
@@ -150,11 +151,23 @@ $$;
|
|
|
150
151
|
|
|
151
152
|
2. **Always set `SET search_path TO 'public'`** - Prevents SQL injection attacks
|
|
152
153
|
|
|
153
|
-
3. **Parameter Naming**:
|
|
154
|
+
3. **Parameter Naming and Types**:
|
|
154
155
|
- Prefix all parameters with `p_` (e.g., `p_event_id`, `p_user_id`)
|
|
155
156
|
- Use `p_user_id UUID DEFAULT auth.uid()` for user context
|
|
156
157
|
- Use `p_organisation_id UUID DEFAULT NULL` for organisation context
|
|
157
158
|
- Use descriptive names
|
|
159
|
+
- **⚠️ CRITICAL: Parameter Type Requirements**:
|
|
160
|
+
- **String parameters MUST use `TEXT`**, NOT `CHARACTER VARYING` or `VARCHAR`
|
|
161
|
+
- **Numeric parameters**: Use `DOUBLE PRECISION` for decimal numbers, `INTEGER` for whole numbers, `SMALLINT` for small integers
|
|
162
|
+
- **Boolean parameters**: Use `BOOLEAN`
|
|
163
|
+
- **Date/Time parameters**: Use `DATE`, `TIMESTAMP`, or `TIMESTAMPTZ` as appropriate
|
|
164
|
+
- **UUID parameters**: Use `UUID`
|
|
165
|
+
- **Why TEXT instead of CHARACTER VARYING?**
|
|
166
|
+
- Application code calls functions with TEXT parameters
|
|
167
|
+
- PostgreSQL cannot automatically choose between TEXT and CHARACTER VARYING versions
|
|
168
|
+
- Having both creates ambiguity errors: "Could not choose the best candidate function"
|
|
169
|
+
- TEXT is the standard PostgreSQL type for string parameters in RPC functions
|
|
170
|
+
- Even though database columns may use CHARACTER VARYING, function parameters should use TEXT
|
|
158
171
|
|
|
159
172
|
4. **Variable Naming**:
|
|
160
173
|
- Prefix local variables with `v_` (e.g., `v_is_super_admin`, `v_event_exists`)
|
|
@@ -710,7 +723,22 @@ rbac_check_permission_simplified(
|
|
|
710
723
|
|
|
711
724
|
3. **Missing page_id parameter**: Always provide the page name as the last parameter (e.g., `'dishes'`, `'meals'`, `'distribution'`)
|
|
712
725
|
|
|
713
|
-
4. **
|
|
726
|
+
4. **Using CHARACTER VARYING instead of TEXT for string parameters**:
|
|
727
|
+
- ❌ **WRONG**: `p_unit_id CHARACTER VARYING` or `p_dish_name VARCHAR`
|
|
728
|
+
- ✅ **CORRECT**: `p_unit_id TEXT` or `p_dish_name TEXT`
|
|
729
|
+
- **CRITICAL**: All string parameters MUST use `TEXT`, NOT `CHARACTER VARYING` or `VARCHAR`
|
|
730
|
+
- Having both TEXT and CHARACTER VARYING versions causes "Could not choose the best candidate function" errors
|
|
731
|
+
- Application code calls functions with TEXT parameters, so functions must accept TEXT
|
|
732
|
+
- Even though database columns may use CHARACTER VARYING, function parameters should use TEXT
|
|
733
|
+
|
|
734
|
+
5. **Creating duplicate function versions**:
|
|
735
|
+
- ❌ **WRONG**: Creating both `app_cake_unit_update(TEXT, ...)` and `app_cake_unit_update(CHARACTER VARYING, ...)`
|
|
736
|
+
- ✅ **CORRECT**: Only create `app_cake_unit_update(TEXT, ...)`
|
|
737
|
+
- Before creating a new function, check if a version already exists
|
|
738
|
+
- If updating a function, use `CREATE OR REPLACE FUNCTION` to update the existing version
|
|
739
|
+
- If you need to change parameter types, drop the old version first: `DROP FUNCTION IF EXISTS ... CASCADE;`
|
|
740
|
+
|
|
741
|
+
6. **Ambiguous column references**:
|
|
714
742
|
- ❌ **WRONG**: `SELECT mealtype_name FROM cake_mealtype`
|
|
715
743
|
- ✅ **CORRECT**: `SELECT cake_mealtype.mealtype_name FROM cake_mealtype`
|
|
716
744
|
- Always fully qualify table names when there might be ambiguity
|
|
@@ -718,7 +746,7 @@ rbac_check_permission_simplified(
|
|
|
718
746
|
- Common ambiguous columns: `organisation_id`, `created_by`, `updated_by`, `created_at`, `updated_at`
|
|
719
747
|
- See "Avoiding Ambiguous Column References" section below for detailed guidance
|
|
720
748
|
|
|
721
|
-
|
|
749
|
+
7. **Not checking existing migrations**: Before creating a new migration, check if a similar one already exists to avoid duplicates
|
|
722
750
|
|
|
723
751
|
### Updating Existing Functions
|
|
724
752
|
|
|
@@ -1046,6 +1074,12 @@ When creating or reviewing an RPC function, ensure:
|
|
|
1046
1074
|
- ✅ Includes `GRANT EXECUTE` statement
|
|
1047
1075
|
- ✅ Tested with various scenarios
|
|
1048
1076
|
|
|
1077
|
+
### ⚠️ Critical Parameter Type Requirements
|
|
1078
|
+
- ✅ **String parameters use TEXT**: All string parameters MUST use `TEXT`, NOT `CHARACTER VARYING` or `VARCHAR`
|
|
1079
|
+
- ✅ **No duplicate function versions**: Only one version of each function exists (TEXT version, not CHARACTER VARYING)
|
|
1080
|
+
- ✅ **Numeric parameters use correct types**: `DOUBLE PRECISION` for decimals, `INTEGER` for whole numbers, `SMALLINT` for small integers
|
|
1081
|
+
- ✅ **Why TEXT?**: Application code calls with TEXT parameters; having both TEXT and CHARACTER VARYING versions causes ambiguity errors
|
|
1082
|
+
|
|
1049
1083
|
### ⚠️ Critical Permission Format
|
|
1050
1084
|
- ✅ **Permission format is correct**: `'operation:page.{pageName}'` (e.g., `'create:page.dishes'`, `'read:page.meals'`)
|
|
1051
1085
|
- ✅ **NOT using wrong format**: `'operation:resource'` (e.g., `'create:dishes'`, `'read:meals'`)
|
|
@@ -1746,35 +1746,80 @@ The import automatically recognizes and maps:
|
|
|
1746
1746
|
/>
|
|
1747
1747
|
```
|
|
1748
1748
|
|
|
1749
|
-
### Custom Export
|
|
1749
|
+
### Custom Export
|
|
1750
1750
|
|
|
1751
1751
|
The export filename is automatically generated from the table `title` prop:
|
|
1752
1752
|
|
|
1753
1753
|
- If `title` is provided: `{title}_{date}.csv` (e.g., `meals_2024-04-11.csv`)
|
|
1754
1754
|
- If no `title`: `data_export_{date}.csv`
|
|
1755
1755
|
|
|
1756
|
-
To customize the filename, you can provide a custom `onExport` handler:
|
|
1756
|
+
By default, the DataTable exports all **visible columns**. To customize the export (different columns, custom filename, etc.), you can provide a custom `onExport` handler:
|
|
1757
1757
|
|
|
1758
1758
|
```tsx
|
|
1759
|
+
import { DataTable, type ExportOptions, exportToCSVWithTableRows, type ExportColumn } from '@jmruthers/pace-core';
|
|
1760
|
+
|
|
1759
1761
|
<DataTable
|
|
1760
1762
|
title="Meals"
|
|
1761
1763
|
columns={columns}
|
|
1762
1764
|
features={{ export: true }}
|
|
1763
|
-
onExport={async () => {
|
|
1764
|
-
//
|
|
1765
|
-
const
|
|
1766
|
-
|
|
1765
|
+
onExport={async (options: ExportOptions<Meal>) => {
|
|
1766
|
+
// Export only specific columns (different from visible columns)
|
|
1767
|
+
const exportColumns: ExportColumn[] = options.allColumns
|
|
1768
|
+
.filter(col => ['name', 'email', 'role'].includes(col.accessorKey || ''))
|
|
1769
|
+
.map(col => ({
|
|
1770
|
+
header: col.header || col.accessorKey,
|
|
1771
|
+
id: col.id || col.accessorKey,
|
|
1772
|
+
accessorKey: col.accessorKey,
|
|
1773
|
+
accessorFn: 'accessorFn' in col ? col.accessorFn : undefined,
|
|
1774
|
+
}));
|
|
1775
|
+
|
|
1776
|
+
// Use the provided table rows and column mapping for proper accessorFn evaluation
|
|
1777
|
+
await exportToCSVWithTableRows(
|
|
1778
|
+
options.tableRows,
|
|
1779
|
+
exportColumns,
|
|
1780
|
+
options.columnIdToTableColumn,
|
|
1781
|
+
'custom-export-name.csv'
|
|
1782
|
+
);
|
|
1767
1783
|
}}
|
|
1768
1784
|
/>
|
|
1769
1785
|
```
|
|
1770
1786
|
|
|
1787
|
+
### Export Options
|
|
1788
|
+
|
|
1789
|
+
The `onExport` handler receives an `ExportOptions` object with:
|
|
1790
|
+
|
|
1791
|
+
- `tableRows` - Filtered table rows with `getValue()` method for proper `accessorFn` evaluation
|
|
1792
|
+
- `allColumns` - All column definitions passed to the DataTable
|
|
1793
|
+
- `visibleColumns` - Currently visible columns in the table
|
|
1794
|
+
- `columnIdToTableColumn` - Mapping of column IDs to TanStack table column instances (for `getValue()` calls)
|
|
1795
|
+
- `data` - Raw data array (unfiltered)
|
|
1796
|
+
- `filename` - Default filename generated from table title
|
|
1797
|
+
- `table` - TanStack table instance for advanced operations
|
|
1798
|
+
|
|
1771
1799
|
### Export Column Selection
|
|
1772
1800
|
|
|
1773
|
-
**
|
|
1801
|
+
**Default Behavior**: Only **visible columns** are exported. If a column is hidden (via column visibility controls), it will not be included in the export.
|
|
1802
|
+
|
|
1803
|
+
**Custom Export**: Use the `onExport` handler to export different columns than what's visible in the table:
|
|
1774
1804
|
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1805
|
+
```tsx
|
|
1806
|
+
onExport={async (options) => {
|
|
1807
|
+
// Export all columns (including hidden ones)
|
|
1808
|
+
const allExportColumns: ExportColumn[] = options.allColumns.map(col => ({
|
|
1809
|
+
header: col.header || col.accessorKey,
|
|
1810
|
+
id: col.id || col.accessorKey,
|
|
1811
|
+
accessorKey: col.accessorKey,
|
|
1812
|
+
accessorFn: 'accessorFn' in col ? col.accessorFn : undefined,
|
|
1813
|
+
}));
|
|
1814
|
+
|
|
1815
|
+
await exportToCSVWithTableRows(
|
|
1816
|
+
options.tableRows,
|
|
1817
|
+
allExportColumns,
|
|
1818
|
+
options.columnIdToTableColumn,
|
|
1819
|
+
'all-columns-export.csv'
|
|
1820
|
+
);
|
|
1821
|
+
}}
|
|
1822
|
+
```
|
|
1778
1823
|
|
|
1779
1824
|
### Import Column Mapping
|
|
1780
1825
|
|
|
@@ -53,6 +53,8 @@ setupRBAC(supabase);
|
|
|
53
53
|
|
|
54
54
|
Layout-level enforcement provides a safety net that prevents consuming apps from forgetting to implement permission checks. It ensures that every route is automatically validated for permissions.
|
|
55
55
|
|
|
56
|
+
**Note:** Super admins automatically bypass all permission checks in PaceAppLayout. The component checks super admin status before enforcing permissions, ensuring super admins can access any route without violations.
|
|
57
|
+
|
|
56
58
|
### Basic Implementation
|
|
57
59
|
|
|
58
60
|
```tsx
|
|
@@ -107,6 +109,8 @@ Configure different permissions for different routes:
|
|
|
107
109
|
/>
|
|
108
110
|
```
|
|
109
111
|
|
|
112
|
+
**Page Name Mapping:** PaceAppLayout automatically extracts the base page name from route paths. For nested routes like `/organisation/scouts-victoria`, it uses `"organisation"` (the first path segment) as the page name. You can override this using `pageIdMapping` to provide custom page IDs for specific routes.
|
|
113
|
+
|
|
110
114
|
### Navigation Filtering
|
|
111
115
|
|
|
112
116
|
Filter navigation items based on user permissions:
|