ViewGroup and ViewFilters side effect in v2 (#15096)

# Introduction

### Summary
Implements side effect handling for `ViewGroup` and `ViewFilters` when
field metadata is updated in the v2 architecture. This ensures that
view-related records are properly maintained when enum field options are
modified, deleted, or created.

### Side effects
- **Side Effect System**: Added side effect handling for field metadata
updates that manages related view groups and view filters
- **Enum Field Updates**: When enum field options are modified, the
system now:
- **View Groups**: Creates new groups for added options, updates
existing groups for modified options, and deletes groups for removed
options
- **View Filters**: Updates filter values to reflect option changes and
removes filters that reference deleted options

### Enum runner fix
Update now works for both atomic enum and array enum ( multi select for
instance )

### Compute flat entity maps from to
Standardized this method usage across v2 services
Next step is to require dependencies dynamically

## Conclusion
closes https://github.com/twentyhq/core-team-issues/issues/1649
This commit is contained in:
Paul Rastoin
2025-10-17 17:09:26 +02:00
committed by GitHub
parent 4f1623ff76
commit 3462a2e288
58 changed files with 3108 additions and 1075 deletions
@@ -0,0 +1,64 @@
import { type AllFlatEntities } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entities.type';
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/add-flat-entity-to-flat-entity-maps-or-throw.util';
import { deleteFlatEntityFromFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/delete-flat-entity-from-flat-entity-maps-or-throw.util';
import { getSubFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/get-sub-flat-entity-maps-or-throw.util';
import { replaceFlatEntityInFlatEntityMapsOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/replace-flat-entity-in-flat-entity-maps-or-throw.util';
type ComputeFlatEntityMapsFromToArgs<T extends AllFlatEntities> = {
flatEntityMaps: FlatEntityMaps<T>;
flatEntityToUpdate: T[];
flatEntityToCreate: T[];
flatEntityToDelete: T[];
};
export const computeFlatEntityMapsFromTo = <T extends AllFlatEntities>({
flatEntityMaps,
flatEntityToCreate,
flatEntityToDelete,
flatEntityToUpdate,
}: ComputeFlatEntityMapsFromToArgs<T>): {
from: FlatEntityMaps<T>;
to: FlatEntityMaps<T>;
} => {
const fromFlatEntityMaps =
flatEntityToDelete.length > 0
? getSubFlatEntityMapsOrThrow({
flatEntityIds: [...flatEntityToDelete, ...flatEntityToUpdate].map(
({ id }) => id,
),
flatEntityMaps,
})
: flatEntityMaps;
const toFlatEntityMapsWithDeleted = flatEntityToDelete.reduce(
(flatEntityMaps, flatEntity) =>
deleteFlatEntityFromFlatEntityMapsOrThrow({
entityToDeleteId: flatEntity.id,
flatEntityMaps,
}),
fromFlatEntityMaps,
);
const toFlatEntityMapsWithUpdated = flatEntityToUpdate.reduce(
(flatEntityMaps, flatEntity) =>
replaceFlatEntityInFlatEntityMapsOrThrow({
flatEntity,
flatEntityMaps,
}),
toFlatEntityMapsWithDeleted,
);
const toFlatEntityMaps = flatEntityToCreate.reduce(
(flatEntityMaps, flatEntity) =>
addFlatEntityToFlatEntityMapsOrThrow({
flatEntity,
flatEntityMaps,
}),
toFlatEntityMapsWithUpdated,
);
return {
from: fromFlatEntityMaps,
to: toFlatEntityMaps,
};
};