Add events on Custom objects (#4625)
This commit is contained in:
@ -39,14 +39,6 @@ export class SaveEventToDbJob implements MessageQueueJob<SaveEventToDbJobData> {
|
|||||||
workspaceMemberId = workspaceMember.id;
|
workspaceMemberId = workspaceMember.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
|
||||||
data.objectName != 'person' &&
|
|
||||||
data.objectName != 'company' &&
|
|
||||||
data.objectName != 'opportunity'
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.details.diff) {
|
if (data.details.diff) {
|
||||||
// we remove "before" and "after" property for a cleaner/slimmer event payload
|
// we remove "before" and "after" property for a cleaner/slimmer event payload
|
||||||
data.details = {
|
data.details = {
|
||||||
|
|||||||
@ -40,6 +40,7 @@ import {
|
|||||||
attachmentStandardFieldIds,
|
attachmentStandardFieldIds,
|
||||||
baseObjectStandardFieldIds,
|
baseObjectStandardFieldIds,
|
||||||
customObjectStandardFieldIds,
|
customObjectStandardFieldIds,
|
||||||
|
eventStandardFieldIds,
|
||||||
favoriteStandardFieldIds,
|
favoriteStandardFieldIds,
|
||||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
} 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';
|
import { createDeterministicUuid } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/create-deterministic-uuid.util';
|
||||||
@ -338,6 +339,11 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
createdObjectMetadata,
|
createdObjectMetadata,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { eventObjectMetadata } = await this.createEventRelation(
|
||||||
|
objectMetadataInput.workspaceId,
|
||||||
|
createdObjectMetadata,
|
||||||
|
);
|
||||||
|
|
||||||
await this.workspaceMigrationService.createCustomMigration(
|
await this.workspaceMigrationService.createCustomMigration(
|
||||||
generateMigrationName(`create-${createdObjectMetadata.nameSingular}`),
|
generateMigrationName(`create-${createdObjectMetadata.nameSingular}`),
|
||||||
createdObjectMetadata.workspaceId,
|
createdObjectMetadata.workspaceId,
|
||||||
@ -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
|
// Add favorite relation
|
||||||
{
|
{
|
||||||
name: computeObjectTargetTable(favoriteObjectMetadata),
|
name: computeObjectTargetTable(favoriteObjectMetadata),
|
||||||
@ -789,6 +829,99 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
return { attachmentObjectMetadata };
|
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(
|
private async createFavoriteRelation(
|
||||||
workspaceId: string,
|
workspaceId: string,
|
||||||
createdObjectMetadata: ObjectMetadataEntity,
|
createdObjectMetadata: ObjectMetadataEntity,
|
||||||
|
|||||||
@ -298,4 +298,5 @@ export const customObjectStandardFieldIds = {
|
|||||||
activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf',
|
activityTargets: '20202020-7f42-40ae-b96c-c8a61acc83bf',
|
||||||
favorites: '20202020-a4a7-4686-b296-1c6c3482ee21',
|
favorites: '20202020-a4a7-4686-b296-1c6c3482ee21',
|
||||||
attachments: '20202020-8d59-46ca-b7b2-73d167712134',
|
attachments: '20202020-8d59-46ca-b7b2-73d167712134',
|
||||||
|
events: '20202020-a508-4334-9724-5c2bf1b05998',
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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 { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata';
|
||||||
import { AttachmentObjectMetadata } from 'src/modules/attachment/standard-objects/attachment.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 { 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()
|
@BaseCustomObjectMetadata()
|
||||||
export class CustomObjectMetadata extends BaseObjectMetadata {
|
export class CustomObjectMetadata extends BaseObjectMetadata {
|
||||||
@ -85,4 +86,20 @@ export class CustomObjectMetadata extends BaseObjectMetadata {
|
|||||||
})
|
})
|
||||||
@IsNullable()
|
@IsNullable()
|
||||||
attachments: AttachmentObjectMetadata[];
|
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[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@ import { OpportunityObjectMetadata } from 'src/modules/opportunity/standard-obje
|
|||||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.object-metadata';
|
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 { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/standard-objects/workspace-member.object-metadata';
|
||||||
import { EventObjectMetadata } from 'src/modules/event/standard-objects/event.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({
|
@ObjectMetadata({
|
||||||
standardId: standardObjectIds.company,
|
standardId: standardObjectIds.company,
|
||||||
@ -222,9 +221,6 @@ export class CompanyObjectMetadata extends BaseObjectMetadata {
|
|||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
})
|
})
|
||||||
@IsNullable()
|
@IsNullable()
|
||||||
@Gate({
|
|
||||||
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
|
|
||||||
})
|
|
||||||
@IsSystem()
|
@IsSystem()
|
||||||
events: EventObjectMetadata[];
|
events: EventObjectMetadata[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
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 { 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 { 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 { 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 { 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 { 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 { 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 { 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';
|
import { ObjectMetadata } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/object-metadata.decorator';
|
||||||
@ -24,9 +22,6 @@ import { WorkspaceMemberObjectMetadata } from 'src/modules/workspace-member/stan
|
|||||||
icon: 'IconJson',
|
icon: 'IconJson',
|
||||||
})
|
})
|
||||||
@IsSystem()
|
@IsSystem()
|
||||||
@Gate({
|
|
||||||
featureFlag: FeatureFlagKeys.IsEventObjectEnabled,
|
|
||||||
})
|
|
||||||
export class EventObjectMetadata extends BaseObjectMetadata {
|
export class EventObjectMetadata extends BaseObjectMetadata {
|
||||||
@FieldMetadata({
|
@FieldMetadata({
|
||||||
standardId: eventStandardFieldIds.properties,
|
standardId: eventStandardFieldIds.properties,
|
||||||
@ -95,7 +90,7 @@ export class EventObjectMetadata extends BaseObjectMetadata {
|
|||||||
standardId: eventStandardFieldIds.custom,
|
standardId: eventStandardFieldIds.custom,
|
||||||
name: oppositeObjectMetadata.nameSingular,
|
name: oppositeObjectMetadata.nameSingular,
|
||||||
label: oppositeObjectMetadata.labelSingular,
|
label: oppositeObjectMetadata.labelSingular,
|
||||||
description: `Favorite ${oppositeObjectMetadata.labelSingular}`,
|
description: `Event ${oppositeObjectMetadata.labelSingular}`,
|
||||||
joinColumn: `${oppositeObjectMetadata.nameSingular}Id`,
|
joinColumn: `${oppositeObjectMetadata.nameSingular}Id`,
|
||||||
icon: 'IconBuildingSkyscraper',
|
icon: 'IconBuildingSkyscraper',
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -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 { FavoriteObjectMetadata } from 'src/modules/favorite/standard-objects/favorite.object-metadata';
|
||||||
import { PersonObjectMetadata } from 'src/modules/person/standard-objects/person.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 { EventObjectMetadata } from 'src/modules/event/standard-objects/event.object-metadata';
|
||||||
import { Gate } from 'src/engine/workspace-manager/workspace-sync-metadata/decorators/gate.decorator';
|
|
||||||
|
|
||||||
@ObjectMetadata({
|
@ObjectMetadata({
|
||||||
standardId: standardObjectIds.opportunity,
|
standardId: standardObjectIds.opportunity,
|
||||||
@ -179,9 +178,6 @@ export class OpportunityObjectMetadata extends BaseObjectMetadata {
|
|||||||
type: RelationMetadataType.ONE_TO_MANY,
|
type: RelationMetadataType.ONE_TO_MANY,
|
||||||
inverseSideTarget: () => EventObjectMetadata,
|
inverseSideTarget: () => EventObjectMetadata,
|
||||||
})
|
})
|
||||||
@Gate({
|
|
||||||
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
|
|
||||||
})
|
|
||||||
@IsNullable()
|
@IsNullable()
|
||||||
events: EventObjectMetadata[];
|
events: EventObjectMetadata[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -233,9 +233,6 @@ export class PersonObjectMetadata extends BaseObjectMetadata {
|
|||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
})
|
})
|
||||||
@IsNullable()
|
@IsNullable()
|
||||||
@Gate({
|
|
||||||
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
|
|
||||||
})
|
|
||||||
@IsSystem()
|
@IsSystem()
|
||||||
events: EventObjectMetadata[];
|
events: EventObjectMetadata[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -247,9 +247,6 @@ export class WorkspaceMemberObjectMetadata extends BaseObjectMetadata {
|
|||||||
onDelete: RelationOnDeleteAction.CASCADE,
|
onDelete: RelationOnDeleteAction.CASCADE,
|
||||||
})
|
})
|
||||||
@IsNullable()
|
@IsNullable()
|
||||||
@Gate({
|
|
||||||
featureFlag: 'IS_EVENT_OBJECT_ENABLED',
|
|
||||||
})
|
|
||||||
@IsSystem()
|
@IsSystem()
|
||||||
events: EventObjectMetadata[];
|
events: EventObjectMetadata[];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user