Add POC for Field translation (#9898)
Similar to ObjectMetadata translation Also fixed an issue linked to the migration from `t` to `message` helper: we're forced to rebuild the ID ourselves
This commit is contained in:
@ -16,6 +16,7 @@ import { FieldMetadataType } from 'twenty-shared';
|
||||
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { IDataloaders } from 'src/engine/dataloaders/dataloader.interface';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
@ -43,6 +44,30 @@ export class FieldMetadataResolver {
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
) {}
|
||||
|
||||
@ResolveField(() => String, { nullable: true })
|
||||
async label(
|
||||
@Parent() fieldMetadata: FieldMetadataDTO,
|
||||
@Context() context: I18nContext,
|
||||
): Promise<string> {
|
||||
return this.fieldMetadataService.resolveTranslatableString(
|
||||
fieldMetadata,
|
||||
'label',
|
||||
context.req.headers['x-locale'],
|
||||
);
|
||||
}
|
||||
|
||||
@ResolveField(() => String, { nullable: true })
|
||||
async description(
|
||||
@Parent() fieldMetadata: FieldMetadataDTO,
|
||||
@Context() context: I18nContext,
|
||||
): Promise<string> {
|
||||
return this.fieldMetadataService.resolveTranslatableString(
|
||||
fieldMetadata,
|
||||
'description',
|
||||
context.req.headers['x-locale'],
|
||||
);
|
||||
}
|
||||
|
||||
@Mutation(() => FieldMetadataDTO)
|
||||
async createOneField(
|
||||
@Args('input') input: CreateOneFieldMetadataInput,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectDataSource, InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { i18n } from '@lingui/core';
|
||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||
import isEmpty from 'lodash.isempty';
|
||||
import { FieldMetadataType } from 'twenty-shared';
|
||||
@ -8,6 +9,7 @@ import { DataSource, FindOneOptions, Repository } from 'typeorm';
|
||||
import { v4 as uuidV4, v4 } from 'uuid';
|
||||
|
||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||
import { generateMessageId } from 'src/engine/core-modules/i18n/utils/generateMessageId';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { compositeTypeDefinitions } from 'src/engine/metadata-modules/field-metadata/composite-types';
|
||||
import { CreateFieldInput } from 'src/engine/metadata-modules/field-metadata/dtos/create-field.input';
|
||||
@ -773,4 +775,29 @@ export class FieldMetadataService extends TypeOrmQueryService<FieldMetadataEntit
|
||||
|
||||
return fieldMetadataInput;
|
||||
}
|
||||
|
||||
async resolveTranslatableString(
|
||||
fieldMetadata: FieldMetadataDTO,
|
||||
labelKey: 'label' | 'description',
|
||||
locale: string | undefined,
|
||||
): Promise<string> {
|
||||
if (fieldMetadata.isCustom) {
|
||||
return fieldMetadata[labelKey] ?? '';
|
||||
}
|
||||
|
||||
if (!locale) {
|
||||
return fieldMetadata[labelKey] ?? '';
|
||||
}
|
||||
|
||||
i18n.activate(locale);
|
||||
|
||||
const messageId = generateMessageId(fieldMetadata[labelKey] ?? '');
|
||||
const translatedMessage = i18n._(messageId);
|
||||
|
||||
if (translatedMessage === messageId) {
|
||||
return fieldMetadata[labelKey] ?? '';
|
||||
}
|
||||
|
||||
return translatedMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@ import {
|
||||
Resolver,
|
||||
} from '@nestjs/graphql';
|
||||
|
||||
import { I18nContext } from 'src/engine/core-modules/i18n/types/i18n-context.type';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AuthWorkspace } from 'src/engine/decorators/auth/auth-workspace.decorator';
|
||||
import { WorkspaceAuthGuard } from 'src/engine/guards/workspace-auth.guard';
|
||||
@ -32,7 +33,7 @@ export class ObjectMetadataResolver {
|
||||
@ResolveField(() => String, { nullable: true })
|
||||
async labelPlural(
|
||||
@Parent() objectMetadata: ObjectMetadataDTO,
|
||||
@Context() context,
|
||||
@Context() context: I18nContext,
|
||||
): Promise<string> {
|
||||
return this.objectMetadataService.resolveTranslatableString(
|
||||
objectMetadata,
|
||||
@ -44,7 +45,7 @@ export class ObjectMetadataResolver {
|
||||
@ResolveField(() => String, { nullable: true })
|
||||
async labelSingular(
|
||||
@Parent() objectMetadata: ObjectMetadataDTO,
|
||||
@Context() context,
|
||||
@Context() context: I18nContext,
|
||||
): Promise<string> {
|
||||
return this.objectMetadataService.resolveTranslatableString(
|
||||
objectMetadata,
|
||||
@ -56,7 +57,7 @@ export class ObjectMetadataResolver {
|
||||
@ResolveField(() => String, { nullable: true })
|
||||
async description(
|
||||
@Parent() objectMetadata: ObjectMetadataDTO,
|
||||
@Context() context,
|
||||
@Context() context: I18nContext,
|
||||
): Promise<string> {
|
||||
return this.objectMetadataService.resolveTranslatableString(
|
||||
objectMetadata,
|
||||
|
||||
@ -11,6 +11,7 @@ import { FindManyOptions, FindOneOptions, In, Not, Repository } from 'typeorm';
|
||||
|
||||
import { ObjectMetadataStandardIdToIdMap } from 'src/engine/metadata-modules/object-metadata/interfaces/object-metadata-standard-id-to-id-map';
|
||||
|
||||
import { generateMessageId } from 'src/engine/core-modules/i18n/utils/generateMessageId';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { IndexMetadataService } from 'src/engine/metadata-modules/index-metadata/index-metadata.service';
|
||||
@ -539,14 +540,18 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
async resolveTranslatableString(
|
||||
objectMetadata: ObjectMetadataDTO,
|
||||
labelKey: 'labelPlural' | 'labelSingular' | 'description',
|
||||
locale: string,
|
||||
locale: string | undefined,
|
||||
): Promise<string> {
|
||||
if (objectMetadata.isCustom) {
|
||||
return objectMetadata[labelKey];
|
||||
}
|
||||
|
||||
if (!locale) {
|
||||
return objectMetadata[labelKey];
|
||||
}
|
||||
|
||||
i18n.activate(locale);
|
||||
|
||||
return i18n._(objectMetadata[labelKey]);
|
||||
return i18n._(generateMessageId(objectMetadata[labelKey]));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user