@jmruthers/pace-core 0.5.113 → 0.5.115
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-YNEB5WDK.js → DataTable-H5KJCAIS.js} +3 -3
- package/dist/{chunk-KISJX3XZ.js → chunk-OUU3SP6I.js} +20 -16
- package/dist/{chunk-KISJX3XZ.js.map → chunk-OUU3SP6I.js.map} +1 -1
- package/dist/{chunk-4OX5PXHX.js → chunk-SYXOZQ4P.js} +4 -5
- package/dist/chunk-SYXOZQ4P.js.map +1 -0
- package/dist/{chunk-YUKG6PXE.js → chunk-XYRZV7R5.js} +15 -7
- package/dist/chunk-XYRZV7R5.js.map +1 -0
- package/dist/components.d.ts +1 -1
- package/dist/components.js +3 -3
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/dist/{useToast-DRah6K-g.d.ts → useToast-DVT4dMtf.d.ts} +8 -6
- 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 +6 -6
- package/docs/architecture/rpc-function-standards.md +131 -11
- package/package.json +1 -1
- package/src/components/DataTable/components/DataTableCore.tsx +3 -15
- package/src/components/DataTable/components/ImportModal.tsx +25 -2
- package/src/components/Dialog/Dialog.tsx +3 -2
- package/src/components/NavigationMenu/NavigationMenu.tsx +29 -5
- package/src/components/Toast/Toast.test.tsx +8 -7
- package/src/components/Toast/Toast.tsx +3 -3
- package/src/hooks/useToast.ts +11 -12
- package/dist/chunk-4OX5PXHX.js.map +0 -1
- package/dist/chunk-YUKG6PXE.js.map +0 -1
- /package/dist/{DataTable-YNEB5WDK.js.map → DataTable-H5KJCAIS.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.115](README.md) / Exports
|
|
2
2
|
|
|
3
|
-
# @jmruthers/pace-core - v0.5.
|
|
3
|
+
# @jmruthers/pace-core - v0.5.115
|
|
4
4
|
|
|
5
5
|
**`File`**
|
|
6
6
|
|
|
@@ -1572,7 +1572,7 @@ ___
|
|
|
1572
1572
|
|
|
1573
1573
|
#### Defined in
|
|
1574
1574
|
|
|
1575
|
-
[packages/core/src/components/Dialog/Dialog.tsx:
|
|
1575
|
+
[packages/core/src/components/Dialog/Dialog.tsx:707](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Dialog/Dialog.tsx#L707)
|
|
1576
1576
|
|
|
1577
1577
|
___
|
|
1578
1578
|
|
|
@@ -1592,7 +1592,7 @@ ___
|
|
|
1592
1592
|
|
|
1593
1593
|
#### Defined in
|
|
1594
1594
|
|
|
1595
|
-
[packages/core/src/components/Dialog/Dialog.tsx:
|
|
1595
|
+
[packages/core/src/components/Dialog/Dialog.tsx:742](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/Dialog/Dialog.tsx#L742)
|
|
1596
1596
|
|
|
1597
1597
|
___
|
|
1598
1598
|
|
|
@@ -4386,12 +4386,12 @@ Object with toast state and control methods
|
|
|
4386
4386
|
| Name | Type | Description |
|
|
4387
4387
|
| :------ | :------ | :------ |
|
|
4388
4388
|
| `toasts` | `ToasterToast`[] | Array of active toasts |
|
|
4389
|
-
| `toast` | (`props`: `Toast`) => \{ `id`: `string` = id; `dismiss`: () => `void` ; `update`: (`props`: `Partial`\<`Omit`\<`ToasterToast`, ``"id"``\>\>) => `void` } | Creates a new toast notification |
|
|
4389
|
+
| `toast` | (`props`: `Toast`) => \{ `id`: `string` = id; `dismiss`: () => `void` ; `update`: (`props`: `Partial`\<`Omit`\<`ToasterToast`, ``"id"`` \| ``"duration"``\>\>) => `void` } | Creates a new toast notification |
|
|
4390
4390
|
| `dismiss` | (`toastId?`: `string`) => `void` | - |
|
|
4391
4391
|
|
|
4392
4392
|
#### Defined in
|
|
4393
4393
|
|
|
4394
|
-
[packages/core/src/hooks/useToast.ts:
|
|
4394
|
+
[packages/core/src/hooks/useToast.ts:229](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useToast.ts#L229)
|
|
4395
4395
|
|
|
4396
4396
|
___
|
|
4397
4397
|
|
|
@@ -120,13 +120,16 @@ BEGIN
|
|
|
120
120
|
|
|
121
121
|
-- 4. Dynamic RBAC permission check (replaces manual organisation/event checks)
|
|
122
122
|
-- Use rbac_check_permission_simplified() for consistency with RLS policies
|
|
123
|
+
-- ⚠️ CRITICAL: Permission format must match what rbac_permissions_get returns
|
|
124
|
+
-- Format: 'operation:page.{pageName}' (e.g., 'read:page.dishes', 'create:page.meals')
|
|
125
|
+
-- The permission string is passed to rbac_permissions_get and must match exactly
|
|
123
126
|
IF NOT rbac_check_permission_simplified(
|
|
124
127
|
COALESCE(p_user_id, auth.uid()),
|
|
125
|
-
'read:
|
|
128
|
+
'read:page.dishes', -- Format: operation:page.{pageName} - MUST match rbac_permissions_get output
|
|
126
129
|
p_organisation_id,
|
|
127
|
-
|
|
130
|
+
p_event_id, -- p_event_id if event-scoped, NULL if org-scoped
|
|
128
131
|
(SELECT id FROM rbac_apps WHERE name = 'CAKE' LIMIT 1), -- p_app_id
|
|
129
|
-
'
|
|
132
|
+
'dishes' -- p_page_id (page name from rbac_app_pages)
|
|
130
133
|
) THEN
|
|
131
134
|
RETURN; -- No permission
|
|
132
135
|
END IF;
|
|
@@ -258,13 +261,15 @@ BEGIN
|
|
|
258
261
|
END IF;
|
|
259
262
|
|
|
260
263
|
-- Use rbac_check_permission_simplified for dynamic RBAC checking
|
|
264
|
+
-- ⚠️ CRITICAL: Permission format must be 'operation:page.{pageName}'
|
|
265
|
+
-- This matches the format returned by rbac_permissions_get()
|
|
261
266
|
IF NOT rbac_check_permission_simplified(
|
|
262
267
|
p_user_id,
|
|
263
|
-
'read:meals',
|
|
268
|
+
'read:page.meals', -- Format: operation:page.{pageName}
|
|
264
269
|
p_organisation_id,
|
|
265
270
|
p_event_id,
|
|
266
271
|
(SELECT id FROM rbac_apps WHERE name = 'CAKE' LIMIT 1),
|
|
267
|
-
'meals'
|
|
272
|
+
'meals' -- Page name (resolved to page ID internally)
|
|
268
273
|
) THEN
|
|
269
274
|
RETURN; -- No permission
|
|
270
275
|
END IF;
|
|
@@ -376,11 +381,11 @@ CREATE POLICY "rbac_cake_meal_select" ON cake_meal
|
|
|
376
381
|
is_user_super_admin()
|
|
377
382
|
OR rbac_check_permission_simplified(
|
|
378
383
|
auth.uid(),
|
|
379
|
-
'read:meals',
|
|
384
|
+
'read:page.meals', -- Format: operation:page.{pageName}
|
|
380
385
|
organisation_id,
|
|
381
386
|
meal_event_id,
|
|
382
387
|
(SELECT id FROM rbac_apps WHERE name = 'CAKE' LIMIT 1),
|
|
383
|
-
'meals'
|
|
388
|
+
'meals' -- Page name
|
|
384
389
|
)
|
|
385
390
|
)
|
|
386
391
|
);
|
|
@@ -396,11 +401,11 @@ BEGIN
|
|
|
396
401
|
v_is_super_admin OR
|
|
397
402
|
rbac_check_permission_simplified(
|
|
398
403
|
p_user_id,
|
|
399
|
-
'read:meals',
|
|
404
|
+
'read:page.meals', -- Format: operation:page.{pageName}
|
|
400
405
|
p_organisation_id,
|
|
401
406
|
p_event_id,
|
|
402
407
|
(SELECT id FROM rbac_apps WHERE name = 'CAKE' LIMIT 1),
|
|
403
|
-
'meals'
|
|
408
|
+
'meals' -- Page name
|
|
404
409
|
)
|
|
405
410
|
) THEN
|
|
406
411
|
RETURN;
|
|
@@ -598,11 +603,91 @@ SELECT * FROM data_user_events_get(NULL, 'user-id', 'org-123');
|
|
|
598
603
|
-- Should return empty gracefully
|
|
599
604
|
```
|
|
600
605
|
|
|
606
|
+
## Permission Format
|
|
607
|
+
|
|
608
|
+
### ⚠️ CRITICAL: Correct Permission Format
|
|
609
|
+
|
|
610
|
+
**The permission string format is critical and must match exactly what `rbac_permissions_get()` returns.**
|
|
611
|
+
|
|
612
|
+
#### Correct Format
|
|
613
|
+
|
|
614
|
+
```sql
|
|
615
|
+
-- ✅ CORRECT: Format is 'operation:page.{pageName}'
|
|
616
|
+
rbac_check_permission_simplified(
|
|
617
|
+
p_user_id,
|
|
618
|
+
'create:page.dishes', -- Format: operation:page.{pageName}
|
|
619
|
+
p_organisation_id,
|
|
620
|
+
p_event_id,
|
|
621
|
+
v_app_id,
|
|
622
|
+
'dishes' -- Page name (resolved to page ID internally)
|
|
623
|
+
)
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
#### Common Mistakes
|
|
627
|
+
|
|
628
|
+
```sql
|
|
629
|
+
-- ❌ WRONG: Missing 'page.' prefix
|
|
630
|
+
'create:dishes'
|
|
631
|
+
|
|
632
|
+
-- ❌ WRONG: Wrong separator
|
|
633
|
+
'create:page/dishes'
|
|
634
|
+
|
|
635
|
+
-- ❌ WRONG: Wrong format entirely
|
|
636
|
+
'dishes:create'
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
#### How to Determine the Correct Format
|
|
640
|
+
|
|
641
|
+
1. **Check existing migrations** - Look at recent migrations that work
|
|
642
|
+
2. **Check RLS policies** - Use the same format as RLS policies for the same resource
|
|
643
|
+
3. **Verify with rbac_permissions_get** - The permission string must match what this function returns in the `permission_type` column
|
|
644
|
+
|
|
645
|
+
#### Examples by Operation Type
|
|
646
|
+
|
|
647
|
+
```sql
|
|
648
|
+
-- Page-based permissions (most common)
|
|
649
|
+
'read:page.dishes' -- Read dishes page
|
|
650
|
+
'create:page.dishes' -- Create dishes
|
|
651
|
+
'update:page.dishes' -- Update dishes
|
|
652
|
+
'delete:page.dishes' -- Delete dishes
|
|
653
|
+
|
|
654
|
+
'read:page.meals' -- Read meals page
|
|
655
|
+
'read:page.distribution' -- Read distribution page
|
|
656
|
+
'read:page.deliveries' -- Read deliveries page
|
|
657
|
+
|
|
658
|
+
-- File-based permissions (special case)
|
|
659
|
+
'read:files' -- Read files
|
|
660
|
+
'create:files' -- Create files
|
|
661
|
+
'delete:files' -- Delete files
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
#### Parameter Guidelines
|
|
665
|
+
|
|
666
|
+
```sql
|
|
667
|
+
rbac_check_permission_simplified(
|
|
668
|
+
p_user_id, -- User ID (required)
|
|
669
|
+
'create:page.dishes', -- Permission string (format: operation:page.{pageName})
|
|
670
|
+
p_organisation_id, -- Organisation ID (required for non-super-admin)
|
|
671
|
+
p_event_id, -- Event ID (optional, for event-scoped permissions)
|
|
672
|
+
v_app_id, -- App ID (required, usually CAKE app)
|
|
673
|
+
'dishes' -- Page name (required, matches the page name in rbac_app_pages)
|
|
674
|
+
)
|
|
675
|
+
```
|
|
676
|
+
|
|
601
677
|
## Migration Guidelines
|
|
602
678
|
|
|
603
679
|
### Creating New Functions
|
|
604
680
|
|
|
605
|
-
1. **Create migration file**:
|
|
681
|
+
1. **Create migration file with correct timestamp**:
|
|
682
|
+
```bash
|
|
683
|
+
# Generate timestamp: YYYYMMDDHHMMSS
|
|
684
|
+
date +%Y%m%d%H%M%S
|
|
685
|
+
# Example output: 20251104113510
|
|
686
|
+
|
|
687
|
+
# Create file: supabase/migrations/20251104113510_descriptive_name.sql
|
|
688
|
+
```
|
|
689
|
+
⚠️ **CRITICAL**: Always generate a NEW timestamp for each migration. Never reuse timestamps from previous migrations, even if they haven't been pushed yet.
|
|
690
|
+
|
|
606
691
|
2. **Add function**: Use standard template above
|
|
607
692
|
3. **Add comments**: Document purpose, parameters, returns
|
|
608
693
|
4. **Add grants**: `GRANT EXECUTE ON FUNCTION ... TO authenticated;`
|
|
@@ -610,6 +695,28 @@ SELECT * FROM data_user_events_get(NULL, 'user-id', 'org-123');
|
|
|
610
695
|
6. **Regenerate types**: Run `npm run generate-types` to automatically generate TypeScript types from the database schema
|
|
611
696
|
7. **Verify types**: Check that `Database['public']['Functions']['function_name']` exists in `packages/core/src/types/database.generated.ts`
|
|
612
697
|
|
|
698
|
+
### ⚠️ Common Migration Mistakes
|
|
699
|
+
|
|
700
|
+
1. **Reusing old migration timestamps**:
|
|
701
|
+
- ❌ **WRONG**: Reusing `20251104113047` if it's already been pushed
|
|
702
|
+
- ✅ **CORRECT**: Generate new timestamp: `date +%Y%m%d%H%M%S` → `20251104113510`
|
|
703
|
+
- Always create a NEW file with a NEW timestamp for each migration
|
|
704
|
+
|
|
705
|
+
2. **Wrong permission format**:
|
|
706
|
+
- ❌ **WRONG**: `'create:dishes'` or `'read:meals'`
|
|
707
|
+
- ✅ **CORRECT**: `'create:page.dishes'` or `'read:page.meals'`
|
|
708
|
+
- Always use `'operation:page.{pageName}'` format, not `'operation:resource'`
|
|
709
|
+
- The format must match exactly what `rbac_permissions_get()` returns
|
|
710
|
+
|
|
711
|
+
3. **Missing page_id parameter**: Always provide the page name as the last parameter (e.g., `'dishes'`, `'meals'`, `'distribution'`)
|
|
712
|
+
|
|
713
|
+
4. **Ambiguous column references**:
|
|
714
|
+
- ❌ **WRONG**: `SELECT mealtype_name FROM cake_mealtype`
|
|
715
|
+
- ✅ **CORRECT**: `SELECT cake_mealtype.mealtype_name FROM cake_mealtype`
|
|
716
|
+
- Always fully qualify table names when there might be ambiguity
|
|
717
|
+
|
|
718
|
+
5. **Not checking existing migrations**: Before creating a new migration, check if a similar one already exists to avoid duplicates
|
|
719
|
+
|
|
613
720
|
### Updating Existing Functions
|
|
614
721
|
|
|
615
722
|
1. **Use `CREATE OR REPLACE FUNCTION`** - Ensures idempotency
|
|
@@ -735,6 +842,7 @@ $$;
|
|
|
735
842
|
|
|
736
843
|
When creating or reviewing an RPC function, ensure:
|
|
737
844
|
|
|
845
|
+
### Function Structure
|
|
738
846
|
- ✅ Follows naming convention: `<family>_<domain>_<verb>`
|
|
739
847
|
- ✅ Uses `SECURITY DEFINER`
|
|
740
848
|
- ✅ Sets `search_path TO 'public'`
|
|
@@ -742,7 +850,7 @@ When creating or reviewing an RPC function, ensure:
|
|
|
742
850
|
- ✅ Checks super_admin status (if applicable)
|
|
743
851
|
- ✅ Validates organisation membership (if applicable)
|
|
744
852
|
- ✅ Validates event access (if event-scoped)
|
|
745
|
-
- ✅ Uses proper error handling
|
|
853
|
+
- ✅ Uses proper error handling with `EXCEPTION WHEN OTHERS`
|
|
746
854
|
- ✅ Returns empty on error (fail-secure)
|
|
747
855
|
- ✅ Has documentation comments
|
|
748
856
|
- ✅ Uses descriptive parameter names (`p_` prefix)
|
|
@@ -751,6 +859,18 @@ When creating or reviewing an RPC function, ensure:
|
|
|
751
859
|
- ✅ Includes `GRANT EXECUTE` statement
|
|
752
860
|
- ✅ Tested with various scenarios
|
|
753
861
|
|
|
862
|
+
### ⚠️ Critical Permission Format
|
|
863
|
+
- ✅ **Permission format is correct**: `'operation:page.{pageName}'` (e.g., `'create:page.dishes'`, `'read:page.meals'`)
|
|
864
|
+
- ✅ **NOT using wrong format**: `'operation:resource'` (e.g., `'create:dishes'`, `'read:meals'`)
|
|
865
|
+
- ✅ **Page name parameter provided**: Last parameter is the page name (e.g., `'dishes'`, `'meals'`)
|
|
866
|
+
- ✅ **Permission format matches rbac_permissions_get output**: Verify by checking existing working migrations
|
|
867
|
+
|
|
868
|
+
### ⚠️ Migration File Requirements
|
|
869
|
+
- ✅ **New timestamp generated**: Run `date +%Y%m%d%H%M%S` to get current timestamp
|
|
870
|
+
- ✅ **New file created**: Never reuse timestamps from previous migrations
|
|
871
|
+
- ✅ **File naming**: `YYYYMMDDHHMMSS_descriptive_name.sql`
|
|
872
|
+
- ✅ **No ambiguous column references**: Fully qualify table names (e.g., `cake_mealtype.mealtype_name`)
|
|
873
|
+
|
|
754
874
|
## References
|
|
755
875
|
|
|
756
876
|
- [RBAC System Documentation](../core-concepts/rbac-system.md)
|
package/package.json
CHANGED
|
@@ -1053,21 +1053,9 @@ function DataTableInternal<TData extends DataRecord>({
|
|
|
1053
1053
|
accessorFn: hasAccessorFn ? (originalCol as any).accessorFn : undefined,
|
|
1054
1054
|
});
|
|
1055
1055
|
|
|
1056
|
-
//
|
|
1057
|
-
//
|
|
1058
|
-
|
|
1059
|
-
// Use the same string fallback logic as the display column to ensure
|
|
1060
|
-
// JSX headers are converted to strings (e.g., accessorKey or column ID)
|
|
1061
|
-
// This prevents "[object Object] (ID)" in the CSV header
|
|
1062
|
-
const idHeader = `${displayHeader} (ID)`;
|
|
1063
|
-
visibleColumns.push({
|
|
1064
|
-
id: editAccessorKey,
|
|
1065
|
-
accessorKey: editAccessorKey,
|
|
1066
|
-
header: idHeader,
|
|
1067
|
-
isIdColumn: true,
|
|
1068
|
-
editAccessorKey: editAccessorKey,
|
|
1069
|
-
});
|
|
1070
|
-
}
|
|
1056
|
+
// Note: We do NOT export editAccessorKey fields as separate columns
|
|
1057
|
+
// Only visible columns (with their display values via accessorFn) are exported
|
|
1058
|
+
// This ensures exports match what users see in the table
|
|
1071
1059
|
});
|
|
1072
1060
|
|
|
1073
1061
|
// Generate filename with timestamp
|
|
@@ -125,6 +125,23 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
|
|
|
125
125
|
};
|
|
126
126
|
}, []);
|
|
127
127
|
|
|
128
|
+
// Reset state when modal opens/closes to ensure clean initial state
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
if (!isOpen) {
|
|
131
|
+
// Reset all state when modal is closed
|
|
132
|
+
setFile(null);
|
|
133
|
+
setPreviewData(null);
|
|
134
|
+
setTotalCount(0);
|
|
135
|
+
setError(null);
|
|
136
|
+
setValidationErrors([]);
|
|
137
|
+
setIsProcessing(false);
|
|
138
|
+
// Reset file input
|
|
139
|
+
if (fileInputRef.current) {
|
|
140
|
+
fileInputRef.current.value = '';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}, [isOpen]);
|
|
144
|
+
|
|
128
145
|
// Extract config with defaults
|
|
129
146
|
const {
|
|
130
147
|
title = 'Import Data',
|
|
@@ -321,7 +338,7 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
|
|
|
321
338
|
)}
|
|
322
339
|
|
|
323
340
|
|
|
324
|
-
{previewData && previewData.length > 0
|
|
341
|
+
{file && previewData && previewData.length > 0 ? (
|
|
325
342
|
<div className="space-y-3">
|
|
326
343
|
<h4 className="text-sec-900">{previewHeaderText}</h4>
|
|
327
344
|
<div className="border rounded-lg overflow-hidden">
|
|
@@ -354,7 +371,13 @@ export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportMo
|
|
|
354
371
|
{totalRowsText.replace('{count}', totalCount.toString())}
|
|
355
372
|
</p>
|
|
356
373
|
</div>
|
|
357
|
-
)
|
|
374
|
+
) : !file ? (
|
|
375
|
+
<div className="border rounded-lg p-6 text-center bg-sec-50">
|
|
376
|
+
<p className="text-sec-500">
|
|
377
|
+
Select a CSV file to preview
|
|
378
|
+
</p>
|
|
379
|
+
</div>
|
|
380
|
+
) : null}
|
|
358
381
|
|
|
359
382
|
<div className="flex justify-end gap-2">
|
|
360
383
|
<Button variant="outline" onClick={handleClose}>
|
|
@@ -694,8 +694,9 @@ const DialogFooter = ({
|
|
|
694
694
|
}: DialogFooterProps) => (
|
|
695
695
|
<footer
|
|
696
696
|
className={cn(
|
|
697
|
-
|
|
698
|
-
|
|
697
|
+
// Only apply default layout classes if no custom className is provided
|
|
698
|
+
!className && 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
|
|
699
|
+
!className && (sticky ? 'sticky bottom-0 z-10 bg-background p-6 pt-4 border-t' : 'p-6 pt-4'),
|
|
699
700
|
className
|
|
700
701
|
)}
|
|
701
702
|
{...props}
|