diff --git a/packages/desktop-client/src/components/filters/FiltersButton.tsx b/packages/desktop-client/src/components/filters/FiltersButton.tsx index ad02f975d1..24b425821e 100644 --- a/packages/desktop-client/src/components/filters/FiltersButton.tsx +++ b/packages/desktop-client/src/components/filters/FiltersButton.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { Trans } from 'react-i18next'; import { Button } from '@actual-app/components/button'; import { SvgFilter } from '@actual-app/components/icons/v1'; @@ -9,7 +10,7 @@ export function FiltersButton({ onPress }: { onPress: () => void }) { {' '} - Filter + Filter ); } diff --git a/packages/desktop-client/src/components/filters/FiltersMenu.jsx b/packages/desktop-client/src/components/filters/FiltersMenu.jsx index 1bf03b8b4b..76867b08ad 100644 --- a/packages/desktop-client/src/components/filters/FiltersMenu.jsx +++ b/packages/desktop-client/src/components/filters/FiltersMenu.jsx @@ -384,7 +384,7 @@ export function FilterButton({ onApply, compact, hover, exclude }) { .sort() .map(([name, text]) => ({ name, - text: titleFirst(text), + text: titleFirst(mapField(text)), }))} /> diff --git a/packages/desktop-client/src/components/modals/EditRuleModal.jsx b/packages/desktop-client/src/components/modals/EditRuleModal.jsx index bbc68d0b73..1f8f5f1c3a 100644 --- a/packages/desktop-client/src/components/modals/EditRuleModal.jsx +++ b/packages/desktop-client/src/components/modals/EditRuleModal.jsx @@ -311,7 +311,7 @@ function ScheduleDescription({ id }) { ); const { schedules, - statuses: scheduleStatuses, + statusLabels, isLoading: isSchedulesLoading, } = useSchedules({ query: scheduleQuery }); @@ -324,7 +324,7 @@ function ScheduleDescription({ id }) { } const [schedule] = schedules; - const status = schedule && scheduleStatuses.get(schedule.id); + const status = schedule && statusLabels.get(schedule.id); return ( diff --git a/packages/desktop-client/src/components/rules/Value.tsx b/packages/desktop-client/src/components/rules/Value.tsx index cdef5c7929..fd503445a9 100644 --- a/packages/desktop-client/src/components/rules/Value.tsx +++ b/packages/desktop-client/src/components/rules/Value.tsx @@ -67,7 +67,7 @@ export function Value({ function formatValue(value) { if (value == null || value === '') { - return '(nothing)'; + return t('(nothing)'); } else if (typeof value === 'boolean') { return value ? 'true' : 'false'; } else { @@ -104,7 +104,7 @@ export function Value({ if (item) { return describe(item); } else { - return '(deleted)'; + return t('(deleted)'); } } diff --git a/packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx b/packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx index ec48fd83f5..baa32a082b 100644 --- a/packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx +++ b/packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx @@ -310,7 +310,7 @@ function MonthlyPatterns({ > [opt.id, opt.name] as const), ]} diff --git a/packages/desktop-client/src/components/util/GenericInput.jsx b/packages/desktop-client/src/components/util/GenericInput.jsx index 4d706457bf..85ae02a01e 100644 --- a/packages/desktop-client/src/components/util/GenericInput.jsx +++ b/packages/desktop-client/src/components/util/GenericInput.jsx @@ -1,4 +1,5 @@ import React from 'react'; +import { useTranslation } from 'react-i18next'; import { Input } from '@actual-app/components/input'; import { View } from '@actual-app/components/view'; @@ -35,6 +36,7 @@ export function GenericInput({ onChange, op = undefined, }) { + const { t } = useTranslation(); const { grouped: categoryGroups } = useCategories(); const { data: savedReports } = useReports(); const saved = useSelector(state => state.queries.saved); @@ -63,7 +65,7 @@ export function GenericInput({ onChange(e.target.value)} onBlur={e => onChange(e.target.value)} /> @@ -95,7 +97,7 @@ export function GenericInput({ onSelect={onChange} inputProps={{ inputRef, - ...(showPlaceholder ? { placeholder: 'nothing' } : null), + ...(showPlaceholder ? { placeholder: t('nothing') } : null), }} /> ); @@ -116,7 +118,7 @@ export function GenericInput({ onSelect={onChange} inputProps={{ inputRef, - ...(showPlaceholder ? { placeholder: 'nothing' } : null), + ...(showPlaceholder ? { placeholder: t('nothing') } : null), }} /> ); @@ -135,7 +137,7 @@ export function GenericInput({ showHiddenCategories={false} inputProps={{ inputRef, - ...(showPlaceholder ? { placeholder: 'nothing' } : null), + ...(showPlaceholder ? { placeholder: t('nothing') } : null), }} /> ); @@ -157,7 +159,7 @@ export function GenericInput({ onSelect={onChange} inputProps={{ inputRef, - ...(showPlaceholder ? { placeholder: 'nothing' } : null), + ...(showPlaceholder ? { placeholder: t('nothing') } : null), }} /> ); @@ -172,7 +174,7 @@ export function GenericInput({ onSelect={onChange} inputProps={{ inputRef, - ...(showPlaceholder ? { placeholder: 'nothing' } : null), + ...(showPlaceholder ? { placeholder: t('nothing') } : null), }} /> ); @@ -261,7 +263,7 @@ export function GenericInput({ onChange(e.target.value)} onBlur={e => onChange(e.target.value)} /> diff --git a/packages/loot-core/src/client/data-hooks/schedules.tsx b/packages/loot-core/src/client/data-hooks/schedules.tsx index c122b818cd..9b6cc3954a 100644 --- a/packages/loot-core/src/client/data-hooks/schedules.tsx +++ b/packages/loot-core/src/client/data-hooks/schedules.tsx @@ -12,7 +12,11 @@ import React, { import { useSyncedPref } from '@actual-app/web/src/hooks/useSyncedPref'; import { q, type Query } from '../../shared/query'; -import { getHasTransactionsQuery, getStatus } from '../../shared/schedules'; +import { + getHasTransactionsQuery, + getStatus, + getStatusLabel, +} from '../../shared/schedules'; import { type AccountEntity, type ScheduleEntity, @@ -24,6 +28,12 @@ import { type LiveQuery, liveQuery } from '../query-helpers'; export type ScheduleStatusType = ReturnType; export type ScheduleStatuses = Map; +export type ScheduleStatusLabelType = ReturnType; +export type ScheduleStatusLabels = Map< + ScheduleEntity['id'], + ScheduleStatusLabelType +>; + function loadStatuses( schedules: readonly ScheduleEntity[], onData: (data: ScheduleStatuses) => void, @@ -58,6 +68,7 @@ type UseSchedulesProps = { type ScheduleData = { schedules: readonly ScheduleEntity[]; statuses: ScheduleStatuses; + statusLabels: ScheduleStatusLabels; }; type UseSchedulesResult = ScheduleData & { readonly isLoading: boolean; @@ -72,6 +83,7 @@ export function useSchedules({ const [data, setData] = useState({ schedules: [], statuses: new Map(), + statusLabels: new Map(), }); const [upcomingLength] = useSyncedPref('upcomingScheduledTransactionLength'); @@ -108,7 +120,16 @@ export function useSchedules({ schedules, (statuses: ScheduleStatuses) => { if (!isUnmounted) { - setData({ schedules, statuses }); + setData({ + schedules, + statuses, + statusLabels: new Map( + [...statuses.keys()].map(key => [ + key, + getStatusLabel(statuses.get(key)), + ]), + ), + }); setIsLoading(false); } }, diff --git a/packages/loot-core/src/shared/schedules.ts b/packages/loot-core/src/shared/schedules.ts index b4546143db..de747b18e3 100644 --- a/packages/loot-core/src/shared/schedules.ts +++ b/packages/loot-core/src/shared/schedules.ts @@ -34,6 +34,23 @@ export function getStatus( } } +export function getStatusLabel(status: string) { + switch (status) { + case 'completed': + return t('completed'); + case 'paid': + return t('paid'); + case 'due': + return t('due'); + case 'upcoming': + return t('upcoming'); + case 'missed': + return t('missed'); + case 'scheduled': + return t('scheduled'); + } +} + export function getHasTransactionsQuery(schedules) { const filters = schedules.map(schedule => { const dateCond = schedule._conditions.find(c => c.field === 'date'); diff --git a/upcoming-release-notes/4635.md b/upcoming-release-notes/4635.md new file mode 100644 index 0000000000..d087a358d5 --- /dev/null +++ b/upcoming-release-notes/4635.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [lelemm] +--- + +More translations for rules and fields \ No newline at end of file