3462a2e288
# 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
62 lines
1.6 KiB
TypeScript
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;
|
|
};
|