Skip to content

Commit

Permalink
Add events on Custom objects (twentyhq#4625)
Browse files Browse the repository at this point in the history
  • Loading branch information
charlesBochet authored Mar 22, 2024
1 parent 278a058 commit de69cb9
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ export class SaveEventToDbJob implements MessageQueueJob<SaveEventToDbJobData> {
workspaceMemberId = workspaceMember.id;
}

if (
data.objectName != 'person' &&
data.objectName != 'company' &&
data.objectName != 'opportunity'
) {
return;
}

if (data.details.diff) {
// we remove "before" and "after" property for a cleaner/slimmer event payload
data.details = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
attachmentStandardFieldIds,
baseObjectStandardFieldIds,
customObjectStandardFieldIds,
eventStandardFieldIds,
favoriteStandardFieldIds,
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { createDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
Expand Down Expand Up @@ -338,6 +339,11 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
createdObjectMetadata,
);

const { eventObjectMetadata } = await this.createEventRelation(
objectMetadataInput.workspaceId,
createdObjectMetadata,
);

await this.workspaceMigrationService.createCustomMigration(
generateMigrationName(`create-${createdObjectMetadata.nameSingular}`),
createdObjectMetadata.workspaceId,
Expand Down Expand Up @@ -414,6 +420,40 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
},
],
},
// Add event relation
{
name: computeObjectTargetTable(eventObjectMetadata),
action: 'alter',
columns: [
{
action: WorkspaceMigrationColumnActionType.CREATE,
columnName: `${computeCustomName(
createdObjectMetadata.nameSingular,
false,
)}Id`,
columnType: 'uuid',
isNullable: true,
} satisfies WorkspaceMigrationColumnCreate,
],
},
{
name: computeObjectTargetTable(eventObjectMetadata),
action: 'alter',
columns: [
{
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
columnName: `${computeCustomName(
createdObjectMetadata.nameSingular,
false,
)}Id`,
referencedTableName: computeObjectTargetTable(
createdObjectMetadata,
),
referencedTableColumnName: 'id',
onDelete: RelationOnDeleteAction.CASCADE,
},
],
},
// Add favorite relation
{
name: computeObjectTargetTable(favoriteObjectMetadata),
Expand Down Expand Up @@ -789,6 +829,99 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
return { attachmentObjectMetadata };
}

private async createEventRelation(
workspaceId: string,
createdObjectMetadata: ObjectMetadataEntity,
) {
const eventObjectMetadata =
await this.objectMetadataRepository.findOneByOrFail({
nameSingular: 'event',
workspaceId: workspaceId,
});

const eventRelationFieldMetadata = await this.fieldMetadataRepository.save([
// FROM
{
standardId: customObjectStandardFieldIds.events,
objectMetadataId: createdObjectMetadata.id,
workspaceId: workspaceId,
isCustom: false,
isActive: true,
type: FieldMetadataType.RELATION,
name: 'events',
label: 'Events',
targetColumnMap: {},
description: `Events tied to the ${createdObjectMetadata.labelSingular}`,
icon: 'IconFileImport',
isNullable: true,
},
// TO
{
standardId: eventStandardFieldIds.custom,
objectMetadataId: eventObjectMetadata.id,
workspaceId: workspaceId,
isCustom: false,
isActive: true,
type: FieldMetadataType.RELATION,
name: createdObjectMetadata.nameSingular,
label: createdObjectMetadata.labelSingular,
targetColumnMap: {},
description: `Event ${createdObjectMetadata.labelSingular}`,
icon: 'IconBuildingSkyscraper',
isNullable: true,
},
// Foreign key
{
standardId: createDeterministicUuid(eventStandardFieldIds.custom),
objectMetadataId: eventObjectMetadata.id,
workspaceId: workspaceId,
isCustom: false,
isActive: true,
type: FieldMetadataType.UUID,
name: `${createdObjectMetadata.nameSingular}Id`,
label: `${createdObjectMetadata.labelSingular} ID (foreign key)`,
targetColumnMap: {
value: `${computeCustomName(
createdObjectMetadata.nameSingular,
false,
)}Id`,
},
description: `Event ${createdObjectMetadata.labelSingular} id foreign key`,
icon: undefined,
isNullable: true,
isSystem: true,
defaultValue: undefined,
},
]);

const eventRelationFieldMetadataMap = eventRelationFieldMetadata.reduce(
(acc, fieldMetadata: FieldMetadataEntity) => {
if (fieldMetadata.type === FieldMetadataType.RELATION) {
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
}

return acc;
},
{},
);

await this.relationMetadataRepository.save([
{
workspaceId: workspaceId,
relationType: RelationMetadataType.ONE_TO_MANY,
fromObjectMetadataId: createdObjectMetadata.id,
toObjectMetadataId: eventObjectMetadata.id,
fromFieldMetadataId:
eventRelationFieldMetadataMap[createdObjectMetadata.id].id,
toFieldMetadataId:
eventRelationFieldMetadataMap[eventObjectMetadata.id].id,
onDeleteAction: RelationOnDeleteAction.CASCADE,
},
]);

return { eventObjectMetadata };
}

