From 4c192d7e1e7e7ef639c15856fc321ce39c98a887 Mon Sep 17 00:00:00 2001 From: Robert Dyer <rdyer@unl.edu> Date: Fri, 16 Aug 2024 07:35:57 -0500 Subject: [PATCH] Translation: desktop-client/components/filters (#3270) * Translation: desktop-client/components/filters * add release note * fix linter * add missing t definition --- .../components/filters/FilterExpression.tsx | 4 ++- .../src/components/filters/FilterMenu.tsx | 27 +++++++++-------- .../src/components/filters/FiltersButton.tsx | 5 +++- .../src/components/filters/FiltersMenu.jsx | 29 ++++++++++++------- .../src/components/filters/NameFilter.tsx | 6 ++-- .../filters/SavedFilterMenuButton.tsx | 8 +++-- upcoming-release-notes/3270.md | 6 ++++ 7 files changed, 56 insertions(+), 29 deletions(-) create mode 100644 upcoming-release-notes/3270.md diff --git a/packages/desktop-client/src/components/filters/FilterExpression.tsx b/packages/desktop-client/src/components/filters/FilterExpression.tsx index 55accb1c8..d649fd09c 100644 --- a/packages/desktop-client/src/components/filters/FilterExpression.tsx +++ b/packages/desktop-client/src/components/filters/FilterExpression.tsx @@ -1,4 +1,5 @@ import React, { useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import { mapField, friendlyOp } from 'loot-core/src/shared/rules'; import { integerToCurrency } from 'loot-core/src/shared/util'; @@ -38,6 +39,7 @@ export function FilterExpression<T extends RuleConditionEntity>({ onChange, onDelete, }: FilterExpressionProps<T>) { + const { t } = useTranslation(); const [editing, setEditing] = useState(false); const triggerRef = useRef(null); @@ -84,7 +86,7 @@ export function FilterExpression<T extends RuleConditionEntity>({ )} </div> </Button> - <Button type="bare" onClick={onDelete} aria-label="Delete filter"> + <Button type="bare" onClick={onDelete} aria-label={t('Delete filter')}> <SvgDelete style={{ width: 8, diff --git a/packages/desktop-client/src/components/filters/FilterMenu.tsx b/packages/desktop-client/src/components/filters/FilterMenu.tsx index b56649567..c3adb2048 100644 --- a/packages/desktop-client/src/components/filters/FilterMenu.tsx +++ b/packages/desktop-client/src/components/filters/FilterMenu.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { Menu } from '../common/Menu'; @@ -11,6 +12,8 @@ export function FilterMenu({ filterId: SavedFilter; onFilterMenuSelect: (item: string) => void; }) { + const { t } = useTranslation(); + return ( <Menu onMenuSelect={item => { @@ -19,29 +22,29 @@ export function FilterMenu({ items={ !filterId.id ? [ - { name: 'save-filter', text: 'Save new filter' }, - { name: 'clear-filter', text: 'Clear all conditions' }, + { name: 'save-filter', text: t('Save new filter') }, + { name: 'clear-filter', text: t('Clear all conditions') }, ] : filterId.id !== null && filterId.status === 'saved' ? [ - { name: 'rename-filter', text: 'Rename' }, - { name: 'delete-filter', text: 'Delete' }, + { name: 'rename-filter', text: t('Rename') }, + { name: 'delete-filter', text: t('Delete') }, Menu.line, { name: 'save-filter', - text: 'Save new filter', + text: t('Save new filter'), disabled: true, }, - { name: 'clear-filter', text: 'Clear all conditions' }, + { name: 'clear-filter', text: t('Clear all conditions') }, ] : [ - { name: 'rename-filter', text: 'Rename' }, - { name: 'update-filter', text: 'Update condtions' }, - { name: 'reload-filter', text: 'Revert changes' }, - { name: 'delete-filter', text: 'Delete' }, + { name: 'rename-filter', text: t('Rename') }, + { name: 'update-filter', text: t('Update condtions') }, + { name: 'reload-filter', text: t('Revert changes') }, + { name: 'delete-filter', text: t('Delete') }, Menu.line, - { name: 'save-filter', text: 'Save new filter' }, - { name: 'clear-filter', text: 'Clear all conditions' }, + { name: 'save-filter', text: t('Save new filter') }, + { name: 'clear-filter', text: t('Clear all conditions') }, ] } /> diff --git a/packages/desktop-client/src/components/filters/FiltersButton.tsx b/packages/desktop-client/src/components/filters/FiltersButton.tsx index 6d82904ee..35be24986 100644 --- a/packages/desktop-client/src/components/filters/FiltersButton.tsx +++ b/packages/desktop-client/src/components/filters/FiltersButton.tsx @@ -1,11 +1,14 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { SvgFilter } from '../../icons/v1/Filter'; import { Button } from '../common/Button'; export function FiltersButton({ onClick }: { onClick: () => void }) { + const { t } = useTranslation(); + return ( - <Button type="bare" onClick={onClick} title="Filters"> + <Button type="bare" onClick={onClick} title={t('Filters')}> <SvgFilter style={{ width: 12, height: 12, marginRight: 5 }} /> Filter </Button> ); diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.jsx b/packages/desktop-client/src/components/filters/FiltersMenu.jsx index fc971664e..61720dff6 100644 --- a/packages/desktop-client/src/components/filters/FiltersMenu.jsx +++ b/packages/desktop-client/src/components/filters/FiltersMenu.jsx @@ -1,5 +1,6 @@ import React, { useState, useRef, useEffect, useReducer } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; +import { Trans, useTranslation } from 'react-i18next'; import { FocusScope } from '@react-aria/focus'; import { @@ -62,6 +63,7 @@ function ConfigureField({ dispatch, onApply, }) { + const { t } = useTranslation(); const [subfield, setSubfield] = useState(initialSubfield); const inputRef = useRef(); const prevOp = useRef(null); @@ -91,15 +93,15 @@ function ConfigureField({ options={ field === 'amount' ? [ - ['amount', 'Amount'], - ['amount-inflow', 'Amount (inflow)'], - ['amount-outflow', 'Amount (outflow)'], + ['amount', t('Amount')], + ['amount-inflow', t('Amount (inflow)')], + ['amount-outflow', t('Amount (outflow)')], ] : field === 'date' ? [ - ['date', 'Date'], - ['month', 'Month'], - ['year', 'Year'], + ['date', t('Date')], + ['month', t('Month')], + ['year', t('Year')], ] : null } @@ -125,7 +127,7 @@ function ConfigureField({ marginBottom: 10, }} > - {field === 'saved' && 'Existing filters will be cleared'} + {field === 'saved' && t('Existing filters will be cleared')} </View> <Stack @@ -231,7 +233,7 @@ function ConfigureField({ }); }} > - Apply + <Trans>Apply</Trans> </Button> </Stack> </form> @@ -240,6 +242,7 @@ function ConfigureField({ } export function FilterButton({ onApply, compact, hover, exclude }) { + const { t } = useTranslation(); const filters = useFilters(); const triggerRef = useRef(null); @@ -285,7 +288,7 @@ export function FilterButton({ onApply, compact, hover, exclude }) { if (isDateValid(date)) { cond.value = formatDate(date, 'yyyy-MM'); } else { - alert('Invalid date format'); + alert(t('Invalid date format')); return; } } else if (cond.options.year) { @@ -293,7 +296,7 @@ export function FilterButton({ onApply, compact, hover, exclude }) { if (isDateValid(date)) { cond.value = formatDate(date, 'yyyy'); } else { - alert('Invalid date format'); + alert(t('Invalid date format')); return; } } @@ -329,7 +332,11 @@ export function FilterButton({ onApply, compact, hover, exclude }) { lineHeight: 1.5, padding: '6px 10px', }} - content={<Text>Filters</Text>} + content={ + <Text> + <Trans>Filters</Trans> + </Text> + } placement="bottom start" triggerProps={{ isDisabled: !hover, diff --git a/packages/desktop-client/src/components/filters/NameFilter.tsx b/packages/desktop-client/src/components/filters/NameFilter.tsx index 0e4285e85..b8ad19ac0 100644 --- a/packages/desktop-client/src/components/filters/NameFilter.tsx +++ b/packages/desktop-client/src/components/filters/NameFilter.tsx @@ -1,4 +1,5 @@ import React, { useRef, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; import { theme } from '../../style'; import { Button } from '../common/Button'; @@ -22,6 +23,7 @@ export function NameFilter({ onAddUpdate: () => void; err: string | null; }) { + const { t } = useTranslation(); const inputRef = useRef<HTMLInputElement>(null); useEffect(() => { @@ -42,7 +44,7 @@ export function NameFilter({ > <FormField style={{ flex: 1 }}> <FormLabel - title="Filter Name" + title={t('Filter Name')} htmlFor="name-field" style={{ userSelect: 'none' }} /> @@ -61,7 +63,7 @@ export function NameFilter({ onAddUpdate(); }} > - {adding ? 'Add' : 'Update'} + {adding ? t('Add') : t('Update')} </Button> </Stack> </form> diff --git a/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx b/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx index ba5658f6b..1a2d68e52 100644 --- a/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx +++ b/packages/desktop-client/src/components/filters/SavedFilterMenuButton.tsx @@ -1,4 +1,5 @@ import React, { useRef, useState } from 'react'; +import { Trans, useTranslation } from 'react-i18next'; import { send, sendCatch } from 'loot-core/src/platform/client/fetch'; import { type TransactionFilterEntity } from 'loot-core/types/models'; @@ -36,6 +37,7 @@ export function SavedFilterMenuButton({ onReloadSavedFilter: (savedFilter: SavedFilter, value?: string) => void; savedFilters: TransactionFilterEntity[]; }) { + const { t } = useTranslation(); const [nameOpen, setNameOpen] = useState(false); const [adding, setAdding] = useState(false); const [menuOpen, setMenuOpen] = useState(false); @@ -176,10 +178,12 @@ export function SavedFilterMenuButton({ flexShrink: 0, }} > - {!filterId.id ? 'Unsaved filter' : filterId.name} + {!filterId.id ? t('Unsaved filter') : filterId.name} </Text> {filterId.id && filterId.status !== 'saved' && ( - <Text>(modified) </Text> + <Text> + <Trans>(modified)</Trans> + </Text> )} <SvgExpandArrow width={8} height={8} style={{ marginRight: 5 }} /> </Button> diff --git a/upcoming-release-notes/3270.md b/upcoming-release-notes/3270.md new file mode 100644 index 000000000..85a2c1b25 --- /dev/null +++ b/upcoming-release-notes/3270.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [psybers] +--- + +Support translations in desktop-client/components/filters. -- GitLab