@jmruthers/pace-core 0.5.45 → 0.5.47
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-PWLLTSP7.js → DataTable-ZR3ZR6HZ.js} +5 -5
- package/dist/{chunk-GIISFLMP.js → chunk-5VISREHF.js} +3 -3
- package/dist/{chunk-NYF3CUNC.js → chunk-B7SEFA3N.js} +2 -2
- package/dist/{chunk-D4X7PPGX.js → chunk-BN5XALQT.js} +3 -3
- package/dist/{chunk-3FAB54BI.js → chunk-FT2CYYHF.js} +4 -4
- package/dist/{chunk-FZ7EBWOT.js → chunk-IWJD4ZNM.js} +3 -3
- package/dist/{chunk-VCHXOYD5.js → chunk-LM3Y67VN.js} +3 -3
- package/dist/{chunk-2T6QEWMI.js → chunk-OYGUYTFO.js} +2 -2
- package/dist/{chunk-OQ6DTLZ6.js → chunk-S6DAOMOC.js} +70 -14
- package/dist/{chunk-OQ6DTLZ6.js.map → chunk-S6DAOMOC.js.map} +1 -1
- package/dist/{chunk-6AQ7X3EE.js → chunk-UVFDU5JT.js} +5 -5
- package/dist/{chunk-3PNBACK3.js → chunk-VSWL652U.js} +2 -2
- package/dist/components.js +7 -7
- package/dist/hooks.js +4 -4
- package/dist/index.js +10 -10
- package/dist/providers.js +3 -3
- package/dist/rbac/index.js +5 -5
- package/dist/utils.js +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/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/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/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.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/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/RBACContextType.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACProviderProps.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/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/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/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 +3 -3
- package/package.json +1 -1
- package/src/providers/OrganisationProvider.tsx +86 -14
- /package/dist/{DataTable-PWLLTSP7.js.map → DataTable-ZR3ZR6HZ.js.map} +0 -0
- /package/dist/{chunk-GIISFLMP.js.map → chunk-5VISREHF.js.map} +0 -0
- /package/dist/{chunk-NYF3CUNC.js.map → chunk-B7SEFA3N.js.map} +0 -0
- /package/dist/{chunk-D4X7PPGX.js.map → chunk-BN5XALQT.js.map} +0 -0
- /package/dist/{chunk-3FAB54BI.js.map → chunk-FT2CYYHF.js.map} +0 -0
- /package/dist/{chunk-FZ7EBWOT.js.map → chunk-IWJD4ZNM.js.map} +0 -0
- /package/dist/{chunk-VCHXOYD5.js.map → chunk-LM3Y67VN.js.map} +0 -0
- /package/dist/{chunk-2T6QEWMI.js.map → chunk-OYGUYTFO.js.map} +0 -0
- /package/dist/{chunk-6AQ7X3EE.js.map → chunk-UVFDU5JT.js.map} +0 -0
- /package/dist/{chunk-3PNBACK3.js.map → chunk-VSWL652U.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.47](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.47
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -4086,7 +4086,7 @@ If used outside OrganisationProvider
|
|
|
4086
4086
|
|
|
4087
4087
|
#### Defined in
|
|
4088
4088
|
|
|
4089
|
-
[packages/core/src/providers/OrganisationProvider.tsx:
|
|
4089
|
+
[packages/core/src/providers/OrganisationProvider.tsx:715](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/providers/OrganisationProvider.tsx#L715)
|
|
4090
4090
|
|
|
4091
4091
|
___
|
|
4092
4092
|
|
package/package.json
CHANGED
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
* - Organisation types - Type definitions
|
|
65
65
|
*/
|
|
66
66
|
|
|
67
|
-
import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
|
|
67
|
+
import React, { createContext, useContext, useState, useEffect, useCallback, useMemo, useRef } from 'react';
|
|
68
68
|
import { useNavigate } from 'react-router-dom';
|
|
69
69
|
import { useUnifiedAuth } from './UnifiedAuthProvider';
|
|
70
70
|
import { setOrganisationContext } from '../utils/organisationContext';
|
|
@@ -108,6 +108,10 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
108
108
|
const [isLoading, setIsLoading] = useState(true);
|
|
109
109
|
const [error, setError] = useState<Error | null>(null);
|
|
110
110
|
const [isContextReady, setIsContextReady] = useState(false);
|
|
111
|
+
const [retryCount, setRetryCount] = useState(0);
|
|
112
|
+
const isLoadingRef = useRef(false);
|
|
113
|
+
const lastLoadTimeRef = useRef(0);
|
|
114
|
+
const hasFailedRef = useRef(false);
|
|
111
115
|
|
|
112
116
|
const { user, session, supabase, signOut } = useUnifiedAuth();
|
|
113
117
|
|
|
@@ -120,6 +124,19 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
120
124
|
navigate = null;
|
|
121
125
|
}
|
|
122
126
|
|
|
127
|
+
// FIXED: Function to clear all cached data
|
|
128
|
+
const clearAllCachedData = useCallback(() => {
|
|
129
|
+
localStorage.removeItem(STORAGE_KEYS.SELECTED_ORGANISATION);
|
|
130
|
+
localStorage.removeItem(STORAGE_KEYS.ORGANISATION_CONTEXT);
|
|
131
|
+
setSelectedOrganisation(null);
|
|
132
|
+
setOrganisations([]);
|
|
133
|
+
setUserMemberships([]);
|
|
134
|
+
setRoleMapState(new Map());
|
|
135
|
+
setError(null);
|
|
136
|
+
setRetryCount(0);
|
|
137
|
+
setIsContextReady(false);
|
|
138
|
+
}, []);
|
|
139
|
+
|
|
123
140
|
// Set organisation context in database session
|
|
124
141
|
const setDatabaseOrganisationContext = useCallback(async (organisation: Organisation): Promise<void> => {
|
|
125
142
|
if (!supabase || !session) {
|
|
@@ -168,11 +185,20 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
168
185
|
}
|
|
169
186
|
|
|
170
187
|
// FIXED: Additional check to prevent loading during auth state changes
|
|
171
|
-
if (
|
|
172
|
-
|
|
188
|
+
if (isLoadingRef.current) {
|
|
189
|
+
console.log("OrganisationProvider", "Already loading, skipping duplicate load");
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// FIXED: Prevent rapid retries - minimum 2 seconds between attempts
|
|
194
|
+
const now = Date.now();
|
|
195
|
+
if (now - lastLoadTimeRef.current < 2000) {
|
|
196
|
+
console.log("OrganisationProvider", "Too soon since last load, skipping");
|
|
173
197
|
return;
|
|
174
198
|
}
|
|
175
199
|
|
|
200
|
+
lastLoadTimeRef.current = now;
|
|
201
|
+
isLoadingRef.current = true;
|
|
176
202
|
setIsLoading(true);
|
|
177
203
|
setError(null);
|
|
178
204
|
|
|
@@ -222,7 +248,14 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
222
248
|
}
|
|
223
249
|
|
|
224
250
|
// FIXED: Debug log to identify any problematic membership data
|
|
251
|
+
console.log("[OrganisationProvider] All memberships data:", memberships);
|
|
225
252
|
memberships.forEach((membership: any, index: number) => {
|
|
253
|
+
console.log(`[OrganisationProvider] Membership ${index}:`, {
|
|
254
|
+
organisation_id: membership.organisation_id,
|
|
255
|
+
type: typeof membership.organisation_id,
|
|
256
|
+
length: membership.organisation_id ? membership.organisation_id.length : 'null/undefined',
|
|
257
|
+
trimmed: membership.organisation_id ? membership.organisation_id.trim() : 'null/undefined'
|
|
258
|
+
});
|
|
226
259
|
if (!membership.organisation_id || membership.organisation_id.trim() === '') {
|
|
227
260
|
console.warn(`[OrganisationProvider] Membership ${index} has invalid organisation_id:`, membership);
|
|
228
261
|
}
|
|
@@ -257,10 +290,32 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
257
290
|
|
|
258
291
|
DebugLogger.log("OrganisationProvider", "Valid organisation IDs:", organisationIds);
|
|
259
292
|
|
|
293
|
+
// FIXED: Additional validation to ensure no empty strings in the array
|
|
294
|
+
console.log("[OrganisationProvider] Raw organisation IDs before cleaning:", organisationIds);
|
|
295
|
+
console.log("[OrganisationProvider] Raw organisation IDs types:", organisationIds.map(id => typeof id));
|
|
296
|
+
console.log("[OrganisationProvider] Raw organisation IDs lengths:", organisationIds.map(id => id ? id.length : 'null/undefined'));
|
|
297
|
+
|
|
298
|
+
const cleanOrganisationIds = organisationIds.filter(id => {
|
|
299
|
+
const isValid = id && typeof id === 'string' && id.trim() !== '';
|
|
300
|
+
if (!isValid) {
|
|
301
|
+
console.warn("[OrganisationProvider] Filtering out invalid ID:", { id, type: typeof id, length: id ? id.length : 'null/undefined' });
|
|
302
|
+
}
|
|
303
|
+
return isValid;
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
console.log("[OrganisationProvider] Clean organisation IDs after filtering:", cleanOrganisationIds);
|
|
307
|
+
|
|
308
|
+
if (cleanOrganisationIds.length === 0) {
|
|
309
|
+
console.warn("[OrganisationProvider] No clean organisation IDs after filtering:", organisationIds);
|
|
310
|
+
throw new Error('No valid organisation IDs found after cleaning') as OrganisationSecurityError;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
DebugLogger.log("OrganisationProvider", "Clean organisation IDs for query:", cleanOrganisationIds);
|
|
314
|
+
|
|
260
315
|
const { data: organisations, error: orgError } = await supabase
|
|
261
316
|
.from('organisations')
|
|
262
317
|
.select('id, name, display_name, subscription_tier, settings, is_active, parent_id, created_at, updated_at')
|
|
263
|
-
.in('id',
|
|
318
|
+
.in('id', cleanOrganisationIds);
|
|
264
319
|
|
|
265
320
|
if (orgError) {
|
|
266
321
|
console.error("[OrganisationProvider] Error loading organisations:", orgError);
|
|
@@ -352,40 +407,57 @@ export function OrganisationProvider({ children }: OrganisationProviderProps) {
|
|
|
352
407
|
userRole: roleMap.get(initialOrg.id)
|
|
353
408
|
});
|
|
354
409
|
|
|
410
|
+
// FIXED: Reset retry count and failed flag on success
|
|
411
|
+
setRetryCount(0);
|
|
412
|
+
hasFailedRef.current = false;
|
|
413
|
+
|
|
355
414
|
} catch (err) {
|
|
356
415
|
console.error("[OrganisationProvider] Failed to load organisations:", err);
|
|
357
416
|
setError(err as Error);
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
417
|
+
// FIXED: Increment retry count on error
|
|
418
|
+
setRetryCount(prev => prev + 1);
|
|
419
|
+
// FIXED: Set failed flag to prevent further attempts
|
|
420
|
+
hasFailedRef.current = true;
|
|
421
|
+
// FIXED: Clear all cached data on error to prevent corruption
|
|
422
|
+
clearAllCachedData();
|
|
363
423
|
} finally {
|
|
424
|
+
isLoadingRef.current = false;
|
|
364
425
|
setIsLoading(false);
|
|
365
426
|
}
|
|
366
|
-
}, [user, session, supabase]);
|
|
427
|
+
}, [user, session, supabase, clearAllCachedData]);
|
|
367
428
|
|
|
368
429
|
// FIXED: Load organisations only when authentication is complete and stable
|
|
369
430
|
useEffect(() => {
|
|
370
431
|
// Only load organizations if we have a valid user and session
|
|
371
432
|
// and we're not in the middle of authentication loading
|
|
372
|
-
if (user && session && supabase && !isLoading) {
|
|
373
|
-
|
|
433
|
+
if (user && session && supabase && !isLoading && !isLoadingRef.current) {
|
|
434
|
+
// FIXED: Prevent infinite retry loops
|
|
435
|
+
if (retryCount >= 3 || hasFailedRef.current) {
|
|
436
|
+
console.error("[OrganisationProvider] Max retry count reached or failed flag set, stopping organisation loading");
|
|
437
|
+
setError(new Error('Failed to load organisations after multiple attempts'));
|
|
438
|
+
setIsLoading(false);
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
console.log("[OrganisationProvider] Authentication stable, loading organizations... (retry:", retryCount, ")");
|
|
374
443
|
loadUserOrganisations();
|
|
375
444
|
} else if (!user && !session) {
|
|
376
445
|
// Clear state if no authentication
|
|
377
|
-
|
|
446
|
+
console.log("[OrganisationProvider] No authentication, clearing organization state");
|
|
378
447
|
setSelectedOrganisation(null);
|
|
379
448
|
setOrganisations([]);
|
|
380
449
|
setUserMemberships([]);
|
|
381
450
|
setRoleMapState(new Map());
|
|
382
451
|
setIsLoading(false);
|
|
383
452
|
setError(null);
|
|
453
|
+
setRetryCount(0); // Reset retry count
|
|
454
|
+
isLoadingRef.current = false; // Reset loading ref
|
|
455
|
+
hasFailedRef.current = false; // Reset failed flag
|
|
384
456
|
// FIXED: Clear localStorage when no authentication to prevent stale data
|
|
385
457
|
localStorage.removeItem(STORAGE_KEYS.SELECTED_ORGANISATION);
|
|
386
458
|
localStorage.removeItem(STORAGE_KEYS.ORGANISATION_CONTEXT);
|
|
387
459
|
}
|
|
388
|
-
}, [user, session, supabase, isLoading,
|
|
460
|
+
}, [user, session, supabase, isLoading, retryCount]);
|
|
389
461
|
|
|
390
462
|
// Handle logout and redirect to login
|
|
391
463
|
const handleLogoutAndRedirect = useCallback(async () => {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|