Add more translations (#9733)
This commit is contained in:
@ -12,6 +12,7 @@ import { isAdvancedModeEnabledState } from '@/ui/navigation/navigation-drawer/st
|
||||
import { useIsSettingsDrawer } from '@/navigation/hooks/useIsSettingsDrawer';
|
||||
|
||||
import { MainNavigationDrawerItems } from '@/navigation/components/MainNavigationDrawerItems';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { AdvancedSettingsToggle } from 'twenty-ui';
|
||||
|
||||
export type AppNavigationDrawerProps = {
|
||||
@ -28,9 +29,11 @@ export const AppNavigationDrawer = ({
|
||||
isAdvancedModeEnabledState,
|
||||
);
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const drawerProps: NavigationDrawerProps = isSettingsDrawer
|
||||
? {
|
||||
title: 'Exit Settings',
|
||||
title: t`'Exit Settings'`,
|
||||
children: <SettingsNavigationDrawerItems />,
|
||||
footer: (
|
||||
<AdvancedSettingsToggle
|
||||
|
||||
@ -11,6 +11,7 @@ import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { isNavigationDrawerExpandedState } from '@/ui/navigation/states/isNavigationDrawerExpanded';
|
||||
import { i18nFrontDecorator } from '~/testing/decorators/i18nFrontDecorator';
|
||||
import {
|
||||
AppNavigationDrawer,
|
||||
AppNavigationDrawerProps,
|
||||
@ -54,6 +55,7 @@ const meta: Meta<StoryArgs> = {
|
||||
decorators: [
|
||||
IconsProviderDecorator,
|
||||
ObjectMetadataItemsDecorator,
|
||||
i18nFrontDecorator,
|
||||
(Story, { args }) => (
|
||||
<MemoryRouter initialEntries={[args.routePath]}>
|
||||
<Story />
|
||||
|
||||
@ -9,8 +9,11 @@ import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
|
||||
import { SettingsAccountsBlocklistInput } from '@/settings/accounts/components/SettingsAccountsBlocklistInput';
|
||||
import { SettingsAccountsBlocklistTable } from '@/settings/accounts/components/SettingsAccountsBlocklistTable';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
export const SettingsAccountsBlocklistSection = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
|
||||
const { records: blocklist } = useFindManyRecords<BlocklistItem>({
|
||||
@ -40,8 +43,8 @@ export const SettingsAccountsBlocklistSection = () => {
|
||||
return (
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Blocklist"
|
||||
description="Exclude the following people and domains from my email sync"
|
||||
title={t`Blocklist`}
|
||||
description={t`Exclude the following people and domains from my email sync`}
|
||||
/>
|
||||
<SettingsAccountsBlocklistInput
|
||||
blockedEmailOrDomainList={blocklist.map((item) => item.handle)}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
import { SettingsCard } from '@/settings/components/SettingsCard';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
|
||||
|
||||
const StyledCardsContainer = styled.div`
|
||||
@ -24,12 +25,13 @@ const StyledCardsContainer = styled.div`
|
||||
`;
|
||||
|
||||
export const SettingsAccountsSettingsSection = () => {
|
||||
const { t } = useLingui();
|
||||
const theme = useTheme();
|
||||
return (
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Settings"
|
||||
description="Configure your emails and calendar settings."
|
||||
title={t`Settings`}
|
||||
description={t`Configure your emails and calendar settings.`}
|
||||
/>
|
||||
<StyledCardsContainer>
|
||||
<UndecoratedLink to={getSettingsPath(SettingsPath.AccountsEmails)}>
|
||||
@ -40,8 +42,8 @@ export const SettingsAccountsSettingsSection = () => {
|
||||
stroke={theme.icon.stroke.sm}
|
||||
/>
|
||||
}
|
||||
title="Emails"
|
||||
description="Set email visibility, manage your blocklist and more."
|
||||
title={t`Emails`}
|
||||
description={t`Set email visibility, manage your blocklist and more.`}
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
<UndecoratedLink to={getSettingsPath(SettingsPath.AccountsCalendars)}>
|
||||
@ -52,8 +54,8 @@ export const SettingsAccountsSettingsSection = () => {
|
||||
stroke={theme.icon.stroke.sm}
|
||||
/>
|
||||
}
|
||||
title="Calendar"
|
||||
description="Configure and customize your calendar preferences."
|
||||
title={t`Calendar`}
|
||||
description={t`Configure and customize your calendar preferences.`}
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
</StyledCardsContainer>
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
import { H2Title, Section } from 'twenty-ui';
|
||||
|
||||
import { SettingsAccountsListEmptyStateCard } from '@/settings/accounts/components/SettingsAccountsListEmptyStateCard';
|
||||
import { t } from '@lingui/core/macro';
|
||||
|
||||
export const SettingsNewAccountSection = () => {
|
||||
return (
|
||||
<Section>
|
||||
<H2Title
|
||||
title="New account"
|
||||
description="Connect a new account to your workspace"
|
||||
title={t`New account`}
|
||||
description={t`Connect a new account to your workspace`}
|
||||
/>
|
||||
<SettingsAccountsListEmptyStateCard label="Connect a Google account" />
|
||||
<SettingsAccountsListEmptyStateCard label={t`Connect a Google account`} />
|
||||
</Section>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,9 +4,12 @@ import { Button, H2Title } from 'twenty-ui';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
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';
|
||||
import { useEmailPasswordResetLinkMutation } from '~/generated/graphql';
|
||||
|
||||
export const ChangePassword = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
|
||||
const currentUser = useRecoilValue(currentUserState);
|
||||
@ -15,7 +18,7 @@ export const ChangePassword = () => {
|
||||
|
||||
const handlePasswordResetClick = async () => {
|
||||
if (!currentUser?.email) {
|
||||
enqueueSnackBar('Invalid email', {
|
||||
enqueueSnackBar(t`Invalid email`, {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
return;
|
||||
@ -28,11 +31,11 @@ export const ChangePassword = () => {
|
||||
},
|
||||
});
|
||||
if (data?.emailPasswordResetLink?.success === true) {
|
||||
enqueueSnackBar('Password reset link has been sent to the email', {
|
||||
enqueueSnackBar(t`Password reset link has been sent to the email`, {
|
||||
variant: SnackBarVariant.Success,
|
||||
});
|
||||
} else {
|
||||
enqueueSnackBar('There was some issue', {
|
||||
enqueueSnackBar(t`There was an issue`, {
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
}
|
||||
@ -46,13 +49,13 @@ export const ChangePassword = () => {
|
||||
return (
|
||||
<>
|
||||
<H2Title
|
||||
title="Change Password"
|
||||
description="Receive an email containing password update link"
|
||||
title={t`Change Password`}
|
||||
description={t`Receive an email containing password update link`}
|
||||
/>
|
||||
<Button
|
||||
onClick={handlePasswordResetClick}
|
||||
variant="secondary"
|
||||
title="Change Password"
|
||||
title={t`Change Password`}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -5,9 +5,11 @@ import { Button, H2Title } from 'twenty-ui';
|
||||
import { useAuth } from '@/auth/hooks/useAuth';
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useDeleteUserAccountMutation } from '~/generated/graphql';
|
||||
|
||||
export const DeleteAccount = () => {
|
||||
const { t } = useLingui();
|
||||
const [isDeleteAccountModalOpen, setIsDeleteAccountModalOpen] =
|
||||
useState(false);
|
||||
|
||||
@ -24,15 +26,15 @@ export const DeleteAccount = () => {
|
||||
return (
|
||||
<>
|
||||
<H2Title
|
||||
title="Danger zone"
|
||||
description="Delete account and all the associated data"
|
||||
title={t`Danger zone`}
|
||||
description={t`Delete account and all the associated data`}
|
||||
/>
|
||||
|
||||
<Button
|
||||
accent="danger"
|
||||
onClick={() => setIsDeleteAccountModalOpen(true)}
|
||||
variant="secondary"
|
||||
title="Delete account"
|
||||
title={t`Delete account`}
|
||||
/>
|
||||
|
||||
<ConfirmationModal
|
||||
@ -40,7 +42,7 @@ export const DeleteAccount = () => {
|
||||
confirmationPlaceholder={userEmail ?? ''}
|
||||
isOpen={isDeleteAccountModalOpen}
|
||||
setIsOpen={setIsDeleteAccountModalOpen}
|
||||
title="Account Deletion"
|
||||
title={t`Account Deletion`}
|
||||
subtitle={
|
||||
<>
|
||||
This action cannot be undone. This will permanently delete your
|
||||
@ -48,7 +50,7 @@ export const DeleteAccount = () => {
|
||||
</>
|
||||
}
|
||||
onConfirmClick={deleteAccount}
|
||||
deleteButtonText="Delete account"
|
||||
deleteButtonText={t`Delete account`}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@ -12,6 +12,7 @@ import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/Snac
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import isPropValid from '@emotion/is-prop-valid';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { IconKey } from 'twenty-ui';
|
||||
import { useListSsoIdentityProvidersByWorkspaceIdQuery } from '~/generated/graphql';
|
||||
@ -29,6 +30,8 @@ export const SettingsSSOIdentitiesProvidersListCard = () => {
|
||||
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
|
||||
const { t } = useLingui();
|
||||
|
||||
const [SSOIdentitiesProviders, setSSOIdentitiesProviders] = useRecoilState(
|
||||
SSOIdentitiesProvidersState,
|
||||
);
|
||||
@ -53,7 +56,7 @@ export const SettingsSSOIdentitiesProvidersListCard = () => {
|
||||
isDisabled={currentWorkspace?.hasValidEntrepriseKey !== true}
|
||||
>
|
||||
<SettingsCard
|
||||
title="Add SSO Identity Provider"
|
||||
title={t`Add SSO Identity Provider`}
|
||||
disabled={currentWorkspace?.hasValidEntrepriseKey !== true}
|
||||
Icon={<IconKey />}
|
||||
/>
|
||||
|
||||
@ -5,6 +5,7 @@ import { SSOIdentitiesProvidersState } from '@/settings/security/states/SSOIdent
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import styled from '@emotion/styled';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import { capitalize } from 'twenty-shared';
|
||||
import {
|
||||
@ -24,6 +25,8 @@ const StyledSettingsSecurityOptionsList = styled.div`
|
||||
`;
|
||||
|
||||
export const SettingsSecurityOptionsList = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const SSOIdentitiesProviders = useRecoilValue(SSOIdentitiesProvidersState);
|
||||
const authProviders = useRecoilValue(authProvidersState);
|
||||
@ -45,13 +48,13 @@ export const SettingsSecurityOptionsList = () => {
|
||||
authProvider: keyof Omit<AuthProviders, '__typename' | 'magicLink' | 'sso'>,
|
||||
) => {
|
||||
if (!currentWorkspace?.id) {
|
||||
throw new Error('User is not logged in');
|
||||
throw new Error(t`User is not logged in`);
|
||||
}
|
||||
|
||||
const key = `is${capitalize(authProvider)}AuthEnabled`;
|
||||
|
||||
if (!isValidAuthProvider(key)) {
|
||||
throw new Error('Invalid auth provider');
|
||||
throw new Error(t`Invalid auth provider`);
|
||||
}
|
||||
|
||||
const allAuthProvidersEnabled = [
|
||||
@ -67,7 +70,7 @@ export const SettingsSecurityOptionsList = () => {
|
||||
1
|
||||
) {
|
||||
return enqueueSnackBar(
|
||||
'At least one authentication method must be enabled',
|
||||
t`At least one authentication method must be enabled`,
|
||||
{
|
||||
variant: SnackBarVariant.Error,
|
||||
},
|
||||
@ -100,7 +103,7 @@ export const SettingsSecurityOptionsList = () => {
|
||||
const handleChange = async (value: boolean) => {
|
||||
try {
|
||||
if (!currentWorkspace?.id) {
|
||||
throw new Error('User is not logged in');
|
||||
throw new Error(t`User is not logged in`);
|
||||
}
|
||||
await updateWorkspace({
|
||||
variables: {
|
||||
@ -129,7 +132,7 @@ export const SettingsSecurityOptionsList = () => {
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconGoogle}
|
||||
title="Google"
|
||||
description="Allow logins through Google's single sign-on functionality."
|
||||
description={t`Allow logins through Google's single sign-on functionality.`}
|
||||
checked={currentWorkspace.isGoogleAuthEnabled}
|
||||
advancedMode
|
||||
divider
|
||||
@ -140,7 +143,7 @@ export const SettingsSecurityOptionsList = () => {
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconMicrosoft}
|
||||
title="Microsoft"
|
||||
description="Allow logins through Microsoft's single sign-on functionality."
|
||||
description={t`Allow logins through Microsoft's single sign-on functionality.`}
|
||||
checked={currentWorkspace.isMicrosoftAuthEnabled}
|
||||
advancedMode
|
||||
divider
|
||||
@ -150,8 +153,8 @@ export const SettingsSecurityOptionsList = () => {
|
||||
{authProviders.password === true && (
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconPassword}
|
||||
title="Password"
|
||||
description="Allow users to sign in with an email and password."
|
||||
title={t`Password`}
|
||||
description={t`Allow users to sign in with an email and password.`}
|
||||
checked={currentWorkspace.isPasswordAuthEnabled}
|
||||
advancedMode
|
||||
onChange={() => toggleAuthMethod('password')}
|
||||
@ -161,8 +164,8 @@ export const SettingsSecurityOptionsList = () => {
|
||||
<Card rounded>
|
||||
<SettingsOptionCardContentToggle
|
||||
Icon={IconLink}
|
||||
title="Invite by Link"
|
||||
description="Allow the invitation of new users by sharing an invite link."
|
||||
title={t`Invite by Link`}
|
||||
description={t`Allow the invitation of new users by sharing an invite link.`}
|
||||
checked={currentWorkspace.isPublicInviteLinkEnabled}
|
||||
advancedMode
|
||||
onChange={() =>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
import { ComponentDecorator } from 'twenty-ui';
|
||||
|
||||
import { i18nDecoratorFront } from '~/testing/decorators/i18nDecoratorFront';
|
||||
import { i18nFrontDecorator } from '~/testing/decorators/i18nFrontDecorator';
|
||||
import { workspaceLogoUrl } from '~/testing/mock-data/users';
|
||||
|
||||
import { ImageInput } from '../ImageInput';
|
||||
@ -9,7 +9,7 @@ import { ImageInput } from '../ImageInput';
|
||||
const meta: Meta<typeof ImageInput> = {
|
||||
title: 'UI/Input/ImageInput/ImageInput',
|
||||
component: ImageInput,
|
||||
decorators: [ComponentDecorator, i18nDecoratorFront],
|
||||
decorators: [ComponentDecorator, i18nFrontDecorator],
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
Reference in New Issue
Block a user