Merge pull request #5507 from betagouv/i18n-tasks

This commit is contained in:
Pierre de La Morinerie 2021-02-04 12:24:23 +01:00 committed by GitHub
commit 82743d7da3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 175 additions and 64 deletions

View file

@ -40,6 +40,7 @@ gem 'groupdate'
gem 'haml-rails'
gem 'hashie'
gem 'http_accept_language'
gem 'i18n-tasks'
gem 'iban-tools'
gem 'image_processing'
gem 'json_schemer'

View file

@ -340,6 +340,7 @@ GEM
hana (1.3.7)
hashdiff (1.0.1)
hashie (4.1.0)
highline (2.0.3)
html2haml (2.2.0)
erubis (~> 2.7.0)
haml (>= 4.0, < 6)
@ -354,6 +355,16 @@ GEM
httpclient (2.8.3)
i18n (1.8.7)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.33)
activesupport (>= 4.0.2)
ast (>= 2.1.0)
erubi
highline (>= 2.0.0)
i18n
parser (>= 2.2.3.0)
rails-i18n
rainbow (>= 2.2.2, < 4.0)
terminal-table (>= 1.5.1)
iban-tools (1.1.0)
ice_nine (0.11.2)
image_processing (1.12.1)
@ -722,6 +733,8 @@ GEM
httpclient (>= 2.4)
sysexits (1.2.0)
temple (0.8.2)
terminal-table (3.0.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thor (1.1.0)
thread_safe (0.3.6)
tilt (2.0.10)
@ -843,6 +856,7 @@ DEPENDENCIES
haml-rails
hashie
http_accept_language
i18n-tasks
iban-tools
image_processing
json_schemer

View file

@ -118,6 +118,7 @@ Pour exécuter les tests de l'application, plusieurs possibilités :
Le projet utilise plusieurs linters pour vérifier la lisibilité et la qualité du code.
- Faire tourner tous les linters : `bin/rake lint`
- Vérifier l'état des traductions : `bundle exec i18n-tasks health`
- [AccessLint](http://accesslint.com/) tourne automatiquement sur les PRs
### Régénérer les binstubs

View file

@ -11,15 +11,18 @@ class Champs::SiretController < ApplicationController
end
if !Siret.new(siret: @siret).valid?
# i18n-tasks-use t('errors.messages.invalid_siret')
return siret_error(:invalid)
end
begin
etablissement = find_etablissement_with_siret
rescue ApiEntreprise::API::Error::RequestFailed, ApiEntreprise::API::Error::ServiceUnavailable
# i18n-tasks-use t('errors.siret_network_error')
return siret_error(:network_error)
end
if etablissement.nil?
# i18n-tasks-use t('errors.messages.siret_not_found')
return siret_error(:not_found)
end

View file

@ -14,6 +14,12 @@ module ProcedureHelper
end
def procedure_publish_text(procedure, key)
# i18n-tasks-use t('modal.publish.body.publish')
# i18n-tasks-use t('modal.publish.body.reopen')
# i18n-tasks-use t('modal.publish.submit.publish')
# i18n-tasks-use t('modal.publish.submit.reopen')
# i18n-tasks-use t('modal.publish.title.publish')
# i18n-tasks-use t('modal.publish.title.reopen')
action = procedure.close? ? :reopen : :publish
t(action, scope: [:modal, :publish, key])
end

View file

@ -22,6 +22,7 @@ class Champs::IntegerNumberChamp < Champ
allow_nil: true,
allow_blank: true,
message: -> (object, _data) {
# i18n-tasks-use t('errors.messages.not_an_integer')
"« #{object.libelle} » " + object.errors.generate_message(:value, :not_an_integer)
}
}

View file

@ -8,6 +8,7 @@
- when :network_error
= t('errors.messages.siret_network_error')
-# i18n-tasks-use t('errors.messages.siret_network_error')
- else
- if siret.present? && siret == etablissement&.siret

136
config/i18n-tasks.yml Normal file
View file

@ -0,0 +1,136 @@
# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks
# The "main" locale.
base_locale: fr
## All available locales are inferred from the data by default. Alternatively, specify them explicitly:
# locales: [es, fr]
## Reporting locale, default: en. Available: en, ru.
# internal_locale: en
# Read and write translations.
data:
## Translations are read from the file system. Supported format: YAML, JSON.
## Provide a custom adapter:
# adapter: I18n::Tasks::Data::FileSystem
# Locale files or `File.find` patterns where translations are read from:
read:
- config/locales/*%{locale}.yml
- config/locales/**/*%{locale}.yml
# Locale files to write new keys to, based on a list of key pattern => file rules. Matched from top to bottom:
# `i18n-tasks normalize -p` will force move the keys according to these rules
write:
## For example, write devise and simple form keys to their respective files:
# - ['{devise, simple_form}.*', 'config/locales/\1.%{locale}.yml']
## Catch-all default:
# - config/locales/%{locale}.yml
# External locale data (e.g. gems).
# This data is not considered unused and is never written to.
external:
## Example (replace %#= with %=):
# - "<%#= %x[bundle show vagrant].chomp %>/templates/locales/%{locale}.yml"
## Specify the router (see Readme for details). Valid values: conservative_router, pattern_router, or a custom class.
# router: conservative_router
yaml:
write:
# do not wrap lines at 80 characters
line_width: -1
## Pretty-print JSON:
# json:
# write:
# indent: ' '
# space: ' '
# object_nl: "\n"
# array_nl: "\n"
# Find translate calls
search:
## Paths or `File.find` patterns to search in:
# paths:
# - app/
## Root directories for relative keys resolution.
# relative_roots:
# - app/controllers
# - app/helpers
# - app/mailers
# - app/presenters
# - app/views
## Files or `File.fnmatch` patterns to exclude from search. Some files are always excluded regardless of this setting:
## %w(*.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
exclude:
- app/assets/images
- app/assets/fonts
- app/assets/videos
## Alternatively, the only files or `File.fnmatch patterns` to search in `paths`:
## If specified, this settings takes priority over `exclude`, but `exclude` still applies.
# only: ["*.rb", "*.html.slim"]
## If `strict` is `false`, guess usages such as t("categories.#{category}.title"). The default is `true`.
# strict: true
## Multiple scanners can be used. Their results are merged.
## The options specified above are passed down to each scanner. Per-scanner options can be specified as well.
## See this example of a custom scanner: https://github.com/glebm/i18n-tasks/wiki/A-custom-scanner-example
## Translation Services
# translation:
# # Google Translate
# # Get an API key and set billing info at https://code.google.com/apis/console to use Google Translate
# google_translate_api_key: "AbC-dEf5"
# # DeepL Pro Translate
# # Get an API key and subscription at https://www.deepl.com/pro to use DeepL Pro
# deepl_api_key: "48E92789-57A3-466A-9959-1A1A1A1A1A1A"
## Do not consider these keys missing:
# ignore_missing:
# - 'errors.messages.{accepted,blank,invalid,too_short,too_long}'
# - '{devise,simple_form}.*'
## Consider these keys used:
ignore_unused:
- 'activerecord.attributes.*'
- 'activerecord.errors.*'
- 'errors.messages.blank'
- 'pluralize.*'
- 'views.pagination.*'
- 'time.formats.default'
# - '{devise,kaminari,will_paginate}.*'
# - 'simple_form.{yes,no}'
# - 'simple_form.{placeholders,hints,labels}.*'
# - 'simple_form.{error_notification,required}.:'
## Exclude these keys from the `i18n-tasks eq-base' report:
# ignore_eq_base:
# all:
# - common.ok
# fr,es:
# - common.brand
## Exclude these keys from the `i18n-tasks check-consistent-interpolations` report:
# ignore_inconsistent_interpolations:
# - 'activerecord.attributes.*'
## Ignore these keys completely:
# ignore:
# - kaminari.*
## Sometimes, it isn't possible for i18n-tasks to match the key correctly,
## e.g. in case of a relative key defined in a helper method.
## In these cases you can use the built-in PatternMapper to map patterns to keys, e.g.:
#
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
# only: %w(*.html.haml *.html.slim),
# patterns: [['= title\b', '.page_title']] %>
#
# The PatternMapper can also match key literals via a special %{key} interpolation, e.g.:
#
# <%# I18n::Tasks.add_scanner 'I18n::Tasks::Scanners::PatternMapper',
# patterns: [['\bSpree\.t[( ]\s*%{key}', 'spree.%{key}']] %>

View file

@ -36,16 +36,6 @@ en:
first: First
truncate: '&hellip;'
# mail:
# administration:
# dossier_expiration_summary:
# expired_dossiers:
# one: "Un dossier a passé sa date limite de conservation"
# other: "%{count} dossiers ont passé leur date limite de conservation"
# expiring_dossiers:
# one: "Un dossier est sur le point de passer sa date limite de conservation"
# other: "%{count} dossiers sont sur le point de passer leur date limite de conservation"
modal:
publish:
title:
@ -61,7 +51,7 @@ en:
activerecord:
attributes:
user:
siret: 'Numéro SIRET'
siret: 'SIRET number'
password: 'password'
instructeur:
password: 'password'
@ -100,38 +90,25 @@ en:
path:
taken: is already used for procedure. You cannot use it because it belongs to another administrator.
# taken_can_be_claimed: est identique à celui dune autre de vos procedures publiées. Si vous publiez cette procedure, lancienne sera dépubliée et ne sera plus accessible au public. Les utilisateurs qui ont commencé un brouillon vont pouvoir le déposer.
invalid: is not valid. It must countain between 3 and 50 characters among a-z, 0-9, '_' et '-'.
invalid: is not valid. It must countain between 3 and 50 characters among a-z, 0-9, '_' and '-'.
errors:
messages:
# already_confirmed: "a déjà été validé(e), veuillez essayer de vous connecter"
# confirmation_period_expired: "à confirmer dans les %{period}, merci de faire une nouvelle demande"
# expired: "a expiré, merci den faire une nouvelle demande"
not_found: "was not found"
not_locked: "was not locked"
not_saved:
one: "1 error prevented this %{resource} from being saved :"
other: "%{count} errors prevented this %{resource} from being saved :"
dossier_not_found: "The file does not exist or you do not have access to it."
dossier_map_not_activated: "The file does not have access to the map."
# # dossier_map_not_activated: "The file does not have access to the map."
invalid_siret: "The SIRET is incorrect"
procedure_not_found: "The procedure does not exist"
siret_unknown: 'Sorry, we did not find any establishment registered under this SIRET number.'
# siret_network_error: 'Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.'
# etablissement_fail: 'Désolé, nous navons pas réussi à enregistrer létablissement correspondant à ce numéro SIRET'
siret_network_error: 'Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.'
siret_not_found: 'Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.'
# # etablissement_fail: 'Désolé, nous navons pas réussi à enregistrer létablissement correspondant à ce numéro SIRET'
france_connect:
connexion: "Error trying to connect to France Connect."
procedure_archived: "This procedure has been closed, it is no longer possible to submit a file."
procedure_not_draft: "THis procedure is not a draft anymore."
# # procedure_not_draft: "This procedure is not a draft anymore."
# cadastres_empty:
# one: "Aucune parcelle cadastrale sur la zone sélectionnée"
# other: "Aucune parcelle cadastrale sur les zones sélectionnées"
# quartiers_prioritaires_empty:
# one: "Aucun quartier prioritaire sur la zone sélectionnée"
# other: "Aucun quartier prioritaire sur les zones sélectionnées"
# parcelles_agricoles_empty:
# one: "Aucune parcelle agricole sur la zone sélectionnée"
# other: "Aucune parcelle agricole sur les zones sélectionnées"
not_an_integer: "must be an integer (without decimal)"
blank: "can't be blank"

View file

@ -36,16 +36,6 @@ fr:
first: Premier
truncate: '&hellip;'
mail:
administration:
dossier_expiration_summary:
expired_dossiers:
one: "Un dossier a passé sa date limite de conservation"
other: "%{count} dossiers ont passé leur date limite de conservation"
expiring_dossiers:
one: "Un dossier est sur le point de passer sa date limite de conservation"
other: "%{count} dossiers sont sur le point de passer leur date limite de conservation"
modal:
publish:
title:
@ -114,34 +104,21 @@ fr:
errors:
messages:
saml_not_authorized: "Vous n'êtes pas autorisé à accéder à ce service."
already_confirmed: "a déjà été validé(e), veuillez essayer de vous connecter"
confirmation_period_expired: "à confirmer dans les %{period}, merci de faire une nouvelle demande"
expired: "a expiré, merci den faire une nouvelle demande"
not_found: "na pas été trouvé(e)"
not_locked: "nétait pas verrouillé(e)"
not_saved:
one: "1 erreur a empêché ce(tte) %{resource} dêtre sauvegardé(e) :"
other: "%{count} erreurs ont empêché ce(tte) %{resource} dêtre sauvegardé(e) :"
dossier_not_found: "Le dossier nexiste pas ou vous ny avez pas accès."
dossier_map_not_activated: "Le dossier na pas accès à la cartographie."
# dossier_map_not_activated: "Le dossier na pas accès à la cartographie."
invalid_siret: "Le siret est incorrect"
procedure_not_found: "La démarche nexiste pas"
siret_unknown: 'Désolé, nous navons pas trouvé détablissement enregistré correspondant à ce numéro SIRET.'
siret_network_error: 'Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.'
etablissement_fail: 'Désolé, nous navons pas réussi à enregistrer létablissement correspondant à ce numéro SIRET'
siret_not_found: 'Nous navons pas trouvé détablissement correspondant à ce numéro de SIRET.'
# etablissement_fail: 'Désolé, nous navons pas réussi à enregistrer létablissement correspondant à ce numéro SIRET'
france_connect:
connexion: "Erreur lors de la connexion à France Connect."
procedure_archived: "Cette démarche en ligne a été close, il nest plus possible de déposer de dossier."
procedure_not_draft: "Cette démarche nest maintenant plus en brouillon."
# procedure_not_draft: "Cette démarche nest maintenant plus en brouillon."
cadastres_empty:
one: "Aucune parcelle cadastrale sur la zone sélectionnée"
other: "Aucune parcelle cadastrale sur les zones sélectionnées"
quartiers_prioritaires_empty:
one: "Aucun quartier prioritaire sur la zone sélectionnée"
other: "Aucun quartier prioritaire sur les zones sélectionnées"
parcelles_agricoles_empty:
one: "Aucune parcelle agricole sur la zone sélectionnée"
other: "Aucune parcelle agricole sur les zones sélectionnées"
not_an_integer: "doit être un nombre entier (sans chiffres après la virgule)"
blank: "doit être rempli"

View file

@ -81,7 +81,7 @@ describe Champs::SiretController, type: :controller do
end
it 'displays a “API is unavailable” error message' do
expect(response.body).to include(I18n.t('errors.messages.siret_network_error'))
expect(response.body).to include('Désolé, la récupération des informations SIRET est temporairement indisponible. Veuillez réessayer dans quelques instants.')
end
end

View file

@ -19,12 +19,6 @@ class AdministrationMailerPreview < ActionMailer::Preview
AdministrationMailer.refuse_admin('bad_admin@pipo.com')
end
def dossier_expiration_summary
expiring_dossiers = [Dossier.new(id: 100, procedure: procedure_1)]
expired_dossiers = [Dossier.new(id: 100, procedure: procedure_2)]
AdministrationMailer.dossier_expiration_summary(expiring_dossiers, expired_dossiers)
end
private
def procedure_1