diff options
36 files changed, 637 insertions, 561 deletions
| diff --git a/.gitignore b/.gitignore index 55f1de2b3..cc3e0cd16 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ public/assets/  chouette2.war  vendor/bundle  .ruby-version +coverage diff --git a/CHANGELOG.md b/CHANGELOG.md index 723dd3dce..6608ab53c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@    * Mise en valeur du format des données importées ou exportées    * Affichage d'une synthèse de la validation effectuée par lignes de transport    * Envoi de mail en asynchrone avec DelayedJob en option +  * Suppression de l'import CSV : l'import CSV peut être fait uniquement désormais au niveau des horaires des séquences d'arrêts  # Version 2.5.3  * Nouvelles fonctionnalités @@ -85,8 +85,9 @@ gem "modernizr-rails", "~> 2.0.6"  # Javascript  source 'https://rails-assets.org' do -  gem 'rails-assets-morrisjs', "~> 0.5.1" -  gem 'rails-assets-raphael', "~> 2.1.3" +  gem 'rails-assets-morrisjs',   '~> 0.5.1' +  gem 'rails-assets-raphael',    '~> 2.1.3' +  gem 'rails-assets-footable',   '~> 2.0.3'    # Use twitter bootstrap resources    gem 'rails-assets-bootstrap-sass-official', '~> 3.3.0' @@ -130,16 +131,16 @@ gem 'apartment', "~> 1.0.0"  gem 'newrelic_rpm'  group :development do -  gem 'capistrano', '2.13.5' +  gem 'capistrano',        '2.13.5'    gem 'capistrano-ext'    gem 'guard'    gem 'guard-rspec'    gem 'rails-erd'    gem 'meta_request'    gem 'letter_opener' -  gem 'quiet_assets',             '~> 1.0' - -  platforms :ruby_20, :ruby_21 do +  gem 'quiet_assets',      '~> 1.0' +  gem 'simplecov',         '~> 0.10.0' +  platforms :ruby_20, :ruby_21, :ruby_22 do      gem 'better_errors'      gem 'binding_of_caller'    end diff --git a/Gemfile.lock b/Gemfile.lock index 451a10ab0..58465495e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,6 +132,7 @@ GEM        actionmailer (>= 3.2.6, < 5)        devise (>= 3.2.0)      diff-lcs (1.2.5) +    docile (1.1.5)      dr-ffi-proj4 (0.0.3)        ffi (>= 1.0.0)      enumerize (0.10.1) @@ -315,6 +316,8 @@ GEM        rails-assets-bootstrap (>= 3.0)        rails-assets-jquery (>= 1.8.3)        rails-assets-moment (>= 2.8.0) +    rails-assets-footable (2.0.3) +      rails-assets-jquery (>= 1.4.4)      rails-assets-jquery (2.1.4)      rails-assets-jquery-tokeninput (1.7.0)        rails-assets-jquery (>= 1.5) @@ -408,6 +411,11 @@ GEM      simple_form (3.1.0)        actionpack (~> 4.0)        activemodel (~> 4.0) +    simplecov (0.10.0) +      docile (~> 1.1.0) +      json (~> 1.8) +      simplecov-html (~> 0.10.0) +    simplecov-html (0.10.0)      slop (3.6.0)      spoon (0.0.4)        ffi @@ -535,6 +543,7 @@ DEPENDENCIES    rails (= 4.1.10)    rails-assets-bootstrap-sass-official (~> 3.3.0)!    rails-assets-eonasdan-bootstrap-datetimepicker (~> 3.1.3)! +  rails-assets-footable (~> 2.0.3)!    rails-assets-jquery-tokeninput (~> 1.7.0)!    rails-assets-morrisjs (~> 0.5.1)!    rails-assets-raphael (~> 2.1.3)! @@ -555,6 +564,7 @@ DEPENDENCIES    sdoc (~> 0.4.0)    shoulda-matchers    simple_form (~> 3.1.0) +  simplecov (~> 0.10.0)    spring    sqlite3    squeel diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index b8e391129..212ccdff8 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -18,6 +18,10 @@  //= require moment/locale/fr  //= require eonasdan-bootstrap-datetimepicker  //= require tagmanager +//= require footable +//= require footable/footable.filter +//= require footable/footable.paginate +//= require footable/footable.sort  //= require_directory ./plugins  //= require_directory .  //= require_directory ./stop_areas diff --git a/app/assets/javascripts/compliance_checks/report.js.coffee b/app/assets/javascripts/compliance_checks/report.js.coffee index cd09cbd5d..2bff8742e 100644 --- a/app/assets/javascripts/compliance_checks/report.js.coffee +++ b/app/assets/javascripts/compliance_checks/report.js.coffee @@ -1,39 +1,48 @@ -$(".compliance_checks.report, .imports.compliance_check").ready -> +$(".compliance_checks.report, .imports.compliance_check, #sidebar.compliance_checks_sidebar").ready -> +  refreshInterval = $(".report").data("refresh-interval") +  if refreshInterval > 0 +    reloadPage = () -> window.location.reload() +    setInterval(reloadPage,refreshInterval * 1000) -  get_compliance_check_results = (html_container, css_class) -> -    html_container.each -> -      if( $( this ).hasClass(css_class) ) -        $( this ).show() -      else -        $( this ).hide() +  footableFilter = (parent, el) -> +    $(parent).footable().bind 'footable_filtering', (e) -> +      selected =  $("select#{el} option:selected").val() +      if selected and selected.length > 0 +        e.filter += if e.filter and e.filter.length > 0 then ' ' + selected else selected +        e.clear = !e.filter +      return +    $("select#{el}").change (e) -> +      e.preventDefault() +      $(parent).trigger 'footable_filter', filter: $("select#{el} option:selected").val() +      return -  Morris.Donut({ -    element: 'error', -    data: [ -      { label: $(".table").data('title-nok'), value: $("tr.nok_error").size() }, -      { label: $(".table").data('title-uncheck'), value: $("tr.uncheck_error").size() }, -      { label: $(".table").data('title-ok'), value: $("tr.ok_error").size() } -    ], -    colors: [ "#e22b1b", "#898e7f", "#8fc861" ] -  }).on('click', update = (i, row) -> -    switch i -      when 0 then get_compliance_check_results( $(".report tbody tr"), "nok_error") -      when 1 then get_compliance_check_results( $(".report tbody tr"), "uncheck_error") -      when 2 then get_compliance_check_results( $(".report tbody tr"), "ok_error") ) +  insertSeverityDonut = (type) -> +    triggerFilter = (type,state) -> +      $("select.filter-status option[value='status-#{state}']").prop('selected', true) +      $('.table').trigger 'footable_filter', filter: "#{state}_#{type}" +    momo = Morris.Donut({ +      element: type, +      data: [ +        { label: $(".table").data('title-nok'), value: $("tr.nok_#{type}").size() }, +        { label: $(".table").data('title-uncheck'), value: $("tr.uncheck_#{type}").size() }, +        { label: $(".table").data('title-ok'), value: $("tr.ok_#{type}").size() } +      ], +      colors: [ "#e22b1b", "#898e7f", "#8fc861" ] +    }).on('click', update = (i, row) -> +      switch i +        when 0 then triggerFilter(type,'nok') +        when 1 then triggerFilter(type,'uncheck') +        when 2 then triggerFilter(type,'ok') +    ) +    $('select.filter-status').change (e)-> +      switch $('select.filter-status option:selected').val() +        when 'status-nok' then momo.select(0) +        when 'status-uncheck' then momo.select(1) +        when 'status-ok' then momo.select(2) +    $("##{type}").hide() -  Morris.Donut({ -    element: 'warning', -    data: [ -      { label: $(".table").data('title-nok'), value: $("tr.nok_warning").size() }, -      { label: $(".table").data('title-uncheck'), value: $("tr.uncheck_warning").size() }, -      { label: $(".table").data('title-ok'), value: $("tr.ok_warning").size() } -    ], -    colors: [ "#ffbd2b", "#898e7f", "#8fc861" ] -  }).on('click', update = (i, row) -> -    switch i -      when 0 then get_compliance_check_results( $(".report tbody tr"), "nok_warning") -      when 1 then get_compliance_check_results( $(".report tbody tr"), "uncheck_warning") -      when 2 then get_compliance_check_results( $(".report tbody tr"), "ok_warning") ) +  insertSeverityDonut('error') +  insertSeverityDonut('warning')    $(".notice").popover({ container: "body", html: false, trigger: "focus", placement: "bottom" })    # Hide and show error details @@ -42,7 +51,12 @@ $(".compliance_checks.report, .imports.compliance_check").ready ->        $(this).next(".details_error").toggle()        $(this).children("i").toggleClass("fa-plus-square fa-minus-square") -  refreshInterval = $(".report").data("refresh-interval") -  if refreshInterval > 0 -    reloadPage = () -> window.location.reload() -    setInterval(reloadPage,refreshInterval * 1000) +  footableFilter('table', '.filter-status') +  footableFilter('table', '.filter-severity') + +  $('select.filter-severity').change (e)-> +    $('.graph').hide() +    if $('select.filter-severity option:selected').val() == 'severity-warning' +      $('#warning').show() +    if $('select.filter-severity option:selected').val() == 'severity-error' +      $('#error').show() diff --git a/app/assets/javascripts/partials/ie_report.js.coffee.erb b/app/assets/javascripts/partials/ie_report.js.coffee.erb index 25ea7dfc0..20c6dbb16 100644 --- a/app/assets/javascripts/partials/ie_report.js.coffee.erb +++ b/app/assets/javascripts/partials/ie_report.js.coffee.erb @@ -1,59 +1,21 @@  $(".imports.show, .exports.show, .compliance_checks.show").ready -> -  get_export_results = (html_container, html_element) -> -    html_container.children().each -> -      if( $( this ).is(html_element) ) -        $( this ).show() -      else -        $( this ).hide() - -  if $( "#files_statistics" ).length -    Morris.Donut({ -      element: 'files_statistics', -      data: [ -        { -          label: $(".files_error").data('label'), -          value: $('.files_error span.file_name').size() -        }, -        { -          label: $(".files_ignored").data('label'), -          value: $('.files_ignored span.file_name').size() -        }, -        { -          label: $(".files_ok").data('label'), -          value: $('.files_ok span.file_name').size() -        } -      ], -      colors: [ "#e22b1b", "#898e7f", "#8fc861" ] -    }).on('click', update = (i, row) -> -      switch i -        when 0 then get_export_results( $(".report"), $(".files_error")) -        when 1 then get_export_results( $(".report"), $(".files_ignored")) -        when 2 then get_export_results( $(".report"), $(".files_ok")) ) - -  Morris.Bar({ -    element: 'objects_statistics', -    data: [ -      { object: $("th.lines").text(), value: $(".lines table").data("total-lines")  }, -      { object: $("th.routes").text(), value: $(".lines table").data("total-routes")  }, -      { object: $("th.connection_links").text(), value: $(".lines table").data("total-connection_links") }, -      { object: $("th.time_tables").text(), value: $(".lines table").data("total-time_tables") }, -      { object: $("th.stop_areas").text(), value: $(".lines table").data("total-stop_areas") }, -      { object: $("th.access_points").text(), value: $(".lines table").data("total-access_points") }, -      { object: $("th.vehicle_journeys").text(), value: $(".lines table").data("total-vehicle_journeys") }, -      { object: $("th.journey_patterns").text(), value: $(".lines table").data("total-journey_patterns") }, -    ], -    xkey: 'object', -    ykeys: ['value'], -    labels: [$(".lines table").data('label')] -    xLabelAngle: 40, -    xAxisLabelTopPadding: 7, -    padding: 40, -    hideHover: true -  }).on('click', update = (i, row) -> -    get_export_results( $(".report"), $("div.lines")) ) -    refreshInterval = $(".report").data("refresh-interval")    if refreshInterval > 0      reloadPage = () -> window.location.reload()      setInterval(reloadPage,refreshInterval * 1000) + +  footableFilter = (parent, el) -> +    $(parent).footable().bind 'footable_filtering', (e) -> +      selected =  $("select#{el} option:selected").val() +      if selected and selected.length > 0 +        e.filter += if e.filter and e.filter.length > 0 then ' ' + selected else selected +        e.clear = !e.filter +      return +    $("select#{el}").change (e) -> +      e.preventDefault() +      $(parent).trigger 'footable_filter', filter: $("select#{el} option:selected").val() +      return + +  footableFilter('#table-file', '.filter-file-status') +  footableFilter('#table-line', '.filter-line-status') diff --git a/app/assets/stylesheets/application.css.scss.erb b/app/assets/stylesheets/application.css.scss.erb index 00ca42512..52405c14c 100644 --- a/app/assets/stylesheets/application.css.scss.erb +++ b/app/assets/stylesheets/application.css.scss.erb @@ -28,6 +28,7 @@ $body-bg: #eee;  @import "morrisjs";  @import "formtastic";  @import 'eonasdan-bootstrap-datetimepicker'; +@import 'footable';  @import "vendor/openlayers_style";  @import "vendor/openlayers_ie6-style"; diff --git a/app/assets/stylesheets/main/compliance_checks.css.scss b/app/assets/stylesheets/main/compliance_checks.css.scss index 34226e9d0..d31dfab62 100644 --- a/app/assets/stylesheets/main/compliance_checks.css.scss +++ b/app/assets/stylesheets/main/compliance_checks.css.scss @@ -9,6 +9,10 @@    @import "../modules/links";  } +#validation_success{ +  margin-top: 15px; +} +  #workspace.compliance_checks.report, #workspace.imports.compliance_check{    @import "../modules/job_status_colors";    @import "../modules/job_status_title"; @@ -63,7 +67,30 @@      .report{          .table { margin-top: 20px; } - +        dl.inline { +          width: 100%; +          overflow: hidden; +        } +        dl.inline dt { +          float: left; +          clear: left; +          width: 35%; +          padding-top: 5px; +          border-top: 1px solid #eee; +          -ms-word-break: break-all; +          word-break: break-all; +          word-break: break-word; +          -webkit-hyphens: auto; +          -moz-hyphens: auto; +          -ms-hyphens: auto; +          hyphens: auto; +        } +        dl.inline dd { +          float: left; +          width: 65%; +          padding-top: 10px; +          border-top: 1px solid #eee; +        }      }      .severity__improvment, .severity_warning, .severity_error { @@ -139,24 +166,8 @@          background-color: #ff9a0c;      } -    .td_error { -        width: 30%; - -        .title_error i { margin-right: 5px; } - -        div.details_error{ -            margin: 0px 0px 0px 3px !important; -            display: none; - -            p.detail_error{ -                margin: 0px 0px 5px 0px !important; -            } - -            .file_error{ -                margin-left: 26px; -                font-size: 10px; -                color: #898e7f; -            } -        } +    .file_error{ +      font-size: 14px; +      color: #898e7f;      }  } diff --git a/app/assets/stylesheets/partials/ie_report.css.scss b/app/assets/stylesheets/partials/ie_report.css.scss index a254b788b..55286d690 100644 --- a/app/assets/stylesheets/partials/ie_report.css.scss +++ b/app/assets/stylesheets/partials/ie_report.css.scss @@ -1,12 +1,6 @@  .status {    margin-left: 10px; -}    - -.status_aborted,.status_canceled { color: #a94442;} -.status_started { color: #31708f;} -.status_scheduled { color: #31708f;} -.status_terminated { color: #3c763d;} - +}  .resume {    &:after{      content: " "; @@ -15,54 +9,27 @@      clear: both;      visibility: hidden;    } - -  #files_statistics { height: 225px; } -  #objects_statistics { height: 225px; } -    .caption {      text-align :center; -  font-weight: bold; +    font-weight: bold;    } -} - -.report { -  margin-top: 20px; - -  .files { -    img { -      margin-right: 5px; -      } - -    .file_name{ -      font-weight: bold; -      margin-right: 30px; -      } +  dl.inline dd { +    display: inline; +    margin: 0;    } - -  .files_error{ -    color: #e22b1b; -    display: none; -  } - -  div.files_ignored{ -    color: #898e7f; -    display: none; +  dl.inline dd:after{ +    display: block; +    content: '';    } - -  div.files_ok{ -    color: #8fc861; -    display: none; +  dl.inline dt{ +    display: inline-block; +    min-width: 180px;    } +} -  div.lines{ -    display: none; -     -    th, td{ -      text-align: center; -      } - -    .fa-check{ color: $brand-success; } -    .fa-times{ color: $brand-danger; }   -         +.report { +  margin-top: 20px; +  .form-group { +    margin-right: 20px;    } -}   +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index df2cb696b..d3e9655b9 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,18 +1,15 @@  module ApplicationHelper -  def font_awesome_classic_tag(name, size = "") -    if name == "fa-file-csv-o" -      name = "fa-file-text-o" -    elsif name == "fa-file-xml-o" -      name = "fa-file-code-o" -    end -    "<i class='fa #{name} #{size}'></i>".html_safe +  def font_awesome_classic_tag(name) +    name = "fa-file-text-o" if name == "fa-file-csv-o" +    name = "fa-file-code-o" if name == "fa-file-xml-o" +    content_tag(:i, nil, {class: "fa #{name}"})    end -   +    def stop_area_picture_url(stop_area)      image_path("map/#{stop_area.area_type.underscore}.png")    end -   +    def selected_referential?      @referential.present? and not @referential.new_record?    end @@ -29,13 +26,13 @@ module ApplicationHelper      relative_url_root = Rails.application.config.relative_url_root      relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source    end -   +    def assets_path_patch( source)      relative_url_root = Rails.application.config.relative_url_root      return "/assets/#{source}" unless relative_url_root      "#{relative_url_root}/assets/#{source}"    end -   +    def help_page?      controller_name == "help" @@ -83,9 +80,9 @@ module ApplicationHelper      else        ""      end -     +      url_for(:controller => "/help", :action => "show") + '/' + target    end -   -   + +  end diff --git a/app/helpers/history_helper.rb b/app/helpers/history_helper.rb index 02a39a3d3..3ad38a11e 100644 --- a/app/helpers/history_helper.rb +++ b/app/helpers/history_helper.rb @@ -4,22 +4,22 @@ module HistoryHelper      field_set_tag t("layouts.history_tag.title"), :class => "history_tag" do        content_tag :ul do          [(content_tag :li do -          if object.has_attribute?(:creation_time)   +          if object.has_attribute?(:creation_time)              object.human_attribute_name('creation_time') + ' : ' + l(object.creation_time, :format => :short) -          else             +          else              object.class.human_attribute_name('created_at') + ' : ' + l(object.created_at, :format => :short)            end -        end),  +        end),          (content_tag :li do             if object.has_attribute?(:creator_id)               object.human_attribute_name('creator_id') + ' : ' + object.creator_id if object.creator_id             end -        end),  +        end),          (content_tag :li do             if object.has_attribute?(:objectid)               object.human_attribute_name('objectid') + ' : ' + object.objectid if object.objectid             end -        end),  +        end),          (content_tag :li do             if object.has_attribute?(:object_version)               object.human_attribute_name('object_version') + ' : ' + object.object_version.to_s if object.object_version @@ -28,26 +28,26 @@ module HistoryHelper        end      end    end -   +    def history_tag(object) -    field_set_tag t("layouts.history_tag.title"), :class => "history_tag" do +    field_set_tag t("layouts.history_tag.title"), class: "history_tag" do        content_tag :ul do -        [(content_tag :li do -          if object.created_at -            t('layouts.history_tag.created_at') + ' : ' + l(object.created_at, :format => :short) -          end -        end), -        (content_tag :li do -          if object.updated_at -            t('layouts.history_tag.updated_at') + ' : ' + l(object.updated_at, :format => :short) -          end -        end),   -        (content_tag :li do -           if  object.user_name -             t('layouts.history_tag.user_name') + ' : ' + object.user_name -           end -        end)].join.html_safe +        [:created_at, :updated_at, :user_name, :no_save].each do |field| +          concat history_tag_li(object, field) +        end        end      end    end + +  protected + +  def history_tag_li(object, field) +    if object.respond_to?(field) +      key = t("layouts.history_tag.#{field}") +      value = object.public_send(field) +      value = l(value, format: :short) if value.is_a?(Time) +      value = t(value.to_s) if value.in?([true, false]) +      content_tag(:li, "#{key} : #{value}") +    end +  end  end diff --git a/app/models/compliance_check.rb b/app/models/compliance_check.rb index 714c183d7..d3e4054a6 100644 --- a/app/models/compliance_check.rb +++ b/app/models/compliance_check.rb @@ -4,19 +4,15 @@ class ComplianceCheck    def initialize( response )      @datas = response    end -   +    def report?      links["action_report"].present?    end -   +    def report      Rails.cache.fetch("#{cache_key}/action_report", expires_in: cache_expiration) do -      report_path = links["action_report"] -      if report_path       -        response = Ievkit.get(report_path) -        ComplianceCheckReport.new(response) -      else -        nil +      if report_path = links["action_report"] +        ComplianceCheckReport.new Ievkit.get(report_path)        end      end    end @@ -24,15 +20,11 @@ class ComplianceCheck    def compliance_check_validation_report?      links["validation_report"].present?    end -   +    def compliance_check_validation_report      Rails.cache.fetch("#{cache_key}/validation_report", expires_in: cache_expiration) do -      report_path = links["validation_report"] -      if report_path       -        response = Ievkit.get(report_path) -        ComplianceCheckResult.new(response) -      else -        nil +      if report_path = links["validation_report"] +        ComplianceCheckResult.new Ievkit.get(report_path)        end      end    end @@ -43,31 +35,24 @@ class ComplianceCheck    def rule_parameter_set      Rails.cache.fetch("#{cache_key}/validation_params", expires_in: cache_expiration) do -      rule_parameter_set_path = links["validation_params"] -      if rule_parameter_set_path +      if rule_parameter_set_path = links["validation_params"]          response = Ievkit.get(rule_parameter_set_path) -        rule_parameter_set = RuleParameterSet.new(:name => "", :compliance_check => self).tap { |rps| rps.parameters = response.validation } -      else -        nil +        RuleParameterSet.new(name: '', compliance_check: self).tap do |rps| +          rps.parameters = response.validation +        end        end      end    end    def destroy -    delete_path =  links["delete"] -    cancel_path = links["cancel"] -     -    if delete_path +    if delete_path =  links["delete"]        Ievkit.delete(delete_path) -    elsif cancel_path +    elsif cancel_path = links["cancel"]        Ievkit.delete(cancel_path) -    else -      nil      end    end    def format      datas.type    end -  end diff --git a/app/models/compliance_check_result.rb b/app/models/compliance_check_result.rb index 399f406a9..cd956a021 100644 --- a/app/models/compliance_check_result.rb +++ b/app/models/compliance_check_result.rb @@ -2,9 +2,9 @@ class ComplianceCheckResult    extend ActiveModel::Naming    extend ActiveModel::Translation    include ActiveModel::Model -   +    attr_accessor :datas -   +    def initialize(response)      @datas = response.validation_report    end @@ -14,44 +14,40 @@ class ComplianceCheckResult    end    def ok_error -    tests? ? tests.select { |test| (test.result == "OK" && test.severity == "ERROR") } : [] +    all('ok', 'error')    end -   +    def nok_error -    tests? ? tests.select { |test| (test.result == "NOK" && test.severity == "ERROR")} : [] +    all('nok', 'error')    end -   +    def na_error -    tests? ? tests.select { |test| (test.result == "UNCHECK" && test.severity == "ERROR")} : [] +    all('uncheck', 'error')    end    def ok_warning -    tests? ? tests.select { |test| (test.result == "OK" && test.severity == "WARNING")} : [] +    all('ok', 'warning')    end -   +    def nok_warning -    tests? ? tests.select { |test| (test.result == "NOK" && test.severity == "WARNING")} : [] +    all('nok', 'warning')    end -   +    def na_warning -    tests? ? tests.select { |test| (test.result == "UNCHECK" && test.severity == "WARNING")} : [] +    all('uncheck', 'warning')    end -   +    def all(status, severity) -    tests? ? tests.select { |test| ( test.result == status && test.severity == severity ) } : [] +    tests? ? tests.select { |test| test.result == status.downcase && test.severity == severity.downcase } : []    end    def tests -    [].tap do |tests| -      datas.tests.each do |test| -        tests << Test.new(test) -      end if datas.tests? -    end +    @tests ||= tests? ? datas.tests.map{ |test| Test.new(test) } : []    end    class Test      attr_reader :options -     +      def initialize( options )        @options = options      end @@ -59,7 +55,7 @@ class ComplianceCheckResult      def test_id        options.test_id if options.test_id?      end -     +      def severity        options.severity.downcase if options.severity?      end @@ -76,5 +72,5 @@ class ComplianceCheckResult        options.error_count if options.error_count?      end    end -   +  end diff --git a/app/models/concerns/job_concern.rb b/app/models/concerns/job_concern.rb index b0c26baa9..4054a4cef 100644 --- a/app/models/concerns/job_concern.rb +++ b/app/models/concerns/job_concern.rb @@ -3,8 +3,8 @@ module JobConcern    extend ActiveModel::Naming    extend ActiveModel::Translation    include ActiveModel::Model -   -  included do     + +  included do      attr_reader :datas    end @@ -13,9 +13,9 @@ module JobConcern    def links      {}.tap do |links| -      datas.links.each do |link| -        links[link["rel"]] = link["href"]  -      end     +      datas['links'].each do |link| +        links[link["rel"]] = link["href"] +      end      end    end @@ -32,9 +32,9 @@ module JobConcern    end    def cache_expiration -    started? ? 10.seconds : 1.hours  +    started? ? 10.seconds : 1.hours    end -   +    def id      datas.id    end @@ -46,16 +46,16 @@ module JobConcern    def referential_name      datas.referential    end -   +    def name      datas.action_parameters.name    end -   -  def user_name     + +  def user_name      datas.action_parameters.user_name    end -   -  def created_at     + +  def created_at      Time.at(datas.created.to_i / 1000) if datas.created    end @@ -66,5 +66,17 @@ module JobConcern    def format      datas.type    end -   + +  def organisation_name +    datas.action_parameters.organisation_name +  end + +  def no_save +    datas.action_parameters.no_save +  end +  alias_method :no_save?, :no_save + +  def clean_repository +    datas.action_parameters.clean_repository +  end  end diff --git a/app/models/concerns/report_concern.rb b/app/models/concerns/report_concern.rb index 6c080578d..b0157fec3 100644 --- a/app/models/concerns/report_concern.rb +++ b/app/models/concerns/report_concern.rb @@ -3,14 +3,19 @@ module ReportConcern    extend ActiveModel::Naming    extend ActiveModel::Translation    include ActiveModel::Model -   -  included do     + +  included do      attr_reader :datas    end    module ClassMethods    end +  delegate :progression?, to: :datas +  delegate :progression, to: :datas +  delegate :zip_file, to: :datas +  delegate :stats, to: :datas +    def failure_code?      datas.result == "NOK" && datas.failure?    end @@ -18,19 +23,11 @@ module ReportConcern    def failure_code      datas.failure.code.downcase if failure_code?    end -   -  def progression? -    datas.progression? -  end -   -  def progression -    datas.progression -  end    def percentage(a, b)      (a.to_f / b.to_f * 100).round(0)    end -   +    def level_progress      percentage( progression.current_step, progression.steps_count) if progression?    end @@ -42,25 +39,21 @@ module ReportConcern    def current_step      datas.progression.steps[ progression.current_step - 1]    end -   +    def step_progress      percentage( current_step.realized, current_step.total )    end -   +    def step_progress_name      return last_step.step  if progression.current_step == progression.steps_count      current_step.step    end -  def zip_file -    datas.zip_file -  end -    def files -    datas.files || [] +    @files ||= datas.files || []    end -   +    def error_files      files.select{ |file| file[:status] == "ERROR"}    end @@ -71,56 +64,59 @@ module ReportConcern    def ok_files      files.select{ |file| file[:status] == "OK"} -  end  -   +  end +    def line_items -    [].tap do |line_items| +    @line_items ||= [].tap do |line_items|        datas.lines.each do |line|          line_items << LineItem.new(line)        end if datas.lines?      end    end -  def stats -    datas.stats  +  def saved_lines +    line_items.map(&:status).count(true) +  end + +  def unsaved_lines +    line_items.map(&:status).count(false)    end -   +    def lines      stats.present? ? stats.line_count : 0    end -   +    def routes      stats.present? ? stats.route_count : 0    end -   +    def connection_links      stats.present? ? stats.connection_link_count : 0    end -   +    def time_tables      stats.present? ? stats.time_table_count : 0    end -   +    def stop_areas      stats.present? ? stats.stop_area_count : 0    end -   +    def access_points      stats.present? ? stats.access_point_count : 0    end -   +    def vehicle_journeys      stats.present? ? stats.vehicle_journey_count : 0    end -   +    def journey_patterns      stats.present? ? stats.journey_pattern_count : 0    end -   -   +    class LineItem      attr_reader :options -     +      def initialize( options )        @options = options      end @@ -134,17 +130,17 @@ module ReportConcern      end      def status -      @status ||= if options.status?         +      @status ||= if options.status?                      if %w{ok warning}.include? options.status.downcase                        true                      else                        false -                    end                     +                    end                    else                      false                    end -    end      -     +    end +      def routes        stats ? stats.route_count : 0      end @@ -164,7 +160,7 @@ module ReportConcern      def access_points        stats ? stats.access_point_count : 0      end -     +      def vehicle_journeys        stats ? stats.vehicle_journey_count : 0      end @@ -173,6 +169,5 @@ module ReportConcern        stats ? stats.journey_pattern_count : 0      end -  end  -   +  end  end diff --git a/app/models/import.rb b/app/models/import.rb index b7cfd5a24..078f1698e 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -84,10 +84,4 @@ class Import    def filename_extension      File.extname(filename).gsub(".", "") if filename    end - -  def no_save -    datas.action_parameters.no_save -  end -  alias_method :no_save?, :no_save -  end diff --git a/app/views/compliance_checks/_compliance_check_results.erb b/app/views/compliance_checks/_compliance_check_results.erb index 80efe9be4..ab8d283eb 100644 --- a/app/views/compliance_checks/_compliance_check_results.erb +++ b/app/views/compliance_checks/_compliance_check_results.erb @@ -1,78 +1,95 @@ -<table class="table table-hover" data-title-nok="<%= t 'nok', :scope => 'compliance_check_result.statuses' %>", data-title-uncheck="<%= t 'uncheck', :scope => 'compliance_check_result.statuses' %>", data-title-ok="<%= t 'ok', :scope => 'compliance_check_result.statuses' %>" > +<p> +<form class="form-inline"> +  <div class="form-group"> +    <label><%= t("shared.ie_report.html.search") %></label> +    <input id="filter" type="text" class="form-control"> +  </div> +  <div class="form-group"> +    <label><%=ComplianceCheckResult.human_attribute_name(:severity)%></label> +    <select class="filter-severity form-control"> +      <option></option> +      <option value="severity-error"><%= t("compliance_check_result.severities.error") %></option> +      <option value="severity-warning"><%= t("compliance_check_result.severities.warning") %></option> +    </select> +  </div> +  <div class="form-group"> +    <label><%=ComplianceCheckResult.human_attribute_name(:status)%></label> +    <select class="filter-status form-control"> +      <option></option> +      <option value="status-ok"><%= t("compliance_check_result.statuses.ok") %></option> +      <option value="status-nok"><%= t("compliance_check_result.statuses.nok") %></option> +      <option value="status-uncheck"><%= t("compliance_check_result.statuses.uncheck") %></option> +    </select> +  </div> +</form> +</p> +<table class="table table-hover toggle-circle toggle-medium" +       data-filter="#filter" +       data-page-size="20" +       data-title-nok="<%=t('compliance_check_result.statuses.nok') %>" +       data-title-uncheck="<%=t('compliance_check_result.statuses.uncheck') %>" +       data-title-ok="<%=t('compliance_check_result.statuses.ok') %>">    <thead>      <tr> -      <th><%= ComplianceCheckResult.human_attribute_name(:status) %></th> -      <th><%= ComplianceCheckResult.human_attribute_name(:severity) %></th> -      <th><%= ComplianceCheckResult.human_attribute_name(:rule_code) %></th> -      <th><%= ComplianceCheckResult.human_attribute_name(:detail) %></th> +      <th data-sort-ignore="true"><%= ComplianceCheckResult.human_attribute_name(:status) %></th> +      <th class="col-md-1" data-sort-ignore="true"><%= ComplianceCheckResult.human_attribute_name(:severity) %></th> +      <th class="col-md-3"><%= ComplianceCheckResult.human_attribute_name(:rule_code) %></th> +      <th class="col-md-2"><%=t('compliance_check_results.errors') %></th> +      <th class="col-md-6" data-toggle="true" data-sort-ignore="true"><%= ComplianceCheckResult.human_attribute_name(:detail) %></th> +      <th data-hide="all" data-sort-ignore="true"></th>      </tr>    </thead>    <tbody>      <% compliance_check_validation_report.tests.each_with_index do |test, index| %>      <tr class='<%= "#{test.result}_#{test.severity}" %>'> -      <td><%= status_icon( test.result, test.severity ) %> </td> -      <td><%= t("compliance_check_result.severities." + test.severity + "_txt") %></td> +      <td data-value="<%="status-#{test.result}"%>"><%= status_icon( test.result, test.severity ) %> </td> +      <td data-value="<%="severity-#{test.severity}"%>"><%= t("compliance_check_result.severities.#{test.severity}_txt") %></td> +      <td data-value="<%= "#{test.result}_#{test.severity}" %>"> +        <%= link_to test.test_id, test_definition(test.test_id), title: ComplianceCheckResult.human_attribute_name(test.test_id), target: "compliance_check" %> +      </td> +      <td> +        <%= ("#{test.error_count || 0} #{ComplianceCheckResult.human_attribute_name(:violation_count)}") if test.errors.present? %> +      </td>        <td> -	<% data_content = t ( "activemodel.attributes.compliance_check_result." + test.test_id ) %> -	<% data_title = t ( "activemodel.attributes.compliance_check_result.title" ) %> -        <button data-content='<%= data_content %>' data-title='<%= data_title %>' rel="popover" data-toggle="popover" class="notice btn btn-info btn-xs" ><i class="fa fa-info"></i></button> -        <%= link_to test.test_id, test_definition(test.test_id), :title => ComplianceCheckResult.human_attribute_name(test.test_id), :target => "compliance_check" %></td> -      <td class="td_error"> +        <%= truncate(t("activemodel.attributes.compliance_check_result.#{test.test_id}"), length: 50)%> +      </td> +      <td> +        <p><b><%=t("activemodel.attributes.compliance_check_result.#{test.test_id}")%></b></p>          <% if test.errors.present? %> -        <span class="title_error"> -          <i class="fa fa-plus-square"></i><%= test.error_count.to_s + " " + ComplianceCheckResult.human_attribute_name(:violation_count) %> -        </span> - - -<!-- error : 1    error_id (string)  -             0..1 source : -                  0..1 file : -                       1    filename (string) -                       0..1 line_number (int) -                       0..1 column_number (int) -                  0..1 objectid (string) -                  0..1 label (string) -                  0..  object_path : -                       1 type : {"network", "company", etc...} -                       1 id (long) -             0..  target : (same as source) -             0..1 error_value (string) -             0..1 reference_value (striung) --> -        <div class="details_error">            <% test.errors.first(10).each do |error| %> -            <p class="detail_error"> -	      <% if error["source"].present? %>		 -	        <% data_content = t("activemodel.attributes.compliance_check_result." + test.test_id) + " " + t("compliance_check_result.details.detail_" + error[:error_id], object_labels_hash(error) ) %> -	        <% data_title = t("activemodel.attributes.compliance_check_result.detail") %> -                |- <button data-content='<%= data_content %>' data-title='<%= data_title %>' data-toggle="popover" class="notice btn btn-info btn-xs"><i class="fa fa-info"></i></button> -		   -		<% if error[:source].object_path.present? %> -		  <% if error[:source].label.present? %> -	            <%= link_to error[:source].label, object_url(@referential.id, error) %> -		  <% else %> -	            <%= link_to "#{error[:source].object_path.type} (#{error[:source].object_path.id})", object_url(@referential.id, error) %> -		  <% end %> -		<% end %> -		<% if error[:source].file.present? %> -		  <% if error[:source].objectid.present? %> -		    <%= "#{error[:source].objectid}" %>		     -		  <% end %> -		  <p class="file_error"> -		  <%= error[:source].file.filename  %> -		  <% if error[:source].file.line_number.present?  %> -		    <%= ", li: #{error[:source].file.line_number}" %> -		  <% end %> -		  <% if error[:source].file.column_number.present?  %> -		    <%= ", co: #{error[:source].file.column_number}" %> -		  <% end %> -		  </p>  -		<% end %>		   -	      <% end %>               -          <% end %>              -        </div> +            <dl class="inline"> +            <dt> +              <% if error["source"].present? %> +                <% if error[:source].object_path.present? %> +                  <% if error[:source].label.present? %> +                    <%= link_to error[:source].label, object_url(@referential.id, error), target: :_blank %> +                  <% else %> +                    <%= link_to "#{error[:source].object_path.type} (#{error[:source].object_path.id})", object_url(@referential.id, error), target: :_blank %> +                  <% end %> +                <% end %> +                <% if error[:source].file.present? %> +                  <%= error[:source].objectid if error[:source].objectid.present? %> +                <% end %> +              <% end %> +            </dt> +            <dd><%=t("compliance_check_result.details.detail_#{error[:error_id]}", object_labels_hash(error))%></dd> +            </dl> +            <% if error[:source].file.present? %> +              <p class="file_error"> +              <%= error[:source].file.filename  %> +                <%= ", li: #{error[:source].file.line_number}" if error[:source].file.line_number.present?  %> +                <%= ", co: #{error[:source].file.column_number}" if error[:source].file.column_number.present?  %> +              </p> +            <% end %> +          <% end %>          <% end %>        </td>      </tr> -  <% end %> +    <% end %>    </tbody> +  <tfoot class="hide-if-no-paging"> +    <tr> +      <td colspan="5"><ul class="pagination pagination-centered"></ul></td> +    </tr> +  </tfoot>  </table> diff --git a/app/views/compliance_checks/report.html.erb b/app/views/compliance_checks/report.html.erb index 67b5206e6..28abd4cbb 100644 --- a/app/views/compliance_checks/report.html.erb +++ b/app/views/compliance_checks/report.html.erb @@ -2,52 +2,48 @@  <div class="compliance_check_show">    <div class="links"> -    <% if @compliance_check.class == Import  %> +    <% if @compliance_check.class == Import %> +      <%= link_to(font_awesome_classic_tag('fa-eye') + t("compliance_checks.report.action_report"), referential_import_path(@referential, @compliance_check.id)) %>        <%= link_to font_awesome_classic_tag("fa-external-link") + t("compliance_checks.rule_parameter_set"), rule_parameter_set_referential_import_path(@referential, @compliance_check.id) if @compliance_check.rule_parameter_set? %>      <% else %> +      <%= link_to(font_awesome_classic_tag('fa-eye') + t("compliance_checks.report.action_report"), referential_compliance_check_path(@referential, @compliance_check.id)) %>        <%= link_to font_awesome_classic_tag("fa-external-link") + t("compliance_checks.rule_parameter_set"), rule_parameter_set_referential_compliance_check_path(@referential, @compliance_check.id) if @compliance_check.rule_parameter_set? %>      <% end %> -     <div class="btn-group pull-right"> -       <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> -         <%= t("compliance_checks.show.export") %> <span class="caret"></span> -       </button> -       <ul class="dropdown-menu" role="menu"> -         <li> -	   <% if @compliance_check.class == Import  %> -	     <%= link_to t("compliance_checks.show.export_csv"), export_referential_import_path(@referential, @compliance_check.id) %> -	   <% else %> -	     <%= link_to t("compliance_checks.show.export_csv"), export_referential_compliance_check_path(@referential, @compliance_check.id) %> -	   <% end %> -	 </li> -       </ul> -     </div> -   </div> - -   <div class="resume"> -     <div class="col1"> -       <div class="caption"><%= t "error", :scope => "compliance_check_result.severities" %></div> -       <div class="graph" id="error"></div> -     </div> -     <div class="col2"> -       <div class="caption"><%= t "warning", :scope => "compliance_check_result.severities" %></div> -       <div class="graph" id="warning"></div> -     </div> -   </div> - -   <div class="report" data-refresh-interval="<%= job_refresh_interval(@compliance_check) %>"> -     <%= render :partial => "compliance_checks/compliance_check_results", :locals => { :compliance_check_validation_report => @compliance_check.compliance_check_validation_report } %> -   </div> +    <div class="btn-group pull-right"> +      <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false"> +        <%= t("compliance_checks.show.export") %> <span class="caret"></span> +      </button> +      <ul class="dropdown-menu" role="menu"> +        <li> +          <% if @compliance_check.class == Import %> +            <%= link_to t("compliance_checks.show.export_csv"), export_referential_import_path(@referential, @compliance_check.id) %> +          <% else %> +            <%= link_to t("compliance_checks.show.export_csv"), export_referential_compliance_check_path(@referential, @compliance_check.id) %> +          <% end %> +        </li> +      </ul> +    </div> +  </div> +  <div class="report" data-refresh-interval="<%= job_refresh_interval(@compliance_check) %>"> +    <%= render :partial => "compliance_checks/compliance_check_results", locals: { compliance_check_validation_report: @compliance_check.compliance_check_validation_report } %> +  </div>  </div>  <% content_for :sidebar do %> -<ul class="actions"> -  <li> -    <% if @compliance_check.class != Import %> -      <%= link_to  t('compliance_checks.actions.destroy'), referential_compliance_check_path(@referential, @compliance_check.id), :method => :delete,  :data => {:confirm =>  t('compliance_checks.actions.destroy_confirm')}, :class => "remove" %> -    <% end %> -  </li> -</ul> - -<%= history_tag(@compliance_check) %> - +  <% if @compliance_check.compliance_check_validation_report.nok_error.blank? %> +    <div class="row"> +      <%=font_awesome_classic_tag('fa-thumbs-up fa-5x col-md-3')%> +      <p class='col-md-7' id='validation_success'><%=t('.validation_success')%></p> +    </div> +  <% end %> +  <ul class="actions"> +    <li> +      <% if @compliance_check.class != Import %> +        <%= link_to  t('compliance_checks.actions.destroy'), referential_compliance_check_path(@referential, @compliance_check.id), :method => :delete,  :data => {:confirm =>  t('compliance_checks.actions.destroy_confirm')}, :class => "remove" %> +      <% end %> +    </li> +  </ul> +  <%= history_tag(@compliance_check) %> +  <div id="error" class="graph"></div> +  <div id="warning" class="graph"></div>  <% end %> diff --git a/app/views/compliance_checks/show.html.erb b/app/views/compliance_checks/show.html.erb index da544a4b3..1a1f842f5 100644 --- a/app/views/compliance_checks/show.html.erb +++ b/app/views/compliance_checks/show.html.erb @@ -13,12 +13,12 @@    <div class="links">      <%= link_to font_awesome_classic_tag("fa-external-link") + t("compliance_checks.actions.report"), report_referential_compliance_check_path(@referential, @compliance_check.id) if @compliance_check.compliance_check_validation_report? %>    </div> -  <%= render( :partial => "shared/ie_report.html", :locals => { :referential => @referential, :job => @compliance_check} ) %> +  <%= render(partial: "shared/ie_report.html", locals: { job: @compliance_check, type: :validation } ) %>  </div>  <% content_for :sidebar do %>    <ul class="actions"> -    <li><%= link_to t('compliance_checks.actions.destroy'), referential_compliance_check_path(@referential, @compliance_check.id), :method => :delete, :data => {:confirm => t('compliance_checks.actions.destroy_confirm')}, :class => "remove" %></li> +    <li><%= link_to t('compliance_checks.actions.destroy'), referential_compliance_check_path(@referential, @compliance_check.id), method: :delete, data: {confirm: t('compliance_checks.actions.destroy_confirm')}, class: "remove" %></li>    </ul>    <%= history_tag(@compliance_check) %> diff --git a/app/views/exports/show.html.erb b/app/views/exports/show.html.erb index 43b9773ae..bc9faf3f2 100644 --- a/app/views/exports/show.html.erb +++ b/app/views/exports/show.html.erb @@ -13,12 +13,12 @@  <% end %>  <div class="progress_bars">    <%= progress_bar_tag(@export) %> -</div>   +</div>  <div class="export_show">    <div class="links">      <%= link_to( font_awesome_classic_tag("fa-file-#{@export.filename_extension}-o") + t("exports.show.exported_file"), exported_file_referential_export_path(@referential, @export.id) ) if @export.file_path %>    </div> -  <%= render( :partial => "shared/ie_report.html", :locals => { :referential => @referential, :job => @export} ) %> +  <%= render( partial: "shared/ie_report.html", locals: { job: @export } ) %>  </div>  <% content_for :sidebar do %> diff --git a/app/views/imports/show.html.erb b/app/views/imports/show.html.erb index 3bdae3e2a..21e06d964 100644 --- a/app/views/imports/show.html.erb +++ b/app/views/imports/show.html.erb @@ -19,12 +19,12 @@      <%= link_to font_awesome_classic_tag("fa-file-#{@import.filename_extension}-o") + t("imports.show.imported_file"), imported_file_referential_import_path(@referential, @import.id) if @import.file_path? %>      <%= link_to font_awesome_classic_tag("fa-external-link") + t("imports.show.compliance_check"), compliance_check_referential_import_path(@referential, @import.id) if @import.compliance_check? %>    </div> -  <%= render( :partial => "shared/ie_report.html", :locals => { :referential => @referential, :job => @import} ) %> +  <%= render(partial: "shared/ie_report.html", locals: {job: @import}) %>  </div>  <% content_for :sidebar do %>    <ul class="actions"> -    <li><%= link_to t('imports.actions.destroy'), referential_import_path(@referential, @import.id), :method => :delete, :data => {:confirm => t('imports.actions.destroy_confirm')}, :class => "remove" %></li> +    <li><%= link_to t('imports.actions.destroy'), referential_import_path(@referential, @import.id), method: :delete, data: {confirm: t('imports.actions.destroy_confirm')}, class: "remove" %></li>    </ul>    <%= history_tag(@import) %> diff --git a/app/views/shared/_header.erb b/app/views/shared/_header.erb index 1ebb78a43..d1e8dd2ce 100644 --- a/app/views/shared/_header.erb +++ b/app/views/shared/_header.erb @@ -10,16 +10,16 @@          <span class="icon-bar version"><%= APP_VERSION %></span>        </button>        <%= link_to referentials_path, :class =>"navbar-brand" do %> -       <%= image_tag("logo_chouette.png") %>        +        <%= image_tag("logo_chouette.png") %>        <% end %> -      <p class="navbar-text"><span class="brand_name">CHOUETTE</span></i><span class="version"><%= APP_VERSION %></span></p>   +      <p class="navbar-text"><span class="brand_name">CHOUETTE</span><span class="version"><%= APP_VERSION %></span></p>      </div>      <!-- Collect the nav links, forms, and other content for toggling -->      <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">        <ul class="nav navbar-nav">          <% if selected_referential? %>          <li class="dropdown"> -          <a href="#" class="dropdown-toggle" data-toggle="dropdown", title="<%= @referential.name %>"><%= truncate @referential.name, :length => 15 %><b class="caret"></b></a> +          <a href="#" class="dropdown-toggle" data-toggle="dropdown" title="<%= @referential.name %>"><%= truncate @referential.name, :length => 15 %><b class="caret"></b></a>            <ul class="dropdown-menu">              <li><%= link_to t("layouts.navbar.return_to_referentials"), referentials_path %></li>              <li class="divider"></li> @@ -81,7 +81,7 @@              <li><%= link_to_language :fr, { :class => language_class( :fr ) } %></li>              <li><%= link_to_language :en, { :class => language_class( :en  ) } %></li>            </ul> -        </li>         +        </li>          <li><%= link_to t('layouts.help'), help_path, :class =>("current" if help_page?), :target => "chouette_help" %></li>          <% if user_signed_in?  %>          <li class="dropdown"> diff --git a/app/views/shared/_ie_report.html.erb b/app/views/shared/_ie_report.html.erb index 0b3be8afa..f4f6fa043 100644 --- a/app/views/shared/_ie_report.html.erb +++ b/app/views/shared/_ie_report.html.erb @@ -1,68 +1,27 @@ -<div class="resume row"> +<div class="resume">    <% if job.respond_to?(:file_path) %> -  <div class="col-md-4"> -    <div class="caption"><%= t(".graph.files.title_default", {:job => job.class.model_name.human, :extension => job.filename_extension} ) %></div> -    <div id="files_statistics"></div> -  </div> -  <% end %> -  <div class="col-md-8"> -    <div class="caption"><%= t ".graph.lines.title" %></div> -    <div id="objects_statistics"></div> -  </div> -</div> +  <ul class="nav nav-tabs" role="tablist"> +    <li role="presentation" class="active"> +      <a href="#ie_tab_line" class="ie_tab_line"  aria-controls="ie_tab_line" role="tab" data-toggle="tab"> +        <%=t('.tab.line')%> +      </a> +    </li> +    <li role="presentation"> +      <a href="#ie_tab_file" class="ie_tab_file" aria-controls="ie_tab_file" role="tab" data-toggle="tab"> +        <%=t('.tab.file')%> +      </a> +    </li> +  </ul> -<div class="report" data-refresh-interval="<%= job_refresh_interval(job) %>"> -  <div class="files files_error" data-label="<%= t('.graph.files.error') %>"> -    <% job.report.error_files.each_with_index do |file, index| %> -      <div class="col-md-6"> -        <%= image_tag "icons/file_xml_md.png" %><span class="file_name" title='<%= file.name %>'><%= truncate(file.name, :length => 40) %></span> -      </div> -    <% end %> -  </div> -  <div class="files files_ignored" data-label="<%= t('.graph.files.ignored') %>"> -    <% job.report.ignored_files.each_with_index do |file, index| %> -      <div class="col-md-6"> -        <%= image_tag "icons/file_xml_md.png" %><span class="file_name" title='<%= file.name %>'><%= truncate(file.name, :length => 40) %></span> -      </div> -    <% end %> -  </div> -  <div class="files files_ok" data-label="<%= t('.graph.files.ok') %>"> -    <% job.report.ok_files.each_with_index do |file, index| %> -      <div class="col-md-6"> -        <%= image_tag "icons/file_xml_md.png" %><span class="file_name" title='<%= file.name %>'><%= truncate(file.name, :length => 40) %></span> -      </div> -    <% end %> -  </div> -  <div class="lines"> -    <table class="table table-hover table-striped" data-label="<%= t('.graph.lines.objects_label') %>" data-total-lines="<%= job.report.lines %>" data-total-routes="<%= job.report.routes %>" data-total-connection_links="<%= job.report.connection_links %>", data-total-time_tables="<%= job.report.time_tables %>" data-total-stop_areas="<%= job.report.stop_areas %>" data-total-access_points="<%= job.report.access_points %>" data-total-vehicle_journeys="<%= job.report.vehicle_journeys %>" data-total-journey_patterns="<%= job.report.journey_patterns %>" > -      <thead> -        <tr> -	  <th class="save"><%= t(".table.line.save") %></th> -          <th class="lines"><%= t(".table.line.lines") %></th> -          <th class="routes"><%= t(".table.line.routes") %></th> -          <th class="connection_links"><%= t(".table.line.connection_links") %></th> -          <th class="time_tables"><%= t(".table.line.time_tables") %></th> -          <th class="stop_areas"><%= t(".table.line.stop_areas") %></th> -          <th class="access_points"><%= t(".table.line.access_points") %></th> -          <th class="vehicle_journeys"><%= t(".table.line.vehicle_journeys") %></th> -          <th class="journey_patterns"><%= t(".table.line.journey_patterns") %></th> -        </tr> -      </thead> -      <tbody> -        <% job.report.line_items.each_with_index do |line_item, index| %> -          <tr> -	    <td><%= line_item.status ? font_awesome_classic_tag("fa-check") : font_awesome_classic_tag("fa-times")  %></td> -            <td><%= line_item.name %></td> -            <td><%= line_item.routes %></td> -            <td><%= line_item.connection_links %></td> -            <td><%= line_item.time_tables %></td> -            <td><%= line_item.stop_areas %></td> -            <td><%= line_item.access_points %></td> -            <td><%= line_item.vehicle_journeys %></td> -            <td><%= line_item.journey_patterns %></td> -          </tr> -        <% end %> -      </tbody> -    </table> +  <div class="tab-content"> +    <div role="tabpanel" class="tab-pane active" id="ie_tab_line"> +        <%= render partial: 'shared/ie_report_line', locals: { job: job, type: (defined?(type) ? type : :default) } %> +    </div> +    <div role="tabpanel" class="tab-pane" id="ie_tab_file"> +      <%= render partial: 'shared/ie_report_file', locals: { job: job } %> +    </div>    </div> +  <% else %> +    <%= render partial: 'shared/ie_report_line', locals: { job: job, type: (defined?(type) ? type : :default) } %> +  <% end %>  </div> diff --git a/app/views/shared/_ie_report_file.html.erb b/app/views/shared/_ie_report_file.html.erb new file mode 100644 index 000000000..20e4bb659 --- /dev/null +++ b/app/views/shared/_ie_report_file.html.erb @@ -0,0 +1,45 @@ +<p class="lead"> +<p class="caption"><%= t(".title_default", {:job => job.class.model_name.human, :extension => job.filename_extension} ) %></p> +</p> +<div class="report results" data-refresh-interval="<%= job_refresh_interval(job) %>"> +  <p> +    <form class="form-inline"> +      <div class="form-group"> +        <label><%= t("shared.ie_report.html.search") %></label> +        <input id="filter-file" type="text" class="form-control"> +      </div> +      <div class="form-group"> +        <label><%= t(".table.state") %></label> +        <select class="filter-file-status form-control"> +          <option></option> +          <option value="ok"><%=t(".table.ok")%></option> +          <option value="error"><%=t(".table.error")%></option> +          <option value="ignored"><%=t(".table.ignored")%></option> +        </select> +      </div> +    </form> +  </p> +  <table id="table-file" class="table table-hover table-striped data-table" data-filter="#filter-file" data-page-size="20"> +    <thead> +      <tr> +        <th class="state"><%= t(".table.state") %></th> +        <th class="name"><%= t(".table.name") %></th> +        <th class="error"><%= t(".table.error") %></th> +      </tr> +    </thead> +    <tbody> +      <% job.report.files.each do |file| %> +        <tr class="<%= file.status == 'ERROR' ? 'danger' : nil %>"> +          <td data-value="<%= file.status.downcase %>"><%= t(".table.#{file.status.downcase}") %></td> +          <td><%= file.name %></td> +          <td><%= file.errors.map{|e| "#{e.code} : #{e.description}"}.join(' | ') if file.errors.present? %></td> +        </tr> +      <% end %> +    </tbody> +    <tfoot> +      <tr> +        <td colspan="5"><ul class="pagination pagination-centered"></ul></td> +      </tr> +    </tfoot> +  </table> +</div> diff --git a/app/views/shared/_ie_report_line.html.erb b/app/views/shared/_ie_report_line.html.erb new file mode 100644 index 000000000..8c635baa8 --- /dev/null +++ b/app/views/shared/_ie_report_line.html.erb @@ -0,0 +1,65 @@ +<p class='lead'> +  <dl class="inline"> +    <dt><%=t('.read_lines') %> :</dt> +    <dd><%= job.report.lines %></dd> +    <dt><%=t('.saved_lines') %> :</dt> +    <dd><%= job.report.saved_lines %></dd> +    <dt><%=t('.unsaved_lines') %> :</dt> +    <dd><%= job.report.unsaved_lines %></dd> +  </dl> +</p> +<div class="report" data-refresh-interval="<%= job_refresh_interval(job) %>"> +  <p> +    <form class="form-inline"> +      <div class="form-group"> +        <label><%= t("shared.ie_report.html.search") %></label> +        <input id="filter-line" type="text" class="form-control"> +      </div> +      <div class="form-group"> +        <label><%= t(".table.line.state") %></label> +        <select class="filter-line-status form-control"> +          <option></option> +          <option value="true"><%=t(".state.#{type}.valid") %></option> +          <option value="false"><%=t(".state.#{type}.invalid") %></option> +        </select> +      </div> +    </form> +  </p> +  <table id="table-line" class="table table-hover table-striped data-table toggle-circle toggle-medium" data-filter="#filter-line" data-page-size="20"> +    <thead> +      <tr> +        <th><%= t(".table.line.state") %></th> +        <th><%= t(".table.line.lines") %></th> +        <th data-toggle="true" data-sort-ignore="true"><%= t(".table.line.details") %></th> +        <th data-hide="all"><%= t(".table.line.routes") %></th> +        <th data-hide="all"><%= t(".table.line.connection_links") %></th> +        <th data-hide="all"><%= t(".table.line.time_tables") %></th> +        <th data-hide="all"><%= t(".table.line.stop_areas") %></th> +        <th data-hide="all"><%= t(".table.line.access_points") %></th> +        <th data-hide="all"><%= t(".table.line.vehicle_journeys") %></th> +        <th data-hide="all"><%= t(".table.line.journey_patterns") %></th> +      </tr> +    </thead> +    <tbody> +      <% job.report.line_items.each_with_index do |line_item, index| %> +        <tr> +          <td data-value="<%=line_item.status%>"><%= line_item.status ? font_awesome_classic_tag("fa-check") : font_awesome_classic_tag("fa-times")  %></td> +          <td><%= line_item.name %></td> +          <td></td> +          <td><%= line_item.routes %></td> +          <td><%= line_item.connection_links %></td> +          <td><%= line_item.time_tables %></td> +          <td><%= line_item.stop_areas %></td> +          <td><%= line_item.access_points %></td> +          <td><%= line_item.vehicle_journeys %></td> +          <td><%= line_item.journey_patterns %></td> +        </tr> +      <% end %> +    </tbody> +    <tfoot> +      <tr> +        <td colspan="5"><ul class="pagination pagination-centered"></ul></td> +      </tr> +    </tfoot> +  </table> +</div> diff --git a/config/locales/compliance_check_results.yml b/config/locales/compliance_check_results.yml index d5c839638..acbaa6826 100644 --- a/config/locales/compliance_check_results.yml +++ b/config/locales/compliance_check_results.yml @@ -1,5 +1,6 @@  en:    compliance_check_results: +    errors: 'Errors'      file:        zip_name_prefix: "compliance_check_results"        summary_errors_file_prefix: "summary_of_tests.csv" @@ -344,6 +345,7 @@ en:          first_violations: "First violations"  fr:    compliance_check_results: +    errors: 'Erreurs'      file:        zip_name_prefix: "resultats_de_validation"        summary_errors_file_prefix: "sommaire_des_tests.csv" @@ -687,4 +689,3 @@ fr:          resource: "Ressource de l'objet en erreur"          url: "URL"          first_violations: "Premières  violations" - diff --git a/config/locales/compliance_checks.yml b/config/locales/compliance_checks.yml index 5917754cb..b94e66d92 100644 --- a/config/locales/compliance_checks.yml +++ b/config/locales/compliance_checks.yml @@ -14,6 +14,8 @@ en:        processing: "[ In progress... ]"        export: "Download test report"        export_csv: "CSV format" +    report: +      validation_success: "Validation successfully passed."      actions:        destroy_confirm: "Do you confirm to destroy this validation ?"        destroy: "Destroy this validation" @@ -83,11 +85,14 @@ fr:        processing: "[ En progression... ]"        export: "Télécharger les résultats"        export_csv: "Format CSV" +    report: +      validation_success: "La validation est passé avec succès." +      action_report: "Rapport d'action"      actions:        destroy_confirm: "Voulez-vous supprimer ce résultat de validation ?"        destroy: "Supprimer cette validation"        edit: "Editer cette validation" -      report: "Rapport" +      report: "Test de conformité"        rule_parameter_set: "Jeu de paramètres"        download: "Télécharger"      statuses: diff --git a/config/locales/en.yml b/config/locales/en.yml index 54c288773..4ebdcc94c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,5 +1,7 @@  en: +  "true": "Yes" +  "false": "No"    time:      formats:        hour: "%Hh%M" -      minute: "%M min"
\ No newline at end of file +      minute: "%M min" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 8ccfaacbf..6522fa211 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1,5 +1,7 @@  fr: +  "true": "Oui" +  "false": "Non"    time:      formats:        hour: "%Hh%M" -      minute: "%M min"
\ No newline at end of file +      minute: "%M min" diff --git a/config/locales/ie_report.en.yml b/config/locales/ie_report.en.yml index 9215bb9a6..06e49c016 100644 --- a/config/locales/ie_report.en.yml +++ b/config/locales/ie_report.en.yml @@ -1,28 +1,42 @@  en:    shared: -    ie_report:       +    ie_report:        html: -        graph: -          files: -            title_default: "%{job} result for %{extension} file" -            error: "Errors" -            ignored: "Ignored" -            ok: "Success" -          lines: -            title: "Data size by object types" -            objects_label: "Objects count"       -        table: -          line: -            save: "Save" -            routes: "Routes" -            lines: "Lines" -            connection_links: "Connection links" -            time_tables: "Timetables" -            stop_areas: "Stop Areas" -            access_points: "Access Points" -            vehicle_journeys: "Vehicle Journeys" -            journey_patterns: "Journey Patterns" -            not_saved: "Not saved" -            saved: "Saved" -            save_error: "Save error" -          
\ No newline at end of file +        search: 'Search' +        tab: +          file: 'Files' +          line: 'Lines' +    ie_report_line: +      state: +        default: +          valid: 'Saved lines' +          invalid: 'Unsaved lines' +        validation: +          valid: 'Valid lines' +          invalid: 'Invalid lines' +      read_lines: 'Read lines' +      saved_lines: 'Saved lines' +      unsaved_lines: 'Unsaved lines' +      table: +        line: +          state: "State" +          routes: "Routes" +          lines: "Lines" +          details: "Details" +          connection_links: "Connection links" +          time_tables: "Timetables" +          stop_areas: "Stop Areas" +          access_points: "Access Points" +          vehicle_journeys: "Vehicle Journeys" +          journey_patterns: "Journey Patterns" +          not_saved: "Not saved" +          saved: "Saved" +          save_error: "Save error" +    ie_report_file: +      title_default: "%{job} result for %{extension} file" +      table: +        state: 'State' +        name: 'Filename' +        error: "Error" +        ignored: "Ignored" +        ok: "Success" diff --git a/config/locales/ie_report.fr.yml b/config/locales/ie_report.fr.yml index 764e1710d..844dfbbe0 100644 --- a/config/locales/ie_report.fr.yml +++ b/config/locales/ie_report.fr.yml @@ -2,27 +2,41 @@ fr:    shared:      ie_report:        html: -        graph: -          files: -            title_default: "Résultat d'%{job} du fichier %{extension}" -            error: "Erreurs" -            ignored: "Ignorés" -            ok: "Succès" -          lines: -            title: "Volume de données lues par type de donnée" -            objects_label: "Quantité lue" -        table: -          line: -            save: "Sauvegarde" -            routes: "Séquences d'arrêts" -            lines: "Lignes" -            connection_links: "Correspondances" -            time_tables: "Calendriers" -            stop_areas: "Arrèts" -            access_points: "Accès" -            vehicle_journeys: "Courses" -            journey_patterns: "Missions" -            not_saved: "Non Sauvé" -            saved: "Sauvé" -            save_error: "Sauvegarde en erreur" - +        search: 'Recherche' +        tab: +          file: 'Fichiers' +          line: 'Lignes' +    ie_report_line: +      state: +        default: +          valid: 'Lignes sauvegardés' +          invalid: 'Lignes non-sauvegardés' +        validation: +          valid: 'Lignes valides' +          invalid: 'Lignes invalides' +      read_lines: 'Lignes lues' +      saved_lines: 'Lignes sauvegardés' +      unsaved_lines: 'Lignes non-sauvegardés' +      table: +        line: +          state: "État" +          routes: "Séquences d'arrêts" +          lines: "Lignes" +          details: "Détails" +          connection_links: "Correspondances" +          time_tables: "Calendriers" +          stop_areas: "Arrèts" +          access_points: "Accès" +          vehicle_journeys: "Courses" +          journey_patterns: "Missions" +          not_saved: "Non Sauvé" +          saved: "Sauvé" +          save_error: "Sauvegarde en erreur" +    ie_report_file: +      title_default: "Résultat d'%{job} du fichier %{extension}" +      table: +        state: 'État' +        name: 'Nom du fichier' +        error: "Erreur" +        ignored: "Ignoré" +        ok: "Succès" diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index 44767a6f5..32c4a2779 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -11,7 +11,7 @@ en:        report: "Report"        imported_file: "Original file"        rule_parameter_set: "Rule parameter set" -      compliance_check: "Validation" +      compliance_check: "Validation report"        compliance_check_of: "Validation of import: "        import_of_validation: "Import of the validation"      compliance_check_task: "Validate Report" diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index af71565eb..0eee4fc02 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -11,7 +11,7 @@ fr:        report: "Rapport"        imported_file: "Fichier source"        rule_parameter_set: "Jeu de paramètres" -      compliance_check: "Validation" +      compliance_check: "Test de conformité"        compliance_check_of: "Validation de l'import : "        import_of_validation: "L'import de la validation"      compliance_check_task: "Validation" @@ -56,4 +56,4 @@ fr:          max_distance_for_commercial: "Distance max pour créer les zones"          max_distance_for_connection_link: "Distance max pour créer les correspondances"          ignore_last_word: "ignorer le dernier mot" -        ignore_end_chars: "ignorer les n derniers caractères"
\ No newline at end of file +        ignore_end_chars: "ignorer les n derniers caractères" diff --git a/config/locales/layouts.yml b/config/locales/layouts.yml index d679fc01f..361f2322f 100644 --- a/config/locales/layouts.yml +++ b/config/locales/layouts.yml @@ -2,7 +2,7 @@ en:    layouts:      back_to_dashboard: "Back to Dashboard"      help: "Help" -    home: "Home"           +    home: "Home"      user:        profile: "My Profile"        sign_out: "Sign out" @@ -13,15 +13,16 @@ en:        return_to_dashboard: "Return to Dashboard"        referential_datas: "Datas"      history_tag: -      title: "Metadatas"   +      title: "Metadatas"        created_at: "Created at"        updated_at: "Updated at"        user_name: "User" +      no_save: "No backup"      flash_messages:        success: "Success"        error: "Error"        alert: "Alert" -      notice: "Info"       +      notice: "Info"      footer:        support:          title: "Support" @@ -35,16 +36,16 @@ en:          user_group: "User group"        contact:          title: "Contact" -        mail: "Contact us"       -        newsletter: "Newsletter"     -        forum: "Forum"          +        mail: "Contact us" +        newsletter: "Newsletter" +        forum: "Forum"  fr:    layouts:      back_to_dashboard: "Retour au Tableau de Bord"      help: "Aide"      home: "Accueil"      user: -      profile: "Mon Profil"       +      profile: "Mon Profil"        sign_out: "Déconnexion"      navbar:        return_to_referentials: "Retour à la liste des espaces de données" @@ -53,10 +54,11 @@ fr:        return_to_dashboard: "Retour au Tableau de Bord"        referential_datas: "Données"      history_tag: -      title: "Métadonnées"     +      title: "Métadonnées"        created_at: "Créé le"        updated_at: "Mise à jour le"        user_name: "Auteur" +      no_save: "Pas de sauvergarde"      flash_messages:        success: "Succès"        error: "Erreur" @@ -75,19 +77,18 @@ fr:          user_group: "Club utilisateur"        contact:          title: "Contact" -        mail: "Contactez nous"       -        newsletter: "Lettre d'information"     -        forum: "Forum"                +        mail: "Contactez nous" +        newsletter: "Lettre d'information" +        forum: "Forum"    true: "oui"    false: "non"    or: "ou"    back: "Revenir"    today: "Aujourd'hui"    yesterday: "Hier" -  edit_periods: "Editer Périodes"    -  delete_periods: "Supprimer Périodes"  +  edit_periods: "Editer Périodes" +  delete_periods: "Supprimer Périodes"    attributes:      author: "Modifié par"      created_at: "Créé le"      updated_at: "Modifié le" -       diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4af9e445c..92afd410b 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,6 +11,10 @@ require 'capybara/poltergeist'  require 'georuby-ext'  require 'will_paginate/array'  require 'fakeweb' +require 'simplecov' +SimpleCov.start 'rails' do +  add_filter "/.bundle" +end  # Requires supporting ruby files with custom matchers and macros, etc, in  # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are | 
