From fb6740f3330bd1b9ffb7650b7a602c4ec0406b97 Mon Sep 17 00:00:00 2001 From: Sepehr Date: Sun, 7 Jun 2026 10:59:57 +0200 Subject: [PATCH] fix(glossaries): correct source/target display mapping (FR=source, EN=target, others=translations[lang]) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avant : getDisplaySource(term, 'en') lisait term.translations.en (qui n'existe pas) puis fallback sur term.source = francais. C'est ce qui affichait du francais et du néerlandais au mauvais endroit. Apres : le mapping reflete la structure reelle des donnees : - FR (lang='fr') → term.source - EN (lang='en') → term.target - autres (de, es, it, pt, nl, ru, ja, ko, zh, ar, fa) → term.translations[lang] - si manquant → '' (placeholder, JAMAIS une autre langue en fallback) Memes regles pour getDisplayTarget, inversees (defaut = target). Edition (handleTermChange) ecrit au bon endroit : - FR → term.source - EN (ou multi) → term.target - autres → translations[lang] Le remap automatique de term.target au changement de targetLanguage est supprime (lecture a la volee maintenant, plus besoin de modifier l'etat des termes). Aucun changement de donnees, aucun changement backend, aucun changement de schema. Fix purement frontend. --- .../app/dashboard/glossaries/[id]/page.tsx | 98 +++++++++---------- 1 file changed, 46 insertions(+), 52 deletions(-) diff --git a/frontend/src/app/dashboard/glossaries/[id]/page.tsx b/frontend/src/app/dashboard/glossaries/[id]/page.tsx index 8bfb140..6719661 100644 --- a/frontend/src/app/dashboard/glossaries/[id]/page.tsx +++ b/frontend/src/app/dashboard/glossaries/[id]/page.tsx @@ -26,28 +26,38 @@ import { ProUpgradePrompt } from '../ProUpgradePrompt'; const MAX_TERMS = 500; -function getDisplayTarget( - term: { target: string; translations?: Record | null }, - lang: string -): string { - if (lang === 'multi' || lang === 'en' || !lang) return term.target; - const translations = term.translations || {}; - return translations[lang] || term.target; -} - -/** Source term in the given language. - * - 'fr' → term.source (the original French) - * - 'multi' / '' / undefined → term.source (no language chosen, default to FR) - * - other langs → term.translations[lang] (the translated source) - * - falls back to term.source if missing +/** Source term in the chosen language. + * Structure du terme : source=FR (fondation), target=EN (fondation), + * translations = 11 autres langues (de, es, it, pt, nl, ru, ja, ko, zh, ar, fa). + * - lang vide / 'multi' → '' (pas de choix) + * - lang === 'fr' → term.source + * - lang === 'en' → term.target (fallback EN depuis le champ legacy) + * - autre lang → term.translations[lang] + * - si manquant → '' (placeholder, JAMAIS une autre langue en fallback) */ function getDisplaySource( - term: { source: string; translations?: Record | null }, + term: { source: string; target: string; translations?: Record | null }, lang: string ): string { - if (!lang || lang === 'multi' || lang === 'fr') return term.source; + if (!lang || lang === 'multi') return ''; + if (lang === 'fr') return term.source; + if (lang === 'en') return term.target; const translations = term.translations || {}; - return translations[lang] || term.source; + return translations[lang] || ''; +} + +/** Target term in the chosen language. Mêmes règles que getDisplaySource, + * mais l'inverse : EN est le défaut (champ target), FR vient de source. + */ +function getDisplayTarget( + term: { source: string; target: string; translations?: Record | null }, + lang: string +): string { + if (!lang || lang === 'multi') return term.target; // multi = défaut = EN + if (lang === 'en') return term.target; + if (lang === 'fr') return term.source; + const translations = term.translations || {}; + return translations[lang] || ''; } export default function GlossaryDetailPage() { @@ -139,51 +149,35 @@ export default function GlossaryDetailPage() { if (i !== index) return t; const translations = { ...(t.translations || {}) } as Record; - if (field === 'source') { - if (!sourceLanguage || sourceLanguage === 'fr') { - // French source → write to term.source - return { ...t, source: value }; - } - // Other source languages → write to translations[sourceLanguage] - translations[sourceLanguage] = value; - return { ...t, source: t.source, translations }; - } + // FR et EN sont dans les champs legacy (term.source / term.target), + // les 11 autres langues dans translations[lang]. + // Pour l'édition, on écrit au bon endroit selon la langue choisie. + const isFr = field === 'source' ? sourceLanguage === 'fr' : targetLanguage === 'fr'; + const isEn = field === 'source' ? sourceLanguage === 'en' : targetLanguage === 'en'; + const otherLang = field === 'source' ? sourceLanguage : targetLanguage; - if (field === 'target') { - if (!targetLanguage || targetLanguage === 'multi' || targetLanguage === 'en') { - // Default target → write to term.target - return { ...t, target: value }; - } - // Other target languages → write to translations[targetLanguage] - translations[targetLanguage] = value; - return { ...t, target: t.target, translations }; + if (isFr) { + // Écriture du français → champ source (legacy) + return { ...t, source: value }; } - - return t; + if (isEn || !otherLang || otherLang === 'multi') { + // Écriture de l'anglais (ou défaut multi) → champ target (legacy) + return { ...t, target: value }; + } + // Autre langue → translations[otherLang] + translations[otherLang] = value; + return { ...t, source: t.source, target: t.target, translations }; })); }; const handleSourceLanguageChange = (newLang: string) => { setSourceLanguage(newLang); - // No term remapping needed — the display reads translations[newLang] on the fly. + // No remap : l'affichage lit translations[newLang] à la volée. }; const handleTargetLanguageChange = (newLang: string) => { - if (glossary) { - setTargetLanguage(newLang); - if (newLang === 'multi' || newLang === 'en') return; - // Remap each term to show translation for the new language (when available) - setTerms((prev) => - prev.map((t) => { - const translations = (t.translations || {}) as Record; - const langTarget = translations[newLang]; - if (langTarget) { - return { ...t, target: langTarget }; - } - return t; - }) - ); - } + setTargetLanguage(newLang); + // No remap : l'affichage lit translations[newLang] à la volée. }; const handleSave = async () => {