Translations - Crowdin, Set workspace member locale on signup, and optimizations (#10091)
More progress on translations: - Migrate from translations.io to crowdin - Optimize performance and robustness - Set workspaceMember/user locale upon signup
This commit is contained in:
@@ -197,6 +197,7 @@ export class AuthResolver {
|
||||
const { userData } = this.authService.formatUserDataPayload(
|
||||
{
|
||||
email: signUpInput.email,
|
||||
locale: signUpInput.locale,
|
||||
},
|
||||
existingUser,
|
||||
);
|
||||
|
||||
+3
-1
@@ -18,8 +18,8 @@ import { GoogleProviderEnabledGuard } from 'src/engine/core-modules/auth/guards/
|
||||
import { AuthService } from 'src/engine/core-modules/auth/services/auth.service';
|
||||
import { GoogleRequest } from 'src/engine/core-modules/auth/strategies/google.auth.strategy';
|
||||
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
|
||||
@Controller('auth/google')
|
||||
@UseFilters(AuthRestApiExceptionFilter)
|
||||
@@ -51,6 +51,7 @@ export class GoogleAuthController {
|
||||
workspaceInviteHash,
|
||||
workspaceId,
|
||||
billingCheckoutSessionState,
|
||||
locale,
|
||||
} = req.user;
|
||||
|
||||
const currentWorkspace = await this.authService.findWorkspaceForSignInUp({
|
||||
@@ -79,6 +80,7 @@ export class GoogleAuthController {
|
||||
lastName,
|
||||
email,
|
||||
picture,
|
||||
locale,
|
||||
},
|
||||
existingUser,
|
||||
);
|
||||
|
||||
+3
-1
@@ -17,8 +17,8 @@ import { MicrosoftProviderEnabledGuard } from 'src/engine/core-modules/auth/guar
|
||||
import { AuthService } from 'src/engine/core-modules/auth/services/auth.service';
|
||||
import { MicrosoftRequest } from 'src/engine/core-modules/auth/strategies/microsoft.auth.strategy';
|
||||
import { LoginTokenService } from 'src/engine/core-modules/auth/token/services/login-token.service';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { GuardRedirectService } from 'src/engine/core-modules/guard-redirect/services/guard-redirect.service';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
|
||||
@Controller('auth/microsoft')
|
||||
@UseFilters(AuthRestApiExceptionFilter)
|
||||
@@ -52,6 +52,7 @@ export class MicrosoftAuthController {
|
||||
workspaceInviteHash,
|
||||
workspaceId,
|
||||
billingCheckoutSessionState,
|
||||
locale,
|
||||
} = req.user;
|
||||
|
||||
const currentWorkspace = await this.authService.findWorkspaceForSignInUp({
|
||||
@@ -80,6 +81,7 @@ export class MicrosoftAuthController {
|
||||
lastName,
|
||||
email,
|
||||
picture,
|
||||
locale,
|
||||
},
|
||||
existingUser,
|
||||
);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ArgsType, Field } from '@nestjs/graphql';
|
||||
|
||||
import { IsEmail, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
@ArgsType()
|
||||
export class SignUpInput {
|
||||
@@ -33,4 +34,9 @@ export class SignUpInput {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
captchaToken?: string;
|
||||
|
||||
@Field(() => String, { nullable: true })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
locale?: keyof typeof APP_LOCALES;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
||||
|
||||
import { Request } from 'express';
|
||||
import { Strategy, VerifyCallback } from 'passport-google-oauth20';
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
import { EnvironmentService } from 'src/engine/core-modules/environment/environment.service';
|
||||
|
||||
@@ -15,6 +16,7 @@ export type GoogleRequest = Omit<
|
||||
lastName?: string | null;
|
||||
email: string;
|
||||
picture: string | null;
|
||||
locale?: keyof typeof APP_LOCALES | null;
|
||||
workspaceInviteHash?: string;
|
||||
workspacePersonalInviteToken?: string;
|
||||
workspaceId?: string;
|
||||
@@ -70,6 +72,7 @@ export class GoogleStrategy extends PassportStrategy(Strategy, 'google') {
|
||||
workspacePersonalInviteToken: state.workspacePersonalInviteToken,
|
||||
workspaceId: state.workspaceId,
|
||||
billingCheckoutSessionState: state.billingCheckoutSessionState,
|
||||
locale: state.locale,
|
||||
};
|
||||
|
||||
done(null, user);
|
||||
|
||||
+4
@@ -3,6 +3,7 @@ import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Request } from 'express';
|
||||
import { VerifyCallback } from 'passport-google-oauth20';
|
||||
import { Strategy } from 'passport-microsoft';
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
import {
|
||||
AuthException,
|
||||
@@ -19,6 +20,7 @@ export type MicrosoftRequest = Omit<
|
||||
lastName?: string | null;
|
||||
email: string;
|
||||
picture: string | null;
|
||||
locale?: keyof typeof APP_LOCALES | null;
|
||||
workspaceInviteHash?: string;
|
||||
workspacePersonalInviteToken?: string;
|
||||
workspaceId?: string;
|
||||
@@ -44,6 +46,7 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
|
||||
state: JSON.stringify({
|
||||
workspaceInviteHash: req.query.workspaceInviteHash,
|
||||
workspaceId: req.params.workspaceId,
|
||||
locale: req.query.locale,
|
||||
billingCheckoutSessionState: req.query.billingCheckoutSessionState,
|
||||
workspacePersonalInviteToken: req.query.workspacePersonalInviteToken,
|
||||
}),
|
||||
@@ -84,6 +87,7 @@ export class MicrosoftStrategy extends PassportStrategy(Strategy, 'microsoft') {
|
||||
workspacePersonalInviteToken: state.workspacePersonalInviteToken,
|
||||
workspaceId: state.workspaceId,
|
||||
billingCheckoutSessionState: state.billingCheckoutSessionState,
|
||||
locale: state.locale,
|
||||
};
|
||||
|
||||
done(null, user);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { WorkspaceAuthProvider } from 'src/engine/core-modules/workspace/types/workspace.type';
|
||||
import { AppToken } from 'src/engine/core-modules/app-token/app-token.entity';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
export type SignInUpBaseParams = {
|
||||
@@ -15,6 +17,7 @@ export type SignInUpNewUserPayload = {
|
||||
lastName?: string | null;
|
||||
picture?: string | null;
|
||||
passwordHash?: string | null;
|
||||
locale?: keyof typeof APP_LOCALES | null;
|
||||
};
|
||||
|
||||
export type PartialUserWithPicture = {
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Injectable, NestMiddleware } from '@nestjs/common';
|
||||
|
||||
import { i18n } from '@lingui/core';
|
||||
import { NextFunction, Request, Response } from 'express';
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
@Injectable()
|
||||
export class I18nMiddleware implements NestMiddleware {
|
||||
use(req: Request, res: Response, next: NextFunction) {
|
||||
const locale = req.headers['x-locale'] as keyof typeof APP_LOCALES;
|
||||
|
||||
if (locale && Object.values(APP_LOCALES).includes(locale)) {
|
||||
i18n.activate(locale);
|
||||
} else {
|
||||
i18n.activate('en');
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Global, Module } from '@nestjs/common';
|
||||
import { Global, MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
|
||||
|
||||
import { I18nMiddleware } from 'src/engine/core-modules/i18n/i18n.middleware';
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
|
||||
@Global()
|
||||
@@ -7,4 +8,8 @@ import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
providers: [I18nService],
|
||||
exports: [I18nService],
|
||||
})
|
||||
export class I18nModule {}
|
||||
export class I18nModule implements NestModule {
|
||||
configure(consumer: MiddlewareConsumer) {
|
||||
consumer.apply(I18nMiddleware).forRoutes('*');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,35 +1,44 @@
|
||||
import { Injectable, OnModuleInit } from '@nestjs/common';
|
||||
|
||||
import { i18n } from '@lingui/core';
|
||||
import { APP_LOCALES } from 'twenty-shared';
|
||||
|
||||
import { messages as deMessages } from 'src/engine/core-modules/i18n/locales/generated/de';
|
||||
import { messages as deMessages } from 'src/engine/core-modules/i18n/locales/generated/de-DE';
|
||||
import { messages as enMessages } from 'src/engine/core-modules/i18n/locales/generated/en';
|
||||
import { messages as esMessages } from 'src/engine/core-modules/i18n/locales/generated/es';
|
||||
import { messages as frMessages } from 'src/engine/core-modules/i18n/locales/generated/fr';
|
||||
import { messages as itMessages } from 'src/engine/core-modules/i18n/locales/generated/it';
|
||||
import { messages as jaMessages } from 'src/engine/core-modules/i18n/locales/generated/ja';
|
||||
import { messages as koMessages } from 'src/engine/core-modules/i18n/locales/generated/ko';
|
||||
import { messages as esMessages } from 'src/engine/core-modules/i18n/locales/generated/es-ES';
|
||||
import { messages as frMessages } from 'src/engine/core-modules/i18n/locales/generated/fr-FR';
|
||||
import { messages as itMessages } from 'src/engine/core-modules/i18n/locales/generated/it-IT';
|
||||
import { messages as jaMessages } from 'src/engine/core-modules/i18n/locales/generated/ja-JP';
|
||||
import { messages as koMessages } from 'src/engine/core-modules/i18n/locales/generated/ko-KR';
|
||||
import { messages as pseudoEnMessages } from 'src/engine/core-modules/i18n/locales/generated/pseudo-en';
|
||||
import { messages as ptBRMessages } from 'src/engine/core-modules/i18n/locales/generated/pt-BR';
|
||||
import { messages as ptPTMessages } from 'src/engine/core-modules/i18n/locales/generated/pt-PT';
|
||||
import { messages as zhHansMessages } from 'src/engine/core-modules/i18n/locales/generated/zh-Hans';
|
||||
import { messages as zhHantMessages } from 'src/engine/core-modules/i18n/locales/generated/zh-Hant';
|
||||
import { messages as zhHansMessages } from 'src/engine/core-modules/i18n/locales/generated/zh-CN';
|
||||
import { messages as zhHantMessages } from 'src/engine/core-modules/i18n/locales/generated/zh-TW';
|
||||
|
||||
@Injectable()
|
||||
export class I18nService implements OnModuleInit {
|
||||
async loadTranslations() {
|
||||
i18n.load('en', enMessages);
|
||||
i18n.load('fr', frMessages);
|
||||
i18n.load('pseudo-en', pseudoEnMessages);
|
||||
i18n.load('ko', koMessages);
|
||||
i18n.load('de', deMessages);
|
||||
i18n.load('it', itMessages);
|
||||
i18n.load('es', esMessages);
|
||||
i18n.load('ja', jaMessages);
|
||||
i18n.load('pt-PT', ptPTMessages);
|
||||
i18n.load('pt-BR', ptBRMessages);
|
||||
i18n.load('zh-Hans', zhHansMessages);
|
||||
i18n.load('zh-Hant', zhHantMessages);
|
||||
const messages: Record<keyof typeof APP_LOCALES, any> = {
|
||||
en: enMessages,
|
||||
'pseudo-en': pseudoEnMessages,
|
||||
'fr-FR': frMessages,
|
||||
'ko-KR': koMessages,
|
||||
'de-DE': deMessages,
|
||||
'it-IT': itMessages,
|
||||
'es-ES': esMessages,
|
||||
'ja-JP': jaMessages,
|
||||
'pt-PT': ptPTMessages,
|
||||
'pt-BR': ptBRMessages,
|
||||
'zh-CN': zhHansMessages,
|
||||
'zh-TW': zhHantMessages,
|
||||
};
|
||||
|
||||
(Object.entries(messages) as [keyof typeof APP_LOCALES, any][]).forEach(
|
||||
([locale, message]) => {
|
||||
i18n.load(locale, message);
|
||||
},
|
||||
);
|
||||
|
||||
i18n.activate('en');
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: de\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: German\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: de\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "Ihr Teammitglied, das für die Verwaltung des Unternehmenskontos verantwortlich ist"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: es\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Spanish\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: es\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "Miembro de su equipo responsable de gestionar la cuenta de la empresa"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: fr\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: French\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: fr\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "Le membre de votre équipe responsable de la gestion du compte entreprise"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: it\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Italian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: it\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "Il membro del team responsabile della gestione dell'account aziendale"
|
||||
|
||||
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: ja\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Japanese\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: ja\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr ""
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr ""
|
||||
|
||||
+12
-6
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: ko\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Korean\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: ko\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "회사 계정을 관리하는 팀원"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: pt-BR\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Language: pt\n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: pt-BR\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "Seu membro da equipe responsável por gerenciar a conta da empresa"
|
||||
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: pt-PT\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Language: pt\n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Portuguese\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: pt\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "O membro da sua equipa responsável pela gestão da conta da empresa"
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+13
-7
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: zh-Hans\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: zh-CN\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "负责管理公司账户的团队成员"
|
||||
|
||||
+13
-7
@@ -1,17 +1,22 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"POT-Creation-Date: 2025-02-01 10:10+0100\n"
|
||||
"POT-Creation-Date: 2025-01-29 18:14+0100\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=utf-8\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: @lingui/cli\n"
|
||||
"Language: zh-Hant\n"
|
||||
"Project-Id-Version: \n"
|
||||
"Language: zh\n"
|
||||
"Project-Id-Version: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"PO-Revision-Date: \n"
|
||||
"PO-Revision-Date: 2025-02-09 12:39\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Plural-Forms: \n"
|
||||
"Language-Team: Chinese Traditional\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Crowdin-Project: cf448e737e0d6d7b78742f963d761c61\n"
|
||||
"X-Crowdin-Project-ID: 1\n"
|
||||
"X-Crowdin-Language: zh-TW\n"
|
||||
"X-Crowdin-File: /packages/twenty-server/src/engine/core-modules/i18n/locales/en.po\n"
|
||||
"X-Crowdin-File-ID: 31\n"
|
||||
|
||||
#: src/modules/view/standard-objects/view-field.workspace-entity.ts:32
|
||||
msgid "(System) View Fields"
|
||||
@@ -2240,3 +2245,4 @@ msgstr "X"
|
||||
#: src/modules/company/standard-objects/company.workspace-entity.ts:177
|
||||
msgid "Your team member responsible for managing the company account"
|
||||
msgstr "負責管理公司帳戶的團隊成員"
|
||||
|
||||
+4
-3
@@ -13,6 +13,7 @@ import {
|
||||
AuthExceptionCode,
|
||||
} from 'src/engine/core-modules/auth/auth.exception';
|
||||
import { AvailableWorkspaceOutput } from 'src/engine/core-modules/auth/dto/available-workspaces.output';
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
import { UserWorkspace } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { User } from 'src/engine/core-modules/user/user.entity';
|
||||
import { userValidator } from 'src/engine/core-modules/user/user.validate';
|
||||
@@ -24,7 +25,6 @@ import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.
|
||||
import { WorkspaceEventEmitter } from 'src/engine/workspace-event-emitter/workspace-event-emitter';
|
||||
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
|
||||
import { assert } from 'src/utils/assert';
|
||||
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
|
||||
|
||||
export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspace> {
|
||||
constructor(
|
||||
@@ -70,14 +70,15 @@ export class UserWorkspaceService extends TypeOrmQueryService<UserWorkspace> {
|
||||
|
||||
await workspaceDataSource?.query(
|
||||
`INSERT INTO ${dataSourceMetadata.schema}."workspaceMember"
|
||||
("nameFirstName", "nameLastName", "colorScheme", "userId", "userEmail", "avatarUrl")
|
||||
VALUES ($1, $2, 'System', $3, $4, $5)`,
|
||||
("nameFirstName", "nameLastName", "colorScheme", "userId", "userEmail", "avatarUrl", "locale")
|
||||
VALUES ($1, $2, 'System', $3, $4, $5, $6)`,
|
||||
[
|
||||
user.firstName,
|
||||
user.lastName,
|
||||
user.id,
|
||||
user.email,
|
||||
user.defaultAvatarUrl ?? '',
|
||||
user.locale ?? 'en',
|
||||
],
|
||||
);
|
||||
const workspaceMember = await workspaceDataSource?.query(
|
||||
|
||||
@@ -81,6 +81,10 @@ export class User {
|
||||
@DeleteDateColumn({ type: 'timestamptz' })
|
||||
deletedAt: Date;
|
||||
|
||||
@Field(() => String, { nullable: false })
|
||||
@Column({ nullable: false, default: 'en' })
|
||||
locale: string;
|
||||
|
||||
@OneToMany(() => AppToken, (appToken) => appToken.user, {
|
||||
cascade: true,
|
||||
})
|
||||
|
||||
+39
-2
@@ -2,10 +2,10 @@ import { Field, InputType } from '@nestjs/graphql';
|
||||
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNotIn,
|
||||
IsOptional,
|
||||
IsString,
|
||||
Matches,
|
||||
IsNotIn,
|
||||
} from 'class-validator';
|
||||
|
||||
@InputType()
|
||||
@@ -92,11 +92,48 @@ export class UpdateWorkspaceInput {
|
||||
'au',
|
||||
'nz',
|
||||
'za',
|
||||
'uk',
|
||||
'eu',
|
||||
'uk',
|
||||
'ru',
|
||||
'ua',
|
||||
'pl',
|
||||
'ro',
|
||||
'bg',
|
||||
'gr',
|
||||
'cz',
|
||||
'sk',
|
||||
'hu',
|
||||
'hr',
|
||||
'si',
|
||||
'rs',
|
||||
'me',
|
||||
'ba',
|
||||
'mk',
|
||||
'al',
|
||||
'az',
|
||||
'tr',
|
||||
'cy',
|
||||
'lv',
|
||||
'lt',
|
||||
'ee',
|
||||
'fi',
|
||||
'is',
|
||||
'no',
|
||||
'se',
|
||||
'dk',
|
||||
'asia',
|
||||
'africa',
|
||||
'america',
|
||||
'europe',
|
||||
'north-america',
|
||||
'south-africa',
|
||||
'north-africa',
|
||||
'south-america',
|
||||
'oceania',
|
||||
'paris',
|
||||
'london',
|
||||
'new-york',
|
||||
'san-francisco',
|
||||
])
|
||||
subdomain?: string;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user