From 1d18bc3e6d96048aab30dc0a36358baab9c63eb8 Mon Sep 17 00:00:00 2001 From: jpl Date: Wed, 5 Jul 2017 12:20:17 +0200 Subject: Refs#3972: Adding proper link to Calendar on side menu --- app/views/layouts/navigation/_main_nav_left.html.slim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/layouts/navigation/_main_nav_left.html.slim b/app/views/layouts/navigation/_main_nav_left.html.slim index efdb81d9c..c72b61c00 100644 --- a/app/views/layouts/navigation/_main_nav_left.html.slim +++ b/app/views/layouts/navigation/_main_nav_left.html.slim @@ -35,8 +35,8 @@ span Jeux de données = link_to '#', class: 'list-group-item' do span Import - = link_to '#', class: 'list-group-item' do - span Modèle de calendrier + = link_to calendars_path, class: 'list-group-item' do + span Modèles de calendrier = link_to '#', class: 'list-group-item' do span Rapport de contrôle = link_to '#', class: 'list-group-item' do -- cgit v1.2.3 From a78db962d1f25f569ff3e8294cd565137ede92d3 Mon Sep 17 00:00:00 2001 From: af83 Date: Thu, 6 Jul 2017 12:18:31 +0200 Subject: Change wording for clean up + add exclusive dates for between clean up --- app/assets/javascripts/cleanup.coffee | 11 ++++++++--- app/models/clean_up.rb | 10 +++++----- app/views/referentials/show.html.slim | 2 +- config/locales/clean_ups.en.yml | 11 +++++++++++ config/locales/clean_ups.fr.yml | 20 +++++++++++++++----- spec/models/clean_up_spec.rb | 20 +++++++++----------- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/cleanup.coffee b/app/assets/javascripts/cleanup.coffee index 169a006a9..7f6594018 100644 --- a/app/assets/javascripts/cleanup.coffee +++ b/app/assets/javascripts/cleanup.coffee @@ -2,8 +2,13 @@ $(document).on("change", 'input[name="clean_up[date_type]"]', (e) -> type = $(this).val() end_date = $('.cleanup_end_date_wrapper') - if type == 'between' - end_date.removeClass('hidden').show() - else + if type == 'before' + end_date.hide() + $("label[for='clean_up_begin_date_3i']").html("Date de fin de purge"); + else if type == 'after' end_date.hide() + $("label[for='clean_up_begin_date_3i']").html("Date de début de purge"); + else + $("label[for='clean_up_begin_date_3i']").html("Date de début de purge"); + end_date.show() ) diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb index cbcde72f5..75fedc732 100644 --- a/app/models/clean_up.rb +++ b/app/models/clean_up.rb @@ -6,8 +6,8 @@ class CleanUp < ActiveRecord::Base enumerize :date_type, in: %i(between before after) - validates :begin_date, presence: true - validates :date_type, presence: true + validates_presence_of :begin_date, message: :presence + validates_presence_of :date_type, message: :presence after_commit :perform_cleanup, :on => :create def perform_cleanup @@ -30,7 +30,7 @@ class CleanUp < ActiveRecord::Base end def destroy_time_tables_between - time_tables = Chouette::TimeTable.where('end_date <= ? AND start_date >= ?', self.end_date, self.begin_date) + time_tables = Chouette::TimeTable.where('end_date < ? AND start_date > ?', self.end_date, self.begin_date) self.destroy_time_tables(time_tables) end @@ -53,7 +53,7 @@ class CleanUp < ActiveRecord::Base end def destroy_time_tables_dates_between - Chouette::TimeTableDate.in_dates.where('date >= ? AND date <= ?', self.begin_date, self.end_date).destroy_all + Chouette::TimeTableDate.in_dates.where('date > ? AND date < ?', self.begin_date, self.end_date).destroy_all end def destroy_time_tables_periods_before @@ -65,7 +65,7 @@ class CleanUp < ActiveRecord::Base end def destroy_time_tables_periods_between - Chouette::TimeTablePeriod.where('period_start >= ? AND period_end <= ?', self.begin_date, self.end_date).destroy_all + Chouette::TimeTablePeriod.where('period_start > ? AND period_end < ?', self.begin_date, self.end_date).destroy_all end def overlapping_periods diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim index 81cd0ebfd..17ba8ad88 100644 --- a/app/views/referentials/show.html.slim +++ b/app/views/referentials/show.html.slim @@ -70,7 +70,7 @@ = f.input :date_type, as: :radio_buttons, label: false = f.input :begin_date, as: :date, label: t('titles.clean_up.begin_date'),:wrapper_html => { class: 'date smart_date', title: t('titles.clean_up.begin_date') } - = f.input :end_date, as: :date, label: t('titles.clean_up.end_date'), :wrapper_html => { class: 'date cleanup_end_date_wrapper hidden smert_date', title: t('titles.clean_up.end_date') } + = f.input :end_date, as: :date, label: t('titles.clean_up.end_date'), :wrapper_html => { class: 'date cleanup_end_date_wrapper smart_date', title: t('titles.clean_up.end_date'), id: "end_date" } .modal-footer button.btn.btn-link type='button' data-dismiss='modal' Annuler diff --git a/config/locales/clean_ups.en.yml b/config/locales/clean_ups.en.yml index 148362c35..588eb55d5 100644 --- a/config/locales/clean_ups.en.yml +++ b/config/locales/clean_ups.en.yml @@ -22,3 +22,14 @@ en: clean_up: begin_date: "Begin date of clean up" end_date: "End date of clean up" + activerecord: + errors: + models: + clean_up: + attributes: + date_type: + presence: "A clean up must have a date type" + begin_date: + presence: "A clean up must have a begin date" + end_date: + presence: "A clean up must have a end date" diff --git a/config/locales/clean_ups.fr.yml b/config/locales/clean_ups.fr.yml index cb0ce3f1a..001c2b1cb 100644 --- a/config/locales/clean_ups.fr.yml +++ b/config/locales/clean_ups.fr.yml @@ -14,11 +14,21 @@ fr: end_date: "Fin date limite : " titles: clean_up: - begin_date: "Début date de la purge" - end_date: "Fin date de la purge" - + begin_date: "Date de début de la purge" + end_date: "Date de fin de la purge" formtastic: titles: clean_up: - begin_date: "Début date de la purge" - end_date: "Fin date de la purge" + begin_date: "Date de début de la purge" + end_date: "Date de fin de la purge" + activerecord: + errors: + models: + clean_up: + attributes: + date_type: + presence: "Une purge doit avoir un type de renseigné" + begin_date: + presence: "Une purge doit avoir une date de début" + end_date: + presence: "Une purge doit avoir une date de fin" diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb index 4dc692ab2..01440be0e 100644 --- a/spec/models/clean_up_spec.rb +++ b/spec/models/clean_up_spec.rb @@ -2,18 +2,17 @@ require 'rails_helper' RSpec.describe CleanUp, :type => :model do - it { should validate_presence_of(:begin_date) } - it { should validate_presence_of(:date_type) } + it { should validate_presence_of(:date_type).with_message(:presence) } + it { should validate_presence_of(:begin_date).with_message(:presence) } it { should belong_to(:referential) } context '#exclude_dates_in_overlapping_period with :before date_type' do let(:time_table) { create(:time_table) } let(:period) { time_table.periods[0] } - let(:cleaner) { create(:clean_up, date_type: :before) } + let(:cleaner) { create(:clean_up, date_type: :before, begin_date: period.period_end) } it 'should add exclude date into period for overlapping period' do days_in_period = (period.period_start..period.period_end).count - cleaner.begin_date = period.period_end expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change { time_table.dates.where(in_out: false).count @@ -31,11 +30,10 @@ RSpec.describe CleanUp, :type => :model do context '#exclude_dates_in_overlapping_period with :after date_type' do let(:time_table) { create(:time_table) } let(:period) { time_table.periods[0] } - let(:cleaner) { create(:clean_up, date_type: :after) } + let(:cleaner) { create(:clean_up, date_type: :after, begin_date: period.period_start + 1.day) } it 'should add exclude date into period for overlapping period' do days_in_period = (period.period_start..period.period_end).count - cleaner.begin_date = period.period_start + 1.day expect { cleaner.exclude_dates_in_overlapping_period(period) }.to change { time_table.dates.where(in_out: false).count }.by(days_in_period - 2) @@ -72,11 +70,11 @@ RSpec.describe CleanUp, :type => :model do end context '#overlapping_periods' do - let(:cleaner) { create(:clean_up, date_type: :before, end_date: nil) } let(:time_table) { create(:time_table) } + let(:period) { time_table.periods[0] } + let(:cleaner) { create(:clean_up, date_type: :before, begin_date: period.period_start) } it 'should detect overlapping periods' do - cleaner.begin_date = time_table.periods[0].period_start expect(cleaner.overlapping_periods).to include(time_table.periods[0]) end @@ -128,7 +126,7 @@ RSpec.describe CleanUp, :type => :model do it 'should destroy record' do expect{ cleaner.destroy_time_tables_dates_between }.to change { Chouette::TimeTableDate.count - }.by(-time_table.dates.count) + }.by(-time_table.dates.count + 2) end it 'should not destroy record not in range' do @@ -155,7 +153,7 @@ RSpec.describe CleanUp, :type => :model do context '#destroy_time_tables_between' do let!(:time_table) { create(:time_table ) } - let(:cleaner) { create(:clean_up, date_type: :after, begin_date: time_table.start_date, end_date: time_table.end_date) } + let(:cleaner) { create(:clean_up, date_type: :between, begin_date: time_table.start_date - 1.day, end_date: time_table.end_date + 1.day) } it 'should destroy time_tables with validity period in purge range' do expect{ cleaner.destroy_time_tables_between }.to change { @@ -240,7 +238,7 @@ RSpec.describe CleanUp, :type => :model do }.by(-1) end - it 'should not destroy time_tables with end_date > purge begin date' do + it 'should not destroy time_tables with end_date > purge begin_date' do cleaner.begin_date = Date.today expect{ cleaner.destroy_time_tables_before }.to_not change { Chouette::TimeTable.count -- cgit v1.2.3 From 2d26c10de73fd6bfbf575dafee7b72e97844ff6b Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 3 Jul 2017 18:29:41 +0200 Subject: TableBuilderHelper::URL: Inject `current_referential` dependency Turns out the only reason why this code worked before was because the only place I was using `table_builder_2` was for a list of `Referential`s, and there's an explicit check for `item.is_a?(Referential)` that avoids calling `current_referential`. Otherwise, when that `unless` condition passes, we get a failure because `current_referential` can't be found. It can't be found because helper methods are not accessible in this scope (duh). In order to make the referential accessible to the method, require one as an argument. Now we explicitly pass the `current_referential` from places where `#polymorphic_url_parts` is called. Refs #3479 --- app/helpers/table_builder_helper.rb | 5 ++++- app/helpers/table_builder_helper/custom_links.rb | 5 ++++- app/helpers/table_builder_helper/url.rb | 7 +++---- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index b93e9b22b..d748ec33a 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -122,7 +122,10 @@ module TableBuilderHelper if column_is_linkable?(column) # Build a link to the `item` - polymorph_url = URL.polymorphic_url_parts(item) + polymorph_url = URL.polymorphic_url_parts( + item, + current_referential + ) bcont << content_tag(:td, link_to(value, polymorph_url), title: 'Voir') else bcont << content_tag(:td, value) diff --git a/app/helpers/table_builder_helper/custom_links.rb b/app/helpers/table_builder_helper/custom_links.rb index abb907678..39cffd2cd 100644 --- a/app/helpers/table_builder_helper/custom_links.rb +++ b/app/helpers/table_builder_helper/custom_links.rb @@ -31,7 +31,10 @@ module TableBuilderHelper polymorph_url << action end - polymorph_url += URL.polymorphic_url_parts(@obj) + polymorph_url += URL.polymorphic_url_parts( + @obj, + @user_context.context[:referential] + ) end def method_for_action(action) diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb index f60864ac1..894e5ddf8 100644 --- a/app/helpers/table_builder_helper/url.rb +++ b/app/helpers/table_builder_helper/url.rb @@ -1,12 +1,11 @@ module TableBuilderHelper - # Depends on `current_referential`, defined in object controllers class URL - def self.polymorphic_url_parts(item) + def self.polymorphic_url_parts(item, referential) polymorph_url = [] unless item.is_a?(Calendar) || item.is_a?(Referential) - if current_referential - polymorph_url << current_referential + if referential + polymorph_url << referential polymorph_url << item.line if item.respond_to? :line polymorph_url << item.route.line if item.is_a?(Chouette::RoutingConstraintZone) polymorph_url << item if item.respond_to? :line_referential -- cgit v1.2.3 From 205ce7c3fbdb025edc62a74b87d26cc237545f36 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 3 Jul 2017 18:34:58 +0200 Subject: Lines#index: Use new `table_builder_2` Convert the table of Lines to use the new version of the table builder. Update the view with the new calling format of the helper. The controller needs to decorate the `@lines` collection in order to make `#action_links` available to the table builder. Needed to update the "_filters.html.slim" template to call `#human_attribute_name` on the class instead of the collection, because we can't do that on a decorated collection. Refs #3479 --- app/controllers/lines_controller.rb | 9 +++++++ app/views/lines/_filters.html.slim | 8 +++--- app/views/lines/index.html.slim | 50 ++++++++++++++++++++++++++++--------- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/app/controllers/lines_controller.rb b/app/controllers/lines_controller.rb index 1e2056aad..4b6448ce8 100644 --- a/app/controllers/lines_controller.rb +++ b/app/controllers/lines_controller.rb @@ -13,6 +13,15 @@ class LinesController < BreadcrumbController def index @hide_group_of_line = line_referential.group_of_lines.empty? index! do |format| + @lines = ModelDecorator.decorate( + @lines, + with: LineDecorator, + context: { + line_referential: @line_referential, + current_organisation: current_organisation + } + ) + format.html { if collection.out_of_bounds? redirect_to params.merge(:page => 1) diff --git a/app/views/lines/_filters.html.slim b/app/views/lines/_filters.html.slim index a0188f562..0e34b2e4c 100644 --- a/app/views/lines/_filters.html.slim +++ b/app/views/lines/_filters.html.slim @@ -8,19 +8,19 @@ .ffg-row .form-group.togglable - = f.label @lines.human_attribute_name(:network), required: false, class: 'control-label' + = f.label Chouette::Line.human_attribute_name(:network), required: false, class: 'control-label' = f.input :network_id_eq_any, collection: @line_referential.networks.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + "").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'} .form-group.togglable - = f.label @lines.human_attribute_name(:company), required: false, class: 'control-label' + = f.label Chouette::Line.human_attribute_name(:company), required: false, class: 'control-label' = f.input :company_id_eq_any, collection: @line_referential.companies.order(name: :asc), as: :check_boxes, label: false, label_method: lambda{|l| ("" + l.name + "").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'} .form-group.togglable - = f.label @lines.human_attribute_name(:transport_mode), required: false, class: 'control-label' + = f.label Chouette::Line.human_attribute_name(:transport_mode), required: false, class: 'control-label' = f.input :transport_mode_eq_any, collection: sorted_transport_mode, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.line.transport_mode.#{l}") + "").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'} .form-group.togglable - = f.label @lines.human_attribute_name(:transport_submode), required: false, class: 'control-label' + = f.label Chouette::Line.human_attribute_name(:transport_submode), required: false, class: 'control-label' = f.input :transport_submode_eq_any, collection: sorted_transport_submode, as: :check_boxes, label: false, label_method: lambda{|l| ("" + t("enumerize.line.transport_submode.#{l}") + "").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'} .actions diff --git a/app/views/lines/index.html.slim b/app/views/lines/index.html.slim index d3ee46b8a..630d63068 100644 --- a/app/views/lines/index.html.slim +++ b/app/views/lines/index.html.slim @@ -16,18 +16,44 @@ - if @lines.any? .row .col-lg-12 - = table_builder @lines, - { 'ID Codifligne' => Proc.new { |n| n.objectid.local_id }, - :number => 'number', - :name => 'name', - :deactivated => Proc.new{|n| n.deactivated? ? t('false') : t('true')}, - 'networks.name' => Proc.new { |n| n.try(:network).try(:name) }, - 'companies.name' => Proc.new { |n| n.try(:company).try(:name) }, - :transport_mode => Proc.new { |n| n.transport_mode.nil? ? '-' : t("enumerize.line.transport_mode.#{n.try(:transport_mode)}") }, - :transport_submode => Proc.new { |n| n.transport_submode.nil? ? '-' : t("enumerize.line.transport_submode.#{n.try(:transport_submode)}") } }, - [:show, :delete], - [], - 'table has-filter has-search' + = table_builder_2 @lines, + [ \ + TableBuilderHelper::Column.new( \ + name: 'ID Codifligne', \ + attribute: Proc.new { |n| n.objectid.local_id }, \ + sortable: false \ + ), \ + TableBuilderHelper::Column.new( \ + key: :number, \ + attribute: 'number' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :name, \ + attribute: 'name' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :deactivated, \ + attribute: Proc.new{|n| n.deactivated? ? t('false') : t('true')} \ + ), \ + TableBuilderHelper::Column.new( \ + key: 'networks.name', \ + attribute: Proc.new { |n| n.try(:network).try(:name) } \ + ), \ + TableBuilderHelper::Column.new( \ + key: 'companies.name', \ + attribute: Proc.new { |n| n.try(:company).try(:name) } \ + ), \ + TableBuilderHelper::Column.new( \ + key: :transport_mode, \ + attribute: Proc.new { |n| n.transport_mode.nil? ? '-' : t("enumerize.line.transport_mode.#{n.try(:transport_mode)}") } \ + ), \ + TableBuilderHelper::Column.new( \ + key: :transport_submode, \ + attribute: Proc.new { |n| n.transport_submode.nil? ? '-' : t("enumerize.line.transport_submode.#{n.try(:transport_submode)}") } \ + ) \ + ], + links: [:show], + cls: 'table has-filter has-search' = new_pagination @lines, 'pull-right' -- cgit v1.2.3 From 8a2818897911e5b33af6849e2ea648ae6e014eef Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 3 Jul 2017 18:44:29 +0200 Subject: TableBuilderHelper: Fix NoMethodError when `current_referential` undef Certain controllers (`Calendar` and `Referential`) don't define a `#current_referential` method. In those cases, we'd get a `NoMethodError` in this function when calling `#current_referential`. To avoid the error, give `current_referential` a default value. Using a default of `nil` works here because the current referential is needed in other places in order to build links. Since the links in the special models don't need a referential in order to be built, we don't care that the value is `nil`. Refs #3479 --- app/helpers/table_builder_helper.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index d748ec33a..1ddd629f8 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -104,6 +104,10 @@ module TableBuilderHelper end def tbody(collection, columns, selectable, links) + # Certain controllers don't define a `#current_referential`. If the method + # is unavailable, give it a default value to avoid a `NoMethodError`. + current_referential ||= nil + content_tag :tbody do collection.map do |item| -- cgit v1.2.3 From 74e94da83d6ea64dcb1e70e69c2fef046453e4a1 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Thu, 6 Jul 2017 10:51:00 +0200 Subject: TableBuilderHelper: Fix specs which mock `current_referential` These two specs were failing because of the line: current_referential ||= nil which would set `current_referential` to `nil` even after updating the object being stubbed to `helper`. Change the specs to stub the method on the correct object now that `TableBuilderHelper::URL` doesn't depend on `current_referential`. Update the faulty line in question to not clobber `current_referential`, but still give us the `nil` value we were looking for when the helper method isn't defined. Refs #3479 --- app/helpers/table_builder_helper.rb | 8 ++++---- spec/helpers/table_builder_helper_spec.rb | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 1ddd629f8..e1b8b406d 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -104,9 +104,9 @@ module TableBuilderHelper end def tbody(collection, columns, selectable, links) - # Certain controllers don't define a `#current_referential`. If the method - # is unavailable, give it a default value to avoid a `NoMethodError`. - current_referential ||= nil + # Certain controllers don't define a `#current_referential`. In these + # cases, avoid a `NoMethodError`. + referential = current_referential if respond_to?(:current_referential) content_tag :tbody do collection.map do |item| @@ -128,7 +128,7 @@ module TableBuilderHelper # Build a link to the `item` polymorph_url = URL.polymorphic_url_parts( item, - current_referential + referential ) bcont << content_tag(:td, link_to(value, polymorph_url), title: 'Voir') else diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb index 67980fc2c..d90c14204 100644 --- a/spec/helpers/table_builder_helper_spec.rb +++ b/spec/helpers/table_builder_helper_spec.rb @@ -176,7 +176,7 @@ describe TableBuilderHelper, type: :helper do referential: referential ) allow(helper).to receive(:current_user).and_return(user_context) - allow(TableBuilderHelper::URL).to receive(:current_referential) + allow(helper).to receive(:current_referential) .and_return(referential) companies = [company] @@ -284,7 +284,7 @@ describe TableBuilderHelper, type: :helper do referential: referential ) allow(helper).to receive(:current_user).and_return(user_context) - allow(TableBuilderHelper::URL).to receive(:current_referential) + allow(helper).to receive(:current_referential) .and_return(referential) companies = [company] -- cgit v1.2.3 From d2153d05b73f4f1af58e8d1ecebae9a5ad168601 Mon Sep 17 00:00:00 2001 From: af83 Date: Thu, 6 Jul 2017 14:01:55 +0200 Subject: Change wording for RCZ wording on validations errors --- config/locales/routing_constraint_zones.fr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/locales/routing_constraint_zones.fr.yml b/config/locales/routing_constraint_zones.fr.yml index 1199bcf3c..c262a851a 100644 --- a/config/locales/routing_constraint_zones.fr.yml +++ b/config/locales/routing_constraint_zones.fr.yml @@ -18,9 +18,9 @@ fr: routing_constraint_zone: attributes: stop_points: - not_enough_stop_points: "Il faut mettre au moins deux arrêts sur séquence d'arrêts." + not_enough_stop_points: "Il faut mettre au moins deux arrêts sur la séquence d'arrêts." stop_points_not_from_route: "Arrêt sur séquence d'arrêts n'appartient pas à la Route de cette Zone de contrainte." - all_stop_points_selected: "Une zone de contrainte ne peut pas couvrir tous les arrêts d'une ligne." + all_stop_points_selected: "Une ITL ne peut pas couvrir tous les arrêts d'un itinéraire." routing_constraint_zones: search_no_results: "Aucune ITL ne correspond à votre recherche" actions: -- cgit v1.2.3