private async createFavoriteRelation(
workspaceId: string,
createdObjectMetadata: ObjectMetadataEntity,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,5 @@ export const customObjectStandardFieldIds = {
activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf',
favorites: '20202020-a4a7-4686-b296-1c6c3482ee21',
attachments: '20202020-8d59-46ca-b7b2-73d167712134',
events: '20202020-a508-4334-9724-5c2bf1b05998',
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { RelationMetadata } from 'src/engine/workspace-manager/workspace-sync-me
import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata';
import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.object-metadata';
import { customObjectStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata';

@BaseCustomObjectMetadata()
export class CustomObjectMetadata extends BaseObjectMetadata {
Expand Down Expand Up @@ -85,4 +86,20 @@ export class CustomObjectMetadata extends BaseObjectMetadata {
})
@IsNullable()
attachments: AttachmentObjectMetadata[];

@FieldMetadata({
standardId: customObjectStandardFieldIds.events,
type: FieldMetadataType.RELATION,
label: 'Events',
description: (objectMetadata) =>
`Events tied to the ${objectMetadata.labelSingular}`,
icon: 'IconJson',
})
@RelationMetadata({
type: RelationMetadataType.ONE_TO_MANY,
inverseSideTarget: () => AttachmentObjectMetadata,
onDelete: RelationOnDeleteAction.CASCADE,
})
@IsNullable()
events: EventObjectMetadata[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-obje
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata';
import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata';
import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator';

@ObjectMetadata({
standardId: standardObjectIds.company,
Expand Down Expand Up @@ -222,9 +221,6 @@ export class CompanyObjectMetadata extends BaseObjectMetadata {
onDelete: RelationOnDeleteAction.CASCADE,
})
@IsNullable()
@Gate({
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
})
@IsSystem()
events: EventObjectMetadata[];
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
import { FeatureFlagKeys } from 'src/engine/core-modules/feature-flag/feature-flag.entity';
import { eventStandardFieldIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
import { standardObjectIds } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids';
import { CustomObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/custom-objects/custom.object-metadata';
import { DynamicRelationFieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/dynamic-field-metadata.interface';
import { FieldMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/field-metadata.decorator';
import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator';
import { IsNullable } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-nullable.decorator';
import { IsSystem } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/is-system.decorator';
import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator';
Expand All @@ -24,9 +22,6 @@ import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/stan
icon: 'IconJson',
})
@IsSystem()
@Gate({
featureFlag: FeatureFlagKeys.IsEventObjectEnabled,
})
export class EventObjectMetadata extends BaseObjectMetadata {
@FieldMetadata({
standardId: eventStandardFieldIds.properties,
Expand Down Expand Up @@ -95,7 +90,7 @@ export class EventObjectMetadata extends BaseObjectMetadata {
standardId: eventStandardFieldIds.custom,
name: oppositeObjectMetadata.nameSingular,
label: oppositeObjectMetadata.labelSingular,
description: `Favorite ${oppositeObjectMetadata.labelSingular}`,
description: `Event ${oppositeObjectMetadata.labelSingular}`,
joinColumn: `${oppositeObjectMetadata.nameSingular}Id`,
icon: 'IconBuildingSkyscraper',
}))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { CompanyObjectMetadata } from 'src/modules/company/standard-objects/comp
import { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata';
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata';
import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator';

@ObjectMetadata({
standardId: standardObjectIds.opportunity,
Expand Down Expand Up @@ -179,9 +178,6 @@ export class OpportunityObjectMetadata extends BaseObjectMetadata {
type: RelationMetadataType.ONE_TO_MANY,
inverseSideTarget: () => EventObjectMetadata,
})
@Gate({
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
})
@IsNullable()
events: EventObjectMetadata[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,6 @@ export class PersonObjectMetadata extends BaseObjectMetadata {
onDelete: RelationOnDeleteAction.CASCADE,
})
@IsNullable()
@Gate({
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
})
@IsSystem()
events: EventObjectMetadata[];
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,6 @@ export class WorkspaceMemberObjectMetadata extends BaseObjectMetadata {
onDelete: RelationOnDeleteAction.CASCADE,
})
@IsNullable()
@Gate({
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
})
@IsSystem()
events: EventObjectMetadata[];
}

0 comments on commit de69cb9

Please sign in to comment.