Email translation and snackbar translation (#10395)

This pull request focuses on improving localization by replacing
hardcoded strings with translatable strings using the `Trans` component
from `@lingui/react/macro`. Additionally, it introduces locale support
to several email components. Here are the most important changes:

### Localization Improvements:

* Replaced hardcoded strings with `Trans` components in various email
templates to support localization.
(`packages/twenty-emails/src/emails/clean-suspended-workspace.email.tsx`,
`packages/twenty-emails/src/emails/password-reset-link.email.tsx`,
`packages/twenty-emails/src/emails/password-update-notify.email.tsx`,
`packages/twenty-emails/src/emails/send-email-verification-link.email.tsx`,
`packages/twenty-emails/src/emails/send-invite-link.email.tsx`,
`packages/twenty-emails/src/emails/warn-suspended-workspace.email.tsx`)
[[1]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbR6-R25)
[[2]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbL42-R45)
[[3]](diffhunk://#diff-523cd37f5680ce418450946f62b7804b6586158efb190ced73920ef0fdf96bc8L1)
[[4]](diffhunk://#diff-523cd37f5680ce418450946f62b7804b6586158efb190ced73920ef0fdf96bc8L23-R23)
[[5]](diffhunk://#diff-cf16aa55d3eeb6be606bbe93de4c83b6f146c49b60d6f512d4b87e49fe14338cL29-R29)
[[6]](diffhunk://#diff-cf16aa55d3eeb6be606bbe93de4c83b6f146c49b60d6f512d4b87e49fe14338cL46-R46)
[[7]](diffhunk://#diff-16b613160f937563ec108176f595d8f275a1d87a5b8245d84df60d775f3efebeL1)
[[8]](diffhunk://#diff-16b613160f937563ec108176f595d8f275a1d87a5b8245d84df60d775f3efebeL22-R22)
[[9]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L1)
[[10]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L42-R41)
[[11]](diffhunk://#diff-0da62e7cc5cfcb32cc25f067fa1d50123047c239af210398f065455ab6700886L57-R56)
[[12]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L1-R21)
[[13]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L28-R31)
[[14]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L53-R55)

### Locale Support:

* Added `locale` prop to email components to dynamically set the locale.
(`packages/twenty-emails/src/emails/clean-suspended-workspace.email.tsx`,
`packages/twenty-emails/src/emails/warn-suspended-workspace.email.tsx`)
[[1]](diffhunk://#diff-ca227a03c0aa66428daff938c743435e8a4dc3ffa960c0952f2697a23e280fdbR6-R25)
[[2]](diffhunk://#diff-483346065c074946a43c18492334bd680422a1d4cb994dc8c3cd39d0208e6016L1-R21)

### SnackBar Messages:

* Replaced hardcoded SnackBar messages with translatable strings using
the `t` function from `@lingui/react/macro`.
(`packages/twenty-front/src/modules/auth/components/VerifyEmailEffect.tsx`,
`packages/twenty-front/src/modules/auth/hooks/useVerifyLogin.ts`,
`packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResendEmailVerificationToken.ts`,
`packages/twenty-front/src/modules/auth/sign-in-up/hooks/useHandleResetPassword.ts`,
`packages/twenty-front/src/modules/object-record/record-field/components/LightCopyIconButton.tsx`,
`packages/twenty-front/src/modules/object-record/record-field/meta-types/display/components/PhonesFieldDisplay.tsx`)
[[1]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42R7)
[[2]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42L24-R29)
[[3]](diffhunk://#diff-551f2f94eacd8856d22bab7e63dd3ad693f87e9fa9b289864802ebc387f72b42L43-R51)
[[4]](diffhunk://#diff-428199461992a01325159f5fbf826d845f05f3361279eccd3f1ce416e0114845R7-R15)
[[5]](diffhunk://#diff-428199461992a01325159f5fbf826d845f05f3361279eccd3f1ce416e0114845L24-R26)
[[6]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403R5)
[[7]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403L16-R17)
[[8]](diffhunk://#diff-cde42d6abfed63e52c2bda09d537a6577148d0baf957fde75ceaa8657ed58403L28-R33)
[[9]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457R5-R17)
[[10]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457L27-R33)
[[11]](diffhunk://#diff-9332c1988864863f12516c2fb77e814af60bedb37c36ffa094f49afc335d5457L42-R44)
[[12]](diffhunk://#diff-8d64afa825b47ab71d18e3e284408e2097f5fd2365eae84d9d25d3568c48e49cR7)
[[13]](diffhunk://#diff-8d64afa825b47ab71d18e3e284408e2097f5fd2365eae84d9d25d3568c48e49cR20-R28)
[[14]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceR6)
[[15]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceR19-R20)
[[16]](diffhunk://#diff-6e4361ded2b5656afaeb1befa8b1d23a45b490a1118550da290e27cdb8ebcdceL29-R38)
This commit is contained in:
Félix Malfait
2025-02-23 21:15:41 +01:00
committed by GitHub
parent 2039986684
commit df0d23a365
33 changed files with 195 additions and 103 deletions

View File

@ -4,6 +4,7 @@ import { IconCopy, LightIconButton } from 'twenty-ui';
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { useLingui } from '@lingui/react/macro';
const StyledButtonContainer = styled.div`
padding: 0 ${({ theme }) => theme.spacing(1)};
@ -16,6 +17,7 @@ export type LightCopyIconButtonProps = {
export const LightCopyIconButton = ({ copyText }: LightCopyIconButtonProps) => {
const { enqueueSnackBar } = useSnackBar();
const theme = useTheme();
const { t } = useLingui();
return (
<StyledButtonContainer>
@ -23,7 +25,7 @@ export const LightCopyIconButton = ({ copyText }: LightCopyIconButtonProps) => {
className="copy-button"
Icon={IconCopy}
onClick={() => {
enqueueSnackBar('Text copied to clipboard', {
enqueueSnackBar(t`Text copied to clipboard`, {
variant: SnackBarVariant.Success,
icon: <IconCopy size={theme.icon.size.md} />,
duration: 2000,

View File

@ -3,6 +3,7 @@ import { usePhonesFieldDisplay } from '@/object-record/record-field/meta-types/h
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { PhonesDisplay } from '@/ui/field/display/components/PhonesDisplay';
import { useLingui } from '@lingui/react/macro';
import React from 'react';
import { useIcons } from 'twenty-ui';
@ -15,6 +16,8 @@ export const PhonesFieldDisplay = () => {
const { getIcon } = useIcons();
const { t } = useLingui();
const IconCircleCheck = getIcon('IconCircleCheck');
const IconExclamationCircle = getIcon('IconExclamationCircle');
@ -26,13 +29,13 @@ export const PhonesFieldDisplay = () => {
try {
await navigator.clipboard.writeText(phoneNumber);
enqueueSnackBar('Phone number copied to clipboard', {
enqueueSnackBar(t`Phone number copied to clipboard`, {
variant: SnackBarVariant.Success,
icon: <IconCircleCheck size={16} color="green" />,
duration: 2000,
});
} catch (err) {
enqueueSnackBar('Error copying to clipboard', {
enqueueSnackBar(t`Error copying to clipboard`, {
variant: SnackBarVariant.Error,
icon: <IconExclamationCircle size={16} color="red" />,
duration: 2000,

View File

@ -3,6 +3,7 @@ import { ComponentDecorator } from 'twenty-ui';
import { PhonesFieldDisplay } from '@/object-record/record-field/meta-types/display/components/PhonesFieldDisplay';
import { getFieldDecorator } from '~/testing/decorators/getFieldDecorator';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { MemoryRouterDecorator } from '~/testing/decorators/MemoryRouterDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { getProfilingStory } from '~/testing/profiling/utils/getProfilingStory';
@ -13,6 +14,7 @@ const meta: Meta = {
MemoryRouterDecorator,
getFieldDecorator('person', 'phones'),
ComponentDecorator,
I18nFrontDecorator,
SnackBarDecorator,
],
component: PhonesFieldDisplay,

View File

@ -8,6 +8,7 @@ import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { FieldContextProvider } from '@/object-record/record-field/meta-types/components/FieldContextProvider';
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { useNumberField } from '../../../hooks/useNumberField';
import { NumberFieldInput, NumberFieldInputProps } from '../NumberFieldInput';
@ -108,7 +109,7 @@ const meta: Meta = {
onTab: { control: false },
onShiftTab: { control: false },
},
decorators: [clearMocksDecorator, SnackBarDecorator],
decorators: [clearMocksDecorator, SnackBarDecorator, I18nFrontDecorator],
parameters: {
clearMocks: true,
},

View File

@ -7,6 +7,7 @@ import { FieldMetadataType } from '~/generated/graphql';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
import { StorybookFieldInputDropdownFocusIdSetterEffect } from '~/testing/components/StorybookFieldInputDropdownFocusIdSetterEffect';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { FieldContextProvider } from '../../../components/FieldContextProvider';
import { useTextField } from '../../../hooks/useTextField';
import { TextFieldInput, TextFieldInputProps } from '../TextFieldInput';
@ -107,7 +108,7 @@ const meta: Meta = {
onTab: { control: false },
onShiftTab: { control: false },
},
decorators: [clearMocksDecorator, SnackBarDecorator],
decorators: [clearMocksDecorator, SnackBarDecorator, I18nFrontDecorator],
parameters: {
clearMocks: true,
},