Files
twenty/packages/twenty-server/src/engine/metadata-modules/flat-field-metadata/utils/compare-two-flat-field-metadata-enum-options.util.ts
T
Paul Rastoin 3462a2e288 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
2025-10-17 17:09:26 +02:00

62 lines
1.6 KiB
TypeScript

import { type EnumFieldMetadataType, type FromTo } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
type FieldMetadataEnumOptions =
FlatFieldMetadata<EnumFieldMetadataType>['options'];
type Differences<T> = {
created: T[];
updated: { from: T; to: T }[];
deleted: T[];
};
export type CompareToFlatFieldMetadataEnumOptionsArgs = FromTo<
FieldMetadataEnumOptions,
'options'
> & {
compareLabel: boolean;
};
export const compareTwoFlatFieldMetadataEnumOptions = ({
compareLabel = false,
fromOptions,
toOptions,
}: CompareToFlatFieldMetadataEnumOptionsArgs): Differences<
FieldMetadataEnumOptions[number]
> => {
const differences: Differences<FieldMetadataEnumOptions[number]> = {
created: [],
updated: [],
deleted: [],
};
const fromOptionsMap = new Map(fromOptions.map((opt) => [opt.id, opt]));
for (const newOption of toOptions) {
const oldOption = fromOptionsMap.get(newOption.id);
if (!isDefined(oldOption)) {
differences.created.push(newOption);
continue;
}
if (
oldOption.value !== newOption.value ||
(compareLabel && oldOption.label !== newOption.label)
) {
differences.updated.push({ from: oldOption, to: newOption });
continue;
}
}
const toOptionsMap = new Map(toOptions.map((opt) => [opt.id, opt]));
for (const oldOption of fromOptions) {
if (!toOptionsMap.has(oldOption.id)) {
differences.deleted.push(oldOption);
}
}
return differences;
};