Add activityTarget relation after custom object creation (#2670)
* Add activityTarget relation after custom object creation * add isCustom check for relations
This commit is contained in:
@ -56,6 +56,10 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
throw new ConflictException('Field already exists');
|
throw new ConflictException('Field already exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (record.name == record.label) {
|
||||||
|
throw new ConflictException('Field name and label cannot be the same');
|
||||||
|
}
|
||||||
|
|
||||||
const createdFieldMetadata = await super.createOne({
|
const createdFieldMetadata = await super.createOne({
|
||||||
...record,
|
...record,
|
||||||
targetColumnMap: generateTargetColumnMap(record.type, true, record.name),
|
targetColumnMap: generateTargetColumnMap(record.type, true, record.name),
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import { WorkspaceMigrationModule } from 'src/metadata/workspace-migration/works
|
|||||||
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
||||||
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
import { TypeORMModule } from 'src/database/typeorm/typeorm.module';
|
||||||
import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity';
|
import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity';
|
||||||
|
import { RelationMetadataEntity } from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
import { ObjectMetadataService } from './object-metadata.service';
|
import { ObjectMetadataService } from './object-metadata.service';
|
||||||
import { ObjectMetadataEntity } from './object-metadata.entity';
|
import { ObjectMetadataEntity } from './object-metadata.entity';
|
||||||
@ -27,7 +28,7 @@ import { ObjectMetadataDTO } from './dtos/object-metadata.dto';
|
|||||||
imports: [
|
imports: [
|
||||||
TypeORMModule,
|
TypeORMModule,
|
||||||
NestjsQueryTypeOrmModule.forFeature(
|
NestjsQueryTypeOrmModule.forFeature(
|
||||||
[ObjectMetadataEntity, FieldMetadataEntity],
|
[ObjectMetadataEntity, FieldMetadataEntity, RelationMetadataEntity],
|
||||||
'metadata',
|
'metadata',
|
||||||
),
|
),
|
||||||
DataSourceModule,
|
DataSourceModule,
|
||||||
|
|||||||
@ -11,9 +11,16 @@ import {
|
|||||||
WorkspaceMigrationColumnCreate,
|
WorkspaceMigrationColumnCreate,
|
||||||
WorkspaceMigrationTableAction,
|
WorkspaceMigrationTableAction,
|
||||||
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
} from 'src/metadata/workspace-migration/workspace-migration.entity';
|
||||||
import { FieldMetadataType } from 'src/metadata/field-metadata/field-metadata.entity';
|
import {
|
||||||
|
FieldMetadataEntity,
|
||||||
|
FieldMetadataType,
|
||||||
|
} from 'src/metadata/field-metadata/field-metadata.entity';
|
||||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||||
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
|
||||||
|
import {
|
||||||
|
RelationMetadataEntity,
|
||||||
|
RelationMetadataType,
|
||||||
|
} from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
import { ObjectMetadataEntity } from './object-metadata.entity';
|
import { ObjectMetadataEntity } from './object-metadata.entity';
|
||||||
|
|
||||||
@ -25,6 +32,12 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
@InjectRepository(ObjectMetadataEntity, 'metadata')
|
||||||
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
private readonly objectMetadataRepository: Repository<ObjectMetadataEntity>,
|
||||||
|
|
||||||
|
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||||
|
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||||
|
|
||||||
|
@InjectRepository(RelationMetadataEntity, 'metadata')
|
||||||
|
private readonly relationMetadataRepository: Repository<RelationMetadataEntity>,
|
||||||
|
|
||||||
private readonly dataSourceService: DataSourceService,
|
private readonly dataSourceService: DataSourceService,
|
||||||
private readonly typeORMService: TypeORMService,
|
private readonly typeORMService: TypeORMService,
|
||||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||||
@ -117,6 +130,86 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const activityTargetObjectMetadata =
|
||||||
|
await this.objectMetadataRepository.findOneByOrFail({
|
||||||
|
nameSingular: 'activityTarget',
|
||||||
|
workspaceId: record.workspaceId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const activityTargetRelationFieldMetadata =
|
||||||
|
await this.fieldMetadataRepository.save([
|
||||||
|
// FROM
|
||||||
|
{
|
||||||
|
objectMetadataId: createdObjectMetadata.id,
|
||||||
|
workspaceId: record.workspaceId,
|
||||||
|
isCustom: true,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: 'activityTargets',
|
||||||
|
label: 'Activities',
|
||||||
|
targetColumnMap: {},
|
||||||
|
description: `Activities tied to the ${record.labelSingular}`,
|
||||||
|
icon: 'IconCheckbox',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// TO
|
||||||
|
{
|
||||||
|
objectMetadataId: activityTargetObjectMetadata.id,
|
||||||
|
workspaceId: record.workspaceId,
|
||||||
|
isCustom: true,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.RELATION,
|
||||||
|
name: record.nameSingular,
|
||||||
|
label: record.labelSingular,
|
||||||
|
targetColumnMap: {},
|
||||||
|
description: `ActivityTarget ${record.labelSingular}`,
|
||||||
|
icon: 'IconBuildingSkyscraper',
|
||||||
|
isNullable: true,
|
||||||
|
},
|
||||||
|
// Foreign key
|
||||||
|
{
|
||||||
|
objectMetadataId: activityTargetObjectMetadata.id,
|
||||||
|
workspaceId: record.workspaceId,
|
||||||
|
isCustom: true,
|
||||||
|
isActive: true,
|
||||||
|
type: FieldMetadataType.UUID,
|
||||||
|
name: `${createdObjectMetadata.targetTableName}Id`,
|
||||||
|
label: `${record.labelSingular} ID (foreign key)`,
|
||||||
|
targetColumnMap: {},
|
||||||
|
description: `ActivityTarget ${record.labelSingular} id foreign key`,
|
||||||
|
icon: undefined,
|
||||||
|
isNullable: true,
|
||||||
|
isSystem: true,
|
||||||
|
defaultValue: undefined,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const activityTargetRelationFieldMetadataMap =
|
||||||
|
activityTargetRelationFieldMetadata.reduce(
|
||||||
|
(acc, fieldMetadata: FieldMetadataEntity) => {
|
||||||
|
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||||
|
acc[fieldMetadata.objectMetadataId] = fieldMetadata;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.relationMetadataRepository.save([
|
||||||
|
{
|
||||||
|
workspaceId: record.workspaceId,
|
||||||
|
relationType: RelationMetadataType.ONE_TO_MANY,
|
||||||
|
fromObjectMetadataId: createdObjectMetadata.id,
|
||||||
|
toObjectMetadataId: activityTargetObjectMetadata.id,
|
||||||
|
fromFieldMetadataId:
|
||||||
|
activityTargetRelationFieldMetadataMap[createdObjectMetadata.id].id,
|
||||||
|
toFieldMetadataId:
|
||||||
|
activityTargetRelationFieldMetadataMap[
|
||||||
|
activityTargetObjectMetadata.id
|
||||||
|
].id,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
await this.workspaceMigrationService.createCustomMigration(
|
await this.workspaceMigrationService.createCustomMigration(
|
||||||
createdObjectMetadata.workspaceId,
|
createdObjectMetadata.workspaceId,
|
||||||
[
|
[
|
||||||
@ -124,6 +217,30 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
|||||||
name: createdObjectMetadata.targetTableName,
|
name: createdObjectMetadata.targetTableName,
|
||||||
action: 'create',
|
action: 'create',
|
||||||
} satisfies WorkspaceMigrationTableAction,
|
} satisfies WorkspaceMigrationTableAction,
|
||||||
|
// Add activity target relation
|
||||||
|
{
|
||||||
|
name: activityTargetObjectMetadata.targetTableName,
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.CREATE,
|
||||||
|
columnName: `${createdObjectMetadata.targetTableName}Id`,
|
||||||
|
columnType: 'uuid',
|
||||||
|
} satisfies WorkspaceMigrationColumnCreate,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: activityTargetObjectMetadata.targetTableName,
|
||||||
|
action: 'alter',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
action: WorkspaceMigrationColumnActionType.RELATION,
|
||||||
|
columnName: `${createdObjectMetadata.targetTableName}Id`,
|
||||||
|
referencedTableName: createdObjectMetadata.targetTableName,
|
||||||
|
referencedTableColumnName: 'id',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
// This is temporary until we implement mainIdentifier
|
// This is temporary until we implement mainIdentifier
|
||||||
{
|
{
|
||||||
name: createdObjectMetadata.targetTableName,
|
name: createdObjectMetadata.targetTableName,
|
||||||
|
|||||||
@ -95,7 +95,7 @@ export class CompositeFieldAliasFactory {
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
let relationAlias = fieldKey;
|
let relationAlias = fieldMetadata.isCustom ? `_${fieldKey}` : fieldKey;
|
||||||
|
|
||||||
// For one to one relations, pg_graphql use the targetTableName on the side that is not storing the foreign key
|
// For one to one relations, pg_graphql use the targetTableName on the side that is not storing the foreign key
|
||||||
// so we need to alias it to the field key
|
// so we need to alias it to the field key
|
||||||
|
|||||||
@ -18,4 +18,5 @@ export interface FieldMetadataInterface<
|
|||||||
isNullable?: boolean;
|
isNullable?: boolean;
|
||||||
fromRelationMetadata?: RelationMetadataEntity;
|
fromRelationMetadata?: RelationMetadataEntity;
|
||||||
toRelationMetadata?: RelationMetadataEntity;
|
toRelationMetadata?: RelationMetadataEntity;
|
||||||
|
isCustom?: boolean;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user