From 0a4bfcc9de293f3a4fe5f35a432f8daf2cfe31d5 Mon Sep 17 00:00:00 2001
From: Yves Pratter <yves.pratter@gmail.com>
Date: Wed, 21 Apr 2021 16:46:07 +0200
Subject: [PATCH] error 404 ! lost in Symfony ;D

---
 src/Admin/Element/ElementAdminAbstract.php    |   4 +-
 src/Admin/Element/ElementAdminShowEdit.php    |  26 ++--
 src/Admin/NewsAdmin.php                       |   4 +-
 .../DuplicatesDetectionController.php         |   7 +-
 .../Admin/ProjectAdminController.php          |   4 +-
 src/Controller/Admin/UserAdminController.php  |  13 +-
 .../blocks/block_recent_elements.html.twig    |   3 +-
 .../custom-fields/display-logs.html.twig      |   4 +-
 .../custom-fields/element-data.html.twig      |  18 +--
 .../admin/pages/bulks/bulk_abstract.html.twig |  20 +--
 .../pages/bulks/bulk_duplicates.html.twig     |  15 +--
 .../display_vote_report_item.html.twig        |   4 +-
 .../partials/show_one_contribution.html.twig  |  90 +++++++-------
 translations/admin+intl-icu.fr.yaml           |  47 +++++--
 translations/messages+intl-icu.fr.yaml        | 116 ++++++++++--------
 15 files changed, 215 insertions(+), 160 deletions(-)

diff --git a/src/Admin/Element/ElementAdminAbstract.php b/src/Admin/Element/ElementAdminAbstract.php
index 664f2df4f..eb6b5d8d3 100755
--- a/src/Admin/Element/ElementAdminAbstract.php
+++ b/src/Admin/Element/ElementAdminAbstract.php
@@ -30,7 +30,7 @@ class ElementAdminAbstract extends GoGoAbstractAdmin
       '7' => 'Importé'
     ];
 
-    protected $moderationChoices = [ // TODO translate
+/*     protected $moderationChoices = [ // TODO translate
       '-2' => 'Erreur geolocalisation',
       '-1' => 'Aucune catégorie renseignée',
       '0' => 'Pas de modération nécessaire',
@@ -39,7 +39,7 @@ class ElementAdminAbstract extends GoGoAbstractAdmin
       '3' => 'En attente depuis trop longtemps',
       '4' => 'Doublon potentiel',
     ];
-
+ */
     protected $reportsValuesChoice = [ // TODO translate
       '0' => "L'élément n'existe plus",
       '1' => 'Les informations sont incorrectes',
diff --git a/src/Admin/Element/ElementAdminShowEdit.php b/src/Admin/Element/ElementAdminShowEdit.php
index 98f2d5833..f46d1a9f1 100755
--- a/src/Admin/Element/ElementAdminShowEdit.php
+++ b/src/Admin/Element/ElementAdminShowEdit.php
@@ -43,8 +43,8 @@ class ElementAdminShowEdit extends ElementAdminList
                 'class' => 'gogo-element-data',
                 'data-props' => json_encode($elementProperties)
               ]])
