@jmruthers/pace-core 0.5.102 → 0.5.103
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-DXELRJIX.js → DataTable-EEDFYMJP.js} +2 -2
- package/dist/{PublicLoadingSpinner-Cvgk-V0F.d.ts → PublicLoadingSpinner-48ewSMKK.d.ts} +1 -96
- package/dist/{chunk-7ME4Z5OY.js → chunk-5SGBVBRU.js} +12 -148
- package/dist/chunk-5SGBVBRU.js.map +1 -0
- package/dist/{chunk-EVVRUGQ2.js → chunk-62AVH7CM.js} +78 -55
- package/dist/{chunk-EVVRUGQ2.js.map → chunk-62AVH7CM.js.map} +1 -1
- package/dist/{chunk-UDWTCBSH.js → chunk-SZWCMVTQ.js} +12 -175
- package/dist/chunk-SZWCMVTQ.js.map +1 -0
- package/dist/{chunk-SZWRW5FD.js → chunk-X33A4WWI.js} +23 -3
- package/dist/{chunk-SZWRW5FD.js.map → chunk-X33A4WWI.js.map} +1 -1
- package/dist/components.d.ts +1 -1
- package/dist/components.js +3 -9
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +2 -9
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -16
- package/dist/index.js.map +1 -1
- package/dist/types.js +3 -3
- package/dist/{usePublicRouteParams-BwMR2uub.d.ts → usePublicRouteParams-BiXgKiYa.d.ts} +1 -117
- 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/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 +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 +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 +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 +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 +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 +2 -150
- package/docs/implementation-guides/file-reference-system.md +31 -19
- package/package.json +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +23 -13
- package/src/components/DataTable/hooks/useTableColumns.ts +36 -6
- package/src/components/PublicLayout/PublicPageHeader.tsx +1 -1
- package/src/components/index.ts +0 -2
- package/src/hooks/public/index.ts +2 -4
- package/src/index.ts +0 -2
- package/src/utils/file-reference.ts +30 -2
- package/src/utils/storage/README.md +22 -20
- package/dist/chunk-7ME4Z5OY.js.map +0 -1
- package/dist/chunk-UDWTCBSH.js.map +0 -1
- package/docs/api/interfaces/UseEventLogoOptions.md +0 -74
- package/docs/api/interfaces/UseEventLogoReturn.md +0 -81
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
- package/src/hooks/public/usePublicEventLogo.ts +0 -295
- package/src/hooks/useEventLogo.ts +0 -316
- /package/dist/{DataTable-DXELRJIX.js.map → DataTable-EEDFYMJP.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.103](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.103
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -85,13 +85,9 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
|
|
|
85
85
|
- [UserMenuProps](interfaces/UserMenuProps.md)
|
|
86
86
|
- [UsePublicEventReturn](interfaces/UsePublicEventReturn.md)
|
|
87
87
|
- [UsePublicEventOptions](interfaces/UsePublicEventOptions.md)
|
|
88
|
-
- [UsePublicEventLogoReturn](interfaces/UsePublicEventLogoReturn.md)
|
|
89
|
-
- [UsePublicEventLogoOptions](interfaces/UsePublicEventLogoOptions.md)
|
|
90
88
|
- [UsePublicFileDisplayReturn](interfaces/UsePublicFileDisplayReturn.md)
|
|
91
89
|
- [UsePublicFileDisplayOptions](interfaces/UsePublicFileDisplayOptions.md)
|
|
92
90
|
- [UsePublicRouteParamsReturn](interfaces/UsePublicRouteParamsReturn.md)
|
|
93
|
-
- [UseEventLogoReturn](interfaces/UseEventLogoReturn.md)
|
|
94
|
-
- [UseEventLogoOptions](interfaces/UseEventLogoOptions.md)
|
|
95
91
|
- [UseInactivityTrackerOptions](interfaces/UseInactivityTrackerOptions.md)
|
|
96
92
|
- [UseInactivityTrackerReturn](interfaces/UseInactivityTrackerReturn.md)
|
|
97
93
|
- [UserEventAccess](interfaces/UserEventAccess.md)
|
|
@@ -273,9 +269,6 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
|
|
|
273
269
|
- [usePublicEvent](modules.md#usepublicevent)
|
|
274
270
|
- [clearPublicEventCache](modules.md#clearpubliceventcache)
|
|
275
271
|
- [getPublicEventCacheStats](modules.md#getpubliceventcachestats)
|
|
276
|
-
- [usePublicEventLogo](modules.md#usepubliceventlogo)
|
|
277
|
-
- [clearPublicLogoCache](modules.md#clearpubliclogocache)
|
|
278
|
-
- [getPublicLogoCacheStats](modules.md#getpubliclogocachestats)
|
|
279
272
|
- [usePublicFileDisplay](modules.md#usepublicfiledisplay)
|
|
280
273
|
- [clearPublicFileDisplayCache](modules.md#clearpublicfiledisplaycache)
|
|
281
274
|
- [getPublicFileDisplayCacheStats](modules.md#getpublicfiledisplaycachestats)
|
|
@@ -288,9 +281,6 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
|
|
|
288
281
|
- [useInactivityService](modules.md#useinactivityservice)
|
|
289
282
|
- [useOrganisationService](modules.md#useorganisationservice)
|
|
290
283
|
- [useAppConfig](modules.md#useappconfig)
|
|
291
|
-
- [useEventLogo](modules.md#useeventlogo)
|
|
292
|
-
- [clearEventLogoCache](modules.md#cleareventlogocache)
|
|
293
|
-
- [getEventLogoCacheStats](modules.md#geteventlogocachestats)
|
|
294
284
|
- [useEventTheme](modules.md#useeventtheme)
|
|
295
285
|
- [useEvents](modules.md#useevents)
|
|
296
286
|
- [useFileReference](modules.md#usefilereference)
|
|
@@ -3803,74 +3793,6 @@ Get cache statistics for debugging
|
|
|
3803
3793
|
|
|
3804
3794
|
___
|
|
3805
3795
|
|
|
3806
|
-
### usePublicEventLogo
|
|
3807
|
-
|
|
3808
|
-
▸ **usePublicEventLogo**(`eventId`, `eventName`, `organisationId`, `options`): [`UsePublicEventLogoReturn`](interfaces/UsePublicEventLogoReturn.md)
|
|
3809
|
-
|
|
3810
|
-
Hook for accessing public event logo URLs
|
|
3811
|
-
|
|
3812
|
-
This hook provides access to event logo URLs without requiring
|
|
3813
|
-
authentication. It includes fallback handling and image validation.
|
|
3814
|
-
|
|
3815
|
-
#### Parameters
|
|
3816
|
-
|
|
3817
|
-
| Name | Type | Description |
|
|
3818
|
-
| :------ | :------ | :------ |
|
|
3819
|
-
| `eventId` | `undefined` \| `string` | The event ID to fetch logo for |
|
|
3820
|
-
| `eventName` | `undefined` \| `string` | The event name for fallback text generation |
|
|
3821
|
-
| `organisationId` | `undefined` \| `string` | The organisation ID for storage path |
|
|
3822
|
-
| `options` | [`UsePublicEventLogoOptions`](interfaces/UsePublicEventLogoOptions.md) | Configuration options for caching and behavior |
|
|
3823
|
-
|
|
3824
|
-
#### Returns
|
|
3825
|
-
|
|
3826
|
-
[`UsePublicEventLogoReturn`](interfaces/UsePublicEventLogoReturn.md)
|
|
3827
|
-
|
|
3828
|
-
Object containing logo URL, fallback text, loading state, error, and refetch function
|
|
3829
|
-
|
|
3830
|
-
#### Defined in
|
|
3831
|
-
|
|
3832
|
-
[packages/core/src/hooks/public/usePublicEventLogo.ts:127](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L127)
|
|
3833
|
-
|
|
3834
|
-
___
|
|
3835
|
-
|
|
3836
|
-
### clearPublicLogoCache
|
|
3837
|
-
|
|
3838
|
-
▸ **clearPublicLogoCache**(): `void`
|
|
3839
|
-
|
|
3840
|
-
Clear all cached public logo data
|
|
3841
|
-
Useful for testing or when you need to force refresh all data
|
|
3842
|
-
|
|
3843
|
-
#### Returns
|
|
3844
|
-
|
|
3845
|
-
`void`
|
|
3846
|
-
|
|
3847
|
-
#### Defined in
|
|
3848
|
-
|
|
3849
|
-
[packages/core/src/hooks/public/usePublicEventLogo.ts:278](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L278)
|
|
3850
|
-
|
|
3851
|
-
___
|
|
3852
|
-
|
|
3853
|
-
### getPublicLogoCacheStats
|
|
3854
|
-
|
|
3855
|
-
▸ **getPublicLogoCacheStats**(): `Object`
|
|
3856
|
-
|
|
3857
|
-
Get cache statistics for debugging
|
|
3858
|
-
|
|
3859
|
-
#### Returns
|
|
3860
|
-
|
|
3861
|
-
`Object`
|
|
3862
|
-
|
|
3863
|
-
| Name | Type |
|
|
3864
|
-
| :------ | :------ |
|
|
3865
|
-
| `size` | `number` |
|
|
3866
|
-
| `keys` | `string`[] |
|
|
3867
|
-
|
|
3868
|
-
#### Defined in
|
|
3869
|
-
|
|
3870
|
-
[packages/core/src/hooks/public/usePublicEventLogo.ts:289](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicEventLogo.ts#L289)
|
|
3871
|
-
|
|
3872
|
-
___
|
|
3873
|
-
|
|
3874
3796
|
### usePublicFileDisplay
|
|
3875
3797
|
|
|
3876
3798
|
▸ **usePublicFileDisplay**(`table_name`, `record_id`, `organisation_id`, `category`, `options`): [`UsePublicFileDisplayReturn`](interfaces/UsePublicFileDisplayReturn.md)
|
|
@@ -4116,76 +4038,6 @@ App configuration and loading state
|
|
|
4116
4038
|
|
|
4117
4039
|
___
|
|
4118
4040
|
|
|
4119
|
-
### useEventLogo
|
|
4120
|
-
|
|
4121
|
-
▸ **useEventLogo**(`supabase`, `eventId`, `eventName`, `organisationId`, `options?`): [`UseEventLogoReturn`](interfaces/UseEventLogoReturn.md)
|
|
4122
|
-
|
|
4123
|
-
Hook for accessing event logo URLs in authenticated contexts
|
|
4124
|
-
|
|
4125
|
-
This hook provides access to event logo URLs for authenticated users.
|
|
4126
|
-
It supports both public and private logos, generating appropriate URLs
|
|
4127
|
-
(public URLs for public files, signed URLs for private files).
|
|
4128
|
-
|
|
4129
|
-
#### Parameters
|
|
4130
|
-
|
|
4131
|
-
| Name | Type | Description |
|
|
4132
|
-
| :------ | :------ | :------ |
|
|
4133
|
-
| `supabase` | ``null`` \| `default`\<`any`, ``"public"``, ``"public"``, `any`, `any`\> | Supabase client instance (required) |
|
|
4134
|
-
| `eventId` | `undefined` \| `string` | The event ID to fetch logo for |
|
|
4135
|
-
| `eventName` | `undefined` \| `string` | The event name for fallback text generation |
|
|
4136
|
-
| `organisationId` | `undefined` \| `string` | The organisation ID for storage path |
|
|
4137
|
-
| `options` | [`UseEventLogoOptions`](interfaces/UseEventLogoOptions.md) | Configuration options for caching and behavior |
|
|
4138
|
-
|
|
4139
|
-
#### Returns
|
|
4140
|
-
|
|
4141
|
-
[`UseEventLogoReturn`](interfaces/UseEventLogoReturn.md)
|
|
4142
|
-
|
|
4143
|
-
Object containing logo URL, fallback text, loading state, error, and refetch function
|
|
4144
|
-
|
|
4145
|
-
#### Defined in
|
|
4146
|
-
|
|
4147
|
-
[packages/core/src/hooks/useEventLogo.ts:131](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L131)
|
|
4148
|
-
|
|
4149
|
-
___
|
|
4150
|
-
|
|
4151
|
-
### clearEventLogoCache
|
|
4152
|
-
|
|
4153
|
-
▸ **clearEventLogoCache**(): `void`
|
|
4154
|
-
|
|
4155
|
-
Clear all cached authenticated event logo data
|
|
4156
|
-
Useful for testing or when you need to force refresh all data
|
|
4157
|
-
|
|
4158
|
-
#### Returns
|
|
4159
|
-
|
|
4160
|
-
`void`
|
|
4161
|
-
|
|
4162
|
-
#### Defined in
|
|
4163
|
-
|
|
4164
|
-
[packages/core/src/hooks/useEventLogo.ts:298](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L298)
|
|
4165
|
-
|
|
4166
|
-
___
|
|
4167
|
-
|
|
4168
|
-
### getEventLogoCacheStats
|
|
4169
|
-
|
|
4170
|
-
▸ **getEventLogoCacheStats**(): `Object`
|
|
4171
|
-
|
|
4172
|
-
Get cache statistics for debugging
|
|
4173
|
-
|
|
4174
|
-
#### Returns
|
|
4175
|
-
|
|
4176
|
-
`Object`
|
|
4177
|
-
|
|
4178
|
-
| Name | Type |
|
|
4179
|
-
| :------ | :------ |
|
|
4180
|
-
| `size` | `number` |
|
|
4181
|
-
| `keys` | `string`[] |
|
|
4182
|
-
|
|
4183
|
-
#### Defined in
|
|
4184
|
-
|
|
4185
|
-
[packages/core/src/hooks/useEventLogo.ts:309](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventLogo.ts#L309)
|
|
4186
|
-
|
|
4187
|
-
___
|
|
4188
|
-
|
|
4189
4041
|
### useEventTheme
|
|
4190
4042
|
|
|
4191
4043
|
▸ **useEventTheme**(): `void`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
|
-
lastUpdated: 2025-
|
|
3
|
-
version: 0.5.
|
|
2
|
+
lastUpdated: 2025-11-01T14:58:00+11:00
|
|
3
|
+
version: 0.5.102
|
|
4
4
|
reviewedBy: content-audit
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -30,7 +30,7 @@ CREATE TABLE file_references (
|
|
|
30
30
|
table_name TEXT NOT NULL, -- Source table (e.g., 'pace_person')
|
|
31
31
|
record_id TEXT NOT NULL, -- Source record ID
|
|
32
32
|
file_path TEXT NOT NULL, -- Storage path
|
|
33
|
-
file_metadata JSONB DEFAULT '{}', -- File metadata
|
|
33
|
+
file_metadata JSONB DEFAULT '{}', -- File metadata (includes category, fileName, fileType, etc.)
|
|
34
34
|
organisation_id UUID NOT NULL, -- For RLS
|
|
35
35
|
app_id UUID NOT NULL, -- Application context
|
|
36
36
|
is_public BOOLEAN DEFAULT false, -- Public vs private
|
|
@@ -39,6 +39,8 @@ CREATE TABLE file_references (
|
|
|
39
39
|
);
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
**Important:** The `category` is stored within the `file_metadata` JSONB field as `file_metadata->>'category'`, **not** as a direct column. Category filtering is performed via RPC functions (`data_file_reference_by_category_list`) that properly query the JSONB field. Direct queries filtering on a non-existent `category` column will fail.
|
|
43
|
+
|
|
42
44
|
### Storage Structure
|
|
43
45
|
|
|
44
46
|
**Organisation-First Structure:**
|
|
@@ -397,25 +399,33 @@ fileReferences.forEach(fileRef => {
|
|
|
397
399
|
});
|
|
398
400
|
```
|
|
399
401
|
|
|
400
|
-
|
|
402
|
+
**Note:** Category filtering uses the RPC function `data_file_reference_by_category_list`, which filters on `file_metadata->>'category'` (the JSONB field), not a direct column. This hook automatically handles the filtering correctly.
|
|
401
403
|
|
|
402
|
-
|
|
403
|
-
import { useEventLogo } from '@jmruthers/pace-core';
|
|
404
|
+
#### Event Logo Display
|
|
404
405
|
|
|
405
|
-
|
|
406
|
-
supabase,
|
|
407
|
-
eventId,
|
|
408
|
-
eventName,
|
|
409
|
-
organisationId,
|
|
410
|
-
{
|
|
411
|
-
validateImage: true,
|
|
412
|
-
enableCache: true,
|
|
413
|
-
cacheTtl: 30 * 60 * 1000 // 30 minutes
|
|
414
|
-
}
|
|
415
|
-
);
|
|
406
|
+
Event logos can be displayed using `FileDisplay` with category filtering:
|
|
416
407
|
|
|
417
|
-
|
|
418
|
-
|
|
408
|
+
```tsx
|
|
409
|
+
import { FileDisplay, FileCategory } from '@jmruthers/pace-core';
|
|
410
|
+
|
|
411
|
+
// Display event logo with fallback
|
|
412
|
+
<FileDisplay
|
|
413
|
+
table_name="event"
|
|
414
|
+
record_id={eventId}
|
|
415
|
+
organisation_id={organisationId}
|
|
416
|
+
category={FileCategory.EVENT_LOGOS}
|
|
417
|
+
displayOnly={true}
|
|
418
|
+
showFallback={true}
|
|
419
|
+
fallbackSize="lg"
|
|
420
|
+
generateFallbackText={(fileName) => {
|
|
421
|
+
if (!eventName) return 'EV';
|
|
422
|
+
return eventName
|
|
423
|
+
.split(/[\s\-_]+/)
|
|
424
|
+
.map(word => word.charAt(0).toUpperCase())
|
|
425
|
+
.join('')
|
|
426
|
+
.substring(0, 3);
|
|
427
|
+
}}
|
|
428
|
+
/>
|
|
419
429
|
```
|
|
420
430
|
|
|
421
431
|
#### useFileReferenceForRecord Hook
|
|
@@ -500,6 +510,8 @@ SELECT data_file_reference_get(
|
|
|
500
510
|
);
|
|
501
511
|
|
|
502
512
|
-- Get files by category
|
|
513
|
+
-- NOTE: Category filtering uses the file_metadata JSONB field (file_metadata->>'category'),
|
|
514
|
+
-- not a direct column. This RPC function properly filters on the JSONB field.
|
|
503
515
|
SELECT data_file_reference_by_category_list(
|
|
504
516
|
p_table_name := 'event',
|
|
505
517
|
p_record_id := 'event-uuid',
|
package/package.json
CHANGED
|
@@ -1147,15 +1147,19 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1147
1147
|
|
|
1148
1148
|
{/* Table header */}
|
|
1149
1149
|
<thead>
|
|
1150
|
-
{table?.getHeaderGroups().map((headerGroup) =>
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1150
|
+
{table?.getHeaderGroups().map((headerGroup) => {
|
|
1151
|
+
// Filter visible headers once to determine first and last
|
|
1152
|
+
const visibleHeaders = headerGroup.headers.filter(header => {
|
|
1153
|
+
return typeof header.column.getIsVisible === 'function'
|
|
1154
|
+
? header.column.getIsVisible()
|
|
1155
|
+
: true;
|
|
1156
|
+
});
|
|
1157
|
+
|
|
1158
|
+
return (
|
|
1159
|
+
<tr key={headerGroup.id}>
|
|
1160
|
+
{visibleHeaders.map((header, index) => {
|
|
1161
|
+
const isFirst = index === 0;
|
|
1162
|
+
const isLast = index === visibleHeaders.length - 1;
|
|
1159
1163
|
const isSortable = header.column.getCanSort();
|
|
1160
1164
|
const ariaSort = isSortable
|
|
1161
1165
|
? (header.column.getIsSorted() === 'asc'
|
|
@@ -1205,7 +1209,12 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1205
1209
|
return (
|
|
1206
1210
|
<th
|
|
1207
1211
|
key={header.id}
|
|
1208
|
-
className={
|
|
1212
|
+
className={cn(
|
|
1213
|
+
'px-3 py-2 bg-main-200',
|
|
1214
|
+
isRightAligned ? 'text-right' : 'text-left',
|
|
1215
|
+
isFirst && 'rounded-l-md',
|
|
1216
|
+
isLast && 'rounded-r-md'
|
|
1217
|
+
)}
|
|
1209
1218
|
scope="col"
|
|
1210
1219
|
role="columnheader"
|
|
1211
1220
|
{...(isSortable ? { 'aria-sort': ariaSort } : {})}
|
|
@@ -1215,7 +1224,7 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1215
1224
|
isSortable ? (
|
|
1216
1225
|
<Button
|
|
1217
1226
|
variant="ghost"
|
|
1218
|
-
className={`h-auto p-0 font-
|
|
1227
|
+
className={`h-auto p-0 font-bold hover:bg-transparent ${isRightAligned ? 'justify-end' : 'justify-start'}`}
|
|
1219
1228
|
onClick={handleSortClick}
|
|
1220
1229
|
{...headerKeyboardHandlers}
|
|
1221
1230
|
aria-label={`Sort by ${typeof header.column.columnDef.header === 'string' ? header.column.columnDef.header : 'column'}`}
|
|
@@ -1241,8 +1250,9 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1241
1250
|
</th>
|
|
1242
1251
|
);
|
|
1243
1252
|
})}
|
|
1244
|
-
|
|
1245
|
-
|
|
1253
|
+
</tr>
|
|
1254
|
+
);
|
|
1255
|
+
})}
|
|
1246
1256
|
</thead>
|
|
1247
1257
|
|
|
1248
1258
|
{/* Table body */}
|
|
@@ -50,12 +50,42 @@ export function useTableColumns<TData extends DataRecord>({
|
|
|
50
50
|
|
|
51
51
|
const enhancedColumns = useMemo(() => {
|
|
52
52
|
// Create enhanced base columns
|
|
53
|
-
const baseColumns: ColumnDef<TData>[] = [...columns].map(column =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
const baseColumns: ColumnDef<TData>[] = [...columns].map(column => {
|
|
54
|
+
const baseColumn = {
|
|
55
|
+
...column,
|
|
56
|
+
enableSorting: features.sorting && (column.enableSorting !== false),
|
|
57
|
+
enableColumnFilter: features.filtering && (column.enableColumnFilter !== false),
|
|
58
|
+
enableGrouping: features.grouping && (column.enableGrouping !== false),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Automatically set right alignment for numeric columns
|
|
62
|
+
// Check if column is numeric by:
|
|
63
|
+
// 1. meta.type === 'number'
|
|
64
|
+
// 2. fieldType === 'number'
|
|
65
|
+
// 3. filterType === 'number'
|
|
66
|
+
// Exclude dates (fieldType === 'date' or meta.type === 'date')
|
|
67
|
+
const dataTableColumn = column as DataTableColumn<TData>;
|
|
68
|
+
const isNumericColumn =
|
|
69
|
+
column.meta?.type === 'number' ||
|
|
70
|
+
dataTableColumn.fieldType === 'number' ||
|
|
71
|
+
dataTableColumn.filterType === 'number';
|
|
72
|
+
|
|
73
|
+
const isDateColumn =
|
|
74
|
+
column.meta?.type === 'date' ||
|
|
75
|
+
dataTableColumn.fieldType === 'date' ||
|
|
76
|
+
dataTableColumn.filterType === 'date';
|
|
77
|
+
|
|
78
|
+
// Set right alignment if numeric and not a date
|
|
79
|
+
if (isNumericColumn && !isDateColumn) {
|
|
80
|
+
baseColumn.meta = {
|
|
81
|
+
...baseColumn.meta,
|
|
82
|
+
align: 'right',
|
|
83
|
+
type: 'number',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return baseColumn;
|
|
88
|
+
});
|
|
59
89
|
|
|
60
90
|
// Create selection column if enabled
|
|
61
91
|
const selectionColumn: ColumnDef<TData> | null = features.selection ? {
|
package/src/components/index.ts
CHANGED
|
@@ -260,8 +260,6 @@ export type {
|
|
|
260
260
|
UseFileReferenceReturn,
|
|
261
261
|
UseFileReferenceForRecordReturn
|
|
262
262
|
} from '../hooks/useFileReference';
|
|
263
|
-
export { useEventLogo, clearEventLogoCache, getEventLogoCacheStats } from '../hooks/useEventLogo';
|
|
264
|
-
export type { UseEventLogoReturn, UseEventLogoOptions } from '../hooks/useEventLogo';
|
|
265
263
|
|
|
266
264
|
export { useToast } from '../hooks/useToast';
|
|
267
265
|
|
|
@@ -10,15 +10,14 @@
|
|
|
10
10
|
*
|
|
11
11
|
* @example
|
|
12
12
|
* // Import individual hooks
|
|
13
|
-
* import { usePublicEvent
|
|
13
|
+
* import { usePublicEvent } from '@jmruthers/pace-core/hooks/public';
|
|
14
14
|
*
|
|
15
15
|
* // Or import from main package
|
|
16
|
-
* import { usePublicEvent
|
|
16
|
+
* import { usePublicEvent } from '@jmruthers/pace-core';
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
// === PUBLIC DATA ACCESS HOOKS ===
|
|
20
20
|
export { usePublicEvent, clearPublicEventCache, getPublicEventCacheStats } from './usePublicEvent';
|
|
21
|
-
export { usePublicEventLogo, clearPublicLogoCache, getPublicLogoCacheStats } from './usePublicEventLogo';
|
|
22
21
|
export { usePublicFileDisplay, clearPublicFileDisplayCache, getPublicFileDisplayCacheStats } from './usePublicFileDisplay';
|
|
23
22
|
|
|
24
23
|
// === PUBLIC ROUTE HOOKS ===
|
|
@@ -31,6 +30,5 @@ export {
|
|
|
31
30
|
|
|
32
31
|
// === PUBLIC TYPES ===
|
|
33
32
|
export type { UsePublicEventReturn, UsePublicEventOptions } from './usePublicEvent';
|
|
34
|
-
export type { UsePublicEventLogoReturn, UsePublicEventLogoOptions } from './usePublicEventLogo';
|
|
35
33
|
export type { UsePublicFileDisplayReturn, UsePublicFileDisplayOptions } from './usePublicFileDisplay';
|
|
36
34
|
export type { UsePublicRouteParamsReturn } from './usePublicRouteParams';
|
package/src/index.ts
CHANGED
|
@@ -224,8 +224,6 @@ export type {
|
|
|
224
224
|
UseFileReferenceReturn,
|
|
225
225
|
UseFileReferenceForRecordReturn
|
|
226
226
|
} from './hooks/useFileReference';
|
|
227
|
-
export { useEventLogo, clearEventLogoCache, getEventLogoCacheStats } from './hooks/useEventLogo';
|
|
228
|
-
export type { UseEventLogoReturn, UseEventLogoOptions } from './hooks/useEventLogo';
|
|
229
227
|
export * from './utils/storage';
|
|
230
228
|
|
|
231
229
|
// Table components
|
|
@@ -342,6 +342,9 @@ export class FileReferenceServiceImpl implements FileReferenceService {
|
|
|
342
342
|
organisation_id: string
|
|
343
343
|
): Promise<FileReference[]> {
|
|
344
344
|
try {
|
|
345
|
+
// Use RPC function to get files by category - this correctly filters on file_metadata->>'category'
|
|
346
|
+
// NOTE: We do NOT filter directly on a 'category' column because it doesn't exist.
|
|
347
|
+
// The category is stored in the JSONB file_metadata field.
|
|
345
348
|
const { data, error } = await this.supabase
|
|
346
349
|
.rpc('data_file_reference_by_category_list', {
|
|
347
350
|
p_table_name: table_name,
|
|
@@ -351,7 +354,16 @@ export class FileReferenceServiceImpl implements FileReferenceService {
|
|
|
351
354
|
});
|
|
352
355
|
|
|
353
356
|
if (error) {
|
|
354
|
-
|
|
357
|
+
// Provide clear error message about category filtering
|
|
358
|
+
console.error('[FileReferenceService] RPC error getting files by category:', {
|
|
359
|
+
error,
|
|
360
|
+
table_name,
|
|
361
|
+
record_id,
|
|
362
|
+
category,
|
|
363
|
+
organisation_id,
|
|
364
|
+
message: 'Category filtering is done via RPC function data_file_reference_by_category_list which filters on file_metadata->>\'category\''
|
|
365
|
+
});
|
|
366
|
+
throw new Error(`Failed to get files by category: ${error.message}. Category filtering uses file_metadata JSONB field, not a direct column.`);
|
|
355
367
|
}
|
|
356
368
|
|
|
357
369
|
// RPC returns partial data, need to fetch full file references
|
|
@@ -360,6 +372,7 @@ export class FileReferenceServiceImpl implements FileReferenceService {
|
|
|
360
372
|
}
|
|
361
373
|
|
|
362
374
|
// Fetch full file reference data for each ID
|
|
375
|
+
// Note: This query does NOT filter by category - the RPC already did that filtering
|
|
363
376
|
const ids = data.map((item: any) => item.id);
|
|
364
377
|
const { data: fullData, error: fetchError } = await this.supabase
|
|
365
378
|
.from('file_references')
|
|
@@ -370,7 +383,22 @@ export class FileReferenceServiceImpl implements FileReferenceService {
|
|
|
370
383
|
throw new Error(`Failed to fetch file references: ${fetchError.message}`);
|
|
371
384
|
}
|
|
372
385
|
|
|
373
|
-
|
|
386
|
+
// Verify that all returned files match the category (defensive check)
|
|
387
|
+
const filteredFiles = (fullData || []).filter((file: any) => {
|
|
388
|
+
const fileCategory = file.file_metadata?.category;
|
|
389
|
+
return fileCategory === category;
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
if (filteredFiles.length !== fullData.length) {
|
|
393
|
+
console.warn('[FileReferenceService] RPC returned files with mismatched categories. Filtering client-side.', {
|
|
394
|
+
expected: category,
|
|
395
|
+
returned: fullData.map((f: any) => f.file_metadata?.category),
|
|
396
|
+
filtered: filteredFiles.length,
|
|
397
|
+
total: fullData.length
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return filteredFiles as FileReference[];
|
|
374
402
|
} catch (error) {
|
|
375
403
|
console.error('Error getting files by category:', error);
|
|
376
404
|
throw error;
|
|
@@ -148,29 +148,31 @@ const { fileReferences, fileUrls, isLoading, error } = useFilesByCategory(
|
|
|
148
148
|
);
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
###
|
|
151
|
+
### FileDisplay Component
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
Display event logos and other files with automatic fallback support.
|
|
154
154
|
|
|
155
155
|
```typescript
|
|
156
|
-
|
|
157
|
-
supabase,
|
|
158
|
-
eventId,
|
|
159
|
-
eventName,
|
|
160
|
-
organisationId,
|
|
161
|
-
{
|
|
162
|
-
validateImage: true,
|
|
163
|
-
enableCache: true,
|
|
164
|
-
cacheTtl: 30 * 60 * 1000 // 30 minutes
|
|
165
|
-
}
|
|
166
|
-
);
|
|
156
|
+
import { FileDisplay, FileCategory } from '@jmruthers/pace-core';
|
|
167
157
|
|
|
168
|
-
// Display logo with fallback
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
158
|
+
// Display event logo with fallback
|
|
159
|
+
<FileDisplay
|
|
160
|
+
table_name="event"
|
|
161
|
+
record_id={eventId}
|
|
162
|
+
organisation_id={organisationId}
|
|
163
|
+
category={FileCategory.EVENT_LOGOS}
|
|
164
|
+
displayOnly={true}
|
|
165
|
+
showFallback={true}
|
|
166
|
+
fallbackSize="lg"
|
|
167
|
+
generateFallbackText={(fileName) => {
|
|
168
|
+
if (!eventName) return 'EV';
|
|
169
|
+
return eventName
|
|
170
|
+
.split(/[\s\-_]+/)
|
|
171
|
+
.map(word => word.charAt(0).toUpperCase())
|
|
172
|
+
.join('')
|
|
173
|
+
.substring(0, 3);
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
174
176
|
```
|
|
175
177
|
|
|
176
178
|
## File Categories
|
|
@@ -331,7 +333,7 @@ await uploadFile({
|
|
|
331
333
|
6. **Memory leak / "Maximum update depth exceeded"**
|
|
332
334
|
- Ensure proper cleanup in useEffect hooks
|
|
333
335
|
- Check for infinite re-render loops in components
|
|
334
|
-
- Use `
|
|
336
|
+
- Use `clearFileDisplayCache()` when unmounting components
|
|
335
337
|
|
|
336
338
|
### Debug Mode
|
|
337
339
|
|