-
Notifications
You must be signed in to change notification settings - Fork 70
Adding FR language #140
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
base: main
Are you sure you want to change the base?
Adding FR language #140
Conversation
WalkthroughThis pull request adds comprehensive internationalization (i18n) support to the application. It replaces hard-coded UI strings with i18n translation keys in view templates and adds complete French localization across models, views, mailers, and dashboard components. The PR also updates English branding references from "Maybe" to "Sure" in existing locale files and enhances the account sidebar with modal and layout attributes. Changes
Sequence Diagram(s)Sequence diagrams are not applicable here as this PR contains no new features or control flow modifications—only i18n data additions and template string replacements. Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Rationale: While the PR spans 100+ files, the changes are highly homogeneous—consisting primarily of YAML locale file additions following consistent patterns and straightforward view template string replacements with i18n keys. The main review focus is verifying key consistency, translation scope accuracy, template replacement correctness, and ensuring no inadvertent logic modifications. The large file count adds time, but the repetitive, low-complexity nature of each change mitigates overall complexity. Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (19)
🚧 Files skipped from review as they are similar to previous changes (16)
🧰 Additional context used📓 Path-based instructions (2)config/**📄 CodeRabbit inference engine (AGENTS.md)
Files:
config/locales/**/*.{yml,yaml,json}📄 CodeRabbit inference engine (.cursor/rules/general-rules.mdc)
Files:
🧠 Learnings (1)📓 Common learnings⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
🔇 Additional comments (2)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
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: 27
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
config/locales/views/invitations/en.yml (1)
12-19: Add missing Frenchinvitations.new.subtitlekey
config/locales/views/invitations/fr.yml doesn’t definefr.invitations.new.subtitle, so the “Send an invitation…” text will be untranslated. Add the matchingsubtitleentry underfr → invitations → new.
🧹 Nitpick comments (79)
config/locales/views/family_exports/fr.yml (3)
5-7: Wording nit: prefer concise status nounsIn French UI labels, single-word nouns are often preferred for statuses. Consider:
- complete → Terminé (OK)
- failed → Échec (instead of past participle “Échoué”), reads cleaner in lists
Proposed change:
fr: family_exports: list: in_progress: En cours complete: Terminé - failed: Échoué + failed: Échec
1-1: Consistency nit: YAML document markerKeep the leading '---' consistent with other locale files in the repo (either all with or all without).
1-7: Enablement checklist for new locale (outside this file)
- Ensure :fr is in I18n.available_locales and fallbacks are configured (e.g., fr → en).
- Verify language switcher exposes “Français” and persists selection (param, cookie, or user setting).
- Run i18n-tasks (if used) to catch missing/unused keys.
config/locales/views/investments/fr.yml (1)
5-5: Confirm placeholder context; consider adding an article if needed.If
%{account}renders a bare name (e.g., "Épargne"), "Modifier le compte %{account}" may read better. If it already includes type/context, current phrasing is fine.Possible tweak:
- edit: Modifier %{account} + edit: Modifier le compte %{account}config/locales/views/depositories/fr.yml (2)
5-5: Use “Modifier” for consistency with other FR filesOther files (e.g., other_liabilities) use “Modifier %{account}”. Align for consistency.
- edit: Éditer %{account} + edit: Modifier %{account}
8-8: Key says “subtype” but string says “type”Match the key intent to avoid UX confusion.
- subtype_prompt: Sélectionnez le type de compte + subtype_prompt: Sélectionnez le sous-type de compteconfig/locales/views/registrations/en.yml (1)
24-24: Hyphenate “Self-Hosted” for standard styleMinor copy tweak; improves consistency with common usage.
- welcome_title: Welcome to Self Hosted Sure! + welcome_title: Welcome to Self-Hosted Sure!config/locales/models/address/fr.yml (1)
5-11: French casing/wording nits; consider address format ordering
- Prefer “Code postal” (lowercase ‘postal’).
- Optional: “Ville” is more common than “Localité” in FR UIs (team’s choice).
- locality: Localité - postal_code: Code Postal + locality: Localité + postal_code: Code postalconfig/locales/models/time_series/value/fr.yml (1)
9-9: French phrasing nit: prefer “objet Money” and lowercase “nombre”.More idiomatic and consistent with FR capitalization of common nouns.
- must_be_a_money_or_numeric: doit être un Money ou un Nombre + must_be_a_money_or_numeric: doit être un objet Money ou un nombreconfig/locales/views/tags/fr.yml (2)
10-11: Use “Modifier” instead of “Éditer” for standard FR UI.Common FR UI term; reads more natural.
- edit: Éditer l'étiquette + edit: Modifier l'étiquette ... - edit: Éditer + edit: ModifierAlso applies to: 21-21
15-18: Optional: deduplicate repeated “new” keys.You have both
index.newandnew.newwith the same value. Consider reusing one via i18n cascade or a shared key to avoid drift.config/locales/models/import/fr.yml (2)
7-7: French wording tweak for clarity.“Format des nombres” is more precise in FR.
- number_format: Format numérique + number_format: Format des nombres
13-13: Shorten CSV error phrasing.Concise and natural FR.
- invalid_csv_format: n'est pas un format CSV valide + invalid_csv_format: n'est pas un CSV valideconfig/locales/views/invite_codes/fr.yml (1)
5-6: Micro copy polish (more natural FR).Optional phrasing that reads a bit smoother.
- invite_code_description: Générez un nouveau code pour le voir affiché ici. Les codes générés qui ont été utilisés ne seront plus affichés. + invite_code_description: Générez un nouveau code pour l'afficher ici. Les codes déjà utilisés ne sont plus affichés. - no_invite_codes: Aucun code à afficher + no_invite_codes: Aucun code à afficherconfig/locales/views/entries/fr.yml (2)
9-10: Word choice: “affiner” is more idiomatic than “raffiner”.Reads more natural in FR UI text.
- description: Essayez d'ajouter une entrée, de modifier les filtres ou de raffiner votre recherche + description: Essayez d'ajouter une entrée, de modifier les filtres ou d'affiner votre recherche
12-12: Optional typography: ellipsis character.Consider using the typographic ellipsis (…) if consistent across locales.
- loading: Chargement des entrées... + loading: Chargement des entrées…config/locales/views/email_confirmation_mailer/fr.yml (1)
5-9: Unify tone and wording; prefer “adresse e‑mail” consistently.Use a more neutral greeting, and align “mail/e‑mail” usage across body/subject/CTA.
- cta: Confirmer la modification de l'e-mail + cta: Confirmer la modification de l'adresse e-mail - greeting: Salut! + greeting: Bonjour, - subject: 'Sure : Confirmez le changement de votre adresse mail' + subject: 'Sure : Confirmez la modification de votre adresse e-mail'Optional: handle singular/plural for hours with CLDR pluralization (one/other) if the caller can pass
count.config/locales/views/valuations/fr.yml (3)
10-15: Normalize casing and fix semantic mismatch (“valuations” vs “value”).Headers mix lowercase and capitalized forms, and “valuations: Valeur” collides with “value: valeur”. Suggest:
- Capitalize headers for consistency.
- Use “Évaluations” for the plural list label; keep “Valeur” for a single value.
Apply:
- change: changement - date: date - valuations: Valeur - value: valeur + change: Changement + date: Date + valuations: Évaluations + value: Valeur
28-28: Use consistent domain wording (“solde” vs “bilan”).Elsewhere you use “solde”. Prefer the same here.
- note_placeholder: Ajoutez tout détail supplémentaire à ce bilan + note_placeholder: Ajoutez tout détail supplémentaire à ce solde
22-22: Align French destructive-action message with shared modal
Thedelete_subtitleinconfig/locales/views/valuations/fr.yml(“Cette action ne peut pas être annulée”) differs fromshared.confirm_modal.body_html(“Vous ne pourrez pas annuler cette décision”). Use the same phrasing to reduce translation drift.config/locales/views/shared/fr.yml (3)
6-6: Standardize destructive-action copy.Recommend the same sentence used in valuations for uniformity.
- body_html: "<p>Vous ne pourrez pas annuler cette décision</p>" + body_html: "<p>Cette action ne peut pas être annulée.</p>"
8-8: French punctuation: narrow non‑breaking space before “?”Optional typographic improvement.
- title: Êtes-vous sûr ? + title: "Êtes-vous sûr ?"
14-14: Casing consistency for standalone labels.Capitalize to match other labels.
- no_change: "pas de changement" + no_change: "Pas de changement"config/locales/views/cryptos/fr.yml (1)
5-5: Harmonize verb with other sections (“Modifier” vs “Éditer”).Elsewhere (other_assets) you use “Modifier %{account}”. Align for consistency.
- edit: Éditer %{account} + edit: Modifier %{account}config/locales/models/user/fr.yml (1)
6-6: Prefer “Adresse e‑mail”.“Adresse mail” is informal; “Adresse e‑mail” is the standard form in product UIs.
- email: Adresse mail + email: Adresse e-mailconfig/locales/views/plaid_items/fr.yml (3)
14-14: Pronoun/wording tweak for clarity.Use “l’ajouter de nouveau” instead of “y ajouter à nouveau”.
- connection_lost_description: Cette connexion n'est plus valide. Vous devrez supprimer cette connexion et y ajouter à nouveau pour pouvoir continuer la synchronisation des données. + connection_lost_description: Cette connexion n'est plus valide. Vous devrez supprimer cette connexion puis l'ajouter de nouveau pour continuer la synchronisation des données.
19-19: Spelling: “Réauthentification” (no hyphen).- requires_update: Re-authentification requise + requires_update: Réauthentification requise
21-21: Article agreement.“Synchronisation des données requise.”
- status_never: Synchronisation de données requise + status_never: Synchronisation des données requiseconfig/locales/models/entry/fr.yml (1)
9-10: French grammar fix and punctuation for error messageUse the negation “n’en … que” and add a period. Also quote to keep it on one line.
- invalid_sell_quantity: Vous ne pouvez pas vendre %{sell_qty} actions de %{ticker} car - vous en détenez que %{current_qty} + invalid_sell_quantity: "Vous ne pouvez pas vendre %{sell_qty} actions de %{ticker} car vous n’en détenez que %{current_qty}."config/locales/views/accounts/fr.yml (4)
7-7: Terminology and agreement fixes (labels and chart message)
- Prefer “Données historiques manquantes”.
- “Asset” → “Actifs”.
- “la période sélectionnée” (féminin).
- “Synchroniser tout” reads better in FR.
- missing_historical: Manque les données historiques + missing_historical: Données historiques manquantes - label_asset: Comptes + label_asset: Actifs - data_not_available: Données non disponibles pour le période sélectionnée + data_not_available: Données non disponibles pour la période sélectionnée - sync: Synchroniser tous + sync: Synchroniser toutAlso applies to: 11-11, 17-17, 35-35
41-43: Natural phrasing for manual entry and titleMinor UX copy polish.
- manual_entry: Entrée du solde du compte - title: Comment voulez-vous l'ajouter ? + manual_entry: Saisir le solde du compte + title: Comment souhaitez-vous l’ajouter ?
61-62: Improve confirmation body French stylePluralize “informations” and tighten the second sentence.
- confirm_body_html: "<p>En supprimant ce compte, vous effacerez son historique de valeur, - affectant divers aspects de votre solde global. Cette action aura un impact direct sur vos calculs de valeur nette et les graphiques des comptes.</p><br /> <p>Après la suppression, il n'y a aucun moyen de restaurer l'information du compte car vous aurez besoin d'en ajouter un nouveau.</p>" + confirm_body_html: "<p>En supprimant ce compte, vous effacerez son historique de valeur, ce qui affectera divers aspects de votre solde global. Cette action aura un impact direct sur vos calculs de valeur nette et les graphiques des comptes.</p><br /> <p>Après la suppression, il n’y a aucun moyen de restaurer les informations du compte ; vous devrez en ajouter un nouveau.</p>"
64-66: FR UX convention: “Modifier” vs “Éditer”“Modifier” is more common in French UI. Optional.
- edit: Éditer + edit: Modifierconfig/locales/models/transfer/fr.yml (2)
9-11: Correct French phrasing and prepositions in validation errorsUse “faire partie de”, “période de 4 jours”, and more natural verbs.
- inflow_cannot_be_in_multiple_transfers: La transaction d'entrée ne peut pas être - partie de plusieurs transferts + inflow_cannot_be_in_multiple_transfers: La transaction d’entrée ne peut pas faire partie de plusieurs transferts - must_be_from_different_accounts: Le transfert doit avoir des comptes différents + must_be_from_different_accounts: Le transfert doit impliquer des comptes différents - must_be_within_date_range: Les dates des transactions de transfert doivent être - dans une période d'4 jours + must_be_within_date_range: Les dates des transactions de transfert doivent être dans une période de 4 jours - outflow_cannot_be_in_multiple_transfers: La transaction de dépense ne peut pas être - partie de plusieurs transferts + outflow_cannot_be_in_multiple_transfers: La transaction de dépense ne peut pas faire partie de plusieurs transfertsAlso applies to: 14-14, 18-19
12-13: Improve word choices (“famille”, “devise”)Optional style tweaks for clarity.
- must_be_from_same_family: Le transfert doit provenir de la même famille + must_be_from_same_family: Le transfert doit appartenir à la même famille - must_have_single_currency: Le transfert doit avoir une seule devise + must_have_single_currency: Le transfert doit être dans une seule deviseAlso applies to: 17-17
config/locales/models/trend/fr.yml (1)
10-11: French style: remove Oxford comma; prefer “actuel” over “courant”Also keep type names as code words while fixing FR grammar.
- must_be_of_type_money_numeric_or_nil: doit être de type Money, Numeric, - ou nil + must_be_of_type_money_numeric_or_nil: doit être de type Money, Numeric ou nil - must_be_of_the_same_type_as_current: doit être du même type que le courant + must_be_of_the_same_type_as_current: doit être du même type que l’actuel - must_be_of_type_money_numeric_or_nil: doit être de type Money, Numeric, - ou nil + must_be_of_type_money_numeric_or_nil: doit être de type Money, Numeric ou nilAlso applies to: 14-15
config/locales/views/credit_cards/fr.yml (2)
9-11: Verify decimal separator for French locale placeholders.FR typically uses a comma for decimals. If the input parser respects locale, prefer “15,99”. If the backend expects a dot, keep as-is to avoid validation errors.
- apr_placeholder: '15.99' + apr_placeholder: '15,99'
5-5: Use more idiomatic action label (“Modifier”).“Modifier %{account}” is more common in FR UIs than “Éditer %{account}”.
- edit: Éditer %{account} + edit: Modifier %{account}config/locales/views/imports/en.yml (2)
37-38: Incomplete sentence (“…types to Sure’s”).Mirror the pattern used for categories to read naturally.
- account_type_mapping_description: Assign all of your imported file's account - types to Sure's + account_type_mapping_description: Assign all of your imported file's account + types to Sure's existing types.
26-26: Rename brand-specific translation key
Changemaybe_mapping_labeltoapp_mapping_labelin all locale files underconfig/locales/views/imports/*.ymland in the view atapp/views/import/confirms/_mappings.html.erb:46. Retainmaybe_mapping_labelas a deprecated alias if backward compatibility is required.config/locales/views/invitation_mailer/fr.yml (2)
8-8: French punctuation consistency before “!”Use a space (ideally a narrow no‑break space) before “!” to match line 6 and FR typographic rules.
- greeting: Bienvenue sur Sure! + greeting: Bienvenue sur Sure !
7-7: Consider pluralization for “days”.Rails I18n supports plural rules; switch to a pluralized key to handle “1 jour” vs “n jours”.
- expiry_notice: Cette invitation expire dans %{days} jours + expiry_notice: + one: Cette invitation expire dans 1 jour + other: Cette invitation expire dans %{count} joursNote: Update callers to pass
count:instead ofdays:.config/locales/views/trades/fr.yml (3)
8-8: Prefer “Symbole” over “Symbole ticker”.More natural FR; “ticker” can be kept in placeholder.
- holding: Symbole ticker + holding: Symbole
22-22: Finance term: use “Plus/moins‑value latente”.Standard FR finance phrasing for unrealized P/L.
- total_return_label: Gain/déficit non réalisé + total_return_label: Plus/moins‑value latente
5-5: Confirm intended meaning of “Compte de transfert”.If this is just the source/destination account, “Compte (facultatif)” may be clearer. If it’s a brokerage account, consider “Compte de courtage”.
- account: Compte de transfert (facultatif) + account: Compte (facultatif)config/locales/views/users/fr.yml (1)
11-12: Polish phrasing and punctuation
- “Les données seront supprimées en arrière-plan dans un certain temps.” is awkward; tighten.
- Add a period to “unauthorized” for consistency.
- success: Votre compte a été réinitialisé. Les données seront supprimées en arrière-plan dans un certain temps. + success: Votre compte a été réinitialisé. Vos données seront supprimées en arrière‑plan sous peu. - unauthorized: Vous n'êtes pas autorisé à effectuer cette action + unauthorized: Vous n'êtes pas autorisé à effectuer cette action.config/locales/views/category/dropdowns/fr.yml (1)
7-11: Harmonize wording with the rest of the UIUse “Modifier” (not “Éditer”) across the app; “Effacer la catégorie” reads like deletion—if this clears a filter/selection, name it accordingly.
- edit: Éditer la catégorie + edit: Modifier la catégorie - clear: Effacer la catégorie + clear: Effacer la sélection - no_categories: Aucune catégorie trouvée + no_categories: Aucune catégorie trouvée - search_placeholder: Rechercher + search_placeholder: Rechercherconfig/locales/views/transactions/fr.yml (2)
44-47: Prefer IT‑French “imports” vs “importations”“Importations” is trade jargon; UI commonly uses “imports”.
- edit_imports: Modifier les importations + edit_imports: Modifier les imports
32-46: Standardize “merchant(s)” terminology in French locales
- In config/locales/views/settings/fr.yml, replace all occurrences of “vendeur”/“vendeurs” with “marchand”/“marchands” (merchant_detector.title & subtitle, confirm_reset.body, reset_account_warning, merchants_label).
- In config/locales/views/transactions/fr.yml, use singular “Marchand” for
merchant_labelandmerchant_filter, and plural “Marchands” foredit_merchants.- Leave “valeur marchande” in config/locales/views/investments/fr.yml unchanged (false positive for market value).
config/locales/views/sessions/fr.yml (1)
10-15: Localize the placeholderKeep the placeholder in French.
- email_placeholder: [email protected] + email_placeholder: [email protected]config/locales/views/settings/fr.yml (5)
11-17: French AI terminologyUse “IA” (not “AI”). Also smooth the transaction categorizer titles.
- subtitle: Instructions fondamentales qui définissent le comportement de l'assistant AI dans toutes les conversations de chat + subtitle: Instructions fondamentales qui définissent le comportement de l'assistant IA dans toutes les conversations - transaction_categorizer: - title: Categoriseur des transactions - subtitle: L'IA catégorise automatiquement vos transactions en fonction de vos catégories définies + transaction_categorizer: + title: Catégorisation des transactions + subtitle: L’IA classe automatiquement vos transactions selon vos catégories
24-40: Label casing and wordingCapitalize nouns in labels and use common UI terms.
- country: Pays - currency: devise + country: Pays + currency: Devise - timezone: fuseau horaire + timezone: Fuseau horaire - theme_light: Léger + theme_light: Clair
42-45: Improve phrasing“Vous ne pouvez pas vous enlever…” → “vous retirer”.
- cannot_remove_self: Vous ne pouvez pas vous enlever de votre compte. + cannot_remove_self: Vous ne pouvez pas vous retirer de votre compte.
83-107: Navigation labels consistencyUse concise, common French UI terms and align with “Marchand(s)”.
- feedback_label: Retour d'information + feedback_label: Commentaires - imports_label: Importer/Exporter + imports_label: Import/Export - merchants_label: Vendeurs + merchants_label: Marchands - guides_label: Guides + guides_label: Guides - other_section_title: Plusieurs options + other_section_title: Autres - whats_new_label: Dernières nouvelles + whats_new_label: Nouveautés - self_hosting_label: Hébergement autonome + self_hosting_label: Auto‑hébergement - bank_sync_label: Synchronisation de la banque + bank_sync_label: Synchronisation bancaire
111-114: French units and action verbUse “Mo” and a more standard action label.
- accepted_formats: JPG ou PNG. 5MB max. - choose: Charger une photo + accepted_formats: JPG ou PNG. 5 Mo max. + choose: Choisir une photoconfig/locales/views/settings/securities/fr.yml (1)
7-8: Fix multiline formatting for confirmation text.Use a folded scalar to ensure consistent rendering across backends.
- disable_mfa_confirm: Êtes-vous sûr(e) de vouloir désactiver l'authentification à deux facteurs ? - Cela rendra votre compte moins sécurisé. + disable_mfa_confirm: >- + Êtes-vous sûr(e) de vouloir désactiver l'authentification à deux facteurs ? + Cela rendra votre compte moins sécurisé.config/locales/views/category/deletions/fr.yml (1)
12-14: Normalize multiline string for the explanation.Use a folded scalar for readability and consistent whitespace.
- explanation: En supprimant cette catégorie, chaque transaction qui a la catégorie "%{category_name}" - sera non catégorisée. Au lieu de les laisser non catégorisées, vous pouvez également attribuer une nouvelle catégorie ci-dessous. + explanation: >- + En supprimant cette catégorie, chaque transaction qui a la catégorie "%{category_name}" sera non + catégorisée. Au lieu de les laisser non catégorisées, vous pouvez également attribuer une nouvelle + catégorie ci-dessous.config/locales/views/categories/fr.yml (1)
8-14: Unify action verb (“Éditer” vs “Modifier”).Pick one across the UI; “Modifier” is more idiomatic in FR UIs.
- edit: Éditer la catégorie + edit: Modifier la catégorie ... - edit: Éditer la catégorie + edit: Modifier la catégorie - new_category: Nouvelle catégorie + new_category: Nouvelle catégorieAlso applies to: 27-27
config/locales/views/imports/fr.yml (2)
29-36: Harmonize “uncategorized” phrasing.Keep “non catégorisées” consistently.
- account_mapping_description: Affectez tous les comptes de votre fichier importé aux comptes Sure existants. Vous pouvez également ajouter de nouveaux comptes ou les laisser sans catégorie. + account_mapping_description: Affectez tous les comptes de votre fichier importé aux comptes Sure existants. Vous pouvez également ajouter de nouveaux comptes ou les laisser non catégorisés. - category_mapping_description: Attribuez toutes les catégories importées dans votre fichier aux catégories existantes de Sure. Vous pouvez également ajouter de nouvelles catégories ou les laisser non catégorisées. + category_mapping_description: Attribuez toutes les catégories importées dans votre fichier aux catégories existantes de Sure. Vous pouvez également ajouter de nouvelles catégories ou les laisser non catégorisées. - tag_mapping_description: Attribuez toutes les étiquettes importées dans votre fichier aux étiquettes existantes de Sure. Vous pouvez également ajouter de nouvelles étiquettes ou les laisser non catégorisées. + tag_mapping_description: Attribuez toutes les étiquettes importées dans votre fichier aux étiquettes existantes de Sure. Vous pouvez également ajouter de nouvelles étiquettes ou les laisser non catégorisées.
39-45: Use “téléverser” and clearer instructions.Improve clarity and FR usage.
- description: Coller ou télécharger votre fichier CSV ci-dessous. Veuillez examiner les instructions dans le tableau ci-dessous avant de commencer. + description: Collez ou téléversez votre fichier CSV ci-dessous. Veuillez lire les instructions dans le tableau avant de commencer. - instructions_2: Votre CSV doit avoir une ligne d'en-tête + instructions_2: Votre CSV doit comporter une ligne d’en-tête. - instructions_3: Vous pouvez nommer vos colonnes ce que vous voulez. Vous les mappez à un stade ultérieur. + instructions_3: Vous pouvez nommer vos colonnes comme vous le souhaitez. Vous les associerez à une étape ultérieure.config/locales/views/properties/fr.yml (2)
5-5: Key name likely mislabeled.Within edit, prefer title key for page heading.
- edit: - edit: Modifier %{account} + edit: + title: Modifier %{account}
12-15: French locale consistency (labels/placeholders).Tighten FR phrasing and FR context.
- country: pays + country: Pays - postal_code: Code postal/ZIP + postal_code: Code postal - region: État/Province + region: Région/Province - region_placeholder: CA + region_placeholder: Île-de-France - market_value: Valeur du marché + market_value: Valeur marchande - purchase_price: Prix d'achat + purchase_price: Prix d’achat - trend: Tendance + trend: TendanceAlso applies to: 17-21, 28-31
config/locales/views/mfa/fr.yml (2)
5-13: Imperative and casing fixes for backup codes.Use “Enregistrez” and sentence case.
- backup_codes_title: Vos Codes de Sauvegarde + backup_codes_title: Vos codes de sauvegarde - title: Enregistrer vos Codes de Sauvegarde + title: Enregistrez vos codes de sauvegarde
33-36: Casing and apostrophes.Minor FR polish.
- page_title: Vérifier l'Authentification à Deux Facteurs + page_title: Vérifier l’authentification à deux facteurs - title: Authentification à Deux Facteurs + title: Authentification à deux facteursconfig/locales/views/impersonation_sessions/fr.yml (1)
11-13: Use consistent noun-phrase success messages.Match “Session terminée” style.
- success: Rejoint la session + success: Session rejointe- success: Parti de la session + success: Session quittéeconfig/locales/views/transfers/fr.yml (1)
12-16: French phrasing/typography tweaks for naturalness and consistency
- Prefer concise field labels: “De” / “Vers”.
- Future tense + proper connector in delete subtitle.
- Add the required space before “?” in French.
- from: D'origine + from: De ... - to: À destination + to: Vers ... - delete_subtitle: Ce transfert est supprimé. Il ne supprimera pas les transactions sous-jacentes. + delete_subtitle: Ce transfert sera supprimé. Cela ne supprimera pas les transactions sous-jacentes. - delete_title: Voulez-vous vraiment supprimer ce transfert? + delete_title: Voulez-vous vraiment supprimer ce transfert ?Also applies to: 21-23
config/locales/views/settings/hostings/fr.yml (1)
6-11: Clarify a few phrasings; align with common FR UI wording
- “Lors du changement” is ambiguous; specify the action.
- “Requérir” → “Exiger” is more idiomatic here.
- “Zone dangereuse” → “Zone de danger”.
- Minor style on Twelve Data strings.
- email_confirmation_description: Lorsqu'il est activé, les utilisateurs doivent confirmer leur adresse e-mail lors du changement. + email_confirmation_description: Lorsqu’il est activé, les utilisateurs doivent confirmer leur adresse e‑mail lorsqu’ils la modifient. - title: Requérir un code d'invitation pour s'inscrire + title: Exiger un code d’invitation pour s’inscrire ... - danger_zone: Zone dangereuse + danger_zone: Zone de danger ... - api_calls_used: "%{used} / %{limit} Appels API journaliers utilisés (%{percentage})" + api_calls_used: "%{used} / %{limit} appels API utilisés aujourd’hui (%{percentage})" ... - plan: "%{plan} Plan" + plan: "Forfait %{plan}"Also applies to: 16-16, 34-35, 39-39
config/locales/views/onboardings/fr.yml (1)
18-18: Improve naturalness; keep tone consistently formal (“vous”)
- “Household name” is better rendered as “Nom du foyer”.
- Welcome copy and title sound more idiomatic in FR.
- household_name: Nom de famille (si applicable) + household_name: Nom du foyer (le cas échéant) ... - message: Nous sommes vraiment excités que vous soyez ici. Dans la prochaine étape, nous allons vous poser quelques questions pour compléter votre profil et ensuite configurer votre compte. + message: Nous sommes ravis de vous compter parmi nous. À l’étape suivante, nous vous poserons quelques questions pour compléter votre profil, puis nous configurerons votre compte. - title: Rencontrez Sure + title: Bienvenue sur SureAlso applies to: 25-27
config/locales/views/pages/fr.yml (1)
7-9: Unify tone (use “vous”) and domain terms
- Switch from “te” to formal “vous”.
- Slightly tighten the cashflow helper text.
- Use “Valeur nette” (standard term) instead of “Richesse totale”.
- welcome_back: Content de te revoir + welcome_back: Ravi de vous revoir - happening_with_finance: Voici ce qui se passe avec vos finances + happening_with_finance: Voici ce qui se passe avec vos finances ... - add_transactions_to_display_cashflow: Ajoutez des transactions pour afficher les données de flux de trésorerie ou étendre la période + add_transactions_to_display_cashflow: Ajoutez des transactions pour afficher les flux de trésorerie ou élargissez la période ... - title: Richesse totale + title: Valeur netteAlso applies to: 13-13, 17-17
config/locales/views/settings/api_keys/fr.yml (2)
23-23: Titre plus naturel“Première sécurité” → “Sécurité avant tout”.
- security_note_title: "Première sécurité" + security_note_title: "Sécurité avant tout"
40-40: Verbe exact pour l’action“Créer une nouvelle clé” suggère une autre clé; pour “regenerate”, préférer “Régénérer la clé”.
- regenerate_key: "Créer une nouvelle clé" + regenerate_key: "Régénérer la clé"config/locales/views/loans/fr.yml (1)
18-18: Optionnel: libellé “N/A”En français, “Non applicable” est plus clair que “N/A”.
- not_applicable: N/A + not_applicable: Non applicableconfig/locales/views/holdings/fr.yml (1)
5-5: Harmoniser le vocabulaire financier (FR)Propositions plus idiomatiques: “Liquidités du compte”, “Positions”, “Rendement total”, “Pondération du portefeuille”, “Symbole”, et reformuler l’info-bulle.
- brokerage_cash: Argent en banque + brokerage_cash: Liquidités du compte - holdings: Holdings + holdings: Positions - return: Retour total + return: Rendement total - description: Cet investissement a des valeurs manquantes et nous ne pouvons pas calculer - son retour ou sa valeur. + description: Cet investissement présente des données manquantes; nous ne pouvons pas calculer sa performance ou sa valeur. - portfolio_weight_label: Poids du portefeuille + portfolio_weight_label: Pondération du portefeuille - ticker_label: Ticker + ticker_label: Symbole - total_return_label: Retour total + total_return_label: Rendement totalAlso applies to: 13-13, 17-17, 20-21, 31-31, 33-33, 35-35
config/locales/views/registrations/fr.yml (1)
14-14: Formulations plus naturellesAlléger “succès” et améliorer les tournures.
- success: Vous avez été inscrit avec succès. + success: Inscription réussie. - welcome_body: Pour commencer, vous devez créer un nouveau compte. Vous pourrez ensuite configurer des paramètres supplémentaires à l'intérieur de l'application. + welcome_body: Pour commencer, créez un nouveau compte. Vous pourrez ensuite configurer des paramètres supplémentaires dans l'application. - welcome_title: Bienvenue sur Sure auto-hébergé ! + welcome_title: Bienvenue sur Sure en auto-hébergement !Also applies to: 22-23
app/views/pages/dashboard.html.erb (1)
16-22: Accessibilité: nom accessible pour le bouton icôneLe lien icône seul n’a pas de texte. Ajouter un title (ou aria-label si supporté par DS::Link) pour l’accessibility name.
- <%= render DS::Link.new( + <%= render DS::Link.new( variant: "icon-inverse", icon: "plus", href: new_account_path, frame: :modal, - class: "rounded-full lg:hidden" + class: "rounded-full lg:hidden", + title: t(".new") ) %>Si DS::Link supporte
aria_label:, préférer:aria_label: t(".new")config/locales/views/pages/en.yml (1)
26-26: Add a trailing newline to satisfy linters.YAMLlint flags “no new line at end of file.”
- new: Add account + new: Add account +app/views/accounts/_account_sidebar_tabs.html.erb (1)
15-19: Use distinct copy for the CTA; avoid reusing the description key.The link repeats the paragraph text. Use a dedicated key like t(".configure_provider") for clarity.
- <p> - <%= link_to t(".describe_party_provider"), settings_hosting_path, class: "text-yellow-600 underline" %> - </p> + <p> + <%= link_to t(".configure_provider"), settings_hosting_path, class: "text-warning underline" %> + </p>Also switches to a design-system token (text-warning) instead of raw Tailwind color to match project guidelines.
Remember to add the new .configure_provider key to en/fr locale files.
config/locales/views/accounts/en.yml (2)
8-8: Hyphenate “third‑party” and consider brand-neutral copy.Minor copy fix and future-proofing for white‑label scenarios.
- describe_party_provider: Sure uses third party providers to fetch historical exchange rates, security prices, and more. This data is required to calculate accurate historical account balances. + describe_party_provider: We use third-party providers to fetch historical exchange rates, securities prices, and more. This data is required to calculate accurate historical account balances.If branding is desired, consider interpolation instead:
- describe_party_provider: Sure uses third party providers to fetch historical exchange rates, security prices, and more. This data is required to calculate accurate historical account balances. + describe_party_provider: %{app_name} uses third-party providers to fetch historical exchange rates, securities prices, and more. This data is required to calculate accurate historical account balances.Remember to pass app_name where rendered.
10-12: Copy consistency: “Liabilities” vs “Debts”.If the UI elsewhere uses “Liabilities,” consider aligning for consistency; if “Debts” is intentional product language, ignore.
- label_liability: Debts + label_liability: Liabilities
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (68)
app/views/accounts/_account_sidebar_tabs.html.erb(3 hunks)app/views/pages/dashboard.html.erb(1 hunks)app/views/pages/dashboard/_cashflow_sankey.html.erb(2 hunks)app/views/pages/dashboard/_no_accounts_graph_placeholder.html.erb(1 hunks)config/locales/mailers/invitation_mailer/fr.yml(1 hunks)config/locales/models/account/fr.yml(1 hunks)config/locales/models/address/fr.yml(1 hunks)config/locales/models/entry/fr.yml(1 hunks)config/locales/models/import/fr.yml(1 hunks)config/locales/models/time_series/value/fr.yml(1 hunks)config/locales/models/transfer/fr.yml(1 hunks)config/locales/models/trend/fr.yml(1 hunks)config/locales/models/user/fr.yml(1 hunks)config/locales/views/accounts/en.yml(1 hunks)config/locales/views/accounts/fr.yml(1 hunks)config/locales/views/categories/fr.yml(1 hunks)config/locales/views/category/deletions/fr.yml(1 hunks)config/locales/views/category/dropdowns/fr.yml(1 hunks)config/locales/views/credit_cards/fr.yml(1 hunks)config/locales/views/cryptos/fr.yml(1 hunks)config/locales/views/depositories/fr.yml(1 hunks)config/locales/views/email_confirmation_mailer/en.yml(1 hunks)config/locales/views/email_confirmation_mailer/fr.yml(1 hunks)config/locales/views/entries/fr.yml(1 hunks)config/locales/views/family_exports/fr.yml(1 hunks)config/locales/views/holdings/fr.yml(1 hunks)config/locales/views/impersonation_sessions/fr.yml(1 hunks)config/locales/views/imports/en.yml(1 hunks)config/locales/views/imports/fr.yml(1 hunks)config/locales/views/investments/fr.yml(1 hunks)config/locales/views/invitation_mailer/fr.yml(1 hunks)config/locales/views/invitations/en.yml(1 hunks)config/locales/views/invitations/fr.yml(1 hunks)config/locales/views/invite_codes/fr.yml(1 hunks)config/locales/views/layout/fr.yml(1 hunks)config/locales/views/loans/fr.yml(1 hunks)config/locales/views/merchants/fr.yml(1 hunks)config/locales/views/mfa/fr.yml(1 hunks)config/locales/views/onboardings/fr.yml(1 hunks)config/locales/views/other_assets/fr.yml(1 hunks)config/locales/views/other_liabilities/fr.yml(1 hunks)config/locales/views/pages/en.yml(2 hunks)config/locales/views/pages/fr.yml(1 hunks)config/locales/views/password_mailer/en.yml(1 hunks)config/locales/views/password_mailer/fr.yml(1 hunks)config/locales/views/password_resets/fr.yml(1 hunks)config/locales/views/passwords/fr.yml(1 hunks)config/locales/views/plaid_items/fr.yml(1 hunks)config/locales/views/properties/fr.yml(1 hunks)config/locales/views/registrations/en.yml(1 hunks)config/locales/views/registrations/fr.yml(1 hunks)config/locales/views/sessions/fr.yml(1 hunks)config/locales/views/settings/api_keys/en.yml(2 hunks)config/locales/views/settings/api_keys/fr.yml(1 hunks)config/locales/views/settings/fr.yml(1 hunks)config/locales/views/settings/hostings/en.yml(1 hunks)config/locales/views/settings/hostings/fr.yml(1 hunks)config/locales/views/settings/securities/fr.yml(1 hunks)config/locales/views/shared/fr.yml(1 hunks)config/locales/views/subscriptions/fr.yml(1 hunks)config/locales/views/tag/deletions/fr.yml(1 hunks)config/locales/views/tags/fr.yml(1 hunks)config/locales/views/trades/fr.yml(1 hunks)config/locales/views/transactions/fr.yml(1 hunks)config/locales/views/transfers/fr.yml(1 hunks)config/locales/views/users/fr.yml(1 hunks)config/locales/views/valuations/fr.yml(1 hunks)config/locales/views/vehicles/fr.yml(1 hunks)
🧰 Additional context used
📓 Path-based instructions (13)
{app,lib}/**/*.{rb,erb}
📄 CodeRabbit inference engine (CLAUDE.md)
{app,lib}/**/*.{rb,erb}: Use Current.user for the authenticated user; do not use current_user
Use Current.family for the current family; do not use current_family
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/views,app/components}/**/*.html.erb
📄 CodeRabbit inference engine (CLAUDE.md)
{app/views,app/components}/**/*.html.erb: In views, always use the icon helper; never call lucide_icon directly
Prefer semantic HTML and server-rendered Hotwire patterns (Turbo) over client-side JS widgets
Use Tailwind functional tokens (e.g., text-primary, bg-container, border-primary) instead of raw color utilities like text-white or bg-white
Keep domain/business logic out of view templates; views should primarily render data
Stimulus controllers must use declarative actions (data-action and data--target) rather than inline JavaScript
Pass data to Stimulus via data--value attributes; do not embed inline JavaScript
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/**/*.rb,app/**/*.erb}
📄 CodeRabbit inference engine (.cursor/rules/general-rules.mdc)
{app/**/*.rb,app/**/*.erb}: UseCurrent.userfor the current user; do not usecurrent_userin Rails code and templates
UseCurrent.familyfor the current family; do not usecurrent_familyin Rails code and templates
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
app/views/**/*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)
app/views/**/*.html.erb: Prefer native semantic HTML elements over custom JS components (e.g., for modals,/for disclosures)
Use Turbo Frames to segment pages instead of JS-driven client-side solutions where possible
Prefer client-side form validation when possible for UX
app/views/**/*.html.erb: Use ViewComponents when the element has complex logic/styling, is reused across contexts, needs variants/sizes or slots, requires interactivity/Stimulus, or needs accessibility/ARIA support
Use partials when the element is primarily static HTML with minimal logic, used in few contexts, simple template content, has no variants/configuration, and is mainly for content organization
Prefer components over partials: if a suitable component exists in app/components, use it; otherwise consider a partial or create a component based on the criteria
Integrate Stimulus declaratively in views: HTML declares actions/targets; controllers respond (avoid imperative JS in templates)
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/helpers/**/*.rb,app/models/**/*.rb,app/views/**/*.html.erb}
📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)
Format currencies, numbers, and dates server-side (helpers/models) and pass formatted values to Stimulus for display only
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/views/**/*.{html,html+turbo-stream}.erb,app/helpers/**/*.rb}
📄 CodeRabbit inference engine (.cursor/rules/project-conventions.mdc)
Always use the icon helper (icon) from application_helper.rb; never call lucide_icon directly
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/javascript/controllers/**/*.@(js|ts),app/components/**/*.@(js|ts),app/views/**/*.html.erb,app/components/**/*.html.erb}
📄 CodeRabbit inference engine (.cursor/rules/stimulus_conventions.mdc)
Use declarative Stimulus actions in ERB (data-action) instead of imperative event listeners in controllers (e.g., avoid addEventListener in connect/initializers).
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/components/**/*.@(js|ts),app/views/**/*.html.erb,app/components/**/*.html.erb}
📄 CodeRabbit inference engine (.cursor/rules/stimulus_conventions.mdc)
Component Stimulus controllers under app/components must only be used within their component views, not in app/views.
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/views/**,app/helpers/**,app/javascript/controllers/**}
📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)
{app/views/**,app/helpers/**,app/javascript/controllers/**}: Author styles assuming TailwindCSS v4.x is in use across the app
Always start by referencing app/assets/tailwind/maybe-design-system.css to understand the base primitives, functional tokens, and component tokens
Prefer functional tokens from maybe-design-system.css over raw colors/utilities (e.g., usetext-primaryovertext-white,bg-containeroverbg-white,border border-primaryoverborder border-gray-200)
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/views/**,app/helpers/**}
📄 CodeRabbit inference engine (.cursor/rules/ui-ux-design-guidelines.mdc)
Always generate semantic HTML
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
{app/views/**/*.html.erb,app/components/**/*.html.erb}
📄 CodeRabbit inference engine (.cursor/rules/view_conventions.mdc)
{app/views/**/*.html.erb,app/components/**/*.html.erb}: Keep domain logic out of views; compute classes and logic in component/view helpers, not inside ERB templates
Pass data from Rails to Stimulus via data-*-value attributes; do not embed inline JavaScript in templates
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
app/views/**/_*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/view_conventions.mdc)
Name partials with an underscore prefix (e.g., _trend_change.html.erb, _form_errors.html.erb)
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
app/views/!(shared)/**/_*.html.erb
📄 CodeRabbit inference engine (.cursor/rules/view_conventions.mdc)
Place context-specific partials in the relevant controller's view directory (not in shared/)
Files:
app/views/pages/dashboard/_cashflow_sankey.html.erbapp/views/pages/dashboard/_no_accounts_graph_placeholder.html.erbapp/views/accounts/_account_sidebar_tabs.html.erb
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: we-promise/sure#0
File: .cursor/rules/general-rules.mdc:0-0
Timestamp: 2025-08-12T01:01:56.633Z
Learning: Ignore i18n methods and files; hardcode strings in English for now to optimize development speed
📚 Learning: 2025-08-12T01:02:31.793Z
Learnt from: CR
PR: we-promise/sure#0
File: .cursor/rules/project-conventions.mdc:0-0
Timestamp: 2025-08-12T01:02:31.793Z
Learning: Applies to {app/helpers/**/*.rb,app/models/**/*.rb,app/views/**/*.html.erb} : Format currencies, numbers, and dates server-side (helpers/models) and pass formatted values to Stimulus for display only
Applied to files:
config/locales/models/time_series/value/fr.ymlconfig/locales/models/import/fr.yml
🪛 YAMLlint (1.37.1)
config/locales/views/subscriptions/fr.yml
[error] 3-3: no new line character at the end of file
(new-line-at-end-of-file)
config/locales/views/pages/en.yml
[error] 26-26: no new line character at the end of file
(new-line-at-end-of-file)
🔇 Additional comments (27)
config/locales/views/family_exports/fr.yml (2)
1-7: LGTM: Correct FR YAML structure and key nestingTop-level locale, indentation, and UTF‑8 diacritics look good.
5-7: Verify locale key alignment in family_exports: ensure config/locales/views/family_exports/{en, fr}.yml both define identical list keys (in_progress, complete, failed) and that views reference these exact keys to avoid missing translation errors.config/locales/views/investments/fr.yml (1)
1-17: Install and run i18n-tasks to verify locale health
YAML parses fine, but i18n-tasks isn’t installed—please add it and run:bundle exec i18n-tasks health bundle exec i18n-tasks unused -l fr bundle exec i18n-tasks missing -l frto catch any missing or unused keys.
config/locales/views/other_liabilities/fr.yml (1)
5-7: LGTM — translations read naturallyWording and placeholder look correct and consistent.
config/locales/views/invitations/en.yml (1)
18-18: LGTM — brand update onlySubtitle correctly reflects the “Sure” branding.
config/locales/models/address/fr.yml (1)
11-11: Confirm renderer collapses blanks in address formatCurrent format can produce double spaces or stray commas if line2/region are blank. Ensure the view/helper compacts empty segments before rendering.
config/locales/models/time_series/value/fr.yml (2)
2-9: Process change check: i18n policy confirmation.Past learning notes suggested deferring i18n. This PR adds FR locales. Please confirm the policy is updated so we proceed with full i18n coverage.
6-9: Confirm model and validation wiring
NoTimeSeries::Valueclass or:must_be_a_money_or_numericvalidation was found—verify thatapp/models/time_series/value.rbdefines the validation on:valueand that the I18n keyactivemodel.errors.models.time_series/value.attributes.value.must_be_a_money_or_numericmatches.config/locales/models/import/fr.yml (1)
12-13: raw_file_str attribute confirmed on Import model
The Import model calls raw_file_str.present? (app/models/import.rb:179) and uses raw_file_str in parsing (app/models/import.rb:250), and the controller permits and assigns :raw_file_str (app/controllers/import/uploads_controller.rb:19, 36, 51), so the locale key matches the model attribute.config/locales/views/email_confirmation_mailer/en.yml (1)
10-10: LGTM — branding updated correctly.config/locales/views/invitations/fr.yml (1)
1-19: LGTM — keys and translations look consistent with EN.config/locales/views/other_assets/fr.yml (1)
5-7: LGTM — clear and idiomatic FR.Wording and interpolation look good.
config/locales/views/cryptos/fr.yml (1)
7-7: Optional: Patterns are consistent for account-like resources
Cryptos, investments, and depositories all use “Saisir le solde du compte,” while other asset types use “Saisir les détails de …”. No change needed.config/locales/views/settings/hostings/en.yml (1)
6-8: LGTM — brand rename reflected correctly.Sentence reads naturally and maintains meaning.
config/locales/views/password_resets/fr.yml (1)
5-12: LGTM for wording and keys.Strings read naturally and match common password reset flows.
config/locales/views/layout/fr.yml (2)
5-13: LGTM; labels are idiomatic.Auth prompts and footer items look good.
3-9: Confirm product direction vs. prior “hardcode English” guidance.Long-term learnings note a preference to avoid i18n and hardcode English. This PR clearly adds FR i18n. Please confirm the strategy shift so future PRs align.
We’re referencing your saved learning to ensure alignment.
config/locales/views/password_mailer/en.yml (1)
8-10: LGTM: brand rename is consistentThe updates to “Sure” look correct and consistent with subject/cta copy elsewhere.
config/locales/views/password_mailer/fr.yml (1)
5-8: Mailer FR copy looks solid.Clear, natural phrasing and correct punctuation/spaces for “:”. No issues spotted.
config/locales/views/settings/fr.yml (1)
1-115: YAML health check passed: All locale files are syntactically valid and contain no duplicate keys.config/locales/views/settings/api_keys/en.yml (1)
18-18: Branding update looks good“Maybe” → “Sure” reads correctly in both strings. No other issues spotted in this hunk.
Also applies to: 39-39
config/locales/views/registrations/fr.yml (1)
9-9: The script will reveal the key hierarchy; once confirmed, we can determine if thecreatelabel undersubmitis used by the registration form’st(".submit"). If the key is indeedviews.registrations.new.submit.create, adjust as proposed:- create: Continuer + create: Créer un compteapp/views/pages/dashboard.html.erb (2)
4-5: LGTM: i18n + design tokens respectésConforme aux guidelines: I18n via t('.…'), Current.user/Current.family, tokens Tailwind DS, Turbo Frame, DS::Link.
Also applies to: 10-10
4-5: Clés i18n déjà présentes
Les clésdashboard.welcome_back,dashboard.happening_with_financeetdashboard.newsont définies dansconfig/locales/views/pages/fr.ymleten.yml. Aucun changement nécessaire.config/locales/models/account/fr.yml (1)
1-21: LGTM — solid FR model/attribute labels.Terminology and accents look correct; aligns with ActiveRecord naming.
app/views/accounts/_account_sidebar_tabs.html.erb (1)
9-9: Translations usage looks good overall.Nice move to localized labels for tabs and “new …” actions; icon helper usage complies with guidelines.
Also applies to: 26-28, 34-34, 54-54, 74-74
config/locales/views/accounts/en.yml (1)
6-15: LGTM on new i18n keys; proceed.Keys are well-namespaced, YAML is valid, and copy reads clearly. Note: intentionally ignoring a previous learning that suggested hardcoding strings; this PR’s goal is i18n.
| <div class="flex justify-between items-center gap-4 px-4 mb-4"> | ||
| <h2 class="text-lg font-medium inline-flex items-center gap-1.5"> | ||
| Cashflow | ||
| <%= t(".title") %> |
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.
💡 Verification agent
🧩 Analysis chain
Fix i18n scope: relative t('.…') won’t resolve with current keys.
This partial scopes t(".…") to pages.dashboard.cashflow_sankey., but en.yml defines pages.dashboard.cashflow.. Users will see missing translations.
Apply minimal fix by using absolute keys:
- <%= t(".title") %>
+ <%= t("pages.dashboard.cashflow.title") %>
- <p class="text-sm font-medium text-primary"><%= t(".no_cashflow") %></p>
- <p class="text-secondary text-sm"><%= t(".add_transactions_to_display_cashflow") %></p>
+ <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.cashflow.no_cashflow") %></p>
+ <p class="text-secondary text-sm"><%= t("pages.dashboard.cashflow.add_transactions_to_display_cashflow") %></p>
- text: t(".new"),
+ text: t("pages.dashboard.cashflow.new"),Run a quick check that the keys exist in both locales:
Also applies to: 33-34, 36-36
🏁 Script executed:
#!/bin/bash
rg -n '^\s+cashflow:\s*$' config/locales/views/pages/en.yml
rg -n '^\s+cashflow:\s*$' config/locales/views/pages/fr.yml
rg -n '^\s+(title|no_cashflow|add_transactions_to_display_cashflow|new):' config/locales/views/pages/en.yml
rg -n '^\s+(title|no_cashflow|add_transactions_to_display_cashflow|new):' config/locales/views/pages/fr.ymlLength of output: 1117
In app/views/pages/dashboard/_cashflow_sankey.html.erb, use absolute I18n keys for cashflow translations
Relative t(".…") calls there resolve to pages.dashboard.cashflow_sankey.*, but your locale files only define pages.dashboard.cashflow.*, so these will 404.
Apply:
- <%= t(".title") %>
+ <%= t("pages.dashboard.cashflow.title") %>
- <p class="text-sm font-medium text-primary"><%= t(".no_cashflow") %></p>
- <p class="text-secondary text-sm"><%= t(".add_transactions_to_display_cashflow") %></p>
+ <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.cashflow.no_cashflow") %></p>
+ <p class="text-secondary text-sm"><%= t("pages.dashboard.cashflow.add_transactions_to_display_cashflow") %></p>
- text: t(".new"),
+ text: t("pages.dashboard.cashflow.new"),Also update the same at lines 33–34 and 36.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <%= t(".title") %> | |
| <!-- line ~5 --> | |
| <%= t("pages.dashboard.cashflow.title") %> | |
| <% if cashflow.empty? %> | |
| - <p class="text-sm font-medium text-primary"><%= t(".no_cashflow") %></p> | |
| <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.cashflow.no_cashflow") %></p> | |
| <p class="text-secondary text-sm"><%= t("pages.dashboard.cashflow.add_transactions_to_display_cashflow") %></p> | |
| <% else %> | |
| <!-- ... --> | |
| text: t("pages.dashboard.cashflow.new"), | |
| <!-- ... --> | |
| <% end %> |
🤖 Prompt for AI Agents
In app/views/pages/dashboard/_cashflow_sankey.html.erb around lines 5, 33-34 and
36, the view uses relative I18n keys like t(".title") which resolve to
pages.dashboard.cashflow_sankey.* but the locale keys live under
pages.dashboard.cashflow.*; change each relative call to the absolute keys (e.g.
t("pages.dashboard.cashflow.title") and the corresponding keys used at lines
33–34 and 36) so they reference pages.dashboard.cashflow.* instead of the
current relative scope.
| <p class="text-sm font-medium text-primary"><%= t(".no_account_yet") %></p> | ||
| <p class="text-secondary text-sm"><%= t(".add_account_to_display") %></p> |
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.
💡 Verification agent
🧩 Analysis chain
Fix i18n scope: partial name is plural, YAML key is singular.
This partial’s t(".…") resolves to pages.dashboard.no_accounts_graph_placeholder., but en.yml uses pages.dashboard.no_account_graph_placeholder.. Switch to absolute keys (minimal change).
- <p class="text-sm font-medium text-primary"><%= t(".no_account_yet") %></p>
- <p class="text-secondary text-sm"><%= t(".add_account_to_display") %></p>
+ <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.no_account_graph_placeholder.no_account_yet") %></p>
+ <p class="text-secondary text-sm"><%= t("pages.dashboard.no_account_graph_placeholder.add_account_to_display") %></p>
- text: t(".new"),
+ text: t("pages.dashboard.no_account_graph_placeholder.new"),Confirm the keys exist in both en/fr locale files with ripgrep (similar to the previous script).
Also applies to: 11-11
🏁 Script executed:
#!/bin/bash
# Search for singular placeholder key in locale YAML files
rg -n "pages\\.dashboard\\.no_account_graph_placeholder" -C1 -- "*.yml"
# Search for plural placeholder key in locale YAML files
rg -n "pages\\.dashboard\\.no_accounts_graph_placeholder" -C1 -- "*.yml"Length of output: 236
🏁 Script executed:
#!/bin/bash
# Search for singular key in the repo
rg -n "no_account_graph_placeholder" -C2 .
# Search for plural key in the repo
rg -n "no_accounts_graph_placeholder" -C2 .Length of output: 1477
🏁 Script executed:
#!/bin/bash
sed -n '1,50p' config/locales/views/pages/en.yml
sed -n '1,50p' config/locales/views/pages/fr.ymlLength of output: 2241
Fix i18n scope mismatch in no_accounts_graph_placeholder partial
The partial’s relative calls (t(".…")) use the plural scope (pages.dashboard.no_accounts_graph_placeholder.*), but the YAML defines singular keys (pages.dashboard.no_account_graph_placeholder.*). Switch to absolute singular keys:
- <p class="text-sm font-medium text-primary"><%= t(".no_account_yet") %></p>
+ <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.no_account_graph_placeholder.no_account_yet") %></p>
- <p class="text-secondary text-sm"><%= t(".add_account_to_display") %></p>
+ <p class="text-secondary text-sm"><%= t("pages.dashboard.no_account_graph_placeholder.add_account_to_display") %></p>
- text: t(".new"),
+ text: t("pages.dashboard.no_account_graph_placeholder.new"),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <p class="text-sm font-medium text-primary"><%= t(".no_account_yet") %></p> | |
| <p class="text-secondary text-sm"><%= t(".add_account_to_display") %></p> | |
| <p class="text-sm font-medium text-primary"><%= t("pages.dashboard.no_account_graph_placeholder.no_account_yet") %></p> | |
| <p class="text-secondary text-sm"><%= t("pages.dashboard.no_account_graph_placeholder.add_account_to_display") %></p> | |
| text: t("pages.dashboard.no_account_graph_placeholder.new"), |
🤖 Prompt for AI Agents
In app/views/pages/dashboard/_no_accounts_graph_placeholder.html.erb around
lines 8 to 9, the partial uses relative translation scopes t(".no_account_yet")
and t(".add_account_to_display") which resolve to
pages.dashboard.no_accounts_graph_placeholder.* but your YAML uses the singular
scope pages.dashboard.no_account_graph_placeholder.*; update both calls to use
the absolute singular keys matching the YAML (e.g.
t("pages.dashboard.no_account_graph_placeholder.no_account_yet") and
t("pages.dashboard.no_account_graph_placeholder.add_account_to_display")) so the
translations resolve correctly.
| account_sidebar_tabs: | ||
| missing_historical: Missing historical data | ||
| describe_party_provider: Sure uses third party providers to fetch historical exchange rates, security prices, and more. This data is required to calculate accurate historical account balances. | ||
| configure_provider: Configure your providers here. | ||
| label_all: All | ||
| label_asset: Assets | ||
| label_liability: Debts | ||
| new_asset: New asset | ||
| new_debt: New debt | ||
| new_account: New account |
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.
💡 Verification agent
🧩 Analysis chain
Verify FR parity and missing keys across locales.
Ensure fr.yml mirrors these keys to avoid runtime fallbacks.
🏁 Script executed:
#!/bin/bash
# Compare en vs fr keys under views/accounts for parity.
pip -q install pyyaml >/dev/null
python - <<'PY'
import sys, yaml, pathlib
def keys(d, prefix=""):
out=[]
for k,v in d.items():
p=f"{prefix}.{k}" if prefix else k
if isinstance(v, dict):
out+=keys(v,p)
else:
out.append(p)
return out
base=pathlib.Path("config/locales/views/accounts")
enf=base/"en.yml"; frf=base/"fr.yml"
en=yaml.safe_load(enf.read_text()) or {}
fr=yaml.safe_load(frf.read_text()) or {}
enk=set(keys(en.get("en",{})))
frk=set(keys(fr.get("fr",{})))
missing_in_fr=sorted(k for k in enk if k.replace("en.","fr.",1) if k.replace("en.","fr.",1) and k.replace("en.","fr.",1) not in frk)
missing_in_fr=[k.split('.',1)[1] for k in enk - {"en"} if k.replace("en","fr",1) not in frk]
print("Missing in fr:", *missing_in_fr, sep="\n ")
extra_in_fr=[k.split('.',1)[1] for k in frk - {"fr"} if k.replace("fr","en",1) not in enk]
print("\nExtra in fr:", *extra_in_fr, sep="\n ")
PYLength of output: 408
Add missing translation keys to fr.yml
The following keys from config/locales/views/accounts/en.yml are not defined in config/locales/views/accounts/fr.yml:
• show.activity.entries, show.activity.no_entries, show.activity.entry
• show.menu.confirm_accept, show.menu.confirm_title, show.menu.import, show.menu.manage, show.menu.edit, show.menu.confirm_body_html
• new.method_selector.connected_entry_eu, new.method_selector.connected_entry, new.method_selector.manual_entry
• new.invalid_token
Define translations for them to prevent runtime fallbacks.
🤖 Prompt for AI Agents
In config/locales/views/accounts/en.yml around lines 6 to 15, several
translation keys used by the app are present in English but missing from
config/locales/views/accounts/fr.yml (show.activity.entries,
show.activity.no_entries, show.activity.entry, show.menu.confirm_accept,
show.menu.confirm_title, show.menu.import, show.menu.manage, show.menu.edit,
show.menu.confirm_body_html, new.method_selector.connected_entry_eu,
new.method_selector.connected_entry, new.method_selector.manual_entry,
new.invalid_token); add these exact keys to config/locales/views/accounts/fr.yml
with appropriate French translations (ensure HTML-safe content for *_body_html),
matching the YAML structure used in en.yml so the i18n lookups do not fall back
at runtime.
| delete_and_leave_uncategorized: Supprimer "%{tag_name}" | ||
| delete_and_recategorize: Supprimer "%{tag_name}" et attribuer une nouvelle étiquette |
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.
Preserve the “leave uncategorized” intent.
The first option drops the “leave uncategorized” part; add it for parity with categories.
- delete_and_leave_uncategorized: Supprimer "%{tag_name}"
- delete_and_recategorize: Supprimer "%{tag_name}" et attribuer une nouvelle étiquette
+ delete_and_leave_uncategorized: Supprimer "%{tag_name}" et laisser non étiquetées
+ delete_and_recategorize: Supprimer "%{tag_name}" et attribuer une nouvelle étiquette📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| delete_and_leave_uncategorized: Supprimer "%{tag_name}" | |
| delete_and_recategorize: Supprimer "%{tag_name}" et attribuer une nouvelle étiquette | |
| delete_and_leave_uncategorized: Supprimer "%{tag_name}" et laisser non étiquetées | |
| delete_and_recategorize: Supprimer "%{tag_name}" et attribuer une nouvelle étiquette |
🤖 Prompt for AI Agents
In config/locales/views/tag/deletions/fr.yml around lines 8 to 9, the
translation for delete_and_leave_uncategorized currently omits the “leave
uncategorized” intent; update the value to keep parity with categories by
appending a phrase like "et laisser sans catégorie" so it reads e.g. Supprimer
"%{tag_name}" et laisser sans catégorie, ensuring the placeholder %{tag_name}
remains intact and punctuation matches the other entry.
| fr: | ||
| vehicles: | ||
| edit: | ||
| edit: Modifier %{account} |
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.
💡 Verification agent
🧩 Analysis chain
Wrong interpolation key (“account”) in vehicles edit title.
Likely copy/paste; this will confuse or break interpolation. Prefer a neutral label or a “vehicle” placeholder.
- edit: Modifier %{account}
+ edit: Modifier le véhicule
+# or, if the view passes a name:
+# edit: Modifier %{vehicle}Run to verify usage and expected placeholders:
🏁 Script executed:
#!/bin/bash
rg -n -C2 -g '!**/node_modules/**' -P "t\(['\"](vehicles\.edit\.edit|\.edit)['\"].*\)" app | sed -n '1,120p'
rg -n -C2 -P "vehicles:\s*\n\s*edit:\s*\n\s*edit:" config/locales -g '!**/node_modules/**'Length of output: 5188
🏁 Script executed:
#!/bin/bash
# Inspect the French locale for vehicles edit translations
sed -n '1,30p' config/locales/views/vehicles/fr.yml
# Find any occurrences of "%{account}" in vehicles locale files
rg -n "%{account}" -g 'config/locales/views/vehicles/*.yml'
# List all interpolation placeholders in vehicles locale files
rg -n "%{" -g 'config/locales/views/vehicles/*.yml'Length of output: 900
Fix interpolation key in FR vehicles edit translation
In config/locales/views/vehicles/fr.yml, replace the account placeholder with a neutral label or the correct vehicle key:
- edit: Modifier %{account}
+ edit: Modifier le véhicule
# or, if you pass a vehicle name:
# edit: Modifier %{vehicle}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| edit: Modifier %{account} | |
| edit: Modifier le véhicule |
🤖 Prompt for AI Agents
In config/locales/views/vehicles/fr.yml around line 5, the FR translation uses
the wrong interpolation key %{account}; update that placeholder to the correct
vehicle key (e.g. %{vehicle}) or replace it with a neutral fixed label (e.g.
"Modifier le véhicule") so the translation matches the vehicles view and no
longer references an account.
Signed-off-by: Juan José Mata <[email protected]>
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.
This PR is being reviewed by Cursor Bugbot
Details
You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.
To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.
| title: Cashflow | ||
| no_cashflow: No cash flow data for this time period | ||
| add_transactions_to_display_cashflow: Add transactions to display cash flow data or expand the time period | ||
| new: Add transactions |
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.
Bug: Translation Key Scope Mismatch Across Locales
The English locale defines translation keys under incorrect scopes for two partials. For _cashflow_sankey.html.erb, keys are under cashflow instead of cashflow_sankey, unlike the French locale. For _no_accounts_graph_placeholder.html.erb, keys are under no_account_graph_placeholder instead of no_accounts_graph_placeholder. This mismatch causes translation lookups to fail.
Additional Locations (1)
|
|
||
| <p> | ||
| <%= link_to "Configure your providers here.", settings_hosting_path, class: "text-yellow-600 underline" %> | ||
| <%= link_to t(".describe_party_provider"), settings_hosting_path, class: "text-yellow-600 underline" %> |
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.
Bug: Incorrect Text Key for Configuration Link
The link to configure data providers uses t(".describe_party_provider") for its text. This key contains a long descriptive paragraph, causing the link to display that full text instead of the intended short phrase "Configure your providers here.", which is in t(".configure_provider").
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.
Can you please update for the new "customizable brand" support using %{product_name} and %{product_brand} interpolations, @Xurron? 🙏
Summary by CodeRabbit
New Features
Localization