-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use useTranslation hook instead of directly importing the t function #3893
base: master
Are you sure you want to change the base?
Conversation
✅ Deploy Preview for actualbudget ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
Bundle Stats — desktop-clientHey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle. As this PR is updated, I'll keep you updated on how the bundle size is impacted. Total
Changeset
View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger
Smaller No assets were smaller Unchanged
|
Bundle Stats — loot-coreHey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle. As this PR is updated, I'll keep you updated on how the bundle size is impacted. Total
Changeset No files were changed View detailed bundle breakdownAdded No assets were added Removed No assets were removed Bigger No assets were bigger Smaller No assets were smaller Unchanged
|
WalkthroughThis pull request introduces a comprehensive update across multiple components in the desktop client, primarily focusing on enhancing internationalization support by integrating the Possibly related PRs
Suggested labels
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint
packages/desktop-client/src/components/ManageRulesPage.tsxOops! Something went wrong! :( ESLint: 8.57.1 ESLint couldn't find the plugin "eslint-plugin-eslint-plugin". (The package "eslint-plugin-eslint-plugin" was not found when loaded as a Node module from the directory "/packages/eslint-plugin-actual".) It's likely that the plugin isn't installed correctly. Try reinstalling by running the following:
The plugin "eslint-plugin-eslint-plugin" was referenced from the config file in "packages/eslint-plugin-actual/.eslintrc.js". If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (70)
packages/desktop-client/src/components/mobile/MobileBackButton.tsx (1)
17-17
: Consider memoization for performance optimizationWhile the current implementation is correct, consider using
useMemo
for the translation function if this component re-renders frequently or is used in a performance-critical part of the application.- const { t } = useTranslation(); + const { t } = useMemo(() => useTranslation(), []);packages/desktop-client/src/components/modals/ManageRulesModal.tsx (1)
Translation keys need to be updated for consistency
Based on the search results, I found that:
- The translation key 'manage-rules' is used consistently in the codebase for modal naming
- However, 'Rules' is used directly without proper translation key formatting (should be kebab-case like other keys)
Locations that need attention:
packages/desktop-client/src/components/ManageRulesPage.tsx
: Changet('Rules')
tot('rules')
packages/desktop-client/src/components/modals/ManageRulesModal.tsx
: Changet('Rules')
tot('rules')
packages/desktop-client/src/components/sidebar/PrimaryButtons.tsx
: Changetitle={t('Rules')}
totitle={t('rules')}
🔗 Analysis chain
Line range hint
29-29
: Verify translation key consistencyThe translation keys 'manage-rules' and 'Rules' are used. Let's ensure these keys:
- Exist in the translation files
- Follow consistent casing conventions across the codebase
Also applies to: 33-33
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check translation keys existence and consistency # Search for translation files echo "Searching for translation files..." fd -e json -e yaml "translation" -x cat {} \; | grep -E "(manage-rules|Rules)" # Check for inconsistent casing in translation keys echo "Checking translation key usage patterns..." rg "t\(['\"].*rules.*['\"]" --type ts --type tsxLength of output: 338
Script:
#!/bin/bash # Let's try a different approach to find translation files and usages # First, let's find all potential translation-related files echo "=== Looking for translation-related files ===" fd "translation|locale|i18n" --type file # Then, let's search for rules-related translations in TypeScript/JavaScript files echo -e "\n=== Searching for translation patterns ===" rg "t\(['\"].*rules.*['\"]" -t ts -t js # Let's also check for the specific keys we're interested in echo -e "\n=== Searching for specific translation keys ===" rg "(manage-rules|Rules)" -t ts -t js -t jsonLength of output: 27828
packages/desktop-client/src/components/modals/BudgetListModal.tsx (1)
Line range hint
11-44
: Consider memoization for performance optimizationSince this modal might be rendered frequently during budget switching operations, consider wrapping the component with React.memo to prevent unnecessary re-renders when parent components update. The useTranslation hook will still trigger re-renders when the language changes.
-export function BudgetListModal() { +export const BudgetListModal = React.memo(function BudgetListModal() { const { t } = useTranslation(); // ... rest of the component -} +});packages/desktop-client/src/components/settings/BudgetTypeSettings.tsx (2)
Line range hint
24-28
: Consider using translation for button textThe button text could benefit from using translations for consistency with the rest of the internationalization efforts.
Consider this improvement:
<Button onPress={onSwitchType}> - Switch to {budgetType === 'report' ? 'envelope' : 'tracking'}{' '} - budgeting + {t('Switch to {{type}} budgeting', { + type: budgetType === 'report' ? t('envelope') : t('tracking') + })} </Button>
Line range hint
31-57
: Consider translating all user-facing stringsWhile "Learn more..." links are translated, the main descriptive text about budget types is not. For consistency and complete internationalization support, consider translating all user-facing strings.
Here's how you could improve it:
<Text> - <strong>Envelope budgeting</strong> (recommended) digitally mimics - physical envelope budgeting system by allocating funds into virtual - envelopes for different expenses. It helps track spending and ensure you - don't overspend in any category.{' '} + {t('envelope_budgeting_description', { + defaultValue: '<strong>Envelope budgeting</strong> (recommended) digitally mimics physical envelope budgeting system by allocating funds into virtual envelopes for different expenses. It helps track spending and ensure you don\'t overspend in any category.', + interpolation: { escapeValue: false } + })}{' '} <Link variant="external" to="https://actualbudget.org/docs/getting-started/envelope-budgeting" linkColor="purple" > {t('Learn more…')} </Link> </Text>Apply similar changes to the tracking budgeting description as well.
packages/desktop-client/src/components/settings/Export.tsx (1)
Line range hint
63-69
: Consider translating all user-facing stringsThere are some hardcoded strings that should be translated for consistency:
- The "Export" text in the strong tag
- The technical explanation about db.sqlite and metadata.json files
Consider updating the text block like this:
- <Text> - <strong>Export</strong> your data as a zip file containing{' '} - <code>db.sqlite</code> and <code>metadata.json</code> files. It can be - imported into another Actual instance by closing an open file (if any), - then clicking the "Import file" button, then choosing "Actual." - </Text> + <Text> + <strong>{t('Export')}</strong>{' '} + {t('your data as a zip file containing {{sqlite}} and {{metadata}} files. It can be imported into another Actual instance by closing an open file (if any), then clicking the "Import file" button, then choosing "Actual."', { + sqlite: <code>db.sqlite</code>, + metadata: <code>metadata.json</code>, + })} + </Text>packages/desktop-client/src/components/settings/UI.tsx (1)
Line range hint
53-93
: Consider adding type safety for translationsTo improve maintainability and catch missing translations at compile time, consider implementing type safety for translation keys. This could be achieved using:
- TypeScript's string literal types for translation keys
- Auto-generated types from your translation files
- A type-safe translation key management solution
This would help prevent typos and make refactoring easier.
packages/desktop-client/src/components/modals/PayeeAutocompleteModal.tsx (3)
26-26
: LGTM: Proper useTranslation hook implementationThe hook is correctly implemented at the component's top level, which will enable automatic re-rendering when the language changes - an improvement over the direct import approach.
This change improves the component's reactivity to language changes, which is particularly important for a modal component that might be open during language switches.
Line range hint
64-64
: Consider translating additional UI elementsWhile the 'Payee' title is now properly translated, consider also translating other user-facing strings that might be passed through props, such as aria-labels or button texts.
For example, you might want to ensure that texts passed to
showManagePayees
andshowMakeTransfer
buttons (if any) are also translated consistently.
Direct imports of
t
from i18next should be migrated touseTranslation
hookFound 6 files still using direct imports of
t
from i18next that should be updated to use theuseTranslation
hook for consistency:
packages/desktop-client/src/components/util/accountValidation.ts
packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
packages/desktop-client/src/components/reports/ReportOptions.ts
packages/desktop-client/src/components/reports/disabledList.ts
packages/desktop-client/src/components/budget/util.ts
packages/desktop-client/src/components/accounts/Account.tsx
🔗 Analysis chain
Line range hint
1-85
: Verify consistent translation pattern across related componentsThe implementation looks good overall. Let's verify that this translation pattern is consistently applied across related components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any remaining direct imports of 't' from i18next rg "import.*\{.*t.*\}.*from 'i18next'" packages/desktop-client/src/ # Check for consistent usage of useTranslation in modal components rg "useTranslation.*from 'react-i18next'" packages/desktop-client/src/components/modals/Length of output: 6979
packages/desktop-client/src/components/settings/Reset.tsx (1)
42-42
: Consider consolidating conditional translationsThe current implementation splits the disabled state message into separate translation keys, which might cause issues for languages with different word orders. Consider consolidating the translation into a single key.
- <Text> - <strong>{t('Reset sync')}</strong> - {t(' is only available when syncing is')} - </Text> + <Text> + {t('Reset sync is only available when syncing is enabled')} + </Text>Also applies to: 74-78
packages/desktop-client/src/components/settings/Themes.tsx (1)
Line range hint
94-97
: Consider combining the translation strings for better localizationThe current implementation splits the text into two parts with a hardcoded space. This could cause issues in languages with different word orders or formatting requirements.
Consider combining the strings into a single translation key:
- <Text> - <strong>{t('Themes')}</strong> - {t(' change the user interface colors.')} - </Text> + <Text> + {t('themes.description', { + themes: text => <strong>{text}</strong> + })} + </Text>Add to your translation file:
{ "themes.description": "{{themes, themes}} change the user interface colors" }This approach:
- Gives translators more context
- Allows for proper word order in different languages
- Eliminates hardcoded spacing issues
packages/desktop-client/src/components/modals/CategoryAutocompleteModal.tsx (1)
Line range hint
52-52
: Consider extracting duplicate translation keyThe translation key 'Category' is used in two places. While the current implementation is functional, consider extracting it to a constant for better maintainability:
+ const CATEGORY_LABEL = 'Category'; return ( <Modal> {({ state: { close } }) => ( <> {isNarrowWidth && ( <ModalHeader title={ <ModalTitle - title={t('Category')} + title={t(CATEGORY_LABEL)} getStyle={() => ({ color: theme.menuAutoCompleteText })} /> } /> )} <View> {!isNarrowWidth && ( <SectionLabel - title={t('Category')} + title={t(CATEGORY_LABEL)} style={{ alignSelf: 'center',Also applies to: 71-71
packages/desktop-client/src/components/Notes.tsx (1)
Line range hint
119-127
: Consider adding ARIA label for better accessibility.While the translation implementation is correct, consider adding an aria-label to improve accessibility for screen readers, as placeholders might not always be read.
<textarea ref={textAreaRef} className={css({ border: '1px solid ' + theme.buttonNormalBorder, padding: 7, ...(!isNarrowWidth && { minWidth: 350, minHeight: 120 }), outline: 'none', backgroundColor: theme.tableBackground, color: theme.tableText, ...getStyle?.(editable), })} value={notes || ''} onChange={e => onChange?.(e.target.value)} onBlur={e => onBlur?.(e.target.value)} placeholder={t('Notes (markdown supported)')} + aria-label={t('Notes input field with markdown support')} />
packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx (1)
Missing translation key and translation file
The translation key 'Scheduled date' is not found because the translation file
en.json
is missing from the configured locationpackages/desktop-client/src/locale/
. Based on the i18n configuration and implementation:
- The translation file should be at
packages/desktop-client/src/locale/en.json
- The configuration is set up to extract translations from source files
- The key separator is disabled, meaning full phrases are used as keys
🔗 Analysis chain
Line range hint
71-71
: Verify translation key existence.The translation key 'Scheduled date' is used for user-facing content.
Let me verify if there are any translation files in the repository first, and then check for similar translation keys to ensure we're searching correctly.
Let's check the i18n configuration and implementation since we found the relevant files.
Let's check for the actual translation file in the location specified in the configuration.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Verify that the translation key exists in translation files # Look for the translation key in JSON/YAML files that might contain translations rg -g '*.{json,yaml,yml}' '"Scheduled date"' || echo "Translation key not found"Length of output: 107
Script:
#!/bin/bash # First, let's find translation files echo "=== Looking for translation files ===" fd -e json -e yaml -e yml | grep -i 'translation\|locale\|lang' echo -e "\n=== Looking for i18n configuration files ===" fd -e js -e ts -e json | grep -i 'i18n' echo -e "\n=== Looking for similar translation keys about scheduling ===" rg -g '*.{json,yaml,yml}' -i 'schedul' || echo "No scheduling-related translations found"Length of output: 958
Script:
#!/bin/bash # Check i18n configuration and implementation echo "=== Checking i18n configuration ===" cat packages/desktop-client/i18next-parser.config.js echo -e "\n=== Checking i18n implementation ===" cat packages/desktop-client/src/i18n.ts echo -e "\n=== Looking for translation files in common locations ===" fd -e json -e yaml -e yml . packages/desktop-client/src/locales packages/desktop-client/public/locales 2>/dev/null || echo "No translation files found in common locations"Length of output: 1802
Script:
#!/bin/bash # Check for translation file in the configured location echo "=== Checking for en.json in src/locale ===" cat packages/desktop-client/src/locale/en.json 2>/dev/null || echo "Translation file not found" echo -e "\n=== Looking for any json files in src/locale ===" fd -e json . packages/desktop-client/src/locale/ 2>/dev/null || echo "No JSON files found in locale directory"Length of output: 459
packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx (1)
Line range hint
89-89
: Consider translating all user-facing strings.While "Budgeted" is now translated, other potential user-facing strings in the component might also need translation for consistency.
Consider adding translations for the modal title and potentially other text:
<ModalHeader - title={<ModalTitle title={category.name} shrinkOnOverflow />} + title={<ModalTitle title={t('category.name', { name: category.name })} shrinkOnOverflow />} rightContent={<ModalCloseButton onPress={close} />} />packages/desktop-client/src/components/settings/FixSplits.tsx (1)
Line range hint
83-108
: Consider improving translation key handling and HTML content
Instead of using string literals directly as translation keys, consider using structured keys (e.g.,
settings.fixSplits.button
,settings.fixSplits.description
). This makes maintenance easier and provides better organization of translations.HTML markup within translation strings (like
<strong>
and list items) could make translations harder to maintain. Consider extracting the markup to the JSX level.Example refactor:
- <Text> - <strong>{t('Repair split transactions')}</strong> - {t( - ' if you are experiencing bugs relating to split transactions and the "Reset budget cache" button above does not help, this tool may fix them. Some examples of bugs include seeing blank payees on splits or incorrect account balances. This tool does two things:', - )} - </Text> + <Text> + <strong>{t('settings.fixSplits.title')}</strong> + {' '} + {t('settings.fixSplits.description')} + </Text>packages/desktop-client/src/components/rules/ActionExpression.tsx (2)
Line range hint
70-82
: Consider improving translation key formatWhile the
useTranslation
hook is correctly implemented, the translation strings contain trailing spaces ("to " and "template "). Consider moving space handling to the translation system or component layout.- <Text>{t('to ')}</Text> + <Text>{t('to')}</Text>{' '} - <Text>{t('template ')}</Text> + <Text>{t('template')}</Text>{' '}
Line range hint
89-143
: Consider internationalizing remaining componentsFor consistency, consider applying the same internationalization approach to other action expression components. Text from
friendlyOp()
andALLOCATION_METHODS
should also be internationalized.Example implementation for SetSplitAmountActionExpression:
function SetSplitAmountActionExpression({ op, value, options, }: SetSplitAmountRuleActionEntity) { + const { t } = useTranslation(); const method = options?.method; if (!method) { return null; } return ( <> - <Text>{friendlyOp(op)}</Text>{' '} + <Text>{t(friendlyOp(op))}</Text>{' '} - <Text style={valueStyle}>{ALLOCATION_METHODS[method]}</Text> + <Text style={valueStyle}>{t(ALLOCATION_METHODS[method])}</Text> {method !== 'remainder' && ': '} // ... rest of the component </> ); }packages/desktop-client/src/components/modals/GoCardlessInitialiseModal.tsx (3)
Line range hint
30-33
: Consider implementing stronger input validationThe current state management for sensitive credentials could benefit from additional validation:
- Length requirements for secrets
- Format validation
- Trimming whitespace
const [secretId, setSecretId] = useState(''); const [secretKey, setSecretKey] = useState(''); +const validateSecrets = (id: string, key: string) => { + const trimmedId = id.trim(); + const trimmedKey = key.trim(); + return { + isValid: trimmedId.length >= 8 && trimmedKey.length >= 8, + trimmedId, + trimmedKey + }; +};
Line range hint
35-52
: Add error handling for network requestsThe submission logic should handle potential network failures and API errors.
const onSubmit = async (close: () => void) => { if (!secretId || !secretKey) { setIsValid(false); return; } setIsLoading(true); + try { await Promise.all([ send('secret-set', { name: 'gocardless_secretId', value: secretId, }), send('secret-set', { name: 'gocardless_secretKey', value: secretKey, }), ]); onSuccess(); - setIsLoading(false); close(); + } catch (error) { + setIsValid(false); + // Consider adding an error state to display API errors + } finally { + setIsLoading(false); + } };
Line range hint
89-117
: Enhance form accessibilityWhile the form implements basic accessibility with labels and IDs, consider adding:
- aria-required attributes
- Error message association with inputs
- Loading state announcement
<Input id="secret-id-field" type="password" value={secretId} + aria-required="true" + aria-invalid={!isValid} + aria-describedby="error-message" onChangeValue={value => { setSecretId(value); setIsValid(true); }} /> {!isValid && ( - <Error> + <Error id="error-message" role="alert"> {t( 'It is required to provide both the secret id and secret key.', )} </Error> )}packages/desktop-client/src/components/settings/Format.tsx (1)
Line range hint
24-44
: Consider extracting and translating static arraysConsider moving the
daysOfWeek
anddateFormats
arrays to a separate constants file and making their labels translatable. This would improve maintainability and ensure consistent internationalization.Example implementation:
// constants/dateFormats.ts export const daysOfWeek = (t: TFunction) => [ { value: '0', label: t('Sunday') }, { value: '1', label: t('Monday') }, // ... ]; export const dateFormats = (t: TFunction) => [ { value: 'MM/dd/yyyy', label: t('MM/DD/YYYY') }, // ... ];packages/desktop-client/src/components/util/AmountInput.tsx (1)
158-158
: Consider using a more specific translation keyWhile the implementation is correct, using a generic translation key like 'and' could lead to maintenance issues or unintended translations. Consider using a more specific, namespaced key that describes its context.
- {t('and')} + {t('amount_input.between_connector')}Also applies to: 171-171
packages/desktop-client/src/components/rules/Value.tsx (2)
1-1
: Consider improving TypeScript implementationThe file has several TypeScript-related improvements that could be made:
- The file starts with
@ts-strict-ignore
- There are multiple
@ts-expect-error
comments- The describe prop type has been improved but the implementation still has a type error
Consider addressing these TypeScript issues in a follow-up PR to improve type safety.
Would you like me to help create a GitHub issue to track these TypeScript improvements?
Also applies to: 33-37
Line range hint
156-162
: Consider translating additional stringsWhile the "and" string is now properly translated, there are several other hardcoded strings in the component that could benefit from translation:
- "(nothing)"
- "(empty)"
- "(deleted)"
- "more items..."
This would provide a more consistent internationalization experience.
Example implementation:
- return '(nothing)'; + return t('nothing'); - return <Text style={valueStyle}>(empty)</Text>; + return <Text style={valueStyle}>{t('empty')}</Text>; - return '(deleted)'; + return t('deleted'); - {numHidden} more items... + {t('more_items', { count: numHidden })}packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx (1)
115-115
: Consider using more specific translation keysWhile the translation implementation is correct, consider using more specific translation keys like
'transactions.balance.cleared'
and'transactions.balance.uncleared'
to maintain a clear hierarchical structure in your translations.packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsx (2)
Line range hint
47-47
: Consider using structured translation keysInstead of using a direct string as a translation key, consider using a structured key format (e.g., 'reports.custom.deleted') for better maintainability and consistency across the application.
- {t('This custom report has been deleted.')} + {t('reports.custom.deleted')}Remember to add the corresponding key-value pair in your translation files.
Missing translations for menu items and tooltip content
The following strings need to be translated:
- Menu items: 'Rename', 'Remove' in
CustomReportListCards.tsx
- Tooltip content: "The widget is configured to use a non-existing filter value..." in
CustomReportListCards.tsx
Evidence:
- The component uses
useTranslation()
hook but doesn't use thet()
function for these strings- Similar menu items in other components also need translation
- The tooltip content contains user-facing text that should be translated for consistency
🔗 Analysis chain
Line range hint
39-170
: Verify translation coverage for all user-facing stringsThere are several other user-facing strings in the component that might need translation, particularly in the menu items and tooltips.
Consider translating these strings as well:
- Menu items: 'Rename', 'Remove'
- Tooltip content for the warning icon
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for potential untranslated strings in the component rg -U "text: '[^']*'" packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsx rg -U "content=\"[^\"]*\"" packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsxLength of output: 452
Script:
#!/bin/bash # Let's check if there are any other similar components using translation ast-grep --pattern 'const { t } = useTranslation()' # Check for any existing translations of these strings in the codebase rg -l "('|\")(Rename|Remove|The widget is configured)('|\")" packages/desktop-client/src/locales/Length of output: 23885
Script:
#!/bin/bash # Let's check the actual location of translation files fd -t f "en.json|en-US.json|translations.json" packages/desktop-client/ # Let's also check if there are any similar menu items in other components that might show the translation pattern rg -U "text: ('|\")(?:Rename|Remove)('|\")" packages/desktop-client/Length of output: 581
packages/desktop-client/src/components/accounts/AccountSyncCheck.tsx (2)
32-33
: Remove empty default cases in switch statements.The empty default cases don't serve any purpose and can be removed to improve code clarity.
case 'ITEM_LOGIN_REQUIRED': return t( 'Your password or something else has changed with your bank and you need to login again.', ); - default: } break; case 'INVALID_INPUT': switch (code.toUpperCase()) { case 'INVALID_ACCESS_TOKEN': return t('Item is no longer authorized. You need to login again.'); - default: } break;Also applies to: 40-41
20-77
: Consider refactoring error message handling for better maintainability.The current implementation mixes string and JSX returns, and has a complex nested switch structure. Consider these improvements:
- Separate string-based messages from JSX-based messages
- Use a lookup object for simple string messages
- Add explicit error codes for better error tracking
Here's a suggested refactor:
function useErrorMessage() { const { t } = useTranslation(); const ERROR_MESSAGES = { 'ITEM_ERROR.NO_ACCOUNTS': t('No open accounts could be found. Did you close the account? If so, unlink the account.'), 'ITEM_ERROR.ITEM_LOGIN_REQUIRED': t('Your password or something else has changed with your bank and you need to login again.'), 'INVALID_INPUT.INVALID_ACCESS_TOKEN': t('Item is no longer authorized. You need to login again.'), 'RATE_LIMIT_EXCEEDED': t('Rate limit exceeded for this item. Please try again later.'), 'INVALID_ACCESS_TOKEN': t('Your SimpleFIN Access Token is no longer valid. Please reset and generate a new token.') }; function getJSXErrorMessage(type: string, code: string) { if (type === 'ACCOUNT_NEEDS_ATTENTION') { return ( <Trans> The account needs your attention at{' '} <Link variant="external" to="https://bridge.simplefin.org/auth/login"> SimpleFIN </Link>. </Trans> ); } return ( <Trans> An internal error occurred. Try to login again, or get{' '} <Link variant="external" to="https://actualbudget.org/contact/"> in touch </Link>{' '} for support. </Trans> ); } function getErrorMessage(type: string, code: string) { const messageKey = code ? `${type}.${code}` : type; return ERROR_MESSAGES[messageKey.toUpperCase()] || getJSXErrorMessage(type, code); } return { getErrorMessage }; }packages/desktop-client/src/components/reports/reports/GetCardData.tsx (1)
Line range hint
26-33
: LGTM: Proper implementation of useTranslation hookThe translation hook is correctly implemented and follows React best practices. The error message is properly internationalized while maintaining the existing styling and layout.
Consider adding type safety to the translation key:
// Define your translation keys type type TranslationKeys = { 'There was a problem loading your report': string; // ... other keys }; // Use it with useTranslation const { t } = useTranslation<keyof TranslationKeys>();packages/desktop-client/src/components/modals/FixEncryptionKeyModal.tsx (1)
Line range hint
27-31
: Consider handling undefined optionsThe default value for
options
has been removed, but the type definition doesn't mark it as optional. This could lead to runtime issues ifoptions
is undefined.Consider either:
-type FixEncryptionKeyModalProps = { - options: FinanceModals['fix-encryption-key']; -}; +type FixEncryptionKeyModalProps = { + options?: FinanceModals['fix-encryption-key']; +};Or restore the default value:
-export function FixEncryptionKeyModal({ - options = {}, -}: FixEncryptionKeyModalProps) { +export function FixEncryptionKeyModal({ + options, +}: FixEncryptionKeyModalProps) {packages/desktop-client/src/components/settings/index.tsx (1)
Line range hint
114-121
: Consider tracking the TODO commentThere's a low-priority TODO comment about eliminating or deciding when to show certain IDs. This could be tracked for future improvements.
Would you like me to create a GitHub issue to track this TODO item?
packages/desktop-client/src/components/reports/ReportTopbar.tsx (2)
Line range hint
74-74
: Consider adding type safety for translation keysWhile the translation implementation is correct, consider improving type safety by defining constants or enums for translation keys. This would help catch missing translations at compile time and make refactoring easier.
Here's an example approach:
// translations/keys.ts export const ReportTranslationKeys = { dataTable: 'Data Table', barGraph: 'Bar Graph', stackedBarGraph: 'Stacked Bar Graph', lineGraph: 'Line Graph', areaGraph: 'Area Graph', donutGraph: 'Donut Graph', showLegend: 'Show Legend', showSummary: 'Show Summary', showLabels: 'Show Labels', } as const; // Then in component: t(ReportTranslationKeys.dataTable)Also applies to: 76-76, 89-93, 106-106, 119-119, 132-132, 145-145, 158-158, 171-171
Migration to useTranslation is inconsistent in reports directory
There are still a few files in the reports directory using direct
t
imports from 'i18next' that need to be migrated touseTranslation
:
packages/desktop-client/src/components/reports/disabledList.ts
packages/desktop-client/src/components/reports/ReportOptions.ts
The rest of the reports directory has properly adopted the
useTranslation
hook from 'react-i18next', showing good progress in the migration.🔗 Analysis chain
Line range hint
1-200
: Verify consistent translation approach across related componentsSince this is part of a larger migration to
useTranslation
, let's verify the consistency of the implementation.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check for any remaining direct t imports echo "Checking for remaining direct t imports..." rg "import.*\{ t \}.*from 'i18next'" packages/desktop-client/src/ # Check for consistent translation key usage echo "Checking for translation key usage patterns..." rg "t\(['\"](?:Data Table|Bar Graph|Stacked Bar Graph|Line Graph|Area Graph|Donut Graph|Show Legend|Show Summary|Show Labels)['\"]" packages/desktop-client/src/Length of output: 1858
Script:
#!/bin/bash # Let's check the implementation of useTranslation in the same directory echo "Checking useTranslation implementations in reports directory..." rg "useTranslation" packages/desktop-client/src/components/reports/ # Check for any other translation-related imports in the reports directory echo "Checking other translation-related imports in reports directory..." rg "import.*from ['\"].*i18next['\"]" packages/desktop-client/src/components/reports/ # Check if there are any other files that might need migration echo "Checking for potential files needing migration..." fd . packages/desktop-client/src/components/reports/ -e tsx -e ts -e jsx -e js --exec grep -l "t("Length of output: 16196
packages/desktop-client/src/components/modals/CategoryMenuModal.tsx (1)
Line range hint
195-213
: Consider translating menu items text.The menu items' text strings ('Show', 'Hide', 'Delete') should be translated for consistency with the rest of the internationalization efforts.
Apply this change to the menu items:
items={[ !categoryGroup?.hidden && { name: 'toggleVisibility', - text: category.hidden ? 'Show' : 'Hide', + text: category.hidden ? t('Show') : t('Hide'), icon: category.hidden ? SvgViewShow : SvgViewHide, iconSize: 16, }, !categoryGroup?.hidden && Menu.line, { name: 'delete', - text: 'Delete', + text: t('Delete'), icon: SvgTrash, iconSize: 15, }, ]}packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx (1)
Line range hint
147-157
: Consider using translation keys with placeholders for interpolated content.The current implementation directly interpolates components within translated strings. Consider using translation keys with placeholders for better maintainability and flexibility across different languages.
Example refactor:
- <Text> - {t('This cannot be changed later.')} <br /> {'\n'} - {t('See')}{' '} - <Link - variant="external" - linkColor="muted" - to="https://actualbudget.org/docs/accounts/#off-budget-accounts" - > - {t('Accounts Overview')} - </Link>{' '} - {t('for more information.')} - </Text> + <Text> + {t('offbudget.warning')} <br /> {'\n'} + {t('offbudget.info_link', { + link: ( + <Link + variant="external" + linkColor="muted" + to="https://actualbudget.org/docs/accounts/#off-budget-accounts" + > + {t('offbudget.docs_link')} + </Link> + ), + })} + </Text>Translation keys would look like:
{ "offbudget": { "warning": "This cannot be changed later.", "info_link": "See {{link}} for more information.", "docs_link": "Accounts Overview" } }packages/desktop-client/src/components/modals/MergeUnusedPayeesModal.tsx (2)
Line range hint
140-150
: Add translation for the conditional textWhile the main message is properly translated, the conditional text should also be translated for consistency:
<Information> {t('Merging will remove the payee and transfer any existing rules to the new payee.')} {!isEditingRule && ( <> {' '} - If checked below, a rule will be created to do this rename - while importing transactions. + {t('If checked below, a rule will be created to do this rename while importing transactions.')} </> )} </Information>
Line range hint
95-120
: Add translations for remaining user-facing stringsSeveral user-facing strings in the main content area are not translated. Consider wrapping these strings with the translation function:
{payees.length === 1 ? ( <> - The payee <Text style={highlightStyle}>{payees[0].name}</Text>{' '} - is not used by transactions any more. Would like to merge it - with <Text style={highlightStyle}>{targetPayee.name}</Text>? + {t('The payee {{payeeName}} is not used by transactions any more. Would like to merge it with {{targetName}}?', { + payeeName: <Text style={highlightStyle}>{payees[0].name}</Text>, + targetName: <Text style={highlightStyle}>{targetPayee.name}</Text> + })} </> ) : ( <> - The following payees are not used by transactions any more. - Would like to merge them with{' '} - <Text style={highlightStyle}>{targetPayee.name}</Text>? + {t('The following payees are not used by transactions any more. Would like to merge them with {{targetName}}?', { + targetName: <Text style={highlightStyle}>{targetPayee.name}</Text> + })} </> )}Also, translate the checkbox label:
<Text style={{ marginLeft: 3 }}> - Automatically rename{' '} - {payees.length === 1 ? 'this payee' : 'these payees'} in the - future + {t('Automatically rename {{count}} in the future', { + count: payees.length, + context: payees.length === 1 ? 'single' : 'multiple' + })} </Text>packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx (1)
175-175
: Consider translating menu item textsWhile the aria-label is properly translated, the menu item texts ("Show", "Hide", "Delete") are still hardcoded in English. Consider wrapping these strings with the translation function for consistency.
Here's how you could update the menu items:
items={ [ { name: 'toggleVisibility', - text: group.hidden ? 'Show' : 'Hide', + text: group.hidden ? t('Show') : t('Hide'), icon: group.hidden ? SvgViewShow : SvgViewHide, iconSize: 16, }, ...(!group.is_income && [ Menu.line, { name: 'delete', - text: 'Delete', + text: t('Delete'), icon: SvgTrash, iconSize: 15, }, ]), ].filter(i => i != null) as ComponentProps<typeof Menu>['items'] }Also applies to: 198-198, 227-229, 235-239
packages/desktop-client/src/components/transactions/SimpleTransactionsTable.tsx (2)
Line range hint
224-270
: Consider using translation key constantsWhile the translation implementation is correct, consider extracting the translation keys into constants to ensure consistency and easier maintenance across the application. This would help prevent typos and make it easier to track all used translations.
Example refactor:
+ const TRANSLATION_KEYS = { + DATE: 'Date', + IMPORTED_PAYEE: 'Imported payee', + PAYEE: 'Payee', + CATEGORY: 'Category', + ACCOUNT: 'Account', + NOTES: 'Notes', + AMOUNT: 'Amount' + } as const; // Then in the render: - {t('Date')} + {t(TRANSLATION_KEYS.DATE)}
Missing translation for 'No account' fallback text
The component has properly translated all column headers using the
t()
function, but there's one untranslated user-facing string:
- The fallback text 'No account' appears twice (in both title and content) in the account field case and needs translation:
<Field key={i} width="flex" title={account?.name || t('No account')}> {account?.name || t('No account')} </Field>🔗 Analysis chain
Line range hint
1-270
: Verify all user-facing strings are translatedLet's verify that no translatable strings were missed in the component.
The string 'No account' in the account field case might need translation:
- {account?.name || 'No account'} + {account?.name || t('No account')}🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for potential hardcoded strings that might need translation rg -U --type typescript --type tsx "['\"](No account|[A-Z][a-zA-Z ]+)['\"]" packages/desktop-client/src/components/transactions/SimpleTransactionsTable.tsxLength of output: 196
Script:
#!/bin/bash # Search for potential hardcoded strings that might need translation, using a more generic pattern rg -U "['\"](No account|[A-Z][a-zA-Z ]+)['\"]" packages/desktop-client/src/components/transactions/SimpleTransactionsTable.tsxLength of output: 506
packages/desktop-client/src/components/modals/CreateEncryptionKeyModal.tsx (4)
Line range hint
41-42
: Consider consistent error state handlingThe error state is set to
null
but rendered directly in the UI. Consider using a consistent approach with empty string to avoid potential rendering issues.- setError(null); + setError('');
Line range hint
39-65
: Enhance password security measuresConsider implementing:
- Password strength validation
- Secure password state management
- Clear password state on component unmount
Would you like me to provide an example implementation of these security enhancements?
Line range hint
89-102
: Translate remaining hardcoded stringsSeveral strings remain untranslated:
"To enable end-to-end encryption, you need to create a key. We will generate a key based on a password and use it to encrypt from now on." "Important:" "if you forget this password" "and" "you will lose access to all your data. The data cannot be decrypted without the password."
Line range hint
146-159
: Consider separating HTML markup from translationsTranslation strings containing HTML markup could cause issues during translation. Consider using React components or translation keys with variables for formatting.
Example approach:
// Instead of t('This will generate a new key for encrypting your data.') + ' ' + <strong>{t('This requires a sync reset')}</strong> // Consider <Trans i18nKey="newKey.description"> This will generate a new key for encrypting your data. <strong>This requires a sync reset</strong> </Trans>packages/desktop-client/src/components/modals/SelectLinkedAccountsModal.jsx (1)
204-204
: LGTM: Proper hook usage in child componentThe useTranslation hook is correctly initialized in the TableRow component, following React hooks best practices by having each component manage its own translations rather than prop drilling the t function.
Consider memoizing the component with React.memo since it's a child component in a list:
-function TableRow({ +const TableRow = React.memo(function TableRow({ externalAccount, chosenAccount, unlinkedAccounts, onSetLinkedAccount, -}) { +}) { const { t } = useTranslation(); // ... rest of the component -} +});packages/desktop-client/src/components/modals/EditFieldModal.tsx (2)
Line range hint
134-134
: Consider using more specific translation keys for UI actionsWhile the translations work, consider using more specific translation keys for UI actions to provide better context for translators and avoid potential key conflicts. For example:
-{t('Prepend')} +{t('notes.actions.prepend')} -{t('Replace')} +{t('notes.actions.replace')} -{t('Append')} +{t('notes.actions.append')}This namespace structure would make it clear these are note-related actions and help translators provide more accurate translations.
Also applies to: 182-182, 230-230
Line range hint
124-234
: Consider extracting button styles to reduce duplicationThe button styles are duplicated across the three amendment mode buttons. Consider extracting this logic into a reusable function to improve maintainability:
const getButtonStyles = (currentMode: NoteAmendMode, buttonMode: NoteAmendMode): CSSProperties => ({ padding: '5px 10px', width: '33.33%', backgroundColor: theme.menuBackground, marginRight: 5, fontSize: 'inherit', ...(currentMode === buttonMode ? { backgroundColor: theme.buttonPrimaryBackground, color: theme.buttonPrimaryText, ':hover': { backgroundColor: theme.buttonPrimaryBackgroundHover, color: theme.buttonPrimaryTextHover, }, } : { backgroundColor: theme.buttonNormalBackground, color: theme.buttonNormalText, ':hover': { backgroundColor: theme.buttonNormalBackgroundHover, color: theme.buttonNormalTextHover, }, }), });Then use it in the buttons:
<Button style={getButtonStyles(noteAmend, 'prepend')} onPress={() => { onChangeMode('prepend'); noteInputRef.current?.focus(); }} > {t('notes.actions.prepend')} </Button>packages/desktop-client/src/components/Notifications.tsx (1)
Line range hint
234-239
: Consider translating additional text content.While the 'Close' aria-label translation is correctly implemented, there are other text elements in the component that could benefit from translation for complete internationalization coverage:
- The
title
prop in the notification- The
pre
text content- The
button.title
textExample implementation:
{title && ( <View style={{ ...styles.mediumText, fontWeight: 700, marginBottom: 10, }} > - {title} + {t(title)} </View> )} // ... and similarly for other text contentpackages/desktop-client/src/components/reports/CategorySelector.tsx (1)
Line range hint
1-215
: Consider translating additional UI textWhile the main button labels are now properly translated, consider also translating:
- Category group names (if they're not coming from the database)
- ARIA labels or titles for accessibility
- Any error messages or tooltips that might be added in the future
packages/desktop-client/src/components/mobile/accounts/Accounts.tsx (2)
Line range hint
165-173
: Consider using a structured translation key.While the translation implementation is correct, using a long text string as a translation key can be harder to maintain. Consider using a structured key instead.
- {t( - 'For Actual to be useful, you need to add an account. You can link an account to automatically download transactions, or manage it locally yourself.', - )} + {t('accounts.empty.message')}This makes the translations more maintainable and easier to track across the application.
Line range hint
1-319
: Consider documenting the translation strategy.The transition to
useTranslation
hook is well implemented. To ensure consistency across the codebase, consider:
- Documenting this approach in the project's contribution guidelines
- Creating a shared translation key structure/naming convention
- Setting up type checking for translation keys to catch missing translations early
This will help maintain consistency as more components are migrated to use the
useTranslation
hook.packages/desktop-client/src/components/Titlebar.tsx (1)
Direct t imports found and potential translation gaps identified
Several components still use direct
t
imports from i18next that should be migrated touseTranslation
hook:
packages/desktop-client/src/components/util/accountValidation.ts
packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
packages/desktop-client/src/components/reports/disabledList.ts
packages/desktop-client/src/components/reports/ReportOptions.ts
packages/desktop-client/src/components/budget/util.ts
packages/desktop-client/src/components/accounts/Account.tsx
Additionally, multiple components contain hardcoded aria-labels that should be translated using the
useTranslation
hook.🔗 Analysis chain
Line range hint
1-359
: Verify consistent translation approach across related componentsLet's ensure this change is consistently applied across all components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check for any remaining direct imports of the t function # that should be replaced with useTranslation hook # Search for direct t imports echo "Checking for direct t imports that should be replaced:" rg "import.*\{.*t.*\}.*from.*['\"]i18next['\"]" packages/desktop-client/src/ # Search for components that might need the useTranslation hook echo -e "\nChecking for potential missing useTranslation usage:" rg -l "aria-label.*['\"][^'\"]+['\"]" packages/desktop-client/src/ | \ grep -v "Titlebar.tsx" | \ xargs -I {} echo "Potential translation needed in: {}"Length of output: 4150
packages/desktop-client/src/components/common/Modal.tsx (2)
Line range hint
98-104
: Consider using a more specific translation keyWhile the translation is correctly implemented, consider using a more specific key like 'common.modal.dialog_label' to better organize translations hierarchically.
17-17
: Well-structured internationalization implementationThe migration to useTranslation hook is well-executed with consistent patterns across components. The implementation:
- Properly scopes translations to individual components
- Maintains good accessibility practices
- Follows React hooks best practices
Consider creating a shared hook (e.g., useModalTranslation) if these translation keys are reused across multiple modal-related components.
Also applies to: 57-57, 304-304, 473-473
packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx (1)
Line range hint
159-159
: Consider internationalizing user-facing strings in SelectedTransactionsFloatingActionBarSeveral hardcoded English strings in this component could benefit from translation for consistency with the rest of the application:
- Selection text: "{count} transactions/transaction selected"
- Button labels: "Edit"
- Menu items: "Account", "Payee", "Notes", etc.
Here's how you could implement this:
function SelectedTransactionsFloatingActionBar({ transactions, style }) { + const { t } = useTranslation(); // ... existing code ... <Text style={styles.mediumText}> - {selectedTransactions.size}{' '} - {isMoreThanOne ? 'transactions' : 'transaction'} selected + {t('{{count}} {{type}} selected', { + count: selectedTransactions.size, + type: isMoreThanOne ? t('transactions') : t('transaction') + })} </Text> <Button variant="bare" ref={editMenuTriggerRef} - aria-label="Edit fields" + aria-label={t('Edit fields')} onPress={() => { setIsEditMenuOpen(true); }} {...buttonProps} > - Edit + {t('Edit')} </Button> // ... in menu items array ... items={[ { name: 'account', - text: 'Account', + text: t('Account'), }, { name: 'payee', - text: 'Payee', + text: t('Payee'), }, // ... continue for other menu items ]}Also applies to: 254-254, 279-279, 359-386
packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx (3)
273-273
: Consider using more descriptive translation keys for aria-labelsWhile the translation implementation is correct, consider using more descriptive translation keys for aria-labels to provide better context for translators. For example:
- 'Remove recurrence' could be 'aria.label.remove_recurrence_button'
- 'Add recurrence' could be 'aria.label.add_recurrence_button'
Also applies to: 324-324, 342-342
354-354
: Improve text concatenation for better translation supportConsider avoiding string concatenation with translations. For example:
- {t('Move schedule')}{' '} + {t('move_schedule_weekend', { mode: state.config.weekendSolveMode })}This allows translators to handle the full sentence structure according to their language's grammar rules.
Also applies to: 486-486, 517-517, 519-519
9-9
: Consider implementing a translation key management strategyWhile the migration to useTranslation is well-implemented, consider:
- Establishing a consistent naming convention for translation keys
- Creating a type-safe translation key management system
- Documenting translation contexts for translators
This will improve maintainability as the application's internationalization grows.
Also applies to: 273-273, 354-354, 558-558
packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx (5)
Line range hint
138-166
: Consider using useReducer for complex state managementThe component manages numerous state variables independently. Consider using
useReducer
to group related state variables and their updates logically. This would make the state transitions more predictable and easier to maintain.For example, group the file-related states, import options, and transaction states:
const initialState = { file: { filename: options.filename, filetype: null, loadingState: 'parsing', error: null }, importOptions: { splitMode: false, flipAmount: false, multiplierEnabled: false, multiplierAmount: '', reconcile: true }, // ... other state groups };
Line range hint
196-308
: Decompose getImportPreview for better maintainabilityThe
getImportPreview
function is handling multiple responsibilities: data transformation, validation, and preview generation. Consider breaking it down into smaller, focused functions:function validateTransaction(trans, parseDateFormat) { if (!validateDate(trans.date, parseDateFormat)) { throw new Error(`Unable to parse date ${trans.date || '(empty)'}`); } if (!validatePayee(trans.payee_name)) { throw new Error(`Unable to parse payee ${trans.payee_name || '(empty')}`); } // ... other validations } function transformTransaction(trans, options) { const { splitMode, inOutMode, outValue, flipAmount, multiplierAmount } = options; return { ...trans, amount: parseAmountFields(trans, splitMode, inOutMode, outValue, flipAmount, multiplierAmount), // ... other transformations }; }
Line range hint
449-456
: Improve multiplier validationThe current regex validation has potential issues:
- It allows leading zeros
- It doesn't prevent multiple decimal points
- It allows empty string which could cause issues downstream
Consider using a more robust validation:
-if (!amt || amt.match(/^\d{1,}(\.\d{0,4})?$/)) { +if (amt === '' || amt.match(/^(?!0\d)\d*\.?\d{0,4}$/)) { setMultiplierAmount(amt); runImportPreview(); +} else { + // Optionally handle invalid input }
Line range hint
458-526
: Enhance error handling in onImportThe error handling uses string concatenation which could be vulnerable to injection. Consider using template literals and structured error objects:
const createError = (type, details) => ({ type, message: t(type, { ...details }), details }); // Usage if (date == null) { errorMessage = createError('INVALID_DATE', { date: trans.date || '(empty)', format: parseDateFormat }); break; }
Line range hint
749-766
: Enhance form accessibilityThe form controls lack proper accessibility attributes. Consider adding:
- ARIA labels for better screen reader support
- Proper form structure with fieldset and legend
- Error message association with form controls
<View style={{ marginTop: 10 }}> + <form role="form" aria-label={t('Import Options')}> + <fieldset> + <legend>{t('CSV Options')}</legend> <Stack direction="row" align="flex-start" spacing={1} style={{ marginTop: 5 }} > {/* ... existing controls ... */} </Stack> + </fieldset> + </form> </View>packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (1)
452-452
: Consider extracting translation keys to constantsTo improve maintainability and reduce the risk of typos in translation keys, consider extracting the translation keys to a separate constants file.
Example implementation:
+// translation-keys.js +export const TRANSACTION_KEYS = { + AMOUNT: 'Amount', + PAYEE: 'Payee', + CATEGORY: 'Category', + NOTES: 'Notes', + DELETE: 'Delete transaction', + // ... other keys +}; // TransactionEdit.jsx -const { t } = useTranslation(); +const { t } = useTranslation(); +const { AMOUNT, PAYEE, CATEGORY, NOTES, DELETE } = TRANSACTION_KEYS;This would make it easier to maintain translation keys and ensure consistency across the application.
packages/desktop-client/src/components/modals/EditRuleModal.jsx (2)
376-376
: Consider translating additional UI strings.While the translation hook is properly implemented, there are some hardcoded strings that should be translated for consistency:
- "allocate" at line 447
- "Add condition" at line 486
Apply this diff to improve internationalization:
- {t('allocate')} + {t('Allocate')}- Add condition + {t('Add condition')}Also applies to: 447-447, 486-486
Line range hint
508-517
: Consider translating the tooltip content.The tooltip text in the StageInfo component should be translated for consistency with the rest of the internationalization efforts.
Apply this diff to translate the tooltip content:
content={ <> - The stage of a rule allows you to force a specific order. Pre rules - always run first, and post rules always run last. Within each stage - rules are automatically ordered from least to most specific. + {t('The stage of a rule allows you to force a specific order. Pre rules always run first, and post rules always run last. Within each stage rules are automatically ordered from least to most specific.')} </> }packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx (1)
70-70
: Consider memoization for performance optimizationWhile the implementation is correct, consider using
useMemo
for translated strings that don't depend on dynamic values to optimize performance by preventing unnecessary re-renders.Example optimization:
const { t } = useTranslation(); +const staticLabels = useMemo(() => ({ + budgeted: t('Budgeted'), + spent: t('Spent'), + balance: t('Balance') +}), [t]);Also applies to: 133-133, 231-231, 1145-1145, 1421-1421, 1642-1642, 1747-1747, 1973-1973
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
upcoming-release-notes/3893.md
is excluded by!**/*.md
📒 Files selected for processing (55)
packages/desktop-client/src/components/ManageRulesPage.tsx
(1 hunks)packages/desktop-client/src/components/Notes.tsx
(2 hunks)packages/desktop-client/src/components/NotesButton.tsx
(2 hunks)packages/desktop-client/src/components/Notifications.tsx
(2 hunks)packages/desktop-client/src/components/ThemeSelector.tsx
(2 hunks)packages/desktop-client/src/components/Titlebar.tsx
(3 hunks)packages/desktop-client/src/components/accounts/AccountSyncCheck.tsx
(3 hunks)packages/desktop-client/src/components/common/Modal.tsx
(4 hunks)packages/desktop-client/src/components/mobile/MobileBackButton.tsx
(2 hunks)packages/desktop-client/src/components/mobile/accounts/Accounts.tsx
(3 hunks)packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx
(10 hunks)packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx
(2 hunks)packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx
(3 hunks)packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx
(2 hunks)packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx
(3 hunks)packages/desktop-client/src/components/modals/BudgetListModal.tsx
(1 hunks)packages/desktop-client/src/components/modals/CategoryAutocompleteModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx
(3 hunks)packages/desktop-client/src/components/modals/CategoryMenuModal.tsx
(3 hunks)packages/desktop-client/src/components/modals/CreateEncryptionKeyModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/EditFieldModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/EditRuleModal.jsx
(4 hunks)packages/desktop-client/src/components/modals/EnvelopeBalanceMenuModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/FixEncryptionKeyModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/GoCardlessInitialiseModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
(2 hunks)packages/desktop-client/src/components/modals/ManageRulesModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/MergeUnusedPayeesModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/PayeeAutocompleteModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx
(3 hunks)packages/desktop-client/src/components/modals/SelectLinkedAccountsModal.jsx
(3 hunks)packages/desktop-client/src/components/modals/TrackingBalanceMenuModal.tsx
(2 hunks)packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx
(2 hunks)packages/desktop-client/src/components/reports/CategorySelector.tsx
(2 hunks)packages/desktop-client/src/components/reports/ReportSidebar.tsx
(2 hunks)packages/desktop-client/src/components/reports/ReportTopbar.tsx
(2 hunks)packages/desktop-client/src/components/reports/SaveReportName.tsx
(2 hunks)packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsx
(2 hunks)packages/desktop-client/src/components/reports/reports/GetCardData.tsx
(2 hunks)packages/desktop-client/src/components/rules/ActionExpression.tsx
(2 hunks)packages/desktop-client/src/components/rules/RulesHeader.tsx
(1 hunks)packages/desktop-client/src/components/rules/Value.tsx
(2 hunks)packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx
(4 hunks)packages/desktop-client/src/components/settings/BudgetTypeSettings.tsx
(2 hunks)packages/desktop-client/src/components/settings/Export.tsx
(2 hunks)packages/desktop-client/src/components/settings/FixSplits.tsx
(2 hunks)packages/desktop-client/src/components/settings/Format.tsx
(2 hunks)packages/desktop-client/src/components/settings/Reset.tsx
(3 hunks)packages/desktop-client/src/components/settings/Themes.tsx
(2 hunks)packages/desktop-client/src/components/settings/UI.tsx
(2 hunks)packages/desktop-client/src/components/settings/index.tsx
(4 hunks)packages/desktop-client/src/components/transactions/SimpleTransactionsTable.tsx
(2 hunks)packages/desktop-client/src/components/util/AmountInput.tsx
(2 hunks)
🧰 Additional context used
📓 Learnings (3)
packages/desktop-client/src/components/mobile/accounts/Accounts.tsx (1)
Learnt from: qedi-r
PR: actualbudget/actual#3527
File: packages/desktop-client/src/components/accounts/Header.jsx:0-0
Timestamp: 2024-11-10T16:45:25.627Z
Learning: In the Actual Budget project, importing `t` directly from 'i18next' is acceptable and commonly used in the codebase.
packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx (1)
Learnt from: qedi-r
PR: actualbudget/actual#3527
File: packages/desktop-client/src/components/accounts/Header.jsx:0-0
Timestamp: 2024-11-10T16:45:25.627Z
Learning: In the Actual Budget project, importing `t` directly from 'i18next' is acceptable and commonly used in the codebase.
packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx (1)
Learnt from: qedi-r
PR: actualbudget/actual#3527
File: packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx:47-47
Timestamp: 2024-11-10T16:45:25.627Z
Learning: Validating balance is outside the scope in `CreateLocalAccountModal.tsx`.
🔇 Additional comments (121)
packages/desktop-client/src/components/ManageRulesPage.tsx (1)
2-2
: LGTM! Clean implementation of the useTranslation hook.
The changes successfully replace the direct t
import with the useTranslation
hook, which will enable automatic re-rendering when the language changes. The implementation follows React hooks best practices and maintains the component's functionality while improving its internationalization support.
Also applies to: 8-8
packages/desktop-client/src/components/rules/RulesHeader.tsx (1)
2-2
: LGTM! Clean migration to useTranslation hook
The changes correctly implement the migration from direct t import to useTranslation hook, following React hooks best practices and maintaining the existing translation functionality.
Also applies to: 8-8
packages/desktop-client/src/components/mobile/transactions/AddTransactionButton.tsx (1)
2-2
: LGTM! Clean implementation of useTranslation hook.
The changes effectively implement the transition from direct t
import to useTranslation
hook while maintaining component functionality and following React best practices.
Also applies to: 19-19
packages/desktop-client/src/components/mobile/MobileBackButton.tsx (2)
2-2
: LGTM: Clean import of useTranslation hook
The import statement follows React conventions and aligns with the PR objective to use hooks for translations.
Line range hint 41-41
: Verify translation key existence
Ensure that the 'Back' translation key exists in all language files to prevent fallback to key name.
packages/desktop-client/src/components/modals/ManageRulesModal.tsx (2)
3-3
: LGTM: Import of useTranslation hook
The import statement correctly introduces the useTranslation
hook from react-i18next, aligning with the PR's objective to enhance internationalization support.
16-16
: LGTM: Proper hook usage
The useTranslation
hook is correctly implemented at the component's top level, following React hooks best practices. This implementation will enable automatic re-rendering when the language changes.
packages/desktop-client/src/components/modals/BudgetListModal.tsx (3)
2-2
: LGTM: Import statement properly added
The useTranslation hook import is correctly placed with other React-related imports.
12-12
: LGTM: Hook usage follows best practices
The useTranslation hook is properly implemented at the component's top level alongside other hooks.
Line range hint 24-24
: Verify translation keys exist
Please ensure that the translation keys 'Switch Budget File' and 'Switching from:' exist in all language files.
Also applies to: 35-35
packages/desktop-client/src/components/ThemeSelector.tsx (2)
2-2
: LGTM! Clean implementation of useTranslation hook.
The migration from direct t
import to useTranslation
hook is implemented correctly, following React hooks best practices and maintaining type safety.
Also applies to: 24-24
Line range hint 45-45
: LGTM! Proper translation of accessibility attribute.
The aria-label is correctly internationalized using the t
function, maintaining accessibility while adding language support.
packages/desktop-client/src/components/settings/BudgetTypeSettings.tsx (1)
2-2
: LGTM! Correct implementation of useTranslation hook
The migration from direct t import to useTranslation hook is implemented correctly, following React hooks best practices.
Also applies to: 12-12
packages/desktop-client/src/components/settings/Export.tsx (3)
2-2
: LGTM: Good migration to useTranslation hook
The addition of useTranslation import aligns with React best practices for internationalization, enabling automatic re-renders on language changes.
17-17
: LGTM: Proper hook initialization
The useTranslation hook is correctly initialized at the component's top level, following React hooks best practices.
Line range hint 1-17
: Verify complete removal of direct t import
Let's ensure there are no remaining direct imports of the t function in this file.
✅ Verification successful
Migration to useTranslation hook is correctly implemented
The verification shows that:
- The file correctly imports
useTranslation
from 'react-i18next' - All usages of the
t
function are properly scoped through the hook's destructuredt
function - No direct imports of
t
from i18next remain
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining direct imports of t function
rg "import.*\{.*t.*\}.*from.*['\"]i18next['\"]" "packages/desktop-client/src/components/settings/Export.tsx"
Length of output: 112
Script:
#!/bin/bash
# Let's check for any i18next imports and their context
rg -A 3 "i18next" "packages/desktop-client/src/components/settings/Export.tsx"
# Also check for any usage of 't' function to ensure it's properly imported
rg -A 2 "\bt\(" "packages/desktop-client/src/components/settings/Export.tsx"
Length of output: 660
packages/desktop-client/src/components/settings/UI.tsx (3)
2-2
: LGTM! Import change aligns with PR objectives
The addition of useTranslation hook import is consistent with the goal of replacing direct t function imports.
53-53
: LGTM! Proper hook implementation
The useTranslation hook is correctly implemented at the component level.
Line range hint 53-93
: Verify translation keys exist
Let's ensure the translation keys 'Advanced Settings' and 'Show advanced settings' are defined in the translation files.
packages/desktop-client/src/components/NotesButton.tsx (2)
8-8
: LGTM! Clean import of useTranslation hook
The import follows the existing grouping pattern and aligns with the PR objective.
38-38
: LGTM! Proper implementation of useTranslation hook
The hook is correctly implemented and follows React best practices:
- Placed at the top of the component
- Used to translate the aria-label, maintaining accessibility
- Clean destructuring of the
t
function
packages/desktop-client/src/components/modals/PayeeAutocompleteModal.tsx (1)
2-2
: LGTM: Import of useTranslation hook
The addition of the useTranslation hook import aligns with the PR objective to enhance i18n support.
packages/desktop-client/src/components/settings/Reset.tsx (2)
2-2
: LGTM: Import change aligns with best practices
The change from direct t
import to useTranslation
hook follows React best practices and enables automatic re-rendering on language changes.
14-14
: LGTM: Proper hook implementation in ResetCache
The useTranslation
hook is correctly implemented at the component level, maintaining React hooks rules and enabling component-level translation management.
packages/desktop-client/src/components/reports/SaveReportName.tsx (1)
3-3
: LGTM: Clean import replacement
The replacement of the direct t
import with useTranslation
hook aligns with React best practices for i18n handling.
packages/desktop-client/src/components/settings/Themes.tsx (3)
2-2
: LGTM: Import placement is correct
The useTranslation hook import is properly placed with other React-related imports.
40-40
: LGTM: Hook usage follows best practices
The useTranslation hook is correctly implemented at the component's top level, following React hooks rules and the PR's standardization goals.
Line range hint 1-97
: Verify consistent hook usage across settings components
Let's ensure this migration pattern is consistently applied across related components.
✅ Verification successful
Migration to useTranslation is consistently applied across settings components
The verification shows that all settings components are consistently using the useTranslation
hook from 'react-i18next', and there are no direct imports of the t
function from 'i18next'. The pattern is uniformly applied across all settings components including BudgetTypeSettings, Encryption, Export, FixSplits, Format, Reset, Themes, and UI components.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check for any remaining direct t imports in settings components
rg "import.*\{.*t.*\}.*from.*['\"]i18next['\"]" "packages/desktop-client/src/components/settings/"
# Check for consistent useTranslation usage pattern in settings components
rg "useTranslation" "packages/desktop-client/src/components/settings/"
Length of output: 2273
packages/desktop-client/src/components/modals/CategoryAutocompleteModal.tsx (2)
2-2
: LGTM: Import of useTranslation hook
The import of useTranslation
from 'react-i18next' is correctly implemented, aligning with the PR's objective to transition from direct t
function imports.
30-30
: LGTM: Proper hook initialization
The useTranslation
hook is correctly initialized at the component's top level, following React hooks best practices.
packages/desktop-client/src/components/modals/TrackingBalanceMenuModal.tsx (3)
5-5
: LGTM: Import statement aligns with PR objectives
The addition of useTranslation
hook import is correct and follows the PR's goal of standardizing translation handling.
41-41
: LGTM: Proper hook implementation
The useTranslation
hook is correctly implemented at the component level, following React hooks rules and providing access to the translation function.
Line range hint 65-67
: Consider comprehensive internationalization
While the "Balance" text is now properly translated, consider reviewing other potential internationalization opportunities in the component:
- Modal title (category.name) might need translation depending on the data source
- Future error states could benefit from translated messages instead of returning null
Let's check for other potential translation opportunities in similar modal components:
packages/desktop-client/src/components/modals/EnvelopeBalanceMenuModal.tsx (3)
5-5
: LGTM: Clean import of useTranslation hook
The import is correctly placed and aligns with the PR objective to use the useTranslation hook.
43-43
: LGTM: Proper hook usage
The useTranslation hook is correctly implemented at the component's top level, following React hooks best practices.
Line range hint 71-71
: LGTM: Translation implementation
The translation is correctly implemented for the "Balance" string.
Let's check for any other potential strings that might need translation in this component:
✅ Verification successful
All strings are properly internationalized
After reviewing the component's source code, I can confirm that there are no hardcoded strings that require translation. The only visible text content "Balance" is already properly translated using the t()
function. Other text content in the component is either:
- Dynamically loaded from variables (like
category.name
) - Handled by child components (
BalanceWithCarryover
,BalanceMenu
, etc.)
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for potential hardcoded strings in the component that might need translation
rg -U --type typescript --type tsx "(<Text[^>]*>([^{<>]|[^<]{[^t][^}]*})*</Text>|title=(\{[^t][^}]*\}|\"[^\"]*\"))" packages/desktop-client/src/components/modals/EnvelopeBalanceMenuModal.tsx
Length of output: 372
Script:
#!/bin/bash
# Let's try a simpler approach to find potential hardcoded strings
# Look for Text components and string literals
rg --type typescript --type tsx -U "Text|['\"][^'\"]+['\"]" packages/desktop-client/src/components/modals/EnvelopeBalanceMenuModal.tsx
Length of output: 177
Script:
#!/bin/bash
# Let's try without file type specification and look at the file content
cat packages/desktop-client/src/components/modals/EnvelopeBalanceMenuModal.tsx
Length of output: 3233
packages/desktop-client/src/components/Notes.tsx (2)
3-3
: LGTM! Import placement is correct.
The useTranslation
hook import is properly placed with other React-related imports.
102-102
: LGTM! Hook usage follows best practices.
The implementation:
- Correctly uses the
useTranslation
hook at the component level - Properly extracts the
t
function - Effectively applies it to translate the placeholder text
Let's verify that all user-facing strings in this component are properly translated:
Also applies to: 126-126
✅ Verification successful
All user-facing strings are properly translated in this component
The verification confirms that:
- The only user-facing string in the component is "Notes (markdown supported)" which is correctly wrapped in the translation function
t()
- All other string literals in the file are related to styling properties or technical configurations
- The component follows translation best practices consistently
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any hardcoded strings that might need translation
rg -U "(?<![a-zA-Z])'[^']*'|(?<![a-zA-Z])\"[^\"]*\"" "packages/desktop-client/src/components/Notes.tsx" \
| grep -v "^import\|^\/\/\|className\|^const\|border\|backgroundColor\|color\|linkTarget\|display\|margin\|padding\|overflowWrap\|outline\|^ '\|^ '\|^}'\|^{'\|borderLeft\|borderTop\|borderRight\|borderBottom"
Length of output: 580
Script:
#!/bin/bash
# Search for any hardcoded strings that might need translation using PCRE2
rg --pcre2 "(?<![a-zA-Z])'[^']*'|(?<![a-zA-Z])\"[^\"]*\"" "packages/desktop-client/src/components/Notes.tsx" -A 2 \
| grep -v "^import\|^\/\/\|className\|^const\|border\|backgroundColor\|color\|linkTarget\|display\|margin\|padding\|overflowWrap\|outline\|^ '\|^ '\|^}'\|^{'\|borderLeft\|borderTop\|borderRight\|borderBottom"
# Also let's check for t() function usage to see translation coverage
rg "t\(['\"].*?['\"]\)" "packages/desktop-client/src/components/Notes.tsx" -A 1
Length of output: 991
packages/desktop-client/src/components/modals/ScheduledTransactionMenuModal.tsx (3)
6-6
: LGTM! Proper implementation of useTranslation hook.
The hook is correctly imported and initialized at the component level, following React hooks best practices.
Also applies to: 30-30
101-101
: LGTM! Proper hook initialization in ScheduledTransactionMenu.
The useTranslation hook is correctly initialized at the component level.
Line range hint 117-124
: Verify menu item translation keys.
The translation keys 'Post transaction' and 'Skip scheduled date' are used for menu items.
packages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsx (3)
7-7
: LGTM: Import change aligns with PR objectives
The addition of useTranslation
hook import is correct and follows the PR's goal of standardizing translation handling.
47-47
: LGTM: Hook usage follows best practices
The useTranslation
hook is correctly implemented at the top level of the component alongside other hooks, following React hooks best practices.
Line range hint 89-89
: Verify translation coverage for all user-facing strings
While the "Budgeted" string is correctly translated, let's ensure all user-facing strings in the modal are handled by the translation system.
packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx (3)
7-7
: LGTM! Import change aligns with project objectives.
The addition of the useTranslation
hook import follows React best practices and aligns with the PR's goal of improving localization handling.
47-47
: LGTM! Hook implementation follows best practices.
The useTranslation
hook is correctly initialized at the component's top level, following React hooks rules.
Line range hint 23-35
: Consider adding null checks for optional props.
While the new props are correctly typed, they're passed directly to BudgetMenu
without checking for undefined values. This could lead to runtime errors if the props aren't provided.
Let's verify how these props are handled in the BudgetMenu component:
Consider adding null checks or providing default values:
export function TrackingBudgetMenuModal({
categoryId,
onUpdateBudget,
onCopyLastMonthAverage,
onSetMonthsAverage,
onApplyBudgetTemplate,
}: TrackingBudgetMenuModalProps) {
// ...
return (
// ...
<BudgetMenu
getItemStyle={() => defaultMenuItemStyle}
- onCopyLastMonthAverage={onCopyLastMonthAverage}
- onSetMonthsAverage={onSetMonthsAverage}
- onApplyBudgetTemplate={onApplyBudgetTemplate}
+ onCopyLastMonthAverage={onCopyLastMonthAverage ?? (() => {})}
+ onSetMonthsAverage={onSetMonthsAverage ?? (() => {})}
+ onApplyBudgetTemplate={onApplyBudgetTemplate ?? (() => {})}
/>
);
}
packages/desktop-client/src/components/settings/FixSplits.tsx (2)
2-2
: LGTM: Import statement correctly added
The useTranslation
hook import is properly placed and aligns with the PR objective of improving i18n support.
57-57
: LGTM: Hook implementation is correct
The useTranslation
hook is properly implemented at the component level.
packages/desktop-client/src/components/rules/ActionExpression.tsx (2)
2-2
: LGTM: Import change aligns with PR objectives
The change from direct t
import to useTranslation
hook is correctly implemented.
Line range hint 4-17
: Verify translation setup for imported utilities
Let's verify if friendlyOp
and ALLOCATION_METHODS
are prepared for internationalization.
packages/desktop-client/src/components/modals/GoCardlessInitialiseModal.tsx (3)
3-3
: LGTM! Proper implementation of useTranslation hook
The migration from direct t import to useTranslation hook is implemented correctly, following React best practices.
Also applies to: 29-29
1-1
: Consider addressing TypeScript strict mode issues
The @ts-strict-ignore
comment suggests there are TypeScript strict mode violations that should be addressed for better type safety.
Let's check for TypeScript configuration and similar patterns:
Line range hint 1-140
: Verify translation key definitions
Let's ensure all translation keys used in this component are defined in the translation files.
packages/desktop-client/src/components/settings/Format.tsx (3)
3-3
: LGTM: Correct implementation of useTranslation import
The addition of useTranslation hook import aligns with React best practices for internationalization.
60-60
: LGTM: Proper hook initialization
The useTranslation hook is correctly initialized at the component's top level, following React hooks best practices.
Line range hint 89-89
: LGTM: Comprehensive translation implementation
All user-facing strings are properly wrapped with the t() function, ensuring consistent internationalization throughout the component.
Let's verify that all user-facing strings are properly translated:
Also applies to: 108-108, 122-122, 134-134, 147-147, 156-160
✅ Verification successful
All user-facing strings are properly translated
The verification shows that all user-facing text content is properly handled:
- Column titles are passed through the t() function
- The "Hide decimal places" label uses t()
- The "Formatting" text and its description use t()
- Day names and date formats are handled through structured data (daysOfWeek and dateFormats arrays)
- Number formats are imported from core utilities (numberFormats)
The only non-translated strings found are:
- Technical IDs (e.g., "settings-textDecimal")
- CSS class names and style properties
- Variable names and technical constants
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any hardcoded strings that might have been missed in translation
# Look for string literals in JSX that aren't wrapped in t()
ast-grep --pattern 'JSXText {
$text
}' packages/desktop-client/src/components/settings/Format.tsx
# Also check for potential string literals in component props
ast-grep --pattern 'JSXAttribute {
$name="$value"
}' packages/desktop-client/src/components/settings/Format.tsx
Length of output: 217
Script:
#!/bin/bash
# Let's try a different approach to check for text content and string literals
# First, let's see the actual content of the file
cat packages/desktop-client/src/components/settings/Format.tsx
# Then let's specifically look for potential untranslated strings using ripgrep
# This will show us string literals in JSX context with surrounding lines
rg -U ">[^<]*[a-zA-Z]" packages/desktop-client/src/components/settings/Format.tsx
# Also look for string literals in props that might need translation
rg "=['\"](.*?)['\"]" packages/desktop-client/src/components/settings/Format.tsx
Length of output: 6984
packages/desktop-client/src/components/util/AmountInput.tsx (1)
11-11
: LGTM: Import change aligns with PR objectives
The change from direct t
function import to useTranslation
hook follows React best practices and enables automatic re-rendering on language changes.
packages/desktop-client/src/components/rules/Value.tsx (2)
3-3
: LGTM: Proper implementation of useTranslation hook
The addition of useTranslation hook and its usage follows React hooks best practices and aligns with the PR objectives.
Also applies to: 39-39
Line range hint 156-162
: Verify consistent translation usage across components
Let's verify if the translation key 'and' is used consistently across other components that might have similar "in between" functionality.
packages/desktop-client/src/components/mobile/transactions/TransactionListWithBalances.jsx (2)
2-2
: LGTM: Import change aligns with PR objectives
The change from direct t
import to useTranslation
hook follows React best practices and enables automatic re-rendering on language changes.
174-174
: Maintain consistent translation key structure
Similar to the previous component, consider using a more specific translation key like 'transactions.balance.total'
for consistency.
Let's verify the translation keys usage across the codebase:
packages/desktop-client/src/components/reports/reports/CustomReportListCards.tsx (2)
2-2
: LGTM: Import statement follows conventions
The addition of the useTranslation
hook import aligns with the PR objective and follows proper import conventions.
39-40
: LGTM: Hook usage follows React best practices
The useTranslation
hook is correctly implemented at the component's top level, following React hooks best practices.
packages/desktop-client/src/components/accounts/AccountSyncCheck.tsx (2)
2-2
: LGTM: Import changes align with PR objectives.
The addition of useTranslation import is appropriate for the intended refactoring.
90-90
: LGTM: Clean integration of useErrorMessage hook.
The hook integration is well-implemented and maintains the existing component functionality.
packages/desktop-client/src/components/reports/reports/GetCardData.tsx (1)
3-3
: LGTM: Import statement is correctly placed and used
The addition of the useTranslation
hook import aligns with the PR objective of migrating from direct t
function imports to hook-based translations.
packages/desktop-client/src/components/modals/FixEncryptionKeyModal.tsx (4)
4-4
: LGTM: Proper implementation of useTranslation hook
The migration from direct t
import to useTranslation
hook follows React best practices and aligns with the PR objectives.
Also applies to: 35-35
Line range hint 63-64
: LGTM: Consistent translation implementation
The translation strings are properly implemented using the useTranslation
hook throughout the component. The usage is consistent and follows i18n best practices.
Also applies to: 77-83, 89-95, 142-142, 165-165, 181-181, 186-186
Line range hint 43-43
: Verify error state handling with null value
The error state is now set to null
instead of an empty string. While the error display logic appears to handle this correctly through the conditional rendering, please verify that all error state consumers handle both empty string and null values consistently.
Also applies to: 123-134
✅ Verification successful
Let me check how these error states are consumed in the UI to ensure consistent handling.
Error state handling is consistent across modal components
The codebase consistently handles error states using conditional rendering with the &&
operator, which safely handles both null
and empty string values. All modal components follow the same pattern where:
- Error states are explicitly set to
null
when clearing errors - Error messages are rendered only when the error state is truthy
- The change from empty string to
null
aligns with the prevalent pattern across other modals
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other uses of setError in similar modal components
rg "setError\(" packages/desktop-client/src/components/modals/
Length of output: 2025
Script:
#!/bin/bash
# Search for error rendering patterns in modal components
rg -A 2 "error\s*[?&]" packages/desktop-client/src/components/modals/
# Also search for error type declarations
ast-grep --pattern 'error: $_'
Length of output: 4655
Line range hint 147-157
: Review password visibility toggle implementation
While the password visibility toggle is a common UX pattern, ensure it follows security best practices:
- Consider auto-hiding the password after a timeout
- Ensure the password state is properly cleared on component unmount
✅ Verification successful
Let me check the implementation details of these components to verify the security practices.
Let me check the complete implementation of these components to better understand the password handling.
Password visibility toggle implementation is secure and consistent
After reviewing the implementation across all password-related components, I can confirm that:
- The password visibility toggle follows a consistent pattern across all components
- The password state is managed locally using React's useState and is automatically cleaned up when components unmount
- The implementation is used in appropriate contexts (encryption key setup and password confirmation)
- The password visibility state is not persisted and defaults to hidden on mount
While auto-hiding after timeout could be an enhancement, the current implementation is secure as:
- It requires explicit user action to show/hide
- The visibility state resets when the modal is closed
- The implementation is used only in modal contexts where the user is actively engaged
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for similar password visibility implementations to ensure consistency
rg "setShowPassword|showPassword.*password" packages/desktop-client/src/
Length of output: 1409
Script:
#!/bin/bash
# Check the cleanup/unmount handling in these components
ast-grep --pattern 'useEffect($$$) {
$$$
return () => {
$$$
}
}' packages/desktop-client/src/components/modals/FixEncryptionKeyModal.tsx packages/desktop-client/src/components/modals/CreateEncryptionKeyModal.tsx packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx
# Check for timeout-based auto-hide implementations
rg "setTimeout.*setShowPassword" packages/desktop-client/src/
Length of output: 368
Script:
#!/bin/bash
# Get the full content of the password-related components
cat packages/desktop-client/src/components/modals/FixEncryptionKeyModal.tsx
cat packages/desktop-client/src/components/modals/CreateEncryptionKeyModal.tsx
cat packages/desktop-client/src/components/manager/subscribe/ConfirmPasswordForm.tsx
# Check for any password-related security utilities
rg -A 3 "password.*security|security.*password" packages/desktop-client/src/
Length of output: 15870
packages/desktop-client/src/components/settings/index.tsx (4)
2-2
: LGTM: Proper implementation of useTranslation hook
The useTranslation
hook is correctly imported and initialized in the component, following React hooks best practices.
Also applies to: 38-38
99-99
: LGTM: Proper implementation of useTranslation hook
The useTranslation
hook is correctly initialized and all user-facing strings are properly wrapped with the translation function.
129-129
: LGTM: Proper implementation of useTranslation hook
The useTranslation
hook is correctly initialized and all user-facing strings are properly wrapped with the translation function. The component's core functionality for handling preferences and budget management remains intact.
38-38
: Verify consistency of translation keys
Let's verify that the translation keys used in this file are consistent with their usage across the codebase.
Also applies to: 99-99, 129-129
✅ Verification successful
Based on the verification results, I can now provide a final response:
Translation keys are consistently used
The translation keys in the settings component are simple, descriptive, and consistently used. They follow a clear pattern:
- Basic UI elements: 'Settings', 'Budget Name', 'Close Budget'
- App information: 'Actual', 'Release Notes'
- Status messages: 'You're up to date!', 'New version available:'
- Technical identifiers: 'IDs', 'Budget ID:', 'Sync ID:'
All keys are properly wrapped in the t()
function from the useTranslation
hook, and their usage is straightforward and maintainable.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistency in translation key usage
# Search for translation keys used in this file
echo "Searching for translation keys usage..."
rg "t\(['\"](?:Actual|Settings|Budget Name|Close Budget|You're up to date!|New version available:|Release Notes|IDs|Budget ID:|Sync ID:)" \
--type ts \
--type tsx \
-g '!*.test.*' \
-g '!**/locales/**'
Length of output: 317
Script:
#!/bin/bash
# Let's first check the content of the settings component to identify the actual translation keys used
echo "Content of settings component:"
cat "packages/desktop-client/src/components/settings/index.tsx"
# Then we'll search for translation key usage across the codebase
# Note: Using simpler rg command without file type filters since tsx wasn't recognized
echo -e "\nSearching for translation key usage across the codebase:"
rg "t\(['\"]" -g "!**/locales/**" -g "!*.test.*"
Length of output: 100955
Script:
#!/bin/bash
# Let's check the translation keys used in the settings component and verify their usage
echo "Checking translation keys in settings/index.tsx:"
rg -A 1 "t\(['\"]" "packages/desktop-client/src/components/settings/index.tsx"
# Let's also check the translation files to ensure these keys are defined
echo -e "\nChecking translation files:"
fd ".*\.(json|po|yaml|yml)" "packages/desktop-client/src/locales" || true
Length of output: 1197
packages/desktop-client/src/components/reports/ReportTopbar.tsx (1)
2-2
: LGTM! Proper implementation of useTranslation hook
The change from direct t
import to useTranslation
hook is implemented correctly. This will enable automatic re-rendering when the language changes, improving the internationalization support.
Also applies to: 55-55
packages/desktop-client/src/components/modals/CategoryMenuModal.tsx (4)
3-3
: LGTM: Import changes align with PR objectives.
The addition of useTranslation
hook import and removal of direct t
function import follows React best practices for internationalization.
42-42
: LGTM: Proper implementation of useTranslation hook.
The hook is correctly initialized at the component level and properly used for translating the button text.
Also applies to: 142-142
Line range hint 47-53
: LGTM: Improved validation in onRename function.
Good improvement in the onRename function to prevent unnecessary saves when the name hasn't changed.
161-161
: LGTM: Proper implementation of useTranslation hook and accessibility.
The hook is correctly initialized and properly used for the Menu button's aria-label.
Also applies to: 180-180
packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx (1)
4-4
: LGTM! Successfully integrated useTranslation hook.
The changes align with the PR objective, replacing direct import of t
with the useTranslation
hook. This will enable automatic re-rendering when the language changes.
Also applies to: 32-32
packages/desktop-client/src/components/modals/MergeUnusedPayeesModal.tsx (3)
2-2
: LGTM: Translation hook import added correctly
The addition of the useTranslation
hook import aligns with the PR objectives and follows React best practices.
29-29
: LGTM: Translation hook initialized correctly
The useTranslation
hook is properly initialized at the component's top level, following React hooks best practices.
Line range hint 180-200
: LGTM: Button texts properly internationalized
All button labels are correctly wrapped with the translation function, ensuring consistent internationalization.
packages/desktop-client/src/components/modals/CategoryGroupMenuModal.tsx (2)
8-8
: LGTM: Import of useTranslation hook
The addition of the useTranslation
hook import aligns with the PR objective and follows React best practices.
49-49
: LGTM: Proper implementation of useTranslation hook
The hook is correctly implemented at the component level and properly used for translating user-facing strings. The changes follow React hooks best practices and maintain component functionality.
Also applies to: 164-164, 172-172
packages/desktop-client/src/components/transactions/SimpleTransactionsTable.tsx (2)
8-8
: LGTM: Import of useTranslation hook
The addition of the useTranslation hook import aligns with the PR objective of improving localization handling.
168-168
: LGTM: Proper hook initialization
The useTranslation hook is correctly initialized at the component level, following React hooks best practices.
packages/desktop-client/src/components/modals/CreateEncryptionKeyModal.tsx (1)
4-4
: LGTM: Translation hook integration
The useTranslation hook is correctly imported and initialized, aligning with the PR's objective to enhance internationalization support.
Also applies to: 38-38
packages/desktop-client/src/components/modals/SelectLinkedAccountsModal.jsx (2)
2-2
: LGTM: Import of useTranslation hook
The addition of the useTranslation hook import aligns with the PR objective and follows proper import organization.
34-34
: LGTM: Proper initialization of useTranslation hook
The hook is correctly initialized at the component level, and all translations are properly handled using the hook's t function.
✅ Verification successful
Translation hook is correctly used throughout the component
The verification confirms that the useTranslation
hook's t
function is consistently used across the component for all user-facing strings, including:
- Modal title and navigation elements
- Table column headers
- Action button labels
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Verify consistent usage of useTranslation across the component
rg "t\(['\"]" packages/desktop-client/src/components/modals/SelectLinkedAccountsModal.jsx -A 1
Length of output: 634
packages/desktop-client/src/components/modals/EditFieldModal.tsx (2)
7-7
: LGTM: Proper implementation of useTranslation hook
The addition of the useTranslation hook and its initialization follows React best practices and aligns with the PR objectives.
Also applies to: 48-48
Line range hint 89-89
: LGTM: Consistent translation of field labels
The translation of field labels is implemented consistently across all field types using the t
function.
Also applies to: 108-108, 201-201
packages/desktop-client/src/components/Notifications.tsx (2)
9-9
: LGTM: Import statement aligns with PR objective.
The addition of the useTranslation
hook import is appropriate for the intended migration from direct t
function imports.
94-94
: LGTM: Hook usage follows React best practices.
The useTranslation
hook is correctly implemented at the component level, enabling automatic re-renders on language changes.
packages/desktop-client/src/components/reports/CategorySelector.tsx (3)
3-3
: LGTM: Import change aligns with React best practices
The change from direct t
import to useTranslation
hook follows React best practices and matches the PR objectives.
36-36
: LGTM: Hook usage follows React conventions
The useTranslation
hook is correctly implemented at the component's top level, following React's rules of hooks.
Line range hint 1-215
: Verify consistent translation pattern usage
Let's verify that similar category selection UI components follow the same translation pattern.
✅ Verification successful
Translation patterns are consistently implemented
All components that use the CategorySelector or handle category-related functionality properly implement translations using the useTranslation
hook from react-i18next
. The CategorySelector component and its related components (ReportSidebar, TransferModal, CoverModal, ConfirmCategoryDeleteModal, CloseAccountModal) all follow the same translation pattern, using the hook to access the translation function and properly translating all user-facing strings.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for similar category selection components that might need the same translation pattern
rg -t typescript -t javascript "CategorySelector|categoryGroups.*categories" packages/desktop-client/src/
Length of output: 142
Script:
#!/bin/bash
# Search for similar category selection components and their translation patterns
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js "CategorySelector|categoryGroups.*categories" packages/desktop-client/src/
Length of output: 1889
Script:
#!/bin/bash
# Let's check the usage of translation in these components
rg --type-add 'ts:*.{ts,tsx}' --type-add 'js:*.{js,jsx}' -t ts -t js -B 2 -A 2 "useTranslation|t\(['\"]" packages/desktop-client/src/components/reports/ReportSidebar.tsx packages/desktop-client/src/components/modals/TransferModal.tsx packages/desktop-client/src/components/modals/CoverModal.tsx packages/desktop-client/src/components/modals/ConfirmCategoryDeleteModal.tsx packages/desktop-client/src/components/modals/CloseAccountModal.tsx
Length of output: 25349
packages/desktop-client/src/components/mobile/accounts/Accounts.tsx (2)
2-2
: LGTM! Import change aligns with PR objectives.
The addition of useTranslation
import is appropriate and consistent with the goal of improving internationalization support.
Line range hint 198-219
: LGTM! Comprehensive translation implementation.
The translation implementation is well done:
- Hook is correctly placed at the component level
- Both visible text and accessibility labels are properly translated
- Maintains existing component functionality
packages/desktop-client/src/components/Titlebar.tsx (2)
3-3
: LGTM: Import statement follows conventions
The addition of the useTranslation
hook import is correctly placed and aligns with the PR's objective.
269-269
: LGTM: Proper implementation of translations
The translation hook is correctly implemented and all user-facing strings are properly translated using the t
function.
Also applies to: 306-306, 342-342
packages/desktop-client/src/components/common/Modal.tsx (3)
17-17
: LGTM: Proper integration of useTranslation hook
The hook is correctly imported and initialized at the component level, following React hooks best practices.
Also applies to: 57-57
304-304
: LGTM: Good accessibility enhancement
The translation of the logo's aria-label improves accessibility for screen readers while maintaining proper i18n practices.
Also applies to: 339-345
Line range hint 473-481
: LGTM: Consistent translation implementation
The close button's aria-label translation is properly implemented. Let's verify the translation key usage across the codebase for consistency.
✅ Verification successful
Translation key 'Close' is consistently implemented across components
The verification shows that the 'Close' translation key is consistently used in similar contexts across the codebase:
- Modal.tsx: Close button with translated aria-label
- Notifications.tsx: Close button with translated aria-label
- UpdateNotification.tsx: Close button with translated aria-label
There is only one instance (in Upcoming.tsx) that uses a hardcoded English string, but it's a different use case with a more specific context "Close upcoming length settings".
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistent usage of the 'Close' translation key across the codebase
# Search for other occurrences of the 'Close' translation key
rg "t\(['\"]Close['\"]\)" --type ts --type tsx
# Search for similar close button implementations
ast-grep --pattern 'Button {
$$$
aria-label={$_}
$$$
}'
Length of output: 144
Script:
#!/bin/bash
# Let's try a different approach to search for translation keys and button implementations
# Search for 'Close' translation key usage with more flexible pattern
rg "t\(['\"](Close|close)['\"]"
# Search for aria-label usage in buttons with more flexible pattern
rg "aria-label.*Close"
# Search for Button components with aria-label
ast-grep --pattern 'Button $$$aria-label={$_}$$$'
Length of output: 787
packages/desktop-client/src/components/mobile/transactions/TransactionList.jsx (2)
9-9
: LGTM: Import statement follows project conventions
The addition of the useTranslation hook import aligns with the PR objective and follows the existing import organization pattern.
49-49
: LGTM: Proper implementation of useTranslation hook
The useTranslation hook is correctly initialized at the component level and properly used for internationalizing the loading text. This implementation follows React hooks best practices and aligns with the PR objectives.
Also applies to: 92-92
packages/desktop-client/src/components/select/RecurringSchedulePicker.tsx (2)
9-9
: LGTM: Import of useTranslation hook
The addition of the useTranslation hook import aligns with the PR objective of replacing direct t function imports.
558-558
: LGTM: Clean implementation of translations
The translation implementation in the RecurringSchedulePicker component is clean and follows React best practices. The conditional rendering with translations is handled appropriately.
Also applies to: 576-579
packages/desktop-client/src/components/reports/ReportSidebar.tsx (3)
2-2
: LGTM: Import change aligns with PR objectives
The addition of useTranslation
hook import is appropriate and follows React's import organization pattern.
92-92
: LGTM: Proper hook initialization
The useTranslation
hook is correctly initialized at the component level, following React hooks best practices.
91-91
: Verify the new default prop value
A default value of false
has been added for isComplexCategoryCondition
. While this is a good practice, it wasn't mentioned in the PR objectives.
✅ Verification successful
Based on the search results, I can generate the final response as I have enough context to verify the concern. The results show that:
- The prop is defined in
ReportSidebar.tsx
with an optional type and a default value offalse
- It's used within
CustomReport.tsx
where it's computed based on category conditions - The prop is passed from
CustomReport
toReportSidebar
and used to conditionally render an information message
Default prop value is justified and aligns with the codebase
The default value of false
for isComplexCategoryCondition
is actually necessary as it's used to control the visibility of an information message about category filters. The prop is properly integrated into the codebase's logic, where CustomReport
component computes this value based on the complexity of category conditions and passes it to the sidebar. This is a valid implementation detail rather than an unnecessary addition.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if this prop is used elsewhere in the codebase
rg "isComplexCategoryCondition" -A 3 -B 3
Length of output: 3639
packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx (1)
138-138
: Verify translation coverage
The change to use useTranslation
hook is good, but let's verify all strings are properly wrapped with the translation function.
✅ Verification successful
Let me generate another script to specifically check the ImportTransactionsModal component for any untranslated strings:
Let me try another script to specifically check for untranslated strings in the ImportTransactionsModal component:
Let me try a simpler approach to check for untranslated strings:
Based on the code inspection and the results from the shell scripts, I can now provide the final response:
Translation implementation is properly done
All user-facing strings in the ImportTransactionsModal component are properly wrapped with the translation function t()
. The component correctly:
- Uses the
useTranslation
hook from react-i18next - Wraps all user-facing strings with
t()
function - Uses
Trans
component for complex text content - Only contains untranslated strings in HTML attributes (ids, types) which don't need translation
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Find potentially untranslated strings in JSX
rg -g '*.jsx' -g '*.js' '\b(title|label|placeholder)=[{"](?!.*\bt\()'
# Find hardcoded strings in JSX text nodes
rg -g '*.jsx' -g '*.js' '>\s*[A-Z][a-zA-Z\s]+\s*<'
Length of output: 2026
Script:
#!/bin/bash
# Check for text content in ImportTransactionsModal
cat packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
# Also search for potential string literals in the same file
rg --pcre2 '"[^"]*"|\'[^\']*\'' packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
Length of output: 34104
Script:
#!/bin/bash
# Search for string literals that might need translation
rg --pcre2 '(?<!t\()["\']([\w\s]+)["\']' packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
# Also check for text content in JSX that might need translation
rg --pcre2 '>\s*[A-Za-z][\w\s]+\s*<' packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
Length of output: 321
Script:
#!/bin/bash
# Look for string literals in the file
rg --pcre2 '"[^"]*"' packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
# Look for text content in JSX
rg --pcre2 '>[^<>]+<' packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.jsx
Length of output: 852
packages/desktop-client/src/components/mobile/transactions/TransactionEdit.jsx (3)
10-10
: LGTM: Clean import of useTranslation hook
The addition of the useTranslation hook import aligns with the PR objective of improving internationalization support.
293-293
: LGTM: Proper implementation of translations in ChildTransactionEdit
The useTranslation hook is correctly initialized and consistently applied to all user-facing strings in the component, including field labels for Payee, Amount, Category, Notes, and the Delete split button.
Also applies to: 316-316, 341-341, 380-380, 440-440
452-452
: LGTM: Comprehensive translation implementation in TransactionEditInner
The useTranslation hook is properly initialized and consistently applied to all user-facing strings throughout the component, including field labels, button texts, and status messages.
Also applies to: 799-799, 824-824, 847-847, 873-873, 891-891, 907-907, 927-927, 947-947, 967-967, 1001-1001
packages/desktop-client/src/components/modals/EditRuleModal.jsx (3)
306-306
: LGTM! Proper implementation of useTranslation hook.
The hook is correctly imported and used at the component level.
765-765
: LGTM! Proper implementation of useTranslation hook.
The hook is correctly imported and used at the component level.
Line range hint 1-1200
: Verify translation key consistency across the application.
The implementation of useTranslation looks good, but we should verify that the translation keys are consistent with other parts of the application.
Run the following script to check translation key usage:
✅ Verification successful
Based on the shell script results showing translation key usage across the codebase, I can now generate the final response:
Translation keys are consistently used across the application
The review comment's concern about translation key consistency has been verified. The codebase shows extensive and consistent use of the t()
function from react-i18next across components, with proper key naming patterns and parameter handling.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistency in translation key usage across the application
# Search for translation key usage patterns
rg -g '*.{js,jsx,ts,tsx}' "t\(['\"]" --json | jq -r '.data.lines.text' | sort | uniq
Length of output: 84831
packages/desktop-client/src/components/mobile/budget/BudgetTable.jsx (2)
2-2
: LGTM: Import of useTranslation hook
The addition of useTranslation
hook import aligns with the PR's objective to improve internationalization handling.
70-70
: Well-structured implementation of useTranslation hook
The hook is consistently implemented across all components, properly handling both UI text and accessibility labels. This systematic approach ensures:
- Consistent translation handling
- Improved accessibility through translated aria-labels
- Better maintainability with centralized translation management
Also applies to: 133-133, 231-231, 1145-1145, 1421-1421, 1642-1642, 1747-1747, 1973-1973
@@ -1,6 +1,5 @@ | |||
import React, { useState } from 'react'; | |||
|
|||
import { t } from 'i18next'; | |||
import { useTranslation } from 'react-i18next'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Inconsistent translation import patterns detected
The codebase shows mixed usage of translation imports:
- Direct
t
imports from 'i18next' in 6 files:- packages/desktop-client/src/components/util/accountValidation.ts
- packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
- packages/desktop-client/src/components/reports/disabledList.ts
- packages/desktop-client/src/components/reports/ReportOptions.ts
- packages/desktop-client/src/components/budget/util.ts
- packages/desktop-client/src/components/accounts/Account.tsx
These files should be updated to use the useTranslation
hook for consistency with the rest of the codebase, which predominantly uses the hook pattern.
🔗 Analysis chain
Verify consistent useTranslation implementation
Let's verify that this pattern is consistently applied across other components in the codebase.
Also applies to: 14-14, 42-42
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for any remaining direct imports of the t function
rg "import.*\{.*t.*\}.*from 'i18next'" packages/desktop-client/src/
# Search for useTranslation usage pattern
rg "const.*\{.*t.*\}.*=.*useTranslation\(\)" packages/desktop-client/src/
Length of output: 23741
const { t } = useTranslation(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codebase verification
Migration to useTranslation hook needs completion
The verification reveals inconsistent translation implementation across the codebase:
- Several files still use direct
import { t } from 'i18next'
which should be migrated touseTranslation
hook:- packages/desktop-client/src/components/schedules/ScheduleDetails.jsx
- packages/desktop-client/src/components/util/accountValidation.ts
- packages/desktop-client/src/components/reports/ReportOptions.ts
- packages/desktop-client/src/components/reports/disabledList.ts
- packages/desktop-client/src/components/budget/util.ts
- packages/desktop-client/src/components/accounts/Account.tsx
🔗 Analysis chain
LGTM: Proper hook implementation
The useTranslation
hook is correctly implemented at the top level of the component, following React hooks rules. The destructured t
function maintains the same usage pattern as before.
Let's verify that this pattern is consistently applied across other components:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining direct imports of 't' from i18next
# and verify consistent usage of useTranslation hook
# Check for any remaining direct 't' imports from i18next
echo "Checking for remaining direct 't' imports from i18next..."
rg "import.*\{.*t.*\}.*from 'i18next'" packages/desktop-client/src/
# Verify useTranslation hook usage pattern
echo "Verifying useTranslation hook usage pattern..."
ast-grep --pattern 'const { t } = useTranslation();'
Length of output: 24564
@@ -107,6 +107,7 @@ type SyncButtonProps = { | |||
isMobile?: boolean; | |||
}; | |||
function SyncButton({ style, isMobile = false }: SyncButtonProps) { | |||
const { t } = useTranslation(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add translations for all user-facing strings
While the aria-label is now translated, there are other user-facing strings that should also be translated for consistency:
<Text style={isMobile ? { ...mobileTextStyle } : { marginLeft: 3 }}>
{syncState === 'disabled'
- ? 'Disabled'
- : syncState === 'offline'
- ? 'Offline'
- : 'Sync'}
+ ? t('Disabled')
+ : syncState === 'offline'
+ ? t('Offline')
+ : t('Sync')}
</Text>
Also applies to: 208-224
We should use
useTranslation
instead of directly import thet
function becauseuseTranslation
has some functionalities that are specific to react e.g. rerendering the components when language changesThere are still some direct imports left in loot-core. We need to assess if we should translate strings at that level or we should do all translations in the desktop-client/component level.
#3329