mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 20:44:32 -05:00
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:
@@ -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,
|
||||
|
||||
@@ -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') },
|
||||
]
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
6
upcoming-release-notes/3270.md
Normal file
6
upcoming-release-notes/3270.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
category: Enhancements
|
||||
authors: [psybers]
|
||||
---
|
||||
|
||||
Support translations in desktop-client/components/filters.
|
||||
Reference in New Issue
Block a user