Files
twenty/packages/twenty-server/src/engine/metadata-modules/flat-view-group/utils/compute-flat-view-groups-on-view-create.util.ts
T
Paul Rastoin 476bdf764c Refactor flat entity maps to be universal oriented (#17665)
# Introduction
In preparation of the workspace agnostic builder, we're migrating
`FlatEntityMaps` to be universal identifier oriented and based
As in the builder context there're won't be any ids at all
Please also note that the FlatEntity is a UniversalFlatEntity superset

From
```ts
import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-from.type';

export type FlatEntityMaps<T extends SyncableFlatEntity> = {
  byId: Partial<Record<string, T>>;
  idByUniversalIdentifier: Partial<Record<string, string>>;
  universalIdentifiersByApplicationId: Partial<Record<string, string[]>>;
};
```

To
```ts
export type FlatEntityMaps<
  T extends SyncableFlatEntity | UniversalSyncableFlatEntity,
> = {
  byUniversalIdentifier: Partial<Record<string, T>>;
  universalIdentifierById: Partial<Record<string, string>>;
  universalIdentifiersByApplicationId: Partial<Record<string, string[]>>; // this might make more sense to be migrated to universalIdentifiersByApplicationUniversalIdentifier but it's the main topic of this PR
};
```

## Low level maps tools
Had to refactor find | create | delete | replace | find-many | get-sub
tools ( through mutations and or throw equivalent )
2026-02-03 16:16:02 +00:00

81 lines
2.7 KiB
TypeScript

import { VIEW_GROUP_VISIBLE_OPTIONS_MAX } from 'twenty-shared/constants';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import {
FlatEntityMapsException,
FlatEntityMapsExceptionCode,
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
import { type FlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group.type';
type ComputeFlatViewGroupsOnViewCreateArgs = {
flatViewToCreateId: string;
mainGroupByFieldMetadataId: string;
} & Pick<AllFlatEntityMaps, 'flatFieldMetadataMaps'>;
export const computeFlatViewGroupsOnViewCreate = ({
flatViewToCreateId,
mainGroupByFieldMetadataId,
flatFieldMetadataMaps,
}: ComputeFlatViewGroupsOnViewCreateArgs): FlatViewGroup[] => {
const mainGroupByFieldMetadata = findFlatEntityByIdInFlatEntityMaps({
flatEntityId: mainGroupByFieldMetadataId,
flatEntityMaps: flatFieldMetadataMaps,
});
if (!isDefined(mainGroupByFieldMetadata)) {
throw new FlatEntityMapsException(
'mainGroupByFieldMetadataId not found',
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
);
}
const createdAt = new Date().toISOString();
const flatViewGroupsFromOptions: FlatViewGroup[] = (
mainGroupByFieldMetadata.options ?? []
).map((option, index) => {
const viewGroupId = v4();
return {
id: viewGroupId,
fieldMetadataId: mainGroupByFieldMetadata.id,
viewId: flatViewToCreateId,
workspaceId: mainGroupByFieldMetadata.workspaceId,
createdAt,
updatedAt: createdAt,
deletedAt: null,
universalIdentifier: viewGroupId,
isVisible: index < VIEW_GROUP_VISIBLE_OPTIONS_MAX,
fieldValue: option.value,
position: index,
applicationId: mainGroupByFieldMetadata.applicationId,
};
});
const flatViewGroups: FlatViewGroup[] = [...flatViewGroupsFromOptions];
if (mainGroupByFieldMetadata.isNullable === true) {
const emptyGroupId = v4();
const emptyGroupPosition = flatViewGroupsFromOptions.length;
flatViewGroups.push({
id: emptyGroupId,
viewId: flatViewToCreateId,
workspaceId: mainGroupByFieldMetadata.workspaceId,
createdAt,
updatedAt: createdAt,
deletedAt: null,
universalIdentifier: emptyGroupId,
isVisible: emptyGroupPosition < VIEW_GROUP_VISIBLE_OPTIONS_MAX,
fieldValue: '',
position: emptyGroupPosition,
applicationId: mainGroupByFieldMetadata.applicationId,
});
}
return flatViewGroups;
};