Add missing translations (#10414)

As per title, add ~200 missing translations in different places of app.
Most places are now available for translation with AI but still some
aren't available - some enums (like in MenuItemSelectColor.tsx) or
values in complex types (like in
SettingsNonCompositeFieldTypeConfigs.ts) or values where are injected
some variables (like in SettingsDataModelFieldNumberForm.tsx)

---------

Co-authored-by: Félix Malfait <felix@twenty.com>
This commit is contained in:
BOHEUS
2025-02-23 22:35:03 +00:00
committed by GitHub
parent 2162538b8b
commit ff001d9def
135 changed files with 24834 additions and 311 deletions

View File

@ -4,6 +4,7 @@ import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdow
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useResetFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useResetFilterDropdown';
import { t } from '@lingui/core/macro';
type AddObjectFilterFromDetailsButtonProps = {
filterDropdownId?: string;
};
@ -24,7 +25,7 @@ export const AddObjectFilterFromDetailsButton = ({
<LightButton
onClick={handleClick}
Icon={IconPlus}
title="Add filter"
title={t`Add filter`}
accent="tertiary"
/>
);

View File

@ -1,39 +1,40 @@
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { t } from '@lingui/core/macro';
export const getOperandLabel = (
operand: ViewFilterOperand | null | undefined,
) => {
switch (operand) {
case ViewFilterOperand.Contains:
return 'Contains';
return t`Contains`;
case ViewFilterOperand.DoesNotContain:
return "Doesn't contain";
return t`Doesn't contain`;
case ViewFilterOperand.GreaterThan:
return 'Greater than';
return t`Greater than`;
case ViewFilterOperand.LessThan:
return 'Less than';
return t`Less than`;
case ViewFilterOperand.IsBefore:
return 'Is before';
return t`Is before`;
case ViewFilterOperand.IsAfter:
return 'Is after';
return t`Is after`;
case ViewFilterOperand.Is:
return 'Is';
return t`Is`;
case ViewFilterOperand.IsNot:
return 'Is not';
return t`Is not`;
case ViewFilterOperand.IsNotNull:
return 'Is not null';
return t`Is not null`;
case ViewFilterOperand.IsEmpty:
return 'Is empty';
return t`Is empty`;
case ViewFilterOperand.IsNotEmpty:
return 'Is not empty';
return t`Is not empty`;
case ViewFilterOperand.IsRelative:
return 'Is relative';
return t`Is relative`;
case ViewFilterOperand.IsInPast:
return 'Is in past';
return t`Is in past`;
case ViewFilterOperand.IsInFuture:
return 'Is in future';
return t`Is in future`;
case ViewFilterOperand.IsToday:
return 'Is today';
return t`Is today`;
default:
return '';
}
@ -48,13 +49,13 @@ export const getOperandLabelShort = (
return ': ';
case ViewFilterOperand.IsNot:
case ViewFilterOperand.DoesNotContain:
return ': Not';
return t`: Not`;
case ViewFilterOperand.IsNotNull:
return ': NotNull';
return t`: NotNull`;
case ViewFilterOperand.IsNotEmpty:
return ': NotEmpty';
return t`: NotEmpty`;
case ViewFilterOperand.IsEmpty:
return ': Empty';
return t`: Empty`;
case ViewFilterOperand.GreaterThan:
return '\u00A0> ';
case ViewFilterOperand.LessThan:
@ -64,11 +65,11 @@ export const getOperandLabelShort = (
case ViewFilterOperand.IsAfter:
return '\u00A0> ';
case ViewFilterOperand.IsInPast:
return ': Past';
return t`: Past`;
case ViewFilterOperand.IsInFuture:
return ': Future';
return t`: Future`;
case ViewFilterOperand.IsToday:
return ': Today';
return t`: Today`;
default:
return ': ';
}

View File

@ -8,8 +8,10 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { ViewType } from '@/views/types/ViewType';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownFieldsContent = () => {
const { t } = useLingui();
const {
viewType,
recordIndexId,
@ -50,10 +52,10 @@ export const ObjectOptionsDropdownFieldsContent = () => {
return (
<>
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={resetContent}>
Fields
{t`Fields`}
</DropdownMenuHeader>
<ViewFieldsVisibilityDropdownSection
title="Visible"
title={t`Visible`}
fields={visibleRecordFields}
isDraggable
onDragEnd={handleReorderFields}
@ -66,7 +68,7 @@ export const ObjectOptionsDropdownFieldsContent = () => {
<MenuItemNavigate
onClick={() => onContentChange('hiddenFields')}
LeftIcon={IconEyeOff}
text="Hidden Fields"
text={t`Hidden Fields`}
/>
</DropdownMenuItemsContainer>
</>

View File

@ -20,8 +20,10 @@ import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMe
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { ViewType } from '@/views/types/ViewType';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownHiddenFieldsContent = () => {
const { t } = useLingui();
const {
viewType,
recordIndexId,
@ -67,11 +69,11 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
StartIcon={IconChevronLeft}
onClick={() => onContentChange('fields')}
>
Hidden Fields
{t`Hidden Fields`}
</DropdownMenuHeader>
{hiddenRecordFields.length > 0 && (
<ViewFieldsVisibilityDropdownSection
title="Hidden"
title={t`Hidden`}
fields={hiddenRecordFields}
isDraggable={false}
onVisibilityChange={handleChangeFieldVisibility}
@ -88,7 +90,7 @@ export const ObjectOptionsDropdownHiddenFieldsContent = () => {
}}
>
<DropdownMenuItemsContainer scrollable={false}>
<MenuItem LeftIcon={IconSettings} text="Edit Fields" />
<MenuItem LeftIcon={IconSettings} text={t`Edit Fields`} />
</DropdownMenuItemsContainer>
</UndecoratedLink>
</>

View File

@ -22,8 +22,10 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/
import { useLocation } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
const { t } = useLingui();
const {
viewType,
currentContentId,
@ -98,7 +100,7 @@ export const ObjectOptionsDropdownHiddenRecordGroupsContent = () => {
}}
>
<DropdownMenuItemsContainer>
<MenuItem LeftIcon={IconSettings} text="Edit field values" />
<MenuItem LeftIcon={IconSettings} text={t`Edit field values`} />
</DropdownMenuItemsContainer>
</UndecoratedLink>
</>

View File

@ -35,8 +35,10 @@ import { ViewType } from '@/views/types/ViewType';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { isDefined } from 'twenty-shared';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownMenuContent = () => {
const { t } = useLingui();
const {
recordIndexId,
objectMetadataItem,
@ -117,7 +119,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
<MenuItem
onClick={() => onContentChange('viewSettings')}
LeftIcon={IconLayout}
text="View settings"
text={t`View settings`}
hasSubMenu
/>
</DropdownMenuItemsContainer>
@ -129,7 +131,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
<MenuItem
onClick={() => onContentChange('fields')}
LeftIcon={IconTag}
text="Fields"
text={t`Fields`}
contextualText={`${visibleBoardFields.length} shown`}
hasSubMenu
/>
@ -142,10 +144,10 @@ export const ObjectOptionsDropdownMenuContent = () => {
: onContentChange('recordGroupFields')
}
LeftIcon={IconLayoutList}
text="Group by"
text={t`Group by`}
contextualText={
!isGroupByEnabled
? 'Not available on Default View'
? t`Not available on Default View`
: recordGroupFieldMetadata?.label
}
hasSubMenu
@ -155,7 +157,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
{!isGroupByEnabled && (
<AppTooltip
anchorSelect={`#group-by-menu-item`}
content="Not available on Default View"
content={t`Not available on Default View`}
noArrow
place="bottom"
width="100%"
@ -177,7 +179,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
openObjectRecordsSpreasheetImportDialog();
}}
LeftIcon={IconFileImport}
text="Import"
text={t`Import`}
/>
</>
)}
@ -188,7 +190,7 @@ export const ObjectOptionsDropdownMenuContent = () => {
closeDropdown();
}}
LeftIcon={IconRotate2}
text={`Deleted ${objectNamePlural}`}
text={t`Deleted ${objectNamePlural}`}
/>
</DropdownMenuItemsContainer>
</>

View File

@ -29,8 +29,10 @@ import { useSetRecoilState } from 'recoil';
import { isDefined } from 'twenty-shared';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
const { t } = useLingui();
const { getIcon } = useIcons();
const {
@ -116,13 +118,13 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
<StyledInput
autoFocus
value={recordGroupFieldSearchInput}
placeholder="Search fields"
placeholder={t`Search fields`}
onChange={(event) => setRecordGroupFieldSearchInput(event.target.value)}
/>
<DropdownMenuItemsContainer>
{viewType === ViewType.Table && (
<MenuItemSelect
text="None"
text={t`None`}
selected={!isDefined(recordGroupFieldMetadata)}
onClick={handleResetRecordGroupField}
/>
@ -146,7 +148,7 @@ export const ObjectOptionsDropdownRecordGroupFieldsContent = () => {
closeDropdown();
}}
>
<MenuItem LeftIcon={IconSettings} text="Create select field" />
<MenuItem LeftIcon={IconSettings} text={t`Create select field`} />
</UndecoratedLink>
</DropdownMenuItemsContainer>
</>

View File

@ -26,8 +26,10 @@ import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownM
import { useRecoilComponentFamilyValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyValueV2';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { useGetCurrentView } from '@/views/hooks/useGetCurrentView';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownRecordGroupsContent = () => {
const { t } = useLingui();
const {
viewType,
currentContentId,
@ -97,14 +99,14 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
<MenuItem
onClick={() => onContentChange('recordGroupFields')}
LeftIcon={IconLayoutList}
text="Group by"
text={t`Group by`}
contextualText={recordGroupFieldMetadata?.label}
hasSubMenu
/>
<MenuItem
onClick={() => onContentChange('recordGroupSort')}
LeftIcon={IconSortDescending}
text="Sort"
text={t`Sort`}
contextualText={recordGroupSort}
hasSubMenu
/>
@ -114,7 +116,7 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
LeftIcon={IconCircleOff}
onToggleChange={handleHideEmptyRecordGroupChange}
toggled={hideEmptyRecordGroup}
text="Hide empty groups"
text={t`Hide empty groups`}
toggleSize="small"
/>
</DropdownMenuItemsContainer>
@ -122,7 +124,7 @@ export const ObjectOptionsDropdownRecordGroupsContent = () => {
<>
<DropdownMenuSeparator />
<RecordGroupsVisibilityDropdownSection
title="Visible groups"
title={t`Visible groups`}
recordGroupIds={visibleRecordGroupIds}
onDragEnd={handleRecordGroupOrderChangeWithModal}
onVisibilityChange={handleRecordGroupVisibilityChange}

View File

@ -18,8 +18,10 @@ import { ViewType } from '@/views/types/ViewType';
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useRecoilValue } from 'recoil';
import { FeatureFlagKey } from '~/generated-metadata/graphql';
import { useLingui } from '@lingui/react/macro';
export const ObjectOptionsDropdownViewSettingsContent = () => {
const { t } = useLingui();
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
const {
@ -46,7 +48,7 @@ export const ObjectOptionsDropdownViewSettingsContent = () => {
return (
<>
<DropdownMenuHeader StartIcon={IconChevronLeft} onClick={resetContent}>
View settings
{t`View settings`}
</DropdownMenuHeader>
<DropdownMenuItemsContainer>
{isCommandMenuV2Enabled && (
@ -57,11 +59,11 @@ export const ObjectOptionsDropdownViewSettingsContent = () => {
? IconLayoutSidebarRight
: IconLayoutNavbar
}
text="Open in"
text={t`Open in`}
contextualText={
recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL
? 'Side Panel'
: 'Record Page'
? t`Side Panel`
: t`Record Page`
}
hasSubMenu
/>
@ -76,7 +78,7 @@ export const ObjectOptionsDropdownViewSettingsContent = () => {
)
}
toggled={isCompactModeActive}
text="Compact view"
text={t`Compact view`}
toggleSize="small"
/>
)}

View File

@ -32,7 +32,7 @@ export const ObjectOptionsDropdownViewSettingsOpenInContent = () => {
<DropdownMenuItemsContainer>
<MenuItemSelect
LeftIcon={IconLayoutSidebarRight}
text="Side Panel"
text={t`Side Panel`}
selected={recordIndexOpenRecordIn === ViewOpenRecordInType.SIDE_PANEL}
onClick={() =>
setAndPersistOpenRecordIn(
@ -43,7 +43,7 @@ export const ObjectOptionsDropdownViewSettingsOpenInContent = () => {
/>
<MenuItemSelect
LeftIcon={IconLayoutNavbar}
text="Record Page"
text={t`Record Page`}
selected={
recordIndexOpenRecordIn === ViewOpenRecordInType.RECORD_PAGE
}

View File

@ -17,6 +17,7 @@ import { useEffect } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { useSetRecoilState } from 'recoil';
import { ContextStoreDecorator } from '~/testing/decorators/ContextStoreDecorator';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { IconsProviderDecorator } from '~/testing/decorators/IconsProviderDecorator';
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
@ -29,6 +30,7 @@ const meta: Meta<typeof ObjectOptionsDropdownContent> = {
'Modules/ObjectRecord/ObjectOptionsDropdown/ObjectOptionsDropdownContent',
component: ObjectOptionsDropdownContent,
decorators: [
I18nFrontDecorator,
(Story) => {
const setObjectMetadataItems = useSetRecoilState(
objectMetadataItemsState,

View File

@ -11,6 +11,7 @@ import {
within,
} from '@storybook/test';
import { DateTime } from 'luxon';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
import { FormDateFieldInput } from '../FormDateFieldInput';
const meta: Meta<typeof FormDateFieldInput> = {
@ -18,6 +19,7 @@ const meta: Meta<typeof FormDateFieldInput> = {
component: FormDateFieldInput,
args: {},
argTypes: {},
decorators: [I18nFrontDecorator],
};
export default meta;

View File

@ -12,12 +12,14 @@ import {
within,
} from '@storybook/test';
import { DateTime } from 'luxon';
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
const meta: Meta<typeof FormDateTimeFieldInput> = {
title: 'UI/Data/Field/Form/Input/FormDateTimeFieldInput',
component: FormDateTimeFieldInput,
args: {},
argTypes: {},
decorators: [I18nFrontDecorator],
};
export default meta;

View File

@ -15,6 +15,7 @@ import { isDefined } from 'twenty-shared';
import { RelationDefinitionType } from '~/generated-metadata/graphql';
import { FieldMetadataType } from '~/generated/graphql';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
import { t } from '@lingui/core/macro';
type GenerateExportOptions = {
columns: ColumnDefinition<FieldMetadata>[];
@ -100,7 +101,7 @@ const percentage = (part: number, whole: number): number => {
export const displayedExportProgress = (progress?: ExportProgress): string => {
if (isUndefinedOrNull(progress?.exportedRecordCount)) {
return 'Export';
return t`Export`;
}
if (

View File

@ -69,7 +69,7 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
onClick={() => {
onContentChange('countAggregateOperationsOptions');
}}
text={'Count'}
text={t`Count`}
hasSubMenu
/>
{!fieldIsRelation && (
@ -77,7 +77,7 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
onClick={() => {
onContentChange('percentAggregateOperationsOptions');
}}
text={'Percent'}
text={t`Percent`}
hasSubMenu
/>
)}
@ -95,7 +95,7 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
onClick={() => {
onContentChange('moreAggregateOperationOptions');
}}
text={'More options'}
text={t`More options`}
hasSubMenu
/>
) : null}
@ -106,7 +106,7 @@ export const RecordTableColumnAggregateFooterMenuContent = () => {
resetContent();
closeDropdown();
}}
text={'None'}
text={t`None`}
RightIcon={
!isDefined(currentViewFieldAggregateOperation)
? IconCheck

View File

@ -15,8 +15,10 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { navigationMemorizedUrlState } from '@/ui/navigation/states/navigationMemorizedUrlState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { getSettingsPath } from '~/utils/navigation/getSettingsPath';
import { useLingui } from '@lingui/react/macro';
export const RecordTableHeaderPlusButtonContent = () => {
const { t } = useLingui();
const { objectMetadataItem } = useRecordTableContextOrThrow();
const { closeDropdown } = useDropdown();
@ -64,7 +66,7 @@ export const RecordTableHeaderPlusButtonContent = () => {
setNavigationMemorizedUrl(location.pathname + location.search);
}}
>
<MenuItem LeftIcon={IconSettings} text="Customize fields" />
<MenuItem LeftIcon={IconSettings} text={t`Customize fields`} />
</UndecoratedLink>
</DropdownMenuItemsContainer>
</>

View File

@ -6,6 +6,7 @@ import { RecordTableActionRow } from '@/object-record/record-table/record-table-
import { useHasObjectReadOnlyPermission } from '@/settings/roles/hooks/useHasObjectReadOnlyPermission';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { IconPlus } from 'twenty-ui';
import { t } from '@lingui/core/macro';
export const RecordTableRecordGroupSectionAddNew = () => {
const { recordTableId, objectMetadataItem } = useRecordTableContextOrThrow();
@ -36,7 +37,7 @@ export const RecordTableRecordGroupSectionAddNew = () => {
draggableId={`add-new-record-${currentRecordGroupId}`}
draggableIndex={recordIds.length + 2}
LeftIcon={IconPlus}
text="Add new"
text={t`Add new`}
onClick={handleAddNewRecord}
/>
);