Translation: desktop-client/components/filters (#3270)

* Translation: desktop-client/components/filters

* add release note

* fix linter

* add missing t definition
This commit is contained in:
Robert Dyer
2024-08-16 07:35:57 -05:00
committed by GitHub
parent f715ceafc9
commit 4c192d7e1e
7 changed files with 56 additions and 29 deletions

View File

@@ -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,

View File

@@ -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') },
]
}
/>

View File

@@ -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>
);

View File

@@ -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,

View File

@@ -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>

View File

@@ -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}&nbsp;
{!filterId.id ? t('Unsaved filter') : filterId.name}&nbsp;
</Text>
{filterId.id && filterId.status !== 'saved' && (
<Text>(modified)&nbsp;</Text>
<Text>
<Trans>(modified)</Trans>&nbsp;
</Text>
)}
<SvgExpandArrow width={8} height={8} style={{ marginRight: 5 }} />
</Button>

View File

@@ -0,0 +1,6 @@
---
category: Enhancements
authors: [psybers]
---
Support translations in desktop-client/components/filters.