-            ->add('userOwnerEmail', EmailType::class, ['required' => false, 'label' => "Email de l'utilisateur propriétaire de cette fiche"])// TODO translate
-            ->add('email', EmailType::class, ['required' => false, 'label' => "Email de l'élément"])// TODO translate
+            ->add('userOwnerEmail', EmailType::class)
+            ->add('email', EmailType::class)
             ->add('images', CollectionType::class, [
               'entry_type' => ElementImageType::class,
               'allow_add' => true,
@@ -72,13 +72,13 @@ class ElementAdminShowEdit extends ElementAdminList
         $needModeration = 0 != $this->subject->getModerationState();
 
         $show
-          ->with('Autre infos', ['class' => 'col-md-6'])
+          ->with('otherInfos', ['class' => 'col-md-6'])
             ->add('id')
             ->add('randomHash')
-            ->add('oldId', null, ['label' => 'Id dans la base de données importée'])// TODO translate
-            ->add('sourceKey', null, ['label' => 'Source'])// TODO translate
-            ->add('createdAt', 'datetime', ['format' => 'd/m/Y à H:i'])// TODO translate
-            ->add('updatedAt', 'datetime', ['format' => 'd/m/Y à H:i'])// TODO translate
+            ->add('oldId')
+            ->add('sourceKey')
+            ->add('createdAt', 'datetime', ['format' => $this->t('commons.format')])
+            ->add('updatedAt', 'datetime', ['format' => $this->t('commons.format')])
           ->end();
 
         if ($this->subject->isPending()) {
@@ -94,13 +94,9 @@ class ElementAdminShowEdit extends ElementAdminList
 
         if ($needModeration) {
             $show
-              ->with('Modération', ['class' => 'col-md-6 col-sm-12'])
-                ->add('moderationState', ChoiceType::class, [
-                    'label' => 'Moderation',// TODO translate
-                      'choices' => $this->moderationChoices,
-                      'template' => 'admin/partials/show_choice_moderation.html.twig',
-                      ])
-                ->add('reports', null, ['template' => 'admin/partials/show_pending_reports.html.twig', 'label' => 'Signalements'])// TODO translate
+              ->with('moderation', ['class' => 'col-md-6 col-sm-12'])
+                ->add('moderationState', ChoiceType::class, ['template' => 'admin/partials/show_choice_moderation.html.twig',])
+                ->add('reports', null, ['template' => 'admin/partials/show_pending_reports.html.twig'])
               ->end();
         }
 
@@ -116,4 +112,4 @@ class ElementAdminShowEdit extends ElementAdminList
             ->add('adminJson')
           ->end();
     }
-}
+}
\ No newline at end of file
diff --git a/src/Admin/NewsAdmin.php b/src/Admin/NewsAdmin.php
index 612be5a36..f934f3da5 100644
--- a/src/Admin/NewsAdmin.php
+++ b/src/Admin/NewsAdmin.php
@@ -36,7 +36,7 @@ final class NewsAdmin extends GoGoAbstractAdmin
     {
         $list
             ->addIdentifier('title', 'text')
-            ->add('publicationDate', 'datetime', ['format' => $this->t('news.format')])
+            ->add('publicationDate', 'datetime', ['format' => $this->t('commons.format')])
             ->add('status', 'choice', ['choices' => [
                 NewsStatus::DRAFT => $this->t('news.fields.status_choices.draft'),
                 NewsStatus::PUBLISHED => $this->t('news.fields.status_choices.published'),
@@ -59,7 +59,7 @@ final class NewsAdmin extends GoGoAbstractAdmin
     {
         $show
             ->add('title', 'text')
-            ->add('publicationDate', 'datetime', ['format' => $this->t('news.format')])
+            ->add('publicationDate', 'datetime', ['format' => $this->t('commons.format')])
             ->add('status', 'choice', ['choices' => [
                 NewsStatus::DRAFT => $this->t('news.fields.status_choices.draft'),
                 NewsStatus::PUBLISHED => $this->t('news.fields.status_choices.published'),
diff --git a/src/Controller/Admin/BulkActions/DuplicatesDetectionController.php b/src/Controller/Admin/BulkActions/DuplicatesDetectionController.php
index 86dad072a..13d64a353 100755
--- a/src/Controller/Admin/BulkActions/DuplicatesDetectionController.php
+++ b/src/Controller/Admin/BulkActions/DuplicatesDetectionController.php
@@ -7,13 +7,14 @@ use App\Services\ElementDuplicatesService;
 use Doctrine\ODM\MongoDB\DocumentManager;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\Session\SessionInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
 
 class DuplicatesDetectionController extends BulkActionsAbstractController
 {
     public function detectDuplicatesAction(Request $request, SessionInterface $session, DocumentManager $dm,
-                                           ElementDuplicatesService $duplicateService)
+                                           ElementDuplicatesService $duplicateService, TranslatorInterface $t)
     {
-        $this->title = 'Détection des doublons'; // TODO translate
+        $this->title = $t->trans('bulk.detectDuplicatesAction', [], 'admin');
         $this->automaticRedirection = false;
         $this->batchSize = 1000;
         $this->duplicateService = $duplicateService;
@@ -31,7 +32,7 @@ class DuplicatesDetectionController extends BulkActionsAbstractController
                 ->execute();
         }
 
-        return $this->elementsBulkAction('detectDuplicates', $dm, $request, $session);
+        return $this->elementsBulkAction('detectDuplicates', $dm, $request, $session, $t);
     }
 
     public function detectDuplicates($element, $dm)
diff --git a/src/Controller/Admin/ProjectAdminController.php b/src/Controller/Admin/ProjectAdminController.php
index f6ff52f56..9105e04c9 100644
--- a/src/Controller/Admin/ProjectAdminController.php
+++ b/src/Controller/Admin/ProjectAdminController.php
@@ -8,14 +8,16 @@ use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
 
 class ProjectAdminController extends Controller
 {
-    public function __construct(DocumentManager $dm, LoggerInterface $projectsLogger, TokenStorageInterface $securityContext)
+    public function __construct(DocumentManager $dm, LoggerInterface $projectsLogger, TokenStorageInterface $securityContext, TranslatorInterface $t)
     {
         $this->dm = $dm;
         $this->logger = $projectsLogger;
         $this->security = $securityContext;
+        $this->t = $t;
     }
 
     /**
diff --git a/src/Controller/Admin/UserAdminController.php b/src/Controller/Admin/UserAdminController.php
index db0b2c5c5..76a9f80df 100755
--- a/src/Controller/Admin/UserAdminController.php
+++ b/src/Controller/Admin/UserAdminController.php
@@ -37,28 +37,29 @@ class UserAdminController extends Controller
                 }
             }
         } catch (\Exception $e) {
-            $this->addFlash('sonata_flash_error', 'ERROR : '.$e->getMessage()); // TODO translate ?
+            $this->addFlash('sonata_flash_error', $this->trans('batch.error', [$e->getMessage()], 'admin'));
 
             return new RedirectResponse($this->admin->generateUrl('list', $this->admin->getFilterParameters()));
         }
 
         if (!$request->get('mail-subject') || !$request->get('mail-content')) {
-            $this->addFlash('sonata_flash_error', $this->t->trans('mailError', [], 'admin'));
+            $this->addFlash('sonata_flash_error', $this->trans('batch.mailError', [], 'admin'));
         } elseif (count($mails) > 0) {
             $result = $this->mailService->sendMail(null, $request->get('mail-subject'), $request->get('mail-content'), $request->get('from'), $mails);
             if ($result['success']) {
-                $this->addFlash('sonata_flash_success', $this->t->trans('batch.sendmails', ['%count%' => count($mails)], 'admin'));
+                $this->addFlash('sonata_flash_success', $this->trans('batch.sendmails', ['%count%' => count($mails)], 'admin'));
             } else {
                 $this->addFlash('sonata_flash_error', $result['message']);
             }
         }
 
         if ($usersWithoutEmail > 0) {
-            $this->addFlash('sonata_flash_error', $this->t->trans('usersWithoutEmail', ['%count%' => $usersWithoutEmail], 'admin'));
+            $this->addFlash('sonata_flash_error', $this->trans('usersWithoutEmail', ['%count%' => $usersWithoutEmail], 'admin'));
         }
 
-        if ($nbreModelsToProceed >= 5000) {
-            $this->addFlash('sonata_flash_info', "Trop d'éléments à traiter ! Seulement 5000 ont été traités"); // TODO translate
+        $limit = 5000;
+        if ($nbreModelsToProceed >= $limit) {
+            $this->addFlash('sonata_flash_info', $this->trans('batch.tooMany', ['%limit%' => $limit], 'admin'));
         }
 
         return new RedirectResponse($this->admin->generateUrl('list', $this->admin->getFilterParameters()));
diff --git a/templates/admin/blocks/block_recent_elements.html.twig b/templates/admin/blocks/block_recent_elements.html.twig
index acc1b494a..d8832a5e7 100755
--- a/templates/admin/blocks/block_recent_elements.html.twig
+++ b/templates/admin/blocks/block_recent_elements.html.twig
@@ -1,4 +1,5 @@
 {% extends sonata_block.templates.block_base %}
+{% trans_default_domain 'admin' %}
 
 {% block block %}
 
@@ -16,7 +17,7 @@
                     <a class="list-group-item" href="{{ path('admin_app_element_showEdit', { 'id': element.id }) }}">
                         <span>{{ element.name|capitalize }}</span>
                         <span style="position: absolute;right: 1.5rem;z-index: 5;background-color: white;padding-left: 10px;">
-                            {{ element.updatedAt|date("d/m/Y à H:i") }}
+                            {{ element.updatedAt|date('commons.format'|trans) }}
                         </span>
                     </a>
                 {% else %}
diff --git a/templates/admin/core_custom/custom-fields/display-logs.html.twig b/templates/admin/core_custom/custom-fields/display-logs.html.twig
index 55341a537..1aa2a26b0 100644
--- a/templates/admin/core_custom/custom-fields/display-logs.html.twig
+++ b/templates/admin/core_custom/custom-fields/display-logs.html.twig
@@ -1,3 +1,5 @@
+{% trans_default_domain 'admin' %}
+
 <script>
   var url = "{{ path('gogo_api_log_hide', {'id': 'ID'}) }}";
 
@@ -22,7 +24,7 @@
     {% if dismissLog is defined %}
       <button type="button" class="close" data-dismiss="alert" aria-label="Fermer" onclick="hideLog({{log.id}})"><span aria-hidden="true" style="font-size: 1.6rem">Ne plus afficher</span></button> {# TODO Translation #}
     {% endif %}
-    {% if log.displayTimestamp %}<strong>{{ log.createdAt|date("d/m/Y à H:i") }}</strong> - {% endif %} {# TODO Translation #}
+    {% if log.displayTimestamp %}<strong>{{ log.createdAt|date('commons.format'|trans) }}</strong> - {% endif %} {# TODO Translation #}
     {{ log.displayMessage|raw }}
   </div>
 {% endfor %}
diff --git a/templates/admin/core_custom/custom-fields/element-data.html.twig b/templates/admin/core_custom/custom-fields/element-data.html.twig
index 788098e82..124b43746 100644
--- a/templates/admin/core_custom/custom-fields/element-data.html.twig
+++ b/templates/admin/core_custom/custom-fields/element-data.html.twig
@@ -1,18 +1,20 @@
+{% trans_default_domain 'admin' %}
+
 {% set element = form.vars.sonata_admin.admin.subject %}
 {% set config = form.vars.sonata_admin.admin.config %}
 
 {% if element.isFromOsm %}
-  	<a href={{ element.getOsmUrl(config)  }} target="_blank">Voir cet élément sur OpenStreetMap</a> {# TODO Translation #}
+  	<a href={{ element.getOsmUrl(config)  }} target="_blank">{{ 'core_custom.seeOnOSM'|trans }}</a>
 {% endif %}
 
 {% if element.duplicateOf %}
-  	Cet élément a été fusionné avec un autre :  {# TODO Translation #}
+  	{{ 'core_custom.duplicateOf'|trans }}
     <a href={{ path('admin_app_element_showEdit', {'id': element.duplicateOf})  }} target="_blank">
-      voir l'élément fusionné {# TODO Translation #}
+      {{ 'core_custom.seeDuplicate'|trans }}
     </a>
 {% endif %}
 
-<h4 style="margin-top: 25px;">Champs Personnalisés</h4> {# TODO Translation #}
+<h4 style="margin-top: 25px;">{{ 'core_custom.customFields'|trans }}</h4>
 <div class="table-responsive no-padding element-data-fields">
   <table class="table">
   <tbody>
@@ -47,10 +49,10 @@
   </tbody>
   </table>
   <button type="button" class="btn btn-add-field btn-default btn-sm" @click="addField()">
-    Ajouter un Champ Personnalisé {# TODO Translation #}
+    {{ 'core_custom.addCustomField'|trans }}
   </button>
 </div>
-<h4>Champs Spéciaux</h4> {# TODO Translation #}
+<h4>{{ 'core_custom.specialFields'|trans }}</h4>
 
 <style>
   .element-data-fields th {
@@ -70,6 +72,4 @@
 
 <script>
   var existingProps = {{ form.vars.attr["data-props"]|raw }};
-</script>
-
-
+</script>
\ No newline at end of file
diff --git a/templates/admin/pages/bulks/bulk_abstract.html.twig b/templates/admin/pages/bulks/bulk_abstract.html.twig
index 9005ca4a4..540f2a970 100755
--- a/templates/admin/pages/bulks/bulk_abstract.html.twig
+++ b/templates/admin/pages/bulks/bulk_abstract.html.twig
@@ -2,7 +2,7 @@
 {% trans_default_domain 'admin' %}
 
 {% block breadcrumb %}
-  <li><a href={{ path('gogo_bulk_actions_index') }}>Bulk actions</a></li> {# TODO Translation #}
+  <li><a href={{ path('gogo_bulk_actions_index') }}>{{ 'bulk._label'|trans }}</a></li>
   <li class="active">{{ title }}</li>
 {% endblock breadcrumb %}
 
@@ -11,23 +11,23 @@
 {% block page_content %}
 
   <div style="margin-bottom: 1rem; text-align: center">
-    <h2 style="margin-top: 0;margin-bottom: 20px;">Analyse des éléments de {{ firstId }} à {{ lastId }}</h2> {# TODO Translation #}
+    <h2 style="margin-top: 0;margin-bottom: 20px;">{{ 'bulk.analyse'|trans({'%first%': firstId, '%last%':lastId}) }}</h2>
     
     {% if isStillElementsToProceed %}
-      <a class="btn btn-success" href='{{ redirectionRoute }}'>Continuer à traiter les éléments suivants (encore {{ elementsToProcceedCount }} à traiter)</a> {# TODO Translation #}
+      <a class="btn btn-success" href='{{ redirectionRoute }}'>{{ 'bulk.continue'|trans({'%count%': elementsToProcceedCount}) }}</a>
     {% else %}
-      <div class="alert alert-success">Tous les éléments ont été traités avec succès</div> {# TODO Translation #}
+      <div class="alert alert-success">{{ 'bulk.done'|trans }}</div>
     {% endif %}
   </div>
 
 {% endblock %}
 
 {% block page_content_after %}
-  <h3 style="margin-bottom: 20px">Résultats</h3> {# TODO Translation #}
-  {% set isDuplicateAction = (title == "Détection des doublons") %} {# TODO Translation #}
+  <h3 style="margin-bottom: 20px">{{ 'bulk.results'|trans }}</h3>
+  {% set isDuplicateAction = (title == 'bulk.isDuplicateAction'|trans) %}
   {% if isDuplicateAction %}
-    <a class="btn btn-primary" href={{ path('gogo_duplicates_index') }}>Gérer les doublons détectés</a> {# TODO Translation #}
-    <a class="btn btn-default" href={{ path('gogo_core_bundle_config_duplicates_admin_classname_list') }}>Retour à la gestion des doublons</a> {# TODO Translation #}
+    <a class="btn btn-primary" href={{ path('gogo_duplicates_index') }}>{{ 'bulk.managed'|trans }}</a>
+    <a class="btn btn-default" href={{ path('gogo_core_bundle_config_duplicates_admin_classname_list') }}>{{ 'bulk.return'|trans }}</a>
   {% endif %}
   
   {% for partialView in renderedViews %}
@@ -35,8 +35,8 @@
   {% endfor %}
 
   {% if isDuplicateAction and renderedViews|length %}
-    <a class="btn btn-primary" href={{ path('gogo_duplicates_index') }}>Gérer les doublons détectés</a> {# TODO Translation #}
-    <a class="btn btn-default" href={{ path('gogo_core_bundle_config_duplicates_admin_classname_list') }}>Retour à la gestion des doublons</a> {# TODO Translation #}
+    <a class="btn btn-primary" href={{ path('gogo_duplicates_index') }}>{{ 'bulk.managed'|trans }}</a>
+    <a class="btn btn-default" href={{ path('gogo_core_bundle_config_duplicates_admin_classname_list') }}>{{ 'bulk.return'|trans }}</a>
   {% endif %}
 
   <style>
diff --git a/templates/admin/pages/bulks/bulk_duplicates.html.twig b/templates/admin/pages/bulks/bulk_duplicates.html.twig
index 5935ea35b..ef0e333ef 100755
--- a/templates/admin/pages/bulks/bulk_duplicates.html.twig
+++ b/templates/admin/pages/bulks/bulk_duplicates.html.twig
@@ -1,6 +1,8 @@
+{% trans_default_domain 'admin' %}
+
 <div class="bs-callout {{ automaticMerge ? 'bs-callout-success' : 'bs-callout-warning' }} bulk-duplicate">
 
-    <h4>{{ automaticMerge ? "Fusion automatique" : "Doublons potentiels détectés" }}</h4> {# TODO Translation #}
+    <h4>{{ automaticMerge ? 'bulk.automaticMerge'|trans : 'bulk.manualMerge'|trans }}</h4>
 
     {% for duplicate in duplicates %}
         <li>
@@ -11,9 +13,9 @@
 
             {% if automaticMerge %}
               {% if loop.first %}
-                <span class="label label-success">Doublon Conservé</span> {# TODO Translation #}
+                <span class="label label-success">{{ 'bulk.duplicateKept'|trans }}</span>
               {% else %}
-                <span class="label label-default">Doublon Supprimé</span> {# TODO Translation #}
+                <span class="label label-default">{{ 'bulk.duplicateDeleted'|trans }}</span>
               {% endif %}
             {% endif %}
 
@@ -38,9 +40,4 @@
     margin-left: 10px;
     margin-right: 0;
   }
-</style>
-
-
-
-
-
+</style>
\ No newline at end of file
diff --git a/templates/admin/partials/display_vote_report_item.html.twig b/templates/admin/partials/display_vote_report_item.html.twig
index d67939974..53bfc96c7 100755
--- a/templates/admin/partials/display_vote_report_item.html.twig
+++ b/templates/admin/partials/display_vote_report_item.html.twig
@@ -1,3 +1,5 @@
+{% trans_default_domain 'admin' %}
+
 {% set userRoles = {
   0: "Anonyme",
   1: 'Anonyme avec mail',
@@ -12,7 +14,7 @@
 <div {% if not loop.last and not itemContainer|default(true) %}class="item-container"{% endif %}>
 	<div style="margin-bottom:5px">
     <span class="label {{ labelClass }}">{{ itemValues[item.value] }}</span> 
-    <div style="float:right">{{ item.createdAt|date("d/m/Y à H:i")}}</div> {# TODO Translation #}
+    <div style="float:right">{{ item.createdAt|date('commons.format'|trans)}}</div>
     {% if smallWidth|default(false) %}
       </br>
       <span style="display:block;padding-top: 5px;">
diff --git a/templates/admin/partials/show_one_contribution.html.twig b/templates/admin/partials/show_one_contribution.html.twig
index 4a932f9ce..305938a34 100755
--- a/templates/admin/partials/show_one_contribution.html.twig
+++ b/templates/admin/partials/show_one_contribution.html.twig
@@ -1,52 +1,56 @@
+{% trans_default_domain 'message' %}
+
 {% set contributionType = {
-	'-1': "Suppression",
-	0: "Ajout",
-	1: 'Modification',
-	2: "Vote",
-	3: "Signalement",
-	4: "Import",
-	5: "Restauration",
-	6: "Resolution modération"
+	'-1': 'commons.contributionType.t-1'|trans,
+	0:    'commons.contributionType.t0'|trans,
+	1:    'commons.contributionType.t1'|trans,
+	2:    'commons.contributionType.t2'|trans,
+	3:    'commons.contributionType.t3'|trans,
+	4:    'commons.contributionType.t4'|trans,
+	5:    'commons.contributionType.t5'|trans,
+	6:    'commons.contributionType.t6'|trans,
 	}
-%} {# TODO Translation #}
+%}
 
 {% set elementStatus = {
-	'' : 'En attente',
-	'-6': "Doublon",
-	'-5': "modified pending",
-	'-4': 'Supprimé',
-	'-3': 'Refusé (votes) ',
-	'-2': 'Refusé (admin)',
-	'-1': 'En attente (modifs)',
-	 0: 'En attente (ajout)',
-	 1: 'Validé (admin)',
-	 2: 'Validé (votes)',
-	 3: 'Ajouté par admin',
-	 4: 'Modifié par admin',
-	 5: 'Modifié par propriétaire',
-	 6: 'Modifié avec lien direct',
-	 7: 'Importé',
+	'' :  'commons.elementStatus.s'|trans,
+	'-6': 'commons.elementStatus.s-6'|trans,
+	'-5': 'commons.elementStatus.s-5'|trans,
+	'-4': 'commons.elementStatus.s-4'|trans,
+	'-3': 'commons.elementStatus.s-3'|trans,
+	'-2': 'commons.elementStatus.s-2'|trans,
+	'-1': 'commons.elementStatus.s-1'|trans,
+	0:   'commons.elementStatus.s0'|trans,
+	1:   'commons.elementStatus.s1'|trans,
+	2:   'commons.elementStatus.s2'|trans,
+	3:   'commons.elementStatus.s3'|trans,
+	4:   'commons.elementStatus.s4'|trans,
+	5:   'commons.elementStatus.s5'|trans,
+	6:   'commons.elementStatus.s6'|trans,
+	7:   'commons.elementStatus.s7'|trans,
 	}
-%} {# TODO Translation #}
-
+%}
+  
 {% set userRoles = {
-	0: "Anonyme",
-	1: 'Anonyme avec mail',
-	2: "Utilisateur loggué",
-	3: "Admin",
-	4: 'Anonyme avec lien',
-	5: 'GoGoBot'
+	0: 'commons.userRoles.r0'|trans,
+	1: 'commons.userRoles.r1'|trans,
+	2: 'commons.userRoles.r2'|trans,
+	3: 'commons.userRoles.r3'|trans,
+	4: 'commons.userRoles.r4'|trans,
+	5: 'commons.userRoles.r5'|trans,
 	}
-%} {# TODO Translation #}
+%}
 
 {% set itemValues = {
-	'-2': 'Ne respecte pas la charte',
-	'-1': "N'existe pas",
-	'0': 'Existe mais infos mauvaises',
-	'1': 'Existe',
-	'2': 'Existe et valide info'
+	'-2': 'commons.userRoles.v-2'|trans,
+	'-1': 'commons.userRoles.v-1'|trans,
+	0: 'commons.userRoles.v0'|trans,
+	1: 'commons.userRoles.v1'|trans,
+	2: 'commons.userRoles.v2'|trans,
 	}
-%} {# TODO Translation #}
+%}
+
+{% trans_default_domain 'admin' %}
 
 {% if value and (not value.isResolved or showResolved|default(false))%}
 	<div class="panel-heading {{ value.votes|length > 0 ? 'body-content' : ''}}" role="tab" id="heading{{value.id}}" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse{{value.id}}" aria-expanded="true" aria-controls="collapse{{value.id}}">
@@ -57,7 +61,7 @@
 					par <u>{{ value.getUserDisplayName }}</u>
 					<span class="label label-default">{{ userRoles[value.userRole] }}</span>
 					<span><i>{{ value.resolvedMessage}}</i><span>
-					<div style="float:right">{{ value.updatedAt|date("d/m/Y à H:i")}}</div> {# TODO Translation #}
+					<div style="float:right">{{ value.updatedAt|date('commons.format'|trans)}}</div>
 			</div>
 		{% else %}
 			<div class="small-margin">
@@ -67,14 +71,14 @@
 					{% if value.resolvedBy %}<span>(<u>{{value.resolvedBy }}</u>)</span>{% endif %}
 
 					{% if showResolved|default(false) %}
-						<div style="float:right">{{ value.updatedAt|date("d/m/Y à H:i")}}</div> {# TODO Translation #}
+						<div style="float:right">{{ value.updatedAt|date('commons.format'|trans)}}</div>
 					{% endif %}
 			</div>
 
 			<div class="small-margin">
-				Proposé par <u>{{ value.getUserDisplayName }}</u>
+				{{ 'xx'|trans({'%name%': value.getUserDisplayName})|raw }}
 				<span class="label label-default">{{ userRoles[value.userRole] }}</span>
-				le {{ value.createdAt|date("d/m/Y à H:i")}} {# TODO Translation #}
+				{{ 'xy'|trans({'%date%': value.createdAt|date('commons.format'|trans)}) }}
 			</div>
 		{% endif %}
 
diff --git a/translations/admin+intl-icu.fr.yaml b/translations/admin+intl-icu.fr.yaml
index 2749c2e0f..5bb3aa4f4 100644
--- a/translations/admin+intl-icu.fr.yaml
+++ b/translations/admin+intl-icu.fr.yaml
@@ -147,14 +147,21 @@ elements:
     sourceKey: "Source"
     optionsString: "Catégories"
     moderationState: "Modération"
-    # Votes ??
-    # Action ??
-
+    userOwnerEmail: "Email de l'utilisateur propriétaire de cette fiche"
+    email: "Email de l'élément"
+    id: "ID"
+    randomHash: "Hâchage aléatoire"
+    oldId: "Id dans la base de données importée"
+    createdAt: "Créé le"
+    reports: "Signalements"
+    optionIds: "Catégories"
   form:
     groups:
-      general: "Informations générales"
+      #general: "Informations générales"
+      general: "Général"
       localisation: "Localisation"
-    optionIds: "Catégories"
+      otherInfos: "Autre infos"
+      moderation: "Modération"
 
   address:
     streetAddress: "Rue"
@@ -542,9 +549,13 @@ webhooks:
 
 commons:
   btn_update_and_edit: "Mettre à jour"
+  format: "d/m/Y à H:i" # TODO use local ?? 
   fields:
     image_placeholder: "Sélectionnez une image déjà importée, ou ajoutez en une !"
 
+xx: "Proposé par <u>{name}</u>"
+xy: "le {date}"
+
 config_general:
   _label: "Configuration Générale"
   fields:
@@ -637,7 +648,6 @@ option_hidden:
 
 news:
   _label: "Actualités (newsletter)"
-  format: "d/m/Y à H:i" # TODO use local ?? 
   fields:
     title: "Titre"
     publicationDate: "Date de publication"
@@ -701,7 +711,8 @@ batch:
                               =1 {# mail n'a pas pu être envoyé car aucune adresse mail n'était renseignée}
                               other {# mails n'ont pas pu être envoyé car aucune adresse mail n'était renseignée}
                       }"
-
+  tooMany: "Trop d'éléments à traiter ! Seulement {limit} ont été traités"
+  error: "ERREUR : {message}"
 
 config_users:
   _label: Configuration
@@ -737,6 +748,18 @@ bulk:
                   =1 {# utilisateur a été mis à jour}
                   other {# utilisateurs ont été mis à jour}
                }"
+  detectDuplicatesAction: "Détection des doublons"
+  analyse: "Analyse des éléments de {first} à {last}"
+  continue: "Continuer à traiter les éléments suivants (encore {count} à traiter)"
+  done: "Tous les éléments ont été traités avec succès"
+  results: "Résultats"
+  isDuplicateAction: "Détection des doublons"
+  managed: "Gérer les doublons détectés"
+  return: "Retour à la gestion des doublons"
+  automaticMerge: "Fusion automatique"
+  manualMerge: "Doublons potentiels détectés"
+  duplicateKept: "Doublon Conservé"
+  duplicateDeleted: "Doublon Supprimé"
 
 help:
   _label: "Aide"
@@ -744,4 +767,12 @@ help:
 
 saas:
   list: "Liste des Projets"
-  config: "Configuration"
\ No newline at end of file
+  config: "Configuration"
+
+  core_custom:
+    seeOnOSM: "Voir cet élément sur OpenStreetMap"
+    customFields: "Champs Personnalisés"
+    duplicateOf: "Cet élément a été fusionné avec un autre :"
+    seeDuplicate: "voir l'élément fusionné"
+    addCustomField: "Ajouter un Champ Personnalisé"
+    specialFields: "Champs Spéciaux"
\ No newline at end of file
diff --git a/translations/messages+intl-icu.fr.yaml b/translations/messages+intl-icu.fr.yaml
index 9511581ca..795cbebda 100644
--- a/translations/messages+intl-icu.fr.yaml
+++ b/translations/messages+intl-icu.fr.yaml
@@ -134,12 +134,6 @@ votes:
   date: Date
   status: Status
   empty: Vous n'avez pas encore voté ! ! Et alors, faut vous y mettre :) </br>Les votes permettent la modération collaborative !
-  voteValues:
-    v-2: Ne respecte pas la charte'
-    v-1: N'existe pas
-    v0: Existe mais infos mauvaises
-    v1: Existe
-    v2: Existe et valide info
 
 reports:
   _label: Mes Signalements
@@ -231,64 +225,88 @@ commons:
     too_long: Oups, ce texte est un peu long !
 
   elementStatus:
-    s:    En attente
-    s-6:  Doublon
-    s-5:  modifié en attente
-    s-4:  Supprimé
-    s-3:  Refusé (votes)
-    s-2:  Refusé (admin)
-    s-1:  En attente (modifs)
-    s0:   En attente (ajout)
-    s1:   Validé (admin)
-    s2:   Validé (votes)
-    s3:   Ajouté par admin
-    s4:   Modifié par admin
-    s5:   Modifié par propriétaire
-    s6:   Modifié avec lien direct
-    s7:   Importé
+    s:    "En attente"
+    s-6:  "Doublon"
+    s-5:  "Modifié en attente"
+    s-4:  "Supprimé"
+    s-3:  "Refusé (votes)"
+    s-2:  "Refusé (admin)"
+    s-1:  "En attente (modifs)"
+    s0:   "En attente (ajout)"
+    s1:   "Validé (admin)"
+    s2:   "Validé (votes)"
+    s3:   "Ajouté par admin"
+    s4:   "Modifié par admin"
+    s5:   "Modifié par propriétaire"
+    s6:   "Modifié avec lien direct"
+    s7:   "Importé"
 
   contributionType:
-    t-1:  Suppression
-    t0:   Ajout
-    t1:   Modif
-    t2:   Vote
-    t3:   Signalement
-    t4:   Import
-    t5:   Restauration
-    t6:   Résolution modération
+    t-1:  "Suppression"
+    t0:   "Ajout"
+    t1:   "Modif"
+    t2:   "Vote"
+    t3:   "Signalement"
+    t4:   "Import"
+    t5:   "Restauration"
+    t6:   "Résolution modération"
+
+  userRoles:
+    r0: "Anonyme"
+    r1: "Anonyme avec mail"
+    r2: "Utilisateur identifié"
+    r3: "Admin"
+    r4: "Anonyme avec lien"
+    r5: "GoGoBot"
+
+  voteValues:
+    v-2: "Ne respecte pas la charte"
+    v-1: "N'existe pas"
+    v0: "Existe mais infos mauvaises"
+    v1: "Existe"
+    v2: "Existe et valide info"
+
+  moderationChoices:
+    c-2: "Erreur geolocalisation"
+    c-1: "Aucune catégorie renseignée"
+    c0: "Pas de modération nécessaire"
+    c1: "Erreurs signalées"
+    c2: "Votes non consensuels"
+    c3: "En attente depuis trop longtemps"
+    c4: "Doublon potentiel"
 
 errors: # TODO erreurs ajax
-  e1: Les identifiants de connexion ne sont pas corrects
-  e2: Une erreur s'est produite lors de la tentative de connexion
+  e1: "Les identifiants de connexion ne sont pas corrects"
+  e2: "Une erreur s'est produite lors de la tentative de connexion"
 
 # If some messages are reused over differents pages
 action:
-  search: Rechercher # just an example, can be deleted
-  submit: Enregistrer
-  geolocalize_me: Géolocaliser ma position # TODO doublon avec home.geolocalize ??
-  create: Créer
-  send: Envoyer
-  send_stay: Envoyer et rester sur le formulaire
-  cancel: Annuler
-  continue: Continuer
+  search: "Rechercher" # just an example, can be deleted
+  submit: "Enregistrer"
+  geolocalize_me: "Géolocaliser ma position" # TODO doublon avec home.geolocalize ??
+  create: "Créer"
+  send: "Envoyer"
+  send_stay: "Envoyer et rester sur le formulaire"
+  cancel: "Annuler"
+  continue: "Continuer"
   error: "Erreur : {message}"
   element: # element controller
     vote:
       unallowed: "Désolé, vous n'êtes pas autorisé à voter !"
-      uncomplete: Les paramètres du vote sont incomplets
+      uncomplete: "Les paramètres du vote sont incomplets"
     report:
       unallowed: "Désolé, vous n'êtes pas autorisé à signaler d'erreurs !"
-      done: Merci, votre signalement a bien été enregistré !
+      done: "Merci, votre signalement a bien été enregistré !"
     delete:
       unallowed: "Désolé, vous n'êtes pas autorisé à supprimer un élément !"
-      uncomplete: Les paramètres sont incomplets
+      uncomplete: "Les paramètres sont incomplets"
       done: "L'élément a bien été supprimé"
     resolveReports:
       unallowed: "Désolé, vous n'êtes pas autorisé à modérer cet élément !"
-      uncomplete: Les paramètres sont incomplets
+      uncomplete: "Les paramètres sont incomplets"
       done: "L'élément a bien été modéré"
     sendMail:
-      uncomplete: Les paramètres sont incomplets
+      uncomplete: "Les paramètres sont incomplets"
       mailSubject: 'Message reçu depuis la plateforme {instance}'
       mailContent: '<p>Bonjour <i>{element}</i>,</p>
             <p>Vous avez reçu un message de la part de <a href="mailto:{sender}">{sender}</a></br>
@@ -298,17 +316,17 @@ action:
       done: "L'email a bien été envoyé"
     stamp:
       unallowed: "Vous n'êtes pas autorisé à utiliser cette étiquette"
-      uncomplete: Les paramètres sont incomplets
+      uncomplete: "Les paramètres sont incomplets"
       done: "L'étiquette a bien été modifiée"
   mailtest:
     draftAutomated:
-      uncomplete: No visible elements in database, please create an element
+      uncomplete: "No visible elements in database, please create an element" # TODO translation
     sentTestAutomated:
       uncomplete: "Aucune adresse mail n'a été renseignée"
-      database_empty: No elements in database, please create an element for email testing
-      done: 'Le mail a bien été envoyé à {mail}</br>Si vous ne le voyez pas vérifiez dans vos SPAMs'
+      database_empty: "No elements in database, please create an element for email testing" # TODO translation
+      done: "Le mail a bien été envoyé à {mail}</br>Si vous ne le voyez pas vérifiez dans vos SPAMs"
     draftTest:
-      done: 'Un customMessage de test'
+      done: "Un customMessage de test"
 
 
 directory: # just an example, can be deleted
-- 
GitLab