Skip to content

Commit 435e21d

Browse files
authored
[FRONT COMPONENTS] Serialize relation between widget and front component (#18228)
This allows us to define page layout widgets of type front component in an app with the front component universal identifier.
1 parent 4482415 commit 435e21d

15 files changed

+118
-5
lines changed

packages/twenty-server/src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { TypeOrmModule } from '@nestjs/typeorm';
33

44
import { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
55
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
6+
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
67
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
78
import { WorkspaceFlatFieldMetadataMapCacheService } from 'src/engine/metadata-modules/flat-field-metadata/services/workspace-flat-field-metadata-map-cache.service';
89
import { WorkspaceFlatIndexMapCacheService } from 'src/engine/metadata-modules/flat-index-metadata/services/workspace-flat-index-map-cache.service';
@@ -56,6 +57,7 @@ import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache
5657
RowLevelPermissionPredicateGroupEntity,
5758
ApplicationEntity,
5859
RoleEntity,
60+
FrontComponentEntity,
5961
]),
6062
],
6163
providers: [

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/flat-page-layout-widget.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { ApplicationEntity } from 'src/engine/core-modules/application/applicati
55
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
66
import { FlatPageLayoutWidgetTypeValidatorService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/flat-page-layout-widget-type-validator.service';
77
import { WorkspaceFlatPageLayoutWidgetMapCacheService } from 'src/engine/metadata-modules/flat-page-layout-widget/services/workspace-flat-page-layout-widget-map-cache.service';
8+
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
89
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
910
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
1011
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
@@ -18,6 +19,7 @@ import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entit
1819
PageLayoutTabEntity,
1920
ObjectMetadataEntity,
2021
FieldMetadataEntity,
22+
FrontComponentEntity,
2123
ViewEntity,
2224
]),
2325
],

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/services/workspace-flat-page-layout-widget-map-cache.service.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/
1010
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
1111
import { FlatPageLayoutWidgetMaps } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget-maps.type';
1212
import { fromPageLayoutWidgetEntityToFlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-entity-to-flat-page-layout-widget.util';
13+
import { FrontComponentEntity } from 'src/engine/metadata-modules/front-component/entities/front-component.entity';
1314
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
1415
import { PageLayoutTabEntity } from 'src/engine/metadata-modules/page-layout-tab/entities/page-layout-tab.entity';
1516
import { PageLayoutWidgetEntity } from 'src/engine/metadata-modules/page-layout-widget/entities/page-layout-widget.entity';
@@ -32,6 +33,8 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
3233
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
3334
@InjectRepository(FieldMetadataEntity)
3435
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
36+
@InjectRepository(FrontComponentEntity)
37+
private readonly frontComponentRepository: Repository<FrontComponentEntity>,
3538
@InjectRepository(ViewEntity)
3639
private readonly viewRepository: Repository<ViewEntity>,
3740
) {
@@ -47,6 +50,7 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
4750
pageLayoutTabs,
4851
objectMetadatas,
4952
fieldMetadatas,
53+
frontComponents,
5054
views,
5155
] = await Promise.all([
5256
this.pageLayoutWidgetRepository.find({
@@ -73,6 +77,11 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
7377
select: ['id', 'universalIdentifier'],
7478
withDeleted: true,
7579
}),
80+
this.frontComponentRepository.find({
81+
where: { workspaceId },
82+
select: ['id', 'universalIdentifier'],
83+
withDeleted: true,
84+
}),
7685
this.viewRepository.find({
7786
where: { workspaceId },
7887
select: ['id', 'universalIdentifier'],
@@ -89,6 +98,9 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
8998
const fieldMetadataUniversalIdentifierById = Object.fromEntries(
9099
createIdToUniversalIdentifierMap(fieldMetadatas),
91100
);
101+
const frontComponentUniversalIdentifierById = Object.fromEntries(
102+
createIdToUniversalIdentifierMap(frontComponents),
103+
);
92104
const viewUniversalIdentifierById = Object.fromEntries(
93105
createIdToUniversalIdentifierMap(views),
94106
);
@@ -103,6 +115,7 @@ export class WorkspaceFlatPageLayoutWidgetMapCacheService extends WorkspaceCache
103115
pageLayoutTabIdToUniversalIdentifierMap,
104116
objectMetadataIdToUniversalIdentifierMap,
105117
fieldMetadataUniversalIdentifierById,
118+
frontComponentUniversalIdentifierById,
106119
viewUniversalIdentifierById,
107120
});
108121

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-create-page-layout-widget-input-to-flat-page-layout-widget-to-create.util.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export type FromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreateArgs =
1919
| 'flatPageLayoutTabMaps'
2020
| 'flatObjectMetadataMaps'
2121
| 'flatFieldMetadataMaps'
22+
| 'flatFrontComponentMaps'
2223
| 'flatViewFieldGroupMaps'
2324
| 'flatViewMaps'
2425
>;
@@ -30,6 +31,7 @@ export const fromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreate = ({
3031
flatPageLayoutTabMaps,
3132
flatObjectMetadataMaps,
3233
flatFieldMetadataMaps,
34+
flatFrontComponentMaps,
3335
flatViewFieldGroupMaps,
3436
flatViewMaps,
3537
}: FromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreateArgs): FlatPageLayoutWidget => {
@@ -82,6 +84,8 @@ export const fromCreatePageLayoutWidgetInputToFlatPageLayoutWidgetToCreate = ({
8284
configuration: createPageLayoutWidgetInput.configuration,
8385
fieldMetadataUniversalIdentifierById:
8486
flatFieldMetadataMaps.universalIdentifierById,
87+
frontComponentUniversalIdentifierById:
88+
flatFrontComponentMaps.universalIdentifierById,
8589
viewFieldGroupUniversalIdentifierById:
8690
flatViewFieldGroupMaps.universalIdentifierById,
8791
viewUniversalIdentifierById: flatViewMaps.universalIdentifierById,

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-configuration-to-universal-configuration.util.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,14 @@ const convertChartFilterToUniversalFilter = ({
7373
export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({
7474
configuration,
7575
fieldMetadataUniversalIdentifierById,
76+
frontComponentUniversalIdentifierById = {},
7677
viewFieldGroupUniversalIdentifierById = {},
7778
viewUniversalIdentifierById = {},
7879
shouldThrowOnMissingIdentifier = false,
7980
}: {
8081
configuration: PageLayoutWidgetConfiguration;
8182
fieldMetadataUniversalIdentifierById: Partial<Record<string, string>>;
83+
frontComponentUniversalIdentifierById?: Partial<Record<string, string>>;
8284
viewFieldGroupUniversalIdentifierById?: Partial<Record<string, string>>;
8385
viewUniversalIdentifierById?: Partial<Record<string, string>>;
8486
shouldThrowOnMissingIdentifier?: boolean;
@@ -326,6 +328,28 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({
326328
};
327329
}
328330

331+
case WidgetConfigurationType.FRONT_COMPONENT: {
332+
const { frontComponentId, ...rest } = configuration;
333+
334+
const frontComponentUniversalIdentifier: string | null =
335+
frontComponentUniversalIdentifierById[frontComponentId] ?? null;
336+
337+
if (
338+
!isDefined(frontComponentUniversalIdentifier) &&
339+
shouldThrowOnMissingIdentifier
340+
) {
341+
throw new FlatEntityMapsException(
342+
`Front component universal identifier not found for id: ${frontComponentId}`,
343+
FlatEntityMapsExceptionCode.RELATION_UNIVERSAL_IDENTIFIER_NOT_FOUND,
344+
);
345+
}
346+
347+
return {
348+
...rest,
349+
frontComponentUniversalIdentifier,
350+
};
351+
}
352+
329353
case WidgetConfigurationType.VIEW:
330354
case WidgetConfigurationType.FIELD:
331355
case WidgetConfigurationType.TIMELINE:
@@ -338,7 +362,6 @@ export const fromPageLayoutWidgetConfigurationToUniversalConfiguration = ({
338362
case WidgetConfigurationType.WORKFLOW:
339363
case WidgetConfigurationType.WORKFLOW_VERSION:
340364
case WidgetConfigurationType.WORKFLOW_RUN:
341-
case WidgetConfigurationType.FRONT_COMPONENT:
342365
case WidgetConfigurationType.IFRAME:
343366
case WidgetConfigurationType.STANDALONE_RICH_TEXT:
344367
return configuration;

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-page-layout-widget-entity-to-flat-page-layout-widget.util.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { type FromEntityToFlatEntityArgs } from 'src/engine/workspace-cache/type
1212
type FromPageLayoutWidgetEntityToFlatPageLayoutWidgetArgs =
1313
FromEntityToFlatEntityArgs<'pageLayoutWidget'> & {
1414
fieldMetadataUniversalIdentifierById: Partial<Record<string, string>>;
15+
frontComponentUniversalIdentifierById?: Partial<Record<string, string>>;
1516
viewFieldGroupUniversalIdentifierById?: Partial<Record<string, string>>;
1617
viewUniversalIdentifierById?: Partial<Record<string, string>>;
1718
};
@@ -22,6 +23,7 @@ export const fromPageLayoutWidgetEntityToFlatPageLayoutWidget = ({
2223
pageLayoutTabIdToUniversalIdentifierMap,
2324
objectMetadataIdToUniversalIdentifierMap,
2425
fieldMetadataUniversalIdentifierById,
26+
frontComponentUniversalIdentifierById,
2527
viewFieldGroupUniversalIdentifierById,
2628
viewUniversalIdentifierById,
2729
}: FromPageLayoutWidgetEntityToFlatPageLayoutWidgetArgs): FlatPageLayoutWidget => {
@@ -74,6 +76,7 @@ export const fromPageLayoutWidgetEntityToFlatPageLayoutWidget = ({
7476
fromPageLayoutWidgetConfigurationToUniversalConfiguration({
7577
configuration: pageLayoutWidgetEntityWithoutRelations.configuration,
7678
fieldMetadataUniversalIdentifierById,
79+
frontComponentUniversalIdentifierById,
7780
viewFieldGroupUniversalIdentifierById,
7881
viewUniversalIdentifierById,
7982
});

packages/twenty-server/src/engine/metadata-modules/flat-page-layout-widget/utils/from-update-page-layout-widget-input-to-flat-page-layout-widget-to-update-or-throw.util.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export const fromUpdatePageLayoutWidgetInputToFlatPageLayoutWidgetToUpdateOrThro
3030
flatPageLayoutWidgetMaps,
3131
flatObjectMetadataMaps,
3232
flatFieldMetadataMaps,
33+
flatFrontComponentMaps,
3334
flatViewFieldGroupMaps,
3435
flatViewMaps,
3536
}: {
@@ -39,6 +40,7 @@ export const fromUpdatePageLayoutWidgetInputToFlatPageLayoutWidgetToUpdateOrThro
3940
AllFlatEntityMaps,
4041
| 'flatObjectMetadataMaps'
4142
| 'flatFieldMetadataMaps'
43+
| 'flatFrontComponentMaps'
4244
| 'flatViewFieldGroupMaps'
4345
| 'flatViewMaps'
4446
>): FlatPageLayoutWidget => {
@@ -102,6 +104,8 @@ export const fromUpdatePageLayoutWidgetInputToFlatPageLayoutWidgetToUpdateOrThro
102104
configuration: flatPageLayoutWidgetToUpdate.configuration,
103105
fieldMetadataUniversalIdentifierById:
104106
flatFieldMetadataMaps.universalIdentifierById,
107+
frontComponentUniversalIdentifierById:
108+
flatFrontComponentMaps.universalIdentifierById,
105109
viewFieldGroupUniversalIdentifierById:
106110
flatViewFieldGroupMaps.universalIdentifierById,
107111
viewUniversalIdentifierById: flatViewMaps.universalIdentifierById,

packages/twenty-server/src/engine/metadata-modules/page-layout-widget/dtos/front-component-configuration.dto.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Field, ObjectType } from '@nestjs/graphql';
22

33
import { IsIn, IsNotEmpty, IsUUID } from 'class-validator';
4-
import { type FrontComponentConfiguration } from 'twenty-shared/types';
4+
import {
5+
type FrontComponentConfiguration,
6+
type SerializedRelation,
7+
} from 'twenty-shared/types';
58

69
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
710
import { WidgetConfigurationType } from 'src/engine/metadata-modules/page-layout-widget/enums/widget-configuration-type.type';
@@ -18,5 +21,5 @@ export class FrontComponentConfigurationDTO
1821
@Field(() => UUIDScalarType)
1922
@IsNotEmpty()
2023
@IsUUID()
21-
frontComponentId: string;
24+
frontComponentId: SerializedRelation;
2225
}

packages/twenty-server/src/engine/metadata-modules/page-layout-widget/services/page-layout-widget.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export class PageLayoutWidgetService {
243243
flatPageLayoutTabMaps,
244244
flatObjectMetadataMaps,
245245
flatFieldMetadataMaps,
246+
flatFrontComponentMaps,
246247
flatViewFieldGroupMaps,
247248
flatViewMaps,
248249
} =
@@ -253,6 +254,7 @@ export class PageLayoutWidgetService {
253254
'flatPageLayoutTabMaps',
254255
'flatObjectMetadataMaps',
255256
'flatFieldMetadataMaps',
257+
'flatFrontComponentMaps',
256258
'flatViewFieldGroupMaps',
257259
'flatViewMaps',
258260
],
@@ -267,6 +269,7 @@ export class PageLayoutWidgetService {
267269
flatPageLayoutTabMaps,
268270
flatObjectMetadataMaps,
269271
flatFieldMetadataMaps,
272+
flatFrontComponentMaps,
270273
flatViewFieldGroupMaps,
271274
flatViewMaps,
272275
});
@@ -327,6 +330,7 @@ export class PageLayoutWidgetService {
327330
const {
328331
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
329332
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
333+
flatFrontComponentMaps: existingFlatFrontComponentMaps,
330334
flatViewFieldGroupMaps: existingFlatViewFieldGroupMaps,
331335
flatViewMaps: existingFlatViewMaps,
332336
} = await this.workspaceManyOrAllFlatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
@@ -335,6 +339,7 @@ export class PageLayoutWidgetService {
335339
flatMapsKeys: [
336340
'flatObjectMetadataMaps',
337341
'flatFieldMetadataMaps',
342+
'flatFrontComponentMaps',
338343
'flatViewFieldGroupMaps',
339344
'flatViewMaps',
340345
],
@@ -369,6 +374,7 @@ export class PageLayoutWidgetService {
369374
flatPageLayoutWidgetMaps: existingFlatPageLayoutWidgetMaps,
370375
flatObjectMetadataMaps: existingFlatObjectMetadataMaps,
371376
flatFieldMetadataMaps: existingFlatFieldMetadataMaps,
377+
flatFrontComponentMaps: existingFlatFrontComponentMaps,
372378
flatViewFieldGroupMaps: existingFlatViewFieldGroupMaps,
373379
flatViewMaps: existingFlatViewMaps,
374380
});

packages/twenty-server/src/engine/metadata-modules/page-layout/services/page-layout-duplication.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export class PageLayoutDuplicationService {
5252
flatPageLayoutWidgetMaps,
5353
flatObjectMetadataMaps,
5454
flatFieldMetadataMaps,
55+
flatFrontComponentMaps,
5556
flatViewFieldGroupMaps,
5657
flatViewMaps,
5758
} = await this.getPageLayoutFlatEntityMaps(workspaceId);
@@ -116,6 +117,7 @@ export class PageLayoutDuplicationService {
116117
flatPageLayoutTabMaps: optimisticFlatPageLayoutTabMaps,
117118
flatObjectMetadataMaps,
118119
flatFieldMetadataMaps,
120+
flatFrontComponentMaps,
119121
flatViewFieldGroupMaps,
120122
flatViewMaps,
121123
});
@@ -185,6 +187,7 @@ export class PageLayoutDuplicationService {
185187
'flatPageLayoutWidgetMaps',
186188
'flatObjectMetadataMaps',
187189
'flatFieldMetadataMaps',
190+
'flatFrontComponentMaps',
188191
'flatViewFieldGroupMaps',
189192
'flatViewMaps',
190193
],
@@ -296,6 +299,7 @@ export class PageLayoutDuplicationService {
296299
flatPageLayoutTabMaps,
297300
flatObjectMetadataMaps,
298301
flatFieldMetadataMaps,
302+
flatFrontComponentMaps,
299303
flatViewFieldGroupMaps,
300304
flatViewMaps,
301305
}: {
@@ -309,6 +313,7 @@ export class PageLayoutDuplicationService {
309313
flatPageLayoutTabMaps: AllFlatEntityMaps['flatPageLayoutTabMaps'];
310314
flatObjectMetadataMaps: AllFlatEntityMaps['flatObjectMetadataMaps'];
311315
flatFieldMetadataMaps: AllFlatEntityMaps['flatFieldMetadataMaps'];
316+
flatFrontComponentMaps: AllFlatEntityMaps['flatFrontComponentMaps'];
312317
flatViewFieldGroupMaps: AllFlatEntityMaps['flatViewFieldGroupMaps'];
313318
flatViewMaps: AllFlatEntityMaps['flatViewMaps'];
314319
}): FlatPageLayoutWidget[] {
@@ -330,6 +335,7 @@ export class PageLayoutDuplicationService {
330335
flatPageLayoutTabMaps,
331336
flatObjectMetadataMaps,
332337
flatFieldMetadataMaps,
338+
flatFrontComponentMaps,
333339
flatViewFieldGroupMaps,
334340
flatViewMaps,
335341
}),

0 commit comments

Comments
 (0)