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
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:
@@ -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(
|
||||||
|
|||||||
@@ -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(() => {
|
||||||
|
|||||||
@@ -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),
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user