fe9d6f34ff
# Introduction
In this PR we're refactoring the `FlatEntity` type to become a superset
of the `UniversalFlatEntity`.
Right now we're storing all the extra properties in `__universal`
property, at some point it might just be sibling to other entity and we
might rely on the `propertiesToCompare` constants and TypeScript
allowing passing a superset type into a smaller subset type
## FromTo utils
The entity to flat entity method now computes the universal information,
standardized a typing and pattern to do
## Example
Also strictly type
```ts
"bbb019ea-6205-498c-aea5-67bc53bce8a9": {
"workspaceId": "20202020-1c25-4d02-bf25-6aeccf7ea419",
"universalIdentifier": "20202020-d111-4d11-8d11-da5ab0a11002",
"applicationId": "d01b010d-b984-465b-b40b-370e954e5188",
"id": "bbb019ea-6205-498c-aea5-67bc53bce8a9",
"pageLayoutTabId": "791a512f-169f-4209-b731-aa86716668c6",
"title": "Deals by Company",
"type": "GRAPH",
"objectMetadataId": "9e14efea-df5b-4c0e-aba9-cfe455f32397",
"gridPosition": { "row": 0, "column": 6, "rowSpan": 6, "columnSpan": 6 },
"configuration": {
"color": "orange",
"orderBy": "FIELD_ASC",
"timezone": "UTC",
"displayLegend": true,
"displayDataLabel": false,
"showCenterMetric": true,
"configurationType": "PIE_CHART",
"firstDayOfTheWeek": 0,
"aggregateOperation": "COUNT",
"groupBySubFieldName": "name",
"groupByFieldMetadataId": "6673ff18-63d2-47a1-8f85-2b9b09ca27a5",
"aggregateFieldMetadataId": "8d64ee41-5dd4-4de6-945a-7c0c18399715"
},
"createdAt": "2026-01-28T14:08:52.140Z",
"updatedAt": "2026-01-28T14:08:52.140Z",
"deletedAt": null,
"__universal": {
"universalIdentifier": "20202020-d111-4d11-8d11-da5ab0a11002",
"applicationUniversalIdentifier": "20202020-64aa-4b6f-b003-9c74b97cee20",
"pageLayoutTabUniversalIdentifier": "20202020-d011-4d11-8d11-da5ab0a01001",
"objectMetadataUniversalIdentifier": "20202020-9549-49dd-b2b2-883999db8938",
"gridPosition": {
"row": 0,
"column": 6,
"rowSpan": 6,
"columnSpan": 6
},
"configuration": {
"color": "orange",
"orderBy": "FIELD_ASC",
"timezone": "UTC",
"displayLegend": true,
"displayDataLabel": false,
"showCenterMetric": true,
"configurationType": "PIE_CHART",
"firstDayOfTheWeek": 0,
"aggregateOperation": "COUNT",
"groupBySubFieldName": "name",
"aggregateFieldMetadataUniversalIdentifier": "20202020-d01a-4131-8a31-f123456789ab",
"groupByFieldMetadataUniversalIdentifier": "20202020-cbac-457e-b565-adece5fc815f"
}
}
},
```
73 lines
3.0 KiB
TypeScript
73 lines
3.0 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
|
|
import { Repository } from 'typeorm';
|
|
|
|
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
|
|
|
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
|
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
|
import { FlatViewGroupMaps } from 'src/engine/metadata-modules/flat-view-group/types/flat-view-group-maps.type';
|
|
import { fromViewGroupEntityToFlatViewGroup } from 'src/engine/metadata-modules/flat-view-group/utils/from-view-group-entity-to-flat-view-group.util';
|
|
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
|
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
|
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
|
import { createIdToUniversalIdentifierMap } from 'src/engine/workspace-cache/utils/create-id-to-universal-identifier-map.util';
|
|
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
|
|
|
@Injectable()
|
|
@WorkspaceCache('flatViewGroupMaps')
|
|
export class WorkspaceFlatViewGroupMapCacheService extends WorkspaceCacheProvider<FlatViewGroupMaps> {
|
|
constructor(
|
|
@InjectRepository(ViewGroupEntity)
|
|
private readonly viewGroupRepository: Repository<ViewGroupEntity>,
|
|
@InjectRepository(ApplicationEntity)
|
|
private readonly applicationRepository: Repository<ApplicationEntity>,
|
|
@InjectRepository(ViewEntity)
|
|
private readonly viewRepository: Repository<ViewEntity>,
|
|
) {
|
|
super();
|
|
}
|
|
|
|
async computeForCache(workspaceId: string): Promise<FlatViewGroupMaps> {
|
|
const [viewGroups, applications, views] = await Promise.all([
|
|
this.viewGroupRepository.find({
|
|
where: { workspaceId },
|
|
withDeleted: true,
|
|
}),
|
|
this.applicationRepository.find({
|
|
where: { workspaceId },
|
|
select: ['id', 'universalIdentifier'],
|
|
withDeleted: true,
|
|
}),
|
|
this.viewRepository.find({
|
|
where: { workspaceId },
|
|
select: ['id', 'universalIdentifier'],
|
|
withDeleted: true,
|
|
}),
|
|
]);
|
|
|
|
const applicationIdToUniversalIdentifierMap =
|
|
createIdToUniversalIdentifierMap(applications);
|
|
const viewIdToUniversalIdentifierMap =
|
|
createIdToUniversalIdentifierMap(views);
|
|
|
|
const flatViewGroupMaps = createEmptyFlatEntityMaps();
|
|
|
|
for (const viewGroupEntity of viewGroups) {
|
|
const flatViewGroup = fromViewGroupEntityToFlatViewGroup({
|
|
entity: viewGroupEntity,
|
|
applicationIdToUniversalIdentifierMap,
|
|
viewIdToUniversalIdentifierMap,
|
|
});
|
|
|
|
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
|
|
flatEntity: flatViewGroup,
|
|
flatEntityMapsToMutate: flatViewGroupMaps,
|
|
});
|
|
}
|
|
|
|
return flatViewGroupMaps;
|
|
}
|
|
}
|