⚠️
- {t('translate.glossary.sourceWarning') || 'Attention :'} Ce glossaire utilise la langue source{getFlag(selected.source_language)} {selected.source_language.toUpperCase()}, {t('translate.glossary.sourceWarningBut') || 'mais votre document est configuré en'} {getFlag(sourceLang)} {sourceLang.toUpperCase()}.
+ {t('translate.glossary.sourceWarning')}{getFlag(selected.source_language)} {selected.source_language.toUpperCase()}, {t('translate.glossary.sourceWarningBut')} {getFlag(sourceLang)} {sourceLang.toUpperCase()}.
)}
diff --git a/frontend/src/lib/i18n.tsx b/frontend/src/lib/i18n.tsx
index 657f21b..240aac1 100644
--- a/frontend/src/lib/i18n.tsx
+++ b/frontend/src/lib/i18n.tsx
@@ -381,6 +381,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Clicking a card creates a pre-filled glossary with domain-specific terms. This glossary will appear in your glossaries below, and you can manually select it on the Translate page to force precise term translations.",
"glossaries.presets.clickHint": "Click a card → glossary created → select it in Translate",
"glossaries.presets.creating": "Creating...",
+ "glossaries.presets.alreadyImported": "Imported",
"glossaries.presets.it.title": "IT / Software",
"glossaries.presets.it.desc": "Development, infrastructure, DevOps",
"glossaries.presets.legal.title": "Legal / Contracts",
@@ -1324,6 +1325,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -2253,6 +2255,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -3137,6 +3140,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -4021,6 +4025,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -4905,6 +4910,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -5789,6 +5795,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -6673,6 +6680,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -7559,6 +7567,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -8442,6 +8451,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -9325,6 +9335,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -10166,6 +10177,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
@@ -11016,6 +11028,7 @@ const messages: Record> = {
"glossaries.presets.whatForDesc": "Cliquer sur une carte crée un glossaire pré-rempli avec les termes spécialisés du domaine. Ce glossaire apparaîtra dans vos glossaires ci-dessous, et vous pourrez le sélectionner manuellement sur la page Traduire pour forcer des traductions de termes précis.",
"glossaries.presets.clickHint": "Cliquez sur une carte → glossaire créé → sélectionnez-le dans Traduire",
"glossaries.presets.creating": "Création…",
+ "glossaries.presets.alreadyImported": "Déjà importé",
"glossaries.presets.it.title": "IT / Logiciel",
"glossaries.presets.it.desc": "Développement, infrastructure, DevOps",
"glossaries.presets.legal.title": "Juridique / Contrats",
diff --git a/routes/glossary_routes.py b/routes/glossary_routes.py
index ce0642a..cac8520 100644
--- a/routes/glossary_routes.py
+++ b/routes/glossary_routes.py
@@ -58,6 +58,7 @@ def _format_glossary(glossary: Glossary) -> dict:
"name": glossary.name,
"source_language": glossary.source_language,
"target_language": getattr(glossary, "target_language", "multi") or "multi",
+ "template_id": getattr(glossary, "template_id", None),
"terms": [_format_term(t) for t in glossary.terms] if glossary.terms else [],
"created_at": glossary.created_at.isoformat() if glossary.created_at else None,
"updated_at": glossary.updated_at.isoformat() if glossary.updated_at else None,
@@ -591,13 +592,30 @@ async def import_glossary_template(
)
glossary_name = name or template_data.get("name", template_info.get("name", template_id))
-
+
with get_sync_session() as session:
+ # Check if user already imported this template
+ existing = (
+ session.query(Glossary)
+ .filter_by(user_id=user.id, template_id=template_id)
+ .first()
+ )
+ if existing:
+ return JSONResponse(
+ status_code=409,
+ content={
+ "error": "TEMPLATE_ALREADY_IMPORTED",
+ "message": f"You already have a glossary from the '{template_id}' template.",
+ "data": _format_glossary(existing),
+ },
+ )
+
glossary = Glossary(
user_id=user.id,
name=glossary_name,
source_language=template_info.get("source_lang", template_data.get("source_lang", "fr")),
target_language=template_info.get("target_lang", template_data.get("target_lang", "multi")),
+ template_id=template_id,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc),
)