fix: glossary selection respects target language — sort by source+target, reset on lang change, fix template import
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled

- GlossarySelector: filteredGlossaries now sorts matching target_language
  first so FR→FA appears before FR→EN when translating to Persian
- GlossarySelector: toggle auto-select prefers glossary matching
  targetLang, falls back to first available
- useTranslationConfig: reset glossaryId when targetLang changes (was
  only resetting on sourceLang change)
- glossary_routes: set target_language from template data on import
  (was missing, defaulted to None/en)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 22:00:40 +02:00
parent 89c31f8298
commit 5122bfdf99
3 changed files with 15 additions and 5 deletions

View File

@@ -239,8 +239,15 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
if (!filterByLang || sourceLang === 'auto') { if (!filterByLang || sourceLang === 'auto') {
return glossaries; return glossaries;
} }
return glossaries.filter(g => g.source_language === sourceLang); return glossaries
}, [glossaries, filterByLang, sourceLang]); .filter(g => g.source_language === sourceLang)
.sort((a, b) => {
// Glossaries matching source + target come first
const aMatch = a.target_language === targetLang ? 0 : 1;
const bMatch = b.target_language === targetLang ? 0 : 1;
return aMatch - bMatch;
});
}, [glossaries, filterByLang, sourceLang, targetLang]);
const filteredTemplates = useMemo(() => { const filteredTemplates = useMemo(() => {
if (!filterByLang || sourceLang === 'auto') { if (!filterByLang || sourceLang === 'auto') {
@@ -278,7 +285,9 @@ export function GlossarySelector({ sourceLang, targetLang, isPro, mode, glossary
if (!nextVal) { if (!nextVal) {
onChange(null); onChange(null);
} else if (filteredGlossaries.length > 0 && !glossaryId) { } else if (filteredGlossaries.length > 0 && !glossaryId) {
onChange(filteredGlossaries[0].id); // Prefer glossary matching target language, fall back to first
const matching = filteredGlossaries.find(g => g.target_language === targetLang);
onChange(matching ? matching.id : filteredGlossaries[0].id);
} }
}} }}
className={cn( className={cn(

View File

@@ -80,10 +80,10 @@ export function useTranslationConfig(hasFile: boolean): UseTranslationConfigRetu
} }
}, [settings.defaultTargetLanguage]); // eslint-disable-line react-hooks/exhaustive-deps }, [settings.defaultTargetLanguage]); // eslint-disable-line react-hooks/exhaustive-deps
// Reset glossary selection when source language changes // Reset glossary selection when source or target language changes
useEffect(() => { useEffect(() => {
setGlossaryId(null); setGlossaryId(null);
}, [sourceLang]); // eslint-disable-line react-hooks/exhaustive-deps }, [sourceLang, targetLang]); // eslint-disable-line react-hooks/exhaustive-deps
// Fetch available (admin-configured) providers // Fetch available (admin-configured) providers
useEffect(() => { useEffect(() => {

View File

@@ -597,6 +597,7 @@ async def import_glossary_template(
user_id=user.id, user_id=user.id,
name=glossary_name, name=glossary_name,
source_language=template_data.get("source_lang", "fr"), source_language=template_data.get("source_lang", "fr"),
target_language=template_data.get("target_lang", "en"),
created_at=datetime.now(timezone.utc), created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc), updated_at=datetime.now(timezone.utc),
) )