Move filter group destruction after filter operations (#22248)
### The current order is: 1. Create filter groups 2. Update filter groups 3. Destroy filter groups ← **happens here** 4. Clean up store (cascade) 5. Create/update/delete filters (which may reference groups just destroyed) The fix is to move filter group destruction after filter operations, so filters that reference those groups get created/updated/deleted first. ### after fix : The persistence order is now: 1. Create filter groups 2. Update filter groups 3. Create/update/delete view filters (these can safely reference groups that still exist) 4. Destroy filter groups (only after all filter mutations are done) 5. Clean up store (cascade-deleted filters **root cause :** step 4 happened before step 3, so filter creates/updates would reference groups that had already been deleted in the same save cycle ; causing the backend to fail with "Migration execution failed" when it couldn't resolve the `viewFilterGroupId `foreign key. this fixes the bug : #21351 <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22248?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Co-authored-by: Souheyl Gouadria <souheyl.gouadria@medius.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
+16
-15
@@ -89,21 +89,6 @@ export const useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters =
|
||||
currentView,
|
||||
);
|
||||
await performViewFilterGroupAPIUpdate(viewFilterGroupsToUpdate);
|
||||
await performViewFilterGroupAPIDestroy(viewFilterGroupIdsToDestroy);
|
||||
|
||||
// Mirror the DB cascade: remove cascade-deleted viewFilters from the store
|
||||
if (viewFilterGroupIdsToDestroy.length > 0) {
|
||||
const destroyedIdsSet = new Set(viewFilterGroupIdsToDestroy);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('viewFilters'), (prev) => ({
|
||||
...prev,
|
||||
current: (prev.current as FlatViewFilter[]).filter(
|
||||
(viewFilter) =>
|
||||
!isDefined(viewFilter.viewFilterGroupId) ||
|
||||
!destroyedIdsSet.has(viewFilter.viewFilterGroupId),
|
||||
),
|
||||
}));
|
||||
}
|
||||
|
||||
const currentViewFilters = currentView.viewFilters ?? [];
|
||||
const currentRecordFilters = store.get(
|
||||
@@ -195,6 +180,22 @@ export const useSaveRecordFiltersAndGroupFiltersToViewFiltersAndGroupFilters =
|
||||
if (deleteResult.status === 'failed') {
|
||||
return;
|
||||
}
|
||||
|
||||
await performViewFilterGroupAPIDestroy(viewFilterGroupIdsToDestroy);
|
||||
|
||||
// Mirror the DB cascade: remove cascade-deleted viewFilters from the store
|
||||
if (viewFilterGroupIdsToDestroy.length > 0) {
|
||||
const destroyedIdsSet = new Set(viewFilterGroupIdsToDestroy);
|
||||
|
||||
store.set(metadataStoreState.atomFamily('viewFilters'), (prev) => ({
|
||||
...prev,
|
||||
current: (prev.current as FlatViewFilter[]).filter(
|
||||
(viewFilter) =>
|
||||
!isDefined(viewFilter.viewFilterGroupId) ||
|
||||
!destroyedIdsSet.has(viewFilter.viewFilterGroupId),
|
||||
),
|
||||
}));
|
||||
}
|
||||
}, [
|
||||
canPersistChanges,
|
||||
currentView,
|
||||
|
||||
Reference in New Issue
Block a user