mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-26 13:31:45 +03:00
Added a RelationFromOneSide ResolveField in FieldMetadata GraphQL Resolver (#4378)
* Added a ResolveField for relationDefinition on a FieldMetadataItem
This commit is contained in:
parent
581dfafe11
commit
a5b41e09f5
@ -0,0 +1,43 @@
|
|||||||
|
import { Field, ObjectType, registerEnumType } from '@nestjs/graphql';
|
||||||
|
|
||||||
|
import { IsEnum, IsNotEmpty } from 'class-validator';
|
||||||
|
|
||||||
|
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
||||||
|
import { ObjectMetadataDTO } from 'src/metadata/object-metadata/dtos/object-metadata.dto';
|
||||||
|
import { RelationMetadataType } from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
|
export enum RelationDefinitionType {
|
||||||
|
ONE_TO_ONE = RelationMetadataType.ONE_TO_ONE,
|
||||||
|
ONE_TO_MANY = RelationMetadataType.ONE_TO_MANY,
|
||||||
|
MANY_TO_MANY = RelationMetadataType.MANY_TO_MANY,
|
||||||
|
MANY_TO_ONE = 'MANY_TO_ONE',
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEnumType(RelationDefinitionType, {
|
||||||
|
name: 'RelationDefinitionType',
|
||||||
|
description: 'Relation definition type',
|
||||||
|
});
|
||||||
|
|
||||||
|
@ObjectType('RelationDefinition')
|
||||||
|
export class RelationDefinitionDTO {
|
||||||
|
@IsNotEmpty()
|
||||||
|
@Field(() => ObjectMetadataDTO)
|
||||||
|
sourceObjectMetadata: ObjectMetadataDTO;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@Field(() => ObjectMetadataDTO)
|
||||||
|
targetObjectMetadata: ObjectMetadataDTO;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@Field(() => FieldMetadataDTO)
|
||||||
|
sourceFieldMetadata: FieldMetadataDTO;
|
||||||
|
|
||||||
|
@IsNotEmpty()
|
||||||
|
@Field(() => FieldMetadataDTO)
|
||||||
|
targetFieldMetadata: FieldMetadataDTO;
|
||||||
|
|
||||||
|
@IsEnum(RelationDefinitionType)
|
||||||
|
@IsNotEmpty()
|
||||||
|
@Field(() => RelationDefinitionType)
|
||||||
|
direction: RelationDefinitionType;
|
||||||
|
}
|
@ -17,6 +17,7 @@ import { IsFieldMetadataDefaultValue } from 'src/metadata/field-metadata/validat
|
|||||||
import { FieldMetadataResolver } from 'src/metadata/field-metadata/field-metadata.resolver';
|
import { FieldMetadataResolver } from 'src/metadata/field-metadata/field-metadata.resolver';
|
||||||
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
||||||
import { IsFieldMetadataOptions } from 'src/metadata/field-metadata/validators/is-field-metadata-options.validator';
|
import { IsFieldMetadataOptions } from 'src/metadata/field-metadata/validators/is-field-metadata-options.validator';
|
||||||
|
import { RelationMetadataEntity } from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
import { FieldMetadataService } from './field-metadata.service';
|
import { FieldMetadataService } from './field-metadata.service';
|
||||||
import { FieldMetadataEntity } from './field-metadata.entity';
|
import { FieldMetadataEntity } from './field-metadata.entity';
|
||||||
@ -28,7 +29,10 @@ import { UpdateFieldInput } from './dtos/update-field.input';
|
|||||||
imports: [
|
imports: [
|
||||||
NestjsQueryGraphQLModule.forFeature({
|
NestjsQueryGraphQLModule.forFeature({
|
||||||
imports: [
|
imports: [
|
||||||
NestjsQueryTypeOrmModule.forFeature([FieldMetadataEntity], 'metadata'),
|
NestjsQueryTypeOrmModule.forFeature(
|
||||||
|
[FieldMetadataEntity, RelationMetadataEntity],
|
||||||
|
'metadata',
|
||||||
|
),
|
||||||
WorkspaceMigrationModule,
|
WorkspaceMigrationModule,
|
||||||
WorkspaceMigrationRunnerModule,
|
WorkspaceMigrationRunnerModule,
|
||||||
ObjectMetadataModule,
|
ObjectMetadataModule,
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
import { UseGuards } from '@nestjs/common';
|
import { UseGuards } from '@nestjs/common';
|
||||||
import { Args, Mutation, Resolver } from '@nestjs/graphql';
|
import {
|
||||||
|
Args,
|
||||||
|
Mutation,
|
||||||
|
Parent,
|
||||||
|
ResolveField,
|
||||||
|
Resolver,
|
||||||
|
} from '@nestjs/graphql';
|
||||||
|
|
||||||
import { Workspace } from 'src/core/workspace/workspace.entity';
|
import { Workspace } from 'src/core/workspace/workspace.entity';
|
||||||
import { AuthWorkspace } from 'src/decorators/auth/auth-workspace.decorator';
|
import { AuthWorkspace } from 'src/decorators/auth/auth-workspace.decorator';
|
||||||
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
||||||
import { CreateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/create-field.input';
|
import { CreateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/create-field.input';
|
||||||
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
||||||
|
import { RelationDefinitionDTO } from 'src/metadata/field-metadata/dtos/relation-definition.dto';
|
||||||
import { UpdateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/update-field.input';
|
import { UpdateOneFieldMetadataInput } from 'src/metadata/field-metadata/dtos/update-field.input';
|
||||||
import { FieldMetadataService } from 'src/metadata/field-metadata/field-metadata.service';
|
import { FieldMetadataService } from 'src/metadata/field-metadata/field-metadata.service';
|
||||||
|
|
||||||
@ -35,4 +42,11 @@ export class FieldMetadataResolver {
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ResolveField(() => RelationDefinitionDTO, { nullable: true })
|
||||||
|
async relationDefinition(
|
||||||
|
@Parent() fieldMetadata: FieldMetadataDTO,
|
||||||
|
): Promise<RelationDefinitionDTO | null> {
|
||||||
|
return await this.fieldMetadataService.getRelationDefinition(fieldMetadata);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,15 @@ import { WorkspaceMigrationFactory } from 'src/metadata/workspace-migration/work
|
|||||||
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
import { computeObjectTargetTable } from 'src/workspace/utils/compute-object-target-table.util';
|
||||||
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
import { generateMigrationName } from 'src/metadata/workspace-migration/utils/generate-migration-name.util';
|
||||||
import { generateNullable } from 'src/metadata/field-metadata/utils/generate-nullable';
|
import { generateNullable } from 'src/metadata/field-metadata/utils/generate-nullable';
|
||||||
|
import { FieldMetadataDTO } from 'src/metadata/field-metadata/dtos/field-metadata.dto';
|
||||||
|
import {
|
||||||
|
RelationDefinitionDTO,
|
||||||
|
RelationDefinitionType,
|
||||||
|
} from 'src/metadata/field-metadata/dtos/relation-definition.dto';
|
||||||
|
import {
|
||||||
|
RelationMetadataEntity,
|
||||||
|
RelationMetadataType,
|
||||||
|
} from 'src/metadata/relation-metadata/relation-metadata.entity';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FieldMetadataEntity,
|
FieldMetadataEntity,
|
||||||
@ -41,7 +50,8 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(FieldMetadataEntity, 'metadata')
|
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||||
|
@InjectRepository(RelationMetadataEntity, 'metadata')
|
||||||
|
private readonly relationMetadataRepository: Repository<RelationMetadataEntity>,
|
||||||
private readonly objectMetadataService: ObjectMetadataService,
|
private readonly objectMetadataService: ObjectMetadataService,
|
||||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||||
@ -340,4 +350,71 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
|||||||
|
|
||||||
return fieldMetadataInputOverrided as UpdateFieldInput;
|
return fieldMetadataInputOverrided as UpdateFieldInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getRelationDefinition(
|
||||||
|
fieldMetadata: FieldMetadataDTO,
|
||||||
|
): Promise<RelationDefinitionDTO | null> {
|
||||||
|
if (fieldMetadata.type !== FieldMetadataType.RELATION) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const foundRelationMetadata = await this.relationMetadataRepository.findOne(
|
||||||
|
{
|
||||||
|
where: [
|
||||||
|
{ fromFieldMetadataId: fieldMetadata.id },
|
||||||
|
{ toFieldMetadataId: fieldMetadata.id },
|
||||||
|
],
|
||||||
|
relations: [
|
||||||
|
'fromObjectMetadata',
|
||||||
|
'toObjectMetadata',
|
||||||
|
'fromFieldMetadata',
|
||||||
|
'toFieldMetadata',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!foundRelationMetadata) {
|
||||||
|
throw new Error('RelationMetadata not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
const isRelationFromSource =
|
||||||
|
foundRelationMetadata.fromFieldMetadata.id === fieldMetadata.id;
|
||||||
|
|
||||||
|
// TODO: implement MANY_TO_MANY
|
||||||
|
if (
|
||||||
|
foundRelationMetadata.relationType === RelationMetadataType.MANY_TO_MANY
|
||||||
|
) {
|
||||||
|
throw new Error(`
|
||||||
|
Relation type ${foundRelationMetadata.relationType} not supported
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRelationFromSource) {
|
||||||
|
const direction =
|
||||||
|
foundRelationMetadata.relationType === RelationMetadataType.ONE_TO_ONE
|
||||||
|
? RelationDefinitionType.ONE_TO_ONE
|
||||||
|
: RelationDefinitionType.ONE_TO_MANY;
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceObjectMetadata: foundRelationMetadata.fromObjectMetadata,
|
||||||
|
sourceFieldMetadata: foundRelationMetadata.fromFieldMetadata,
|
||||||
|
targetObjectMetadata: foundRelationMetadata.toObjectMetadata,
|
||||||
|
targetFieldMetadata: foundRelationMetadata.toFieldMetadata,
|
||||||
|
direction,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
const direction =
|
||||||
|
foundRelationMetadata.relationType === RelationMetadataType.ONE_TO_ONE
|
||||||
|
? RelationDefinitionType.ONE_TO_ONE
|
||||||
|
: RelationDefinitionType.MANY_TO_ONE;
|
||||||
|
|
||||||
|
return {
|
||||||
|
sourceObjectMetadata: foundRelationMetadata.toObjectMetadata,
|
||||||
|
sourceFieldMetadata: foundRelationMetadata.toFieldMetadata,
|
||||||
|
targetObjectMetadata: foundRelationMetadata.fromObjectMetadata,
|
||||||
|
targetFieldMetadata: foundRelationMetadata.fromFieldMetadata,
|
||||||
|
direction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,8 @@ export class ObjectMetadataDTO {
|
|||||||
updatedAt: Date;
|
updatedAt: Date;
|
||||||
|
|
||||||
@Field({ nullable: true })
|
@Field({ nullable: true })
|
||||||
labelIdentifierFieldMetadataId: string;
|
labelIdentifierFieldMetadataId?: string;
|
||||||
|
|
||||||
@Field({ nullable: true })
|
@Field({ nullable: true })
|
||||||
imageIdentifierFieldMetadataId: string;
|
imageIdentifierFieldMetadataId?: string;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user