diff options
| author | Marc Florisson | 2014-01-22 17:41:04 +0100 | 
|---|---|---|
| committer | Marc Florisson | 2014-01-22 17:41:04 +0100 | 
| commit | c9437fc2e96f415e38c1e72fa10337769381f289 (patch) | |
| tree | 199b39a7c8c5cc2cfef539f73f73c1b5fbea8a72 | |
| parent | 4e71abdc01f9f04ce6eec1989fa756ffc823fd65 (diff) | |
| download | chouette-core-c9437fc2e96f415e38c1e72fa10337769381f289.tar.bz2 | |
merge branch validation
230 files changed, 4845 insertions, 2859 deletions
| @@ -1 +1 @@ -rvm ruby-1.8.7-p374 +rvm ruby-1.9.3-p448 diff --git a/.travis.yml b/.travis.yml index d91cd343e..3b34b286e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,18 @@  language: ruby  rvm: -  - 1.8.7 -  - jruby-18mode +  - 1.9.3 +  - jruby-19mode  jdk:    - oraclejdk7    - openjdk7  matrix:    exclude: -    - rvm:  1.8.7 -      jdk: openjdk7      - rvm:  1.9.3        jdk: openjdk7 +notifications: +    - mflorisson@cityway.fr +    - ldonnet@cityway.fr +    - metienne@cityway.fr  before_install:    - sudo apt-get update    - sudo apt-get install build-essential ruby-dev libproj-dev libgeos-dev libffi-dev libsparsehash-dev zlib1g-dev libxslt1-dev libxml2-dev libbz2-dev @@ -1,36 +1,29 @@  source 'http://rubygems.org' -gem 'rails', '3.2.6' +gem 'rails', '3.2.6'      platforms :jruby do    gem 'activerecord-jdbcpostgresql-adapter', '1.2.9'    gem 'activerecord-jdbcsqlite3-adapter'    gem 'jruby-openssl'    gem "jruby-rack-worker" -  gem 'warbler' -  gem 'therubyrhino' +  gem 'warbler'    +  gem 'therubyrhino'        end  platforms :ruby do -  gem 'therubyracer', '~> 0.10.2' -  gem 'pg', '~> 0.11.0' +  gem 'therubyracer', '~> 0.10.2'           +  gem 'pg', '~> 0.11.0'     gem 'sqlite3'  end -gem 'google-analytics-rails' -  # Authentication  gem 'devise', '2.1.3'  gem 'devise_invitable'  # Map, Geolocalization  gem "map_layers", "0.0.4" -gem "georuby-ext", :git => 'https://github.com/dryade/georuby-ext.git' , :ref => '69e3460141d831f0ad76780ee2b3f0a925a744f8' -gem "geokit","1.6.5" -gem "dbf","2.0.5" -gem "json_pure","1.7.7" -gem "multi_json","1.7.7" - +gem "georuby-ext", :git => 'git://github.com/dryade/georuby-ext.git'  #gem "georuby-ext", "0.0.2"  # User interface @@ -42,6 +35,9 @@ gem 'formtastic'  gem 'RedCloth'  gem 'jquery-rails', '2.2.1'  gem "modernizr-rails", "~> 2.0.6" +gem 'morrisjs-rails' +gem 'raphael-rails' +gem 'font-awesome-sass'  # Format Output  gem 'json' @@ -58,6 +54,7 @@ gem 'squeel'  gem 'ninoxe', '0.1.3'  gem 'acts_as_list', '0.1.6'  gem "acts_as_tree-1.8", '1.1.0', :require => "acts_as_tree" +gem "active_enum"  gem 'delayed_job_active_record'  gem 'dr-apartment', :require => "apartment" @@ -74,20 +71,20 @@ group :assets do    gem 'uglifier', '>= 1.0.3'  end -group :development do +group :development do     gem 'capistrano' -  gem 'capistrano-ext' +  gem 'capistrano-ext'       gem 'guard'    gem 'guard-rspec' -  gem 'rails-erd' +  gem 'rails-erd'         end  group :test, :development do    gem "rspec-rails", "~> 2.0" -  gem "remarkable", "~> 4.0.0.alpha4" -  gem "remarkable_activerecord", "~> 4.0.0.alpha4" +  gem "remarkable", "~> 4.0.0.alpha4"            +  gem "remarkable_activerecord", "~> 4.0.0.alpha4"     gem "shoulda-matchers" -  gem 'capybara' +  gem 'capybara'         gem 'launchy'    gem 'factory_girl_rails', '1.7'    gem 'rb-inotify', :require => RUBY_PLATFORM.include?('linux') && 'rb-inotify' @@ -95,7 +92,6 @@ group :test, :development do  end  group :production do -  gem "SyslogLogger" -  gem "daemons" +   gem "SyslogLogger"  end diff --git a/Gemfile.lock b/Gemfile.lock index bfd5cf59b..9cd208a8f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,6 @@  GIT -  remote: https://github.com/dryade/georuby-ext.git +  remote: git://github.com/dryade/georuby-ext.git    revision: 69e3460141d831f0ad76780ee2b3f0a925a744f8 -  ref: 69e3460141d831f0ad76780ee2b3f0a925a744f8    specs:      georuby-ext (0.0.2)        activesupport @@ -33,6 +32,8 @@ GEM        rack-cache (~> 1.2)        rack-test (~> 0.6.1)        sprockets (~> 2.1.3) +    active_enum (0.9.12) +      activesupport (~> 3.0)      activemodel (3.2.6)        activesupport (= 3.2.6)        builder (~> 3.0.0) @@ -57,8 +58,8 @@ GEM      acts_as_list (0.1.6)      acts_as_tree-1.8 (1.1.0)        activerecord (>= 3.0.0) -    addressable (2.2.8) -    arel (3.0.2) +    addressable (2.3.5) +    arel (3.0.3)      bcrypt-ruby (3.0.1)      bcrypt-ruby (3.0.1-java)      bouncy-castle-java (1.5.0146.1) @@ -80,8 +81,8 @@ GEM        rack-test (>= 0.5.4)        selenium-webdriver (~> 2.0)        xpath (~> 0.1.4) -    childprocess (0.3.5) -      ffi (~> 1.0, >= 1.0.6) +    childprocess (0.3.9) +      ffi (~> 1.0, >= 1.0.11)      choice (0.1.6)      cocoon (1.1.2)      coffee-rails (3.2.2) @@ -91,7 +92,6 @@ GEM        coffee-script-source        execjs      coffee-script-source (1.3.3) -    daemons (1.1.6)      dbf (2.0.5)        fastercsv (~> 1.5.4)      delayed_job (3.0.3) @@ -125,6 +125,8 @@ GEM      ffi (1.0.11-java)      ffi-geos (0.1.1)        ffi (>= 1.0.0) +    font-awesome-sass (4.0.2) +      sass-rails (>= 3.1.1)      foreigner (1.4.0)        activerecord (>= 3.0.0)      formtastic (2.2.1) @@ -132,20 +134,21 @@ GEM      geokit (1.6.5)        multi_json      georuby (1.9.8) -    google-analytics-rails (0.0.4)      gravatar_image_tag (1.1.3)      guard (1.3.2)        listen (>= 0.4.2)        thor (>= 0.14.6)      guard-rspec (1.2.1)        guard (>= 1.1) -    has_scope (0.5.1) +    has_scope (0.6.0.rc) +      actionpack (>= 3.2, < 5) +      activesupport (>= 3.2, < 5)      highline (1.6.15) -    hike (1.2.2) -    i18n (0.6.5) -    inherited_resources (1.3.1) -      has_scope (~> 0.5.0) -      responders (~> 0.6) +    hike (1.2.3) +    i18n (0.6.9) +    inherited_resources (1.4.1) +      has_scope (~> 0.6.0.rc) +      responders (~> 1.0.0.rc)      jdbc-postgres (9.2.1002.1)      jdbc-sqlite3 (3.7.2.1)      journey (1.0.4) @@ -158,18 +161,12 @@ GEM      jruby-rack (1.1.9)      jruby-rack-worker (0.4-java)        jruby-rack (>= 1.1.1) -    json (1.7.7) -    json (1.7.7-java) -    json_pure (1.7.7) -    launchy (2.1.0) -      addressable (~> 2.2.6) -    launchy (2.1.0-java) -      addressable (~> 2.2.6) -      ffi (~> 1.0.9) -      spoon (~> 0.0.1) +    json (1.8.1) +    json (1.8.1-java) +    json_pure (1.8.0) +    launchy (2.3.0) +      addressable (~> 2.3)      libv8 (3.3.10.4) -    libwebsocket (0.1.5) -      addressable      listen (0.4.7)        rb-fchange (~> 0.0.5)        rb-fsevent (~> 0.9.1) @@ -179,9 +176,11 @@ GEM        mime-types (~> 1.16)        treetop (~> 1.4.8)      map_layers (0.0.4) -    mime-types (1.19) +    mime-types (1.25.1)      modernizr-rails (2.0.6) -    multi_json (1.7.7) +    morrisjs-rails (0.4.3) +      railties (> 3.1, < 5) +    multi_json (1.8.2)      net-scp (1.0.4)        net-ssh (>= 1.99.1)      net-sftp (2.0.5) @@ -232,11 +231,12 @@ GEM        rake (>= 0.8.7)        rdoc (~> 3.4)        thor (>= 0.14.6, < 2.0) -    rake (10.0.4) +    rake (10.1.0)      ransack (0.7.0)        actionpack (~> 3.0)        activerecord (~> 3.0)        polyamorous (~> 0.5.0) +    raphael-rails (2.1.2)      rb-fchange (0.0.5)        ffi      rb-fsevent (0.9.1) @@ -253,8 +253,8 @@ GEM        remarkable (~> 4.0.0.alpha4)        remarkable_activemodel (~> 4.0.0.alpha4)        rspec (>= 2.0.0.alpha11) -    responders (0.9.2) -      railties (~> 3.1) +    responders (1.0.0) +      railties (>= 3.2, < 5)      rgeo (0.3.20)      rspec (2.13.0)        rspec-core (~> 2.13.0) @@ -278,14 +278,13 @@ GEM        railties (~> 3.2.0)        sass (>= 3.1.10)        tilt (~> 1.3) -    selenium-webdriver (2.25.0) +    selenium-webdriver (2.35.1)        childprocess (>= 0.2.5) -      libwebsocket (~> 0.1.3)        multi_json (~> 1.0) -      rubyzip +      rubyzip (< 1.0.0) +      websocket (~> 1.0.4)      shoulda-matchers (1.2.0)        activesupport (>= 3.0.0) -    spoon (0.0.1)      sprockets (2.1.3)        hike (~> 1.2)        rack (~> 1.0) @@ -301,11 +300,11 @@ GEM        therubyrhino_jar (>= 1.7.3)      therubyrhino_jar (1.7.4)      thor (0.18.1) -    tilt (1.3.6) -    treetop (1.4.12) +    tilt (1.4.1) +    treetop (1.4.15)        polyglot        polyglot (>= 0.3.1) -    tzinfo (0.3.37) +    tzinfo (0.3.38)      uglifier (1.2.7)        execjs (>= 0.3.0)        multi_json (~> 1.3) @@ -318,6 +317,7 @@ GEM        rubyzip (>= 0.9.4)      warden (1.2.1)        rack (>= 1.0) +    websocket (1.0.7)      will_paginate (3.0.3)      xpath (0.1.4)        nokogiri (~> 1.3) @@ -329,6 +329,7 @@ PLATFORMS  DEPENDENCIES    RedCloth    SyslogLogger +  active_enum    activerecord-jdbcpostgresql-adapter (= 1.2.9)    activerecord-jdbcsqlite3-adapter    acts_as_list (= 0.1.6) @@ -340,17 +341,14 @@ DEPENDENCIES    cocoon (= 1.1.2)    coffee-rails (~> 3.2.1)    coffee-script-source -  daemons -  dbf (= 2.0.5)    delayed_job_active_record    devise (= 2.1.3)    devise_invitable    dr-apartment    factory_girl_rails (= 1.7) +  font-awesome-sass    formtastic -  geokit (= 1.6.5)    georuby-ext! -  google-analytics-rails    gravatar_image_tag    guard    guard-rspec @@ -359,17 +357,17 @@ DEPENDENCIES    jruby-openssl    jruby-rack-worker    json -  json_pure (= 1.7.7)    launchy    map_layers (= 0.0.4)    modernizr-rails (~> 2.0.6) -  multi_json (= 1.7.7) +  morrisjs-rails    ninoxe (= 0.1.3)    pg (~> 0.11.0)    rabl    rails (= 3.2.6)    rails-erd    ransack +  raphael-rails    rb-fsevent    rb-inotify    remarkable (~> 4.0.0.alpha4) diff --git a/app/assets/images/import-completed.png b/app/assets/images/compliance_check_task-completed.pngBinary files differ index a76d76b13..a76d76b13 100644 --- a/app/assets/images/import-completed.png +++ b/app/assets/images/compliance_check_task-completed.png diff --git a/app/assets/images/import-failed.png b/app/assets/images/compliance_check_task-failed.pngBinary files differ index f13b19234..f13b19234 100644 --- a/app/assets/images/import-failed.png +++ b/app/assets/images/compliance_check_task-failed.png diff --git a/app/assets/images/import-pending.png b/app/assets/images/compliance_check_task-pending.pngBinary files differ index 1e50e36ac..1e50e36ac 100644 --- a/app/assets/images/import-pending.png +++ b/app/assets/images/compliance_check_task-pending.png diff --git a/app/assets/images/compliance_check_task-processing.png b/app/assets/images/compliance_check_task-processing.pngBinary files differ new file mode 100644 index 000000000..1e50e36ac --- /dev/null +++ b/app/assets/images/compliance_check_task-processing.png diff --git a/app/assets/images/icons/collapse.png b/app/assets/images/icons/collapse.pngBinary files differ new file mode 100644 index 000000000..5411a1b91 --- /dev/null +++ b/app/assets/images/icons/collapse.png diff --git a/app/assets/images/icons/expand.png b/app/assets/images/icons/expand.pngBinary files differ new file mode 100644 index 000000000..8cad0129b --- /dev/null +++ b/app/assets/images/icons/expand.png diff --git a/app/assets/images/icons/file_basic.png b/app/assets/images/icons/file_basic.pngBinary files differ new file mode 100644 index 000000000..ec5bec65f --- /dev/null +++ b/app/assets/images/icons/file_basic.png diff --git a/app/assets/images/icons/file_xml.png b/app/assets/images/icons/file_xml.pngBinary files differ new file mode 100644 index 000000000..bff923f27 --- /dev/null +++ b/app/assets/images/icons/file_xml.png diff --git a/app/assets/images/icons/file_xml_md.png b/app/assets/images/icons/file_xml_md.pngBinary files differ new file mode 100644 index 000000000..6e471ca2a --- /dev/null +++ b/app/assets/images/icons/file_xml_md.png diff --git a/app/assets/images/icons/file_zip.png b/app/assets/images/icons/file_zip.pngBinary files differ new file mode 100644 index 000000000..9893c5cfb --- /dev/null +++ b/app/assets/images/icons/file_zip.png diff --git a/app/assets/images/icons/help-contents.png b/app/assets/images/icons/help-contents.pngBinary files differ new file mode 100644 index 000000000..a6a986e19 --- /dev/null +++ b/app/assets/images/icons/help-contents.png diff --git a/app/assets/images/icons/help.png b/app/assets/images/icons/help.pngBinary files differ new file mode 100644 index 000000000..e6edf6ba2 --- /dev/null +++ b/app/assets/images/icons/help.png diff --git a/app/assets/images/icons/link_page.png b/app/assets/images/icons/link_page.pngBinary files differ new file mode 100644 index 000000000..a2c53bf3e --- /dev/null +++ b/app/assets/images/icons/link_page.png diff --git a/app/assets/images/icons/notice.png b/app/assets/images/icons/notice.pngBinary files differ new file mode 100644 index 000000000..16510c9c4 --- /dev/null +++ b/app/assets/images/icons/notice.png diff --git a/app/assets/images/icons/status_na.png b/app/assets/images/icons/status_na.pngBinary files differ new file mode 100644 index 000000000..4a892e60c --- /dev/null +++ b/app/assets/images/icons/status_na.png diff --git a/app/assets/images/icons/status_nok.png b/app/assets/images/icons/status_nok.pngBinary files differ new file mode 100644 index 000000000..8dd9d2968 --- /dev/null +++ b/app/assets/images/icons/status_nok.png diff --git a/app/assets/images/icons/status_ok.png b/app/assets/images/icons/status_ok.pngBinary files differ new file mode 100644 index 000000000..ab7c378c0 --- /dev/null +++ b/app/assets/images/icons/status_ok.png diff --git a/app/assets/images/import_task-completed.png b/app/assets/images/import_task-completed.pngBinary files differ new file mode 100644 index 000000000..a76d76b13 --- /dev/null +++ b/app/assets/images/import_task-completed.png diff --git a/app/assets/images/import_task-failed.png b/app/assets/images/import_task-failed.pngBinary files differ new file mode 100644 index 000000000..f13b19234 --- /dev/null +++ b/app/assets/images/import_task-failed.png diff --git a/app/assets/images/import_task-pending.png b/app/assets/images/import_task-pending.pngBinary files differ new file mode 100644 index 000000000..1e50e36ac --- /dev/null +++ b/app/assets/images/import_task-pending.png diff --git a/app/assets/images/import_task-processing.png b/app/assets/images/import_task-processing.pngBinary files differ new file mode 100644 index 000000000..1e50e36ac --- /dev/null +++ b/app/assets/images/import_task-processing.png diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 69d083fe7..6b7b38a3a 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -9,5 +9,6 @@  //= require jquery-ui  //= require modernizr  //= require cocoon -//= require_directory ./public +//= require raphael +//= require morris  //= require_directory . diff --git a/app/assets/javascripts/compliance_check_tasks.js.coffee b/app/assets/javascripts/compliance_check_tasks.js.coffee new file mode 100644 index 000000000..feed5de2d --- /dev/null +++ b/app/assets/javascripts/compliance_check_tasks.js.coffee @@ -0,0 +1,14 @@ +jQuery -> +  compliance_check_task_references_type_change = (event) -> +    references_type = $(event.target).val() + +    toggle_input = (li) -> +      enabled = (li.data("type") == references_type) +      # Hide li block +      li.toggle(enabled) +      # Disable textarea to ignore it in POST data +      li.find("textarea").attr("disabled", ! enabled) + +    toggle_input($(li)) for li in $(event.target).parents('form').find("li.compliance_check_task_reference_ids") + +  $('select[name="compliance_check_task[references_type]"]').change(compliance_check_task_references_type_change) diff --git a/app/assets/javascripts/exports.js.coffee b/app/assets/javascripts/exports.js.coffee index 71b565e91..045b95e2e 100644 --- a/app/assets/javascripts/exports.js.coffee +++ b/app/assets/javascripts/exports.js.coffee @@ -1,5 +1,5 @@  jQuery -> -  export_references_type_change = (event) ->  +  export_references_type_change = (event) ->      references_type = $(event.target).val()      toggle_input = (li) -> @@ -15,7 +15,7 @@ jQuery ->    $('#export_type_submit').hide() -  export_type_change = (event) ->  +  export_type_change = (event) ->      export_type = $("input:radio:checked").attr("value")      $(form).toggle($(form).is("#" + export_type + "_new")) for form in $('form.export[method = "post"]') diff --git a/app/assets/javascripts/import_tasks.js.coffee b/app/assets/javascripts/import_tasks.js.coffee new file mode 100644 index 000000000..690d86976 --- /dev/null +++ b/app/assets/javascripts/import_tasks.js.coffee @@ -0,0 +1,10 @@ +jQuery -> + +  import_format_change = (event) ->  +    import_task_type = $("input:radio:checked").attr("value") +    console.log("import_task_type="+import_task_type) +    $(form).toggle($(form).is("#" + import_task_type + "_new")) for form in $('form.import_task[method = "post"]')   + +  $("#import_task_format_input :radio[name='import_task[format]']").change(import_format_change) +   +  $('.import_tasks [title]').tipsy({gravity: 'w'})
\ No newline at end of file diff --git a/app/assets/javascripts/imports.js.coffee b/app/assets/javascripts/imports.js.coffee deleted file mode 100644 index ea6473595..000000000 --- a/app/assets/javascripts/imports.js.coffee +++ /dev/null @@ -1,9 +0,0 @@ -jQuery -> -  $('#import_type_submit').hide() - -  import_type_change = (event) ->  -    import_type = $("input:radio:checked").attr("value") -    console.log("import_type="+import_type) -    $(form).toggle($(form).is("#" + import_type + "_new")) for form in $('form.import[method = "post"]') - -  $("#import_type_input :radio[name='import[type]']").change(import_type_change) diff --git a/app/assets/javascripts/plugins.js b/app/assets/javascripts/plugins.js new file mode 100644 index 000000000..6f6a902ae --- /dev/null +++ b/app/assets/javascripts/plugins.js @@ -0,0 +1 @@ +//= require_directory ./plugins diff --git a/app/assets/javascripts/plugins/bootstrap.min.js b/app/assets/javascripts/plugins/bootstrap.min.js new file mode 100644 index 000000000..fb820c1a2 --- /dev/null +++ b/app/assets/javascripts/plugins/bootstrap.min.js @@ -0,0 +1,11 @@ +/*! + * Bootstrap v3.0.3 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + ++function(a){"use strict";var b='[data-dismiss="alert"]',c=function(c){a(c).on("click",b,this.close)};c.prototype.close=function(b){function f(){e.trigger("closed.bs.alert").remove()}var c=a(this),d=c.attr("data-target");d||(d=c.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));var e=a(d);b&&b.preventDefault(),e.length||(e=c.hasClass("alert")?c:c.parent()),e.trigger(b=a.Event("close.bs.alert"));if(b.isDefaultPrevented())return;e.removeClass("in"),a.support.transition&&e.hasClass("fade")?e.one(a.support.transition.end,f).emulateTransitionEnd(150):f()};var d=a.fn.alert;a.fn.alert=function(b){return this.each(function(){var d=a(this),e=d.data("bs.alert");e||d.data("bs.alert",e=new c(this)),typeof b=="string"&&e[b].call(d)})},a.fn.alert.Constructor=c,a.fn.alert.noConflict=function(){return a.fn.alert=d,this},a(document).on("click.bs.alert.data-api",b,c.prototype.close)}(jQuery),+function(a){"use strict";var b=function(c,d){this.$element=a(c),this.options=a.extend({},b.DEFAULTS,d)};b.DEFAULTS={loadingText:"loading..."},b.prototype.setState=function(a){var b="disabled",c=this.$element,d=c.is("input")?"val":"html",e=c.data();a+="Text",e.resetText||c.data("resetText",c[d]()),c[d](e[a]||this.options[a]),setTimeout(function(){a=="loadingText"?c.addClass(b).attr(b,b):c.removeClass(b).removeAttr(b)},0)},b.prototype.toggle=function(){var a=this.$element.closest('[data-toggle="buttons"]'),b=!0;if(a.length){var c=this.$element.find("input");c.prop("type")==="radio"&&(c.prop("checked")&&this.$element.hasClass("active")?b=!1:a.find(".active").removeClass("active")),b&&c.prop("checked",!this.$element.hasClass("active")).trigger("change")}b&&this.$element.toggleClass("active")};var c=a.fn.button;a.fn.button=function(c){return this.each(function(){var d=a(this),e=d.data("bs.button"),f=typeof c=="object"&&c;e||d.data("bs.button",e=new b(this,f)),c=="toggle"?e.toggle():c&&e.setState(c)})},a.fn.button.Constructor=b,a.fn.button.noConflict=function(){return a.fn.button=c,this},a(document).on("click.bs.button.data-api","[data-toggle^=button]",function(b){var c=a(b.target);c.hasClass("btn")||(c=c.closest(".btn")),c.button("toggle"),b.preventDefault()})}(jQuery),+function(a){function e(){a(b).remove(),a(c).each(function(b){var c=f(a(this));if(!c.hasClass("open"))return;c.trigger(b=a.Event("hide.bs.dropdown"));if(b.isDefaultPrevented())return;c.removeClass("open").trigger("hidden.bs.dropdown")})}function f(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}"use strict";var b=".dropdown-backdrop",c="[data-toggle=dropdown]",d=function(b){a(b).on("click.bs.dropdown",this.toggle)};d.prototype.toggle=function(b){var c=a(this);if(c.is(".disabled, :disabled"))return;var d=f(c),g=d.hasClass("open");e();if(!g){"ontouchstart"in document.documentElement&&!d.closest(".navbar-nav").length&&a('<div class="dropdown-backdrop"/>').insertAfter(a(this)).on("click",e),d.trigger(b=a.Event("show.bs.dropdown"));if(b.isDefaultPrevented())return;d.toggleClass("open").trigger("shown.bs.dropdown"),c.focus()}return!1},d.prototype.keydown=function(b){if(!/(38|40|27)/.test(b.keyCode))return;var d=a(this);b.preventDefault(),b.stopPropagation();if(d.is(".disabled, :disabled"))return;var e=f(d),g=e.hasClass("open");if(!g||g&&b.keyCode==27)return b.which==27&&e.find(c).focus(),d.click();var h=a("[role=menu] li:not(.divider):visible a",e);if(!h.length)return;var i=h.index(h.filter(":focus"));b.keyCode==38&&i>0&&i--,b.keyCode==40&&i<h.length-1&&i++,~i||(i=0),h.eq(i).focus()};var g=a.fn.dropdown;a.fn.dropdown=function(b){return this.each(function(){var c=a(this),e=c.data("bs.dropdown");e||c.data("bs.dropdown",e=new d(this)),typeof b=="string"&&e[b].call(c)})},a.fn.dropdown.Constructor=d,a.fn.dropdown.noConflict=function(){return a.fn.dropdown=g,this},a(document).on("click.bs.dropdown.data-api",e).on("click.bs.dropdown.data-api",".dropdown form",function(a){a.stopPropagation()}).on("click.bs.dropdown.data-api",c,d.prototype.toggle).on("keydown.bs.dropdown.data-api",c+", [role=menu]",d.prototype.keydown)}(jQuery),+function(a){"use strict";var b=function(b,c){this.options=c,this.$element=a(b),this.$backdrop=this.isShown=null,this.options.remote&&this.$element.load(this.options.remote)};b.DEFAULTS={backdrop:!0,keyboard:!0,show:!0},b.prototype.toggle=function(a){return this[this.isShown?"hide":"show"](a)},b.prototype.show=function(b){var c=this,d=a.Event("show.bs.modal",{relatedTarget:b});this.$element.trigger(d);if(this.isShown||d.isDefaultPrevented())return;this.isShown=!0,this.escape(),this.$element.on("click.dismiss.modal",'[data-dismiss="modal"]',a.proxy(this.hide,this)),this.backdrop(function(){var d=a.support.transition&&c.$element.hasClass("fade");c.$element.parent().length||c.$element.appendTo(document.body),c.$element.show(),d&&c.$element[0].offsetWidth,c.$element.addClass("in").attr("aria-hidden",!1),c.enforceFocus();var e=a.Event("shown.bs.modal",{relatedTarget:b});d?c.$element.find(".modal-dialog").one(a.support.transition.end,function(){c.$element.focus().trigger(e)}).emulateTransitionEnd(300):c.$element.focus().trigger(e)})},b.prototype.hide=function(b){b&&b.preventDefault(),b=a.Event("hide.bs.modal"),this.$element.trigger(b);if(!this.isShown||b.isDefaultPrevented())return;this.isShown=!1,this.escape(),a(document).off("focusin.bs.modal"),this.$element.removeClass("in").attr("aria-hidden",!0).off("click.dismiss.modal"),a.support.transition&&this.$element.hasClass("fade")?this.$element.one(a.support.transition.end,a.proxy(this.hideModal,this)).emulateTransitionEnd(300):this.hideModal()},b.prototype.enforceFocus=function(){a(document).off("focusin.bs.modal").on("focusin.bs.modal",a.proxy(function(a){this.$element[0]!==a.target&&!this.$element.has(a.target).length&&this.$element.focus()},this))},b.prototype.escape=function(){this.isShown&&this.options.keyboard?this.$element.on("keyup.dismiss.bs.modal",a.proxy(function(a){a.which==27&&this.hide()},this)):this.isShown||this.$element.off("keyup.dismiss.bs.modal")},b.prototype.hideModal=function(){var a=this;this.$element.hide(),this.backdrop(function(){a.removeBackdrop(),a.$element.trigger("hidden.bs.modal")})},b.prototype.removeBackdrop=function(){this.$backdrop&&this.$backdrop.remove(),this.$backdrop=null},b.prototype.backdrop=function(b){var c=this,d=this.$element.hasClass("fade")?"fade":"";if(this.isShown&&this.options.backdrop){var e=a.support.transition&&d;this.$backdrop=a('<div class="modal-backdrop '+d+'" />').appendTo(document.body),this.$element.on("click.dismiss.modal",a.proxy(function(a){if(a.target!==a.currentTarget)return;this.options.backdrop=="static"?this.$element[0].focus.call(this.$element[0]):this.hide.call(this)},this)),e&&this.$backdrop[0].offsetWidth,this.$backdrop.addClass("in");if(!b)return;e?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()}else!this.isShown&&this.$backdrop?(this.$backdrop.removeClass("in"),a.support.transition&&this.$element.hasClass("fade")?this.$backdrop.one(a.support.transition.end,b).emulateTransitionEnd(150):b()):b&&b()};var c=a.fn.modal;a.fn.modal=function(c,d){return this.each(function(){var e=a(this),f=e.data("bs.modal"),g=a.extend({},b.DEFAULTS,e.data(),typeof c=="object"&&c);f||e.data("bs.modal",f=new b(this,g)),typeof c=="string"?f[c](d):g.show&&f.show(d)})},a.fn.modal.Constructor=b,a.fn.modal.noConflict=function(){return a.fn.modal=c,this},a(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',function(b){var c=a(this),d=c.attr("href"),e=a(c.attr("data-target")||d&&d.replace(/.*(?=#[^\s]+$)/,"")),f=e.data("modal")?"toggle":a.extend({remote:!/#/.test(d)&&d},e.data(),c.data());b.preventDefault(),e.modal(f,this).one("hide",function(){c.is(":visible")&&c.focus()})}),a(document).on("show.bs.modal",".modal",function(){a(document.body).addClass("modal-open")}).on("hidden.bs.modal",".modal",function(){a(document.body).removeClass("modal-open")})}(jQuery),+function(a){"use strict";var b=function(a,b){this.type=this.options=this.enabled=this.timeout=this.hoverState=this.$element=null,this.init("tooltip",a,b)};b.DEFAULTS={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1},b.prototype.init=function(b,c,d){this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d);var e=this.options.trigger.split(" ");for(var f=e.length;f--;){var g=e[f];if(g=="click")this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if(g!="manual"){var h=g=="hover"?"mouseenter":"focus",i=g=="hover"?"mouseleave":"blur";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&typeof b.delay=="number"&&(b.delay={show:b.delay,hide:b.delay}),b},b.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},b.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);clearTimeout(c.timeout),c.hoverState="in";if(!c.options.delay||!c.options.delay.show)return c.show();c.timeout=setTimeout(function(){c.hoverState=="in"&&c.show()},c.options.delay.show)},b.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type);clearTimeout(c.timeout),c.hoverState="out";if(!c.options.delay||!c.options.delay.hide)return c.hide();c.timeout=setTimeout(function(){c.hoverState=="out"&&c.hide()},c.options.delay.hide)},b.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);if(b.isDefaultPrevented())return;var c=this.tip();this.setContent(),this.options.animation&&c.addClass("fade");var d=typeof this.options.placement=="function"?this.options.placement.call(this,c[0],this.$element[0]):this.options.placement,e=/\s?auto?\s?/i,f=e.test(d);f&&(d=d.replace(e,"")||"top"),c.detach().css({top:0,left:0,display:"block"}).addClass(d),this.options.container?c.appendTo(this.options.container):c.insertAfter(this.$element);var g=this.getPosition(),h=c[0].offsetWidth,i=c[0].offsetHeight;if(f){var j=this.$element.parent(),k=d,l=document.documentElement.scrollTop||document.body.scrollTop,m=this.options.container=="body"?window.innerWidth:j.outerWidth(),n=this.options.container=="body"?window.innerHeight:j.outerHeight(),o=this.options.container=="body"?0:j.offset().left;d=d=="bottom"&&g.top+g.height+i-l>n?"top":d=="top"&&g.top-l-i<0?"bottom":d=="right"&&g.right+h>m?"left":d=="left"&&g.left-h<o?"right":d,c.removeClass(k).addClass(d)}var p=this.getCalculatedOffset(d,g,h,i);this.applyPlacement(p,d),this.$element.trigger("shown.bs."+this.type)}},b.prototype.applyPlacement=function(a,b){var c,d=this.tip(),e=d[0].offsetWidth,f=d[0].offsetHeight,g=parseInt(d.css("margin-top"),10),h=parseInt(d.css("margin-left"),10);isNaN(g)&&(g=0),isNaN(h)&&(h=0),a.top=a.top+g,a.left=a.left+h,d.offset(a).addClass("in");var i=d[0].offsetWidth,j=d[0].offsetHeight;b=="top"&&j!=f&&(c=!0,a.top=a.top+f-j);if(/bottom|top/.test(b)){var k=0;a.left<0&&(k=a.left*-2,a.left=0,d.offset(a),i=d[0].offsetWidth,j=d[0].offsetHeight),this.replaceArrow(k-e+i,i,"left")}else this.replaceArrow(j-f,j,"top");c&&d.offset(a)},b.prototype.replaceArrow=function(a,b,c){this.arrow().css(c,a?50*(1-a/b)+"%":"")},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle();a.find(".tooltip-inner")[this.options.html?"html":"text"](b),a.removeClass("fade in top bottom left right")},b.prototype.hide=function(){function e(){b.hoverState!="in"&&c.detach()}var b=this,c=this.tip(),d=a.Event("hide.bs."+this.type);this.$element.trigger(d);if(d.isDefaultPrevented())return;return c.removeClass("in"),a.support.transition&&this.$tip.hasClass("fade")?c.one(a.support.transition.end,e).emulateTransitionEnd(150):e(),this.$element.trigger("hidden.bs."+this.type),this},b.prototype.fixTitle=function(){var a=this.$element;(a.attr("title")||typeof a.attr("data-original-title")!="string")&&a.attr("data-original-title",a.attr("title")||"").attr("title","")},b.prototype.hasContent=function(){return this.getTitle()},b.prototype.getPosition=function(){var b=this.$element[0];return a.extend({},typeof b.getBoundingClientRect=="function"?b.getBoundingClientRect():{width:b.offsetWidth,height:b.offsetHeight},this.$element.offset())},b.prototype.getCalculatedOffset=function(a,b,c,d){return a=="bottom"?{top:b.top+b.height,left:b.left+b.width/2-c/2}:a=="top"?{top:b.top-d,left:b.left+b.width/2-c/2}:a=="left"?{top:b.top+b.height/2-d/2,left:b.left-c}:{top:b.top+b.height/2-d/2,left:b.left+b.width}},b.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||(typeof c.title=="function"?c.title.call(b[0]):c.title),a},b.prototype.tip=function(){return this.$tip=this.$tip||a(this.options.template)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},b.prototype.validate=function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},b.prototype.enable=function(){this.enabled=!0},b.prototype.disable=function(){this.enabled=!1},b.prototype.toggleEnabled=function(){this.enabled=!this.enabled},b.prototype.toggle=function(b){var c=b?a(b.currentTarget)[this.type](this.getDelegateOptions()).data("bs."+this.type):this;c.tip().hasClass("in")?c.leave(c):c.enter(c)},b.prototype.destroy=function(){this.hide().$element.off("."+this.type).removeData("bs."+this.type)};var c=a.fn.tooltip;a.fn.tooltip=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tooltip"),f=typeof c=="object"&&c;e||d.data("bs.tooltip",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.tooltip.Constructor=b,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=c,this}}(jQuery),+function(a){"use strict";var b=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");b.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'}),b.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),b.prototype.constructor=b,b.prototype.getDefaults=function(){return b.DEFAULTS},b.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content")[this.options.html?"html":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},b.prototype.hasContent=function(){return this.getTitle()||this.getContent()},b.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||(typeof b.content=="function"?b.content.call(a[0]):b.content)},b.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")},b.prototype.tip=function(){return this.$tip||(this.$tip=a(this.options.template)),this.$tip};var c=a.fn.popover;a.fn.popover=function(c){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f=typeof c=="object"&&c;e||d.data("bs.popover",e=new b(this,f)),typeof c=="string"&&e[c]()})},a.fn.popover.Constructor=b,a.fn.popover.noConflict=function(){return a.fn.popover=c,this}}(jQuery),+function(a){"use strict";var b=function(b){this.element=a(b)};b.prototype.show=function(){var b=this.element,c=b.closest("ul:not(.dropdown-menu)"),d=b.data("target");d||(d=b.attr("href"),d=d&&d.replace(/.*(?=#[^\s]*$)/,""));if(b.parent("li").hasClass("active"))return;var e=c.find(".active:last a")[0],f=a.Event("show.bs.tab",{relatedTarget:e});b.trigger(f);if(f.isDefaultPrevented())return;var g=a(d);this.activate(b.parent("li"),c),this.activate(g,g.parent(),function(){b.trigger({type:"shown.bs.tab",relatedTarget:e})})},b.prototype.activate=function(b,c,d){function g(){e.removeClass("active").find("> .dropdown-menu > .active").removeClass("active"),b.addClass("active"),f?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu")&&b.closest("li.dropdown").addClass("active"),d&&d()}var e=c.find("> .active"),f=d&&a.support.transition&&e.hasClass("fade");f?e.one(a.support.transition.end,g).emulateTransitionEnd(150):g(),e.removeClass("in")};var c=a.fn.tab;a.fn.tab=function(c){return this.each(function(){var d=a(this),e=d.data("bs.tab");e||d.data("bs.tab",e=new b(this)),typeof c=="string"&&e[c]()})},a.fn.tab.Constructor=b,a.fn.tab.noConflict=function(){return a.fn.tab=c,this},a(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',function(b){b.preventDefault(),a(this).tab("show")})}(jQuery)
\ No newline at end of file diff --git a/app/assets/javascripts/public/formtastic.qtip2.min.js b/app/assets/javascripts/plugins/formtastic.qtip2.min.js index 52a1ef1f7..52a1ef1f7 100644 --- a/app/assets/javascripts/public/formtastic.qtip2.min.js +++ b/app/assets/javascripts/plugins/formtastic.qtip2.min.js diff --git a/app/assets/javascripts/public/jquery.qtip.min.js b/app/assets/javascripts/plugins/jquery.qtip.min.js index 1ed034ee3..1ed034ee3 100644 --- a/app/assets/javascripts/public/jquery.qtip.min.js +++ b/app/assets/javascripts/plugins/jquery.qtip.min.js diff --git a/app/assets/javascripts/plugins/jquery.tipsy.js b/app/assets/javascripts/plugins/jquery.tipsy.js new file mode 100644 index 000000000..f95c063fd --- /dev/null +++ b/app/assets/javascripts/plugins/jquery.tipsy.js @@ -0,0 +1,258 @@ +// tipsy, facebook style tooltips for jquery +// version 1.0.0a +// (c) 2008-2010 jason frame [jason@onehackoranother.com] +// released under the MIT license + +(function($) { +     +    function maybeCall(thing, ctx) { +        return (typeof thing == 'function') ? (thing.call(ctx)) : thing; +    }; +     +    function isElementInDOM(ele) { +      while (ele = ele.parentNode) { +        if (ele == document) return true; +      } +      return false; +    }; +     +    function Tipsy(element, options) { +        this.$element = $(element); +        this.options = options; +        this.enabled = true; +        this.fixTitle(); +    }; +     +    Tipsy.prototype = { +        show: function() { +            var title = this.getTitle(); +            if (title && this.enabled) { +                var $tip = this.tip(); +                 +                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title); +                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity +                $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body); +                 +                var pos = $.extend({}, this.$element.offset(), { +                    width: this.$element[0].offsetWidth, +                    height: this.$element[0].offsetHeight +                }); +                 +                var actualWidth = $tip[0].offsetWidth, +                    actualHeight = $tip[0].offsetHeight, +                    gravity = maybeCall(this.options.gravity, this.$element[0]); +                 +                var tp; +                switch (gravity.charAt(0)) { +                    case 'n': +                        tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; +                        break; +                    case 's': +                        tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2}; +                        break; +                    case 'e': +                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset}; +                        break; +                    case 'w': +                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset}; +                        break; +                } +                 +                if (gravity.length == 2) { +                    if (gravity.charAt(1) == 'w') { +                        tp.left = pos.left + pos.width / 2 - 15; +                    } else { +                        tp.left = pos.left + pos.width / 2 - actualWidth + 15; +                    } +                } +                 +                $tip.css(tp).addClass('tipsy-' + gravity); +                $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0); +                if (this.options.className) { +                    $tip.addClass(maybeCall(this.options.className, this.$element[0])); +                } +                 +                if (this.options.fade) { +                    $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity}); +                } else { +                    $tip.css({visibility: 'visible', opacity: this.options.opacity}); +                } +            } +        }, +         +        hide: function() { +            if (this.options.fade) { +                this.tip().stop().fadeOut(function() { $(this).remove(); }); +            } else { +                this.tip().remove(); +            } +        }, +         +        fixTitle: function() { +            var $e = this.$element; +            if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') { +                $e.attr('original-title', $e.attr('title') || '').removeAttr('title'); +            } +        }, +         +        getTitle: function() { +            var title, $e = this.$element, o = this.options; +            this.fixTitle(); +            var title, o = this.options; +            if (typeof o.title == 'string') { +                title = $e.attr(o.title == 'title' ? 'original-title' : o.title); +            } else if (typeof o.title == 'function') { +                title = o.title.call($e[0]); +            } +            title = ('' + title).replace(/(^\s*|\s*$)/, ""); +            return title || o.fallback; +        }, +         +        tip: function() { +            if (!this.$tip) { +                this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>'); +                this.$tip.data('tipsy-pointee', this.$element[0]); +            } +            return this.$tip; +        }, +         +        validate: function() { +            if (!this.$element[0].parentNode) { +                this.hide(); +                this.$element = null; +                this.options = null; +            } +        }, +         +        enable: function() { this.enabled = true; }, +        disable: function() { this.enabled = false; }, +        toggleEnabled: function() { this.enabled = !this.enabled; } +    }; +     +    $.fn.tipsy = function(options) { +         +        if (options === true) { +            return this.data('tipsy'); +        } else if (typeof options == 'string') { +            var tipsy = this.data('tipsy'); +            if (tipsy) tipsy[options](); +            return this; +        } +         +        options = $.extend({}, $.fn.tipsy.defaults, options); +         +        function get(ele) { +            var tipsy = $.data(ele, 'tipsy'); +            if (!tipsy) { +                tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options)); +                $.data(ele, 'tipsy', tipsy); +            } +            return tipsy; +        } +         +        function enter() { +            var tipsy = get(this); +            tipsy.hoverState = 'in'; +            if (options.delayIn == 0) { +                tipsy.show(); +            } else { +                tipsy.fixTitle(); +                setTimeout(function() { if (tipsy.hoverState == 'in') tipsy.show(); }, options.delayIn); +            } +        }; +         +        function leave() { +            var tipsy = get(this); +            tipsy.hoverState = 'out'; +            if (options.delayOut == 0) { +                tipsy.hide(); +            } else { +                setTimeout(function() { if (tipsy.hoverState == 'out') tipsy.hide(); }, options.delayOut); +            } +        }; +         +        if (!options.live) this.each(function() { get(this); }); +         +        if (options.trigger != 'manual') { +            var binder   = options.live ? 'live' : 'bind', +                eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus', +                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur'; +            this[binder](eventIn, enter)[binder](eventOut, leave); +        } +         +        return this; +         +    }; +     +    $.fn.tipsy.defaults = { +        className: null, +        delayIn: 0, +        delayOut: 0, +        fade: false, +        fallback: '', +        gravity: 'n', +        html: false, +        live: false, +        offset: 0, +        opacity: 0.8, +        title: 'title', +        trigger: 'hover' +    }; +     +    $.fn.tipsy.revalidate = function() { +      $('.tipsy').each(function() { +        var pointee = $.data(this, 'tipsy-pointee'); +        if (!pointee || !isElementInDOM(pointee)) { +          $(this).remove(); +        } +      }); +    }; +     +    // Overwrite this method to provide options on a per-element basis. +    // For example, you could store the gravity in a 'tipsy-gravity' attribute: +    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' }); +    // (remember - do not modify 'options' in place!) +    $.fn.tipsy.elementOptions = function(ele, options) { +        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options; +    }; +     +    $.fn.tipsy.autoNS = function() { +        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n'; +    }; +     +    $.fn.tipsy.autoWE = function() { +        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w'; +    }; +     +    /** +     * yields a closure of the supplied parameters, producing a function that takes +     * no arguments and is suitable for use as an autogravity function like so: +     * +     * @param margin (int) - distance from the viewable region edge that an +     *        element should be before setting its tooltip's gravity to be away +     *        from that edge. +     * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer +     *        if there are no viewable region edges effecting the tooltip's +     *        gravity. It will try to vary from this minimally, for example, +     *        if 'sw' is preferred and an element is near the right viewable  +     *        region edge, but not the top edge, it will set the gravity for +     *        that element's tooltip to be 'se', preserving the southern +     *        component. +     */ +     $.fn.tipsy.autoBounds = function(margin, prefer) { +		return function() { +			var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)}, +			    boundTop = $(document).scrollTop() + margin, +			    boundLeft = $(document).scrollLeft() + margin, +			    $this = $(this); + +			if ($this.offset().top < boundTop) dir.ns = 'n'; +			if ($this.offset().left < boundLeft) dir.ew = 'w'; +			if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e'; +			if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's'; + +			return dir.ns + (dir.ew ? dir.ew : ''); +		} +	}; +     +})(jQuery); diff --git a/app/assets/javascripts/public/jquery.tokeninput.js b/app/assets/javascripts/plugins/jquery.tokeninput.js index 87641a57a..87641a57a 100644 --- a/app/assets/javascripts/public/jquery.tokeninput.js +++ b/app/assets/javascripts/plugins/jquery.tokeninput.js diff --git a/app/assets/javascripts/public/jquery.ui.datepicker-i18n.js b/app/assets/javascripts/plugins/jquery.ui.datepicker-i18n.js index b7748a77a..b7748a77a 100644 --- a/app/assets/javascripts/public/jquery.ui.datepicker-i18n.js +++ b/app/assets/javascripts/plugins/jquery.ui.datepicker-i18n.js diff --git a/app/assets/javascripts/public/proj4js-compressed.js b/app/assets/javascripts/plugins/proj4js-compressed.js index 3da44ad15..3da44ad15 100644 --- a/app/assets/javascripts/public/proj4js-compressed.js +++ b/app/assets/javascripts/plugins/proj4js-compressed.js diff --git a/app/assets/javascripts/public/proj4js-defs.js b/app/assets/javascripts/plugins/proj4js-defs.js index fe77a033c..fe77a033c 100644 --- a/app/assets/javascripts/public/proj4js-defs.js +++ b/app/assets/javascripts/plugins/proj4js-defs.js diff --git a/app/assets/javascripts/rule_parameter_set.js.coffee b/app/assets/javascripts/rule_parameter_set.js.coffee new file mode 100644 index 000000000..bb1e2226b --- /dev/null +++ b/app/assets/javascripts/rule_parameter_set.js.coffee @@ -0,0 +1,10 @@ +jQuery -> +  mode_change = (event) -> +    $(".mode_specific.selected").toggle() +    $(".mode_specific.selected").toggleClass( "selected" ) +    mode_selected = $("option:selected").attr("value") +    $(".mode_specific."+mode_selected).toggle() +    $(".mode_specific."+mode_selected).toggleClass( "selected" ) + +  $("#mode").change(mode_change) + diff --git a/app/assets/stylesheets/access_links.css.scss b/app/assets/stylesheets/access_links.css.scss index 63a55e021..c076b30b1 100644 --- a/app/assets/stylesheets/access_links.css.scss +++ b/app/assets/stylesheets/access_links.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.access_links.show diff --git a/app/assets/stylesheets/access_points.css.scss b/app/assets/stylesheets/access_points.css.scss index 22dc3ac3d..6545a32aa 100644 --- a/app/assets/stylesheets/access_points.css.scss +++ b/app/assets/stylesheets/access_points.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.access_points.index  { diff --git a/app/assets/stylesheets/api_keys.css.scss b/app/assets/stylesheets/api_keys.css.scss index cca96321e..2c1c45cdb 100644 --- a/app/assets/stylesheets/api_keys.css.scss +++ b/app/assets/stylesheets/api_keys.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the routes controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.referentials.show  { diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 7a73fd3fe..b773f970a 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -5,5 +5,7 @@   *= require_self   *= require formtastic   *= require jquery-ui + *= require morris + *= require font-awesome   *= require_tree .   */
\ No newline at end of file diff --git a/app/assets/stylesheets/common.css.scss b/app/assets/stylesheets/common.css.scss index 91050771e..950004ec8 100644 --- a/app/assets/stylesheets/common.css.scss +++ b/app/assets/stylesheets/common.css.scss @@ -1,81 +1,4 @@ -@mixin div_for_object {  -    margin-bottom: 10px; -    background-color: #DEFFA8; -    padding-top: 10px; -    padding-bottom: 10px; -    margin-right: 10px; -    padding-left: 10px; - -    .color { -        width: 64px; -        height: 64px; -        float: left; -        margin-right: 10px; -    } - -    img { -        float: left; -        margin-right: 10px; -    } - -    img.preview { -        width: 90px; -        height: 70px; -    } - -    a {  -        display:block; -        text-decoration: underline; -        margin: 5px 0px 0px 0px; -    } - -    .info { -        font-size: 10px; -        color: #777; -        font-weight: normal; -        line-height: 14px; -        margin-top: 5px; - -        a { -            display:inline; -            color: #777; -        } - -        .actions { -            margin-top: 10px; -            a { -                color: #666; -                padding-left: 12px; -            } - -            a.link { -                background: url(image-path('icons/link-small.png')) no-repeat 0% 50%; -            } -            a.edit { -                background: url(image-path('user_interface/ui/edit-small.png')) no-repeat 0% 50%; -            } -            a.remove { -                background: url(image-path('user_interface/ui/remove-small.png')) no-repeat 0% 50%; -            } -            a.download { -                background: url(image-path('download-small.png')) no-repeat 0% 50%; -            } -        } - -        p { -            margin:0; -        } -    } -} - -@mixin content_to_clear { -    content: " ";   -    display: block;  -    height: 0;  -    clear: both; -    visibility: hidden; -} - -@mixin after_div_for_object { -    @include content_to_clear; -} +/* +  *= require_tree ./common +  *= require_tree ./plugins +*/ diff --git a/app/assets/stylesheets/common/mixins.css.scss b/app/assets/stylesheets/common/mixins.css.scss new file mode 100644 index 000000000..91050771e --- /dev/null +++ b/app/assets/stylesheets/common/mixins.css.scss @@ -0,0 +1,81 @@ +@mixin div_for_object {  +    margin-bottom: 10px; +    background-color: #DEFFA8; +    padding-top: 10px; +    padding-bottom: 10px; +    margin-right: 10px; +    padding-left: 10px; + +    .color { +        width: 64px; +        height: 64px; +        float: left; +        margin-right: 10px; +    } + +    img { +        float: left; +        margin-right: 10px; +    } + +    img.preview { +        width: 90px; +        height: 70px; +    } + +    a {  +        display:block; +        text-decoration: underline; +        margin: 5px 0px 0px 0px; +    } + +    .info { +        font-size: 10px; +        color: #777; +        font-weight: normal; +        line-height: 14px; +        margin-top: 5px; + +        a { +            display:inline; +            color: #777; +        } + +        .actions { +            margin-top: 10px; +            a { +                color: #666; +                padding-left: 12px; +            } + +            a.link { +                background: url(image-path('icons/link-small.png')) no-repeat 0% 50%; +            } +            a.edit { +                background: url(image-path('user_interface/ui/edit-small.png')) no-repeat 0% 50%; +            } +            a.remove { +                background: url(image-path('user_interface/ui/remove-small.png')) no-repeat 0% 50%; +            } +            a.download { +                background: url(image-path('download-small.png')) no-repeat 0% 50%; +            } +        } + +        p { +            margin:0; +        } +    } +} + +@mixin content_to_clear { +    content: " ";   +    display: block;  +    height: 0;  +    clear: both; +    visibility: hidden; +} + +@mixin after_div_for_object { +    @include content_to_clear; +} diff --git a/app/assets/stylesheets/companies.css.scss b/app/assets/stylesheets/companies.css.scss index 7e490841a..c3569c4fd 100644 --- a/app/assets/stylesheets/companies.css.scss +++ b/app/assets/stylesheets/companies.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.companies.index  { diff --git a/app/assets/stylesheets/compliance_check_tasks.css.scss b/app/assets/stylesheets/compliance_check_tasks.css.scss new file mode 100644 index 000000000..10ba55893 --- /dev/null +++ b/app/assets/stylesheets/compliance_check_tasks.css.scss @@ -0,0 +1,257 @@ +@import "common/mixins"; + +.status { +    margin-left: 10px; +} + +.status_failed { color: #a94442;} +.status_pending { color: #31708f;} +.status_processing { color: #31708f;} +.status_completed { color: #3c763d;} + +#workspace.compliance_check_tasks.index +{ +    .compliance_check_task:after { +        @include after_div_for_object; +    } + +    .compliance_check_tasks { +        margin-top: 20px; +    } + +    .compliance_check_tasks:after { +        @include content_to_clear; +    } + +    .compliance_check_task { +        width: 300px; +        float: left; +        padding: 5px; +        margin: 0 10px 10px 0px; +        background-color: #DEFFA8; +        border: 1px solid #61970b; +        -moz-border-radius: 3px; +        -webkit-border-radius: 3px; + +        div.icon{ +            display: inline-block; +            vertical-align: top; +            width: 74px; +            padding-right: 5px; + +            img{ +                width: 64px; +                height: 64px; +            } +        } + +        div.resume{ +            display: inline-block; + +            ul.header{ +                font-size: 14px; +                width: 209px; + +                .title{ float: left; } +                .remove{ +                    float: right; +                    padding-right: 10px; +                    color: #494949; +                } +            } + +            .links { +                font-size: 10px; +                height: 38px; + +                p { margin: 3px 0px 0px 0px !important; } +                 +                img { margin-right: 10px;} +            } + +            .history { +                margin-top: 10px; +                font-size: 10px; +                color: #777; +            } +        } +    } +} + +#workspace.compliance_check_tasks.show { + +    .links{ +        margin: 0px 0 20px 0; +    } + +    .order{ +        margin-bottom: 10px; +        padding: 5px; +        border-top: 1px solid #e4e4e4; +        border-bottom: 1px solid #e4e4e4; +    } + +    .resume { +        &:after{ +            content: " "; +            display: block; +            height: 0; +            clear: both; +            visibility: hidden; +        } + +        .col1 { +            float: left; +            width: 45%; +        } + +        .col2 { +            margin-left: 10px; +            float: left; +            width: 45%; +            } + +        .graph { height: 200px; } + +        .caption { +            text-align :center; +                font-weight: bold; +        } +    } + +    .report{ +        .table { margin-top: 20px; } + +    } + +    .severity__improvment, .severity_warning, .severity_error { +        border: 1px solid; +        margin: 10px 0px; +        padding:10px 10px 10px 10px; +        background-repeat: no-repeat; +        background-position: 10px center;-moz-border-radius:.5em; +        -webkit-border-radius:.5em; +        border-radius:.5em; +        height: 100%; + +        &:after{ +            content: " "; +            display: block; +            height: 0; +            clear: both; +            visibility: hidden; +        } + +        .status_icon { +            float: left; +            width: 20%; +            height: auto; + +            img { +                vertical-align: middle; +                width: 48px; +                height: 48px; +            } +        } + +        .status_text{ +            float: left; +            width: 70%; + +            .code{ +                font-size: 12px; +                font-weight: bold; +            } + +            .severity { +                font-size: 10px; +            } + +            .explanation{ +                display: none; +                font-size: 12px; +                margin: 5px 0 0 0; +            } + +            .attributes{ +                font-size: 10px; +                font-weight: bold; +                margin: 5px 0 0px 0; +            } +        } + +    } + +    .severity_improvment { +        color: black; +        background-color: #c5cf4c; +    } + +    .severity_warning { +        color: black; +        background-color: #f1dd30; +    } + +    .severity_error { +        color: black; +        background-color: #ff9a0c; +    } + +    .td_error { +        width: 30%; +         +        i { margin-right: 10px; } +         +        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; +            } +        } +    } +} + +#workspace.compliance_check_tasks.new, #workspace.compliance_check_tasks.create +{ +    padding: 0; +    margin-top: -0.3em; +    margin-bottom: 1em; + + + +  .inputs ol { +      margin-top: -0.3em; +      margin-bottom: 1em; +      padding: 0; +      width: 100%; +    } +    .inputs ol li { padding : 0.3em 0; } + +    .inputs ol li textarea { +      width: 54%; +    } +    .inputs ol li label { +      width: 40%; +      margin-top: -0.3em; +    } + +  .inputs ol li.fl label { width: 40%; margin-top: -0.3em; } +  .inputs ol li.fl input { width: 21%; padding: 0; } + +  .inputs ol li.fl1 {float: left; width: 70% ;} +  .inputs ol li.fl1 label {width: 57%; margin-top: -0.3em; } +  .inputs ol li.fl1 input { width: 30%; } + +  .inputs ol li.fl2 {float: left; width: 25% ;} +  .inputs ol li.fl2 label {width: 10%; margin-top: -0.3em;} +  .inputs ol li.fl2 input { width: 85%; } + +} diff --git a/app/assets/stylesheets/connection_links.css.scss b/app/assets/stylesheets/connection_links.css.scss index 00868e49f..b2ad0de75 100644 --- a/app/assets/stylesheets/connection_links.css.scss +++ b/app/assets/stylesheets/connection_links.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.connection_links.index  { diff --git a/app/assets/stylesheets/exports.css.scss b/app/assets/stylesheets/exports.css.scss index f9312cc1c..d26ef2c8d 100644 --- a/app/assets/stylesheets/exports.css.scss +++ b/app/assets/stylesheets/exports.css.scss @@ -2,7 +2,7 @@  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.exports.index  { @@ -71,4 +71,4 @@      select {          width: 25%;      } -}
\ No newline at end of file +} diff --git a/app/assets/stylesheets/file_validations.css.scss b/app/assets/stylesheets/file_validations.css.scss deleted file mode 100644 index 187c74b3c..000000000 --- a/app/assets/stylesheets/file_validations.css.scss +++ /dev/null @@ -1,137 +0,0 @@ -@import "common"; - -#workspace.file_validations.index -{ -    .file_validation:after {  -        @include after_div_for_object;   -    } - -    .file_validations { -        margin-top: 20px; -    } - -    .file_validations:after { -        @include content_to_clear; -    } -     -    .file_validation { -        @include div_for_object; - -        /* to create multi-column index */ -        width: 300px; -        float: left; -        padding-right: 10px; -    } -} - -#workspace.file_validations.show { -    .file_validation_show { -      width: 95% -    } -    .panelDataSection -    { -      font-size: 14px; -      padding: 3px 0px 3px 20px; -      BACKGROUND-COLOR: #FaFaFa; -      margin: 10px 0px 0px 0px; -      BORDER-LEFT: 1px solid #B0BCD6; -      BORDER-RIGHT: 1px solid #B0BCD6; -      BORDER-TOP: 1px solid #B0BCD6; -      FONT-WEIGHT: bold; -    } -  .neptune-panel{ -    font-family: Arial, Verdana, Helvetica, sans-serif; -    font-size: 13px; -    background-color: #FFFFFF; -    margin: 0px 0px 2px 0px; -    padding: 10px 10px 10px 10px; -    border: 1px solid #B0BCD6; -    table { -      border: 0px; -      td { -          padding: 20px; -         } -      } -    } -    .category{ -      font-weight: bold; -    } -     -     -.ok{ -  background: url(image-path('severity-ok.png')) no-repeat 98% 0%; -  } -   -.uncheck { -  background: url(image-path('severity-uncheck.png')) no-repeat 98% 0%; -  } -   -.warning{ -  background: url(image-path('severity-warning.png')) no-repeat 98% 0%; -  }    - -.error{ -  background: url(image-path('severity-error.png')) no-repeat 98% 0%; -  color: red; -  } -.fatal{ -  background: url(image-path('severity-fatal.png')) no-repeat 98% 0%; -  color: red; -  } -   -.step { -   width: 80%;  -   padding-left:100px;  -   margin-top:-15px; -}   -.detail { -  margin: 0 0 0 660px; -  padding: 5px 0 0 0; -  } -.neptune-panel-inSide -{ -  background-color: #FFFFFF; -    padding: 5px 5px; -    margin:0 0 5px 100px; -    width: 80%; -    font-size: 12px; -    border: 1px solid #B0BCD6; -} -} - -#workspace.file_validations.new, #workspace.file_validations.create  -{ -    padding: 0; -    margin-top: -0.3em; -    margin-bottom: 1em; -     -    -     -  .inputs ol { -      margin-top: -0.3em; -      margin-bottom: 1em; -      padding: 0; -      width: 100%; -    } -    .inputs ol li { padding : 0.3em 0; } - -    .inputs ol li textarea { -      width: 54%; -    } -    .inputs ol li label { -      width: 40%; -      margin-top: -0.3em; -    } -     -  .inputs ol li.fl label { width: 40%; margin-top: -0.3em; } -  .inputs ol li.fl input { width: 21%; padding: 0; } -   -  .inputs ol li.fl1 {float: left; width: 70% ;} -  .inputs ol li.fl1 label {width: 57%; margin-top: -0.3em; } -  .inputs ol li.fl1 input { width: 30%; } -   -  .inputs ol li.fl2 {float: left; width: 25% ;} -  .inputs ol li.fl2 label {width: 10%; margin-top: -0.3em;} -  .inputs ol li.fl2 input { width: 85%; } - -} diff --git a/app/assets/stylesheets/group_of_lines.css.scss b/app/assets/stylesheets/group_of_lines.css.scss index 24fbdce12..bcfca6f4e 100644 --- a/app/assets/stylesheets/group_of_lines.css.scss +++ b/app/assets/stylesheets/group_of_lines.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.group_of_lines.index  { diff --git a/app/assets/stylesheets/import_tasks.css.scss b/app/assets/stylesheets/import_tasks.css.scss new file mode 100644 index 000000000..153f5f097 --- /dev/null +++ b/app/assets/stylesheets/import_tasks.css.scss @@ -0,0 +1,163 @@ +@import "common/mixins"; + +.status { +    margin-left: 10px; +} + +.status_failed { color: #a94442;} +.status_pending { color: #31708f;} +.status_processing { color: #31708f;} +.status_completed { color: #3c763d;} + +#workspace.import_tasks.index +{ +    .import_task:after { +        @include after_div_for_object; +    } + +    .import_tasks { +        margin-top: 20px; +    } + +    .import_tasks:after { +        @include content_to_clear; +    } + +    .import_task { +        width: 300px; +        float: left; +        padding: 5px; +        margin: 0 10px 10px 0px; +        background-color: #DEFFA8; +        border: 1px solid #61970b; +        -moz-border-radius: 3px; +        -webkit-border-radius: 3px; + +        div.icon{ +            display: inline-block; +            vertical-align: top; +            width: 74px; +            padding-right: 5px; + +            img{ +                width: 64px; +                height: 64px; +            } +        } + +        div.resume{ +            display: inline-block; + +            ul.header{ +                font-size: 14px; +                width: 209px; + +                .title{ float: left; } +                .remove{ +                    float: right; +                    padding-right: 10px; +                } +            } + +            .links { +                font-size: 10px; +                height: 38px; + +                p { margin: 3px 0px 0px 0px !important; } +                 +                img { margin-right: 10px;} +            } + +            .history { +                margin-top: 10px; +                font-size: 10px; +                color: #777; +            } +        } +    } +} + +#workspace.import_tasks.show { + +    .links{ +        margin: 0 0 20px 0; + +        img { margin-right: 10px; } +    } + +    .resume { +        &:after{ +            content: " "; +            display: block; +            height: 0; +            clear: both; +            visibility: hidden; +        } + +        .col1 { +            float: left; +            width: 45%; +        } + +        .col2 { +            margin-left: 10px; +            float: left; +            width: 45%; +        } + +        #files_statistics { height: 200px; } +        #objects_statistics { height: 200px; } + +        .caption { +            text-align :center; +            font-weight: bold; +        } +    } + +    .report { +        margin-top: 20px; + +        .files { +            img { +                margin-right: 5px; +            } + +            .file_name{ +                font-weight: bold; +                margin-right: 30px; +            } +        } + +        .files_error{ +            color: #e22b1b; +            display: none; +        } + +        .files_ignored{ +            color: #ffbd2b; +            display: none; +        } + +        .files_ok{ +            color: #8fc861; +            display: none; +        } + +        .lines{ display: none; } +    } +} + +#workspace.import_tasks.new #workspace.import_tasks.create form.import_task_new { +    padding: 0.5em 0; +    margin-top: -0.5em; +    margin-bottom: 1em; + +    label { +        display: block; +        width: 25%; +        float: left; +    } +    select { +        width: 25%; +    } +} diff --git a/app/assets/stylesheets/imports.css.scss b/app/assets/stylesheets/imports.css.scss deleted file mode 100644 index 6241a09e8..000000000 --- a/app/assets/stylesheets/imports.css.scss +++ /dev/null @@ -1,70 +0,0 @@ -@import "common"; - -#workspace.imports.index -{ -    .import:after {  -        @include after_div_for_object;   -    } - -    .imports { -        margin-top: 20px; -    } - -    .imports:after { -        @include content_to_clear; -    } -     -    .import { -        @include div_for_object; - -        /* to create multi-column index */ -        width: 300px; -        float: left; -        padding-right: 10px; -    } -} - -#workspace.imports.show { -    table { -        th { -            font-style: italic; -        } -        th.severity { -            width: 30px; -        } -        th.created_at { -            text-align: center; -            width: 100px; -        } -        th.position { -            padding-right: 5px; -            text-align: right; -            width: 40px; -        } -        td.severity { -            text-align: center; -        } -        td.created_at { -            padding-right: 3px; -        } -        td.position { -            padding-right: 5px; -            text-align: right; -        } -    }                        -} - -#workspace.imports.new #workspace.imports.create form.import_new { -    padding: 0.5em 0; -    margin-top: -0.5em; -    margin-bottom: 1em; - -    label { -        display: block; -        width: 25%; -        float: left; -    } -    select { -        width: 25%; -    } -} diff --git a/app/assets/stylesheets/journey_patterns.css.scss b/app/assets/stylesheets/journey_patterns.css.scss index 0e9113f41..232a9fa66 100644 --- a/app/assets/stylesheets/journey_patterns.css.scss +++ b/app/assets/stylesheets/journey_patterns.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the routes controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.journey_patterns.edit, #workspace.journey_patterns.new, #workspace.journey_patterns.create, #workspace.journey_patterns.update  { diff --git a/app/assets/stylesheets/layout.css.scss b/app/assets/stylesheets/layout.css.scss index 4a5237aa7..0505512fe 100644 --- a/app/assets/stylesheets/layout.css.scss +++ b/app/assets/stylesheets/layout.css.scss @@ -7,6 +7,12 @@ $text_color: #222;  @import "user_interface/layout"; +// Override user_interface/layout +b { font-weight: bold; } + +// Add margin-top to alert +.alert { margin-top: 10px;} +  p.after_map {    clear: both;  } diff --git a/app/assets/stylesheets/lines.css.scss b/app/assets/stylesheets/lines.css.scss index 8632a72b2..f3ce676e2 100644 --- a/app/assets/stylesheets/lines.css.scss +++ b/app/assets/stylesheets/lines.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.lines.index  { diff --git a/app/assets/stylesheets/networks.css.scss b/app/assets/stylesheets/networks.css.scss index da43b41f8..dafe42c98 100644 --- a/app/assets/stylesheets/networks.css.scss +++ b/app/assets/stylesheets/networks.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.networks.index  { diff --git a/app/assets/stylesheets/organisations.css.scss b/app/assets/stylesheets/organisations.css.scss index cb794940a..4ce671436 100644 --- a/app/assets/stylesheets/organisations.css.scss +++ b/app/assets/stylesheets/organisations.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.organisations.show  { diff --git a/app/assets/stylesheets/plugins/bootstrap.min.css b/app/assets/stylesheets/plugins/bootstrap.min.css new file mode 100644 index 000000000..145037827 --- /dev/null +++ b/app/assets/stylesheets/plugins/bootstrap.min.css @@ -0,0 +1,11 @@ +/*! + * Bootstrap v3.0.3 + * + * Copyright 2013 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block;}audio,canvas,video{display:inline-block;}audio:not([controls]){display:none;height:0;}[hidden],template{display:none;}html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;}body{margin:0;}a{background:transparent;}a:focus{outline:thin dotted;}a:active,a:hover{outline:0;}h1{font-size:2em;margin:0.67em 0;}abbr[title]{border-bottom:1px dotted;}b,strong{font-weight:bold;}dfn{font-style:italic;}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0;}mark{background:#ff0;color:#000;}code,kbd,pre,samp{font-family:monospace, serif;font-size:1em;}pre{white-space:pre-wrap;}q{quotes:"\201C" "\201D" "\2018" "\2019";}small{font-size:80%;}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}sup{top:-0.5em;}sub{bottom:-0.25em;}img{border:0;}svg:not(:root){overflow:hidden;}figure{margin:0;}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em;}legend{border:0;padding:0;}button,input,select,textarea{font-family:inherit;font-size:100%;margin:0;}button,input{line-height:normal;}button,select{text-transform:none;}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer;}button[disabled],html input[disabled]{cursor:default;}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0;}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}textarea{overflow:auto;vertical-align:top;}table{border-collapse:collapse;border-spacing:0;}@media print{*{text-shadow:none !important;color:#000 !important;background:transparent !important;box-shadow:none !important;} a,a:visited{text-decoration:underline;} a[href]:after{content:" (" attr(href) ")";} abbr[title]:after{content:" (" attr(title) ")";} a[href^="javascript:"]:after,a[href^="#"]:after{content:"";} pre,blockquote{border:1px solid #999;page-break-inside:avoid;} thead{display:table-header-group;} tr,img{page-break-inside:avoid;} img{max-width:100% !important;} @page {margin:2cm .5cm;}p,h2,h3{orphans:3;widows:3;} h2,h3{page-break-after:avoid;} select{background:#fff !important;} .navbar{display:none;} .table td,.table th{background-color:#fff !important;} .btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important;} .label{border:1px solid #000;} .table{border-collapse:collapse !important;} .table-bordered th,.table-bordered td{border:1px solid #ddd !important;}}*,*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}html{font-size:62.5%;-webkit-tap-highlight-color:rgba(0, 0, 0, 0);}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.428571429;color:#333333;background-color:#ffffff;}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit;}a{color:#428bca;text-decoration:none;}a:hover,a:focus{color:#2a6496;text-decoration:underline;}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}img{vertical-align:middle;}.img-responsive{display:block;max-width:100%;height:auto;}.img-rounded{border-radius:6px;}.img-thumbnail{padding:4px;line-height:1.428571429;background-color:#ffffff;border:1px solid #dddddd;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;display:inline-block;max-width:100%;height:auto;}.img-circle{border-radius:50%;}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eeeeee;}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0;}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace;}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;white-space:nowrap;border-radius:4px;}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.428571429;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:4px;}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0;}.pre-scrollable{max-height:340px;overflow-y:scroll;}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px;}.container:before,.container:after{content:" ";display:table;}.container:after{clear:both;}.container:before,.container:after{content:" ";display:table;}.container:after{clear:both;}@media (min-width:768px){.container{width:750px;}}@media (min-width:992px){.container{width:970px;}}@media (min-width:1200px){.container{width:1170px;}}.row{margin-left:-15px;margin-right:-15px;}.row:before,.row:after{content:" ";display:table;}.row:after{clear:both;}.row:before,.row:after{content:" ";display:table;}.row:after{clear:both;}.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px;}.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12{float:left;}.col-xs-12{width:100%;}.col-xs-11{width:91.66666666666666%;}.col-xs-10{width:83.33333333333334%;}.col-xs-9{width:75%;}.col-xs-8{width:66.66666666666666%;}.col-xs-7{width:58.333333333333336%;}.col-xs-6{width:50%;}.col-xs-5{width:41.66666666666667%;}.col-xs-4{width:33.33333333333333%;}.col-xs-3{width:25%;}.col-xs-2{width:16.666666666666664%;}.col-xs-1{width:8.333333333333332%;}.col-xs-pull-12{right:100%;}.col-xs-pull-11{right:91.66666666666666%;}.col-xs-pull-10{right:83.33333333333334%;}.col-xs-pull-9{right:75%;}.col-xs-pull-8{right:66.66666666666666%;}.col-xs-pull-7{right:58.333333333333336%;}.col-xs-pull-6{right:50%;}.col-xs-pull-5{right:41.66666666666667%;}.col-xs-pull-4{right:33.33333333333333%;}.col-xs-pull-3{right:25%;}.col-xs-pull-2{right:16.666666666666664%;}.col-xs-pull-1{right:8.333333333333332%;}.col-xs-pull-0{right:0%;}.col-xs-push-12{left:100%;}.col-xs-push-11{left:91.66666666666666%;}.col-xs-push-10{left:83.33333333333334%;}.col-xs-push-9{left:75%;}.col-xs-push-8{left:66.66666666666666%;}.col-xs-push-7{left:58.333333333333336%;}.col-xs-push-6{left:50%;}.col-xs-push-5{left:41.66666666666667%;}.col-xs-push-4{left:33.33333333333333%;}.col-xs-push-3{left:25%;}.col-xs-push-2{left:16.666666666666664%;}.col-xs-push-1{left:8.333333333333332%;}.col-xs-push-0{left:0%;}.col-xs-offset-12{margin-left:100%;}.col-xs-offset-11{margin-left:91.66666666666666%;}.col-xs-offset-10{margin-left:83.33333333333334%;}.col-xs-offset-9{margin-left:75%;}.col-xs-offset-8{margin-left:66.66666666666666%;}.col-xs-offset-7{margin-left:58.333333333333336%;}.col-xs-offset-6{margin-left:50%;}.col-xs-offset-5{margin-left:41.66666666666667%;}.col-xs-offset-4{margin-left:33.33333333333333%;}.col-xs-offset-3{margin-left:25%;}.col-xs-offset-2{margin-left:16.666666666666664%;}.col-xs-offset-1{margin-left:8.333333333333332%;}.col-xs-offset-0{margin-left:0%;}@media (min-width:768px){.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12{float:left;} .col-sm-12{width:100%;} .col-sm-11{width:91.66666666666666%;} .col-sm-10{width:83.33333333333334%;} .col-sm-9{width:75%;} .col-sm-8{width:66.66666666666666%;} .col-sm-7{width:58.333333333333336%;} .col-sm-6{width:50%;} .col-sm-5{width:41.66666666666667%;} .col-sm-4{width:33.33333333333333%;} .col-sm-3{width:25%;} .col-sm-2{width:16.666666666666664%;} .col-sm-1{width:8.333333333333332%;} .col-sm-pull-12{right:100%;} .col-sm-pull-11{right:91.66666666666666%;} .col-sm-pull-10{right:83.33333333333334%;} .col-sm-pull-9{right:75%;} .col-sm-pull-8{right:66.66666666666666%;} .col-sm-pull-7{right:58.333333333333336%;} .col-sm-pull-6{right:50%;} .col-sm-pull-5{right:41.66666666666667%;} .col-sm-pull-4{right:33.33333333333333%;} .col-sm-pull-3{right:25%;} .col-sm-pull-2{right:16.666666666666664%;} .col-sm-pull-1{right:8.333333333333332%;} .col-sm-pull-0{right:0%;} .col-sm-push-12{left:100%;} .col-sm-push-11{left:91.66666666666666%;} .col-sm-push-10{left:83.33333333333334%;} .col-sm-push-9{left:75%;} .col-sm-push-8{left:66.66666666666666%;} .col-sm-push-7{left:58.333333333333336%;} .col-sm-push-6{left:50%;} .col-sm-push-5{left:41.66666666666667%;} .col-sm-push-4{left:33.33333333333333%;} .col-sm-push-3{left:25%;} .col-sm-push-2{left:16.666666666666664%;} .col-sm-push-1{left:8.333333333333332%;} .col-sm-push-0{left:0%;} .col-sm-offset-12{margin-left:100%;} .col-sm-offset-11{margin-left:91.66666666666666%;} .col-sm-offset-10{margin-left:83.33333333333334%;} .col-sm-offset-9{margin-left:75%;} .col-sm-offset-8{margin-left:66.66666666666666%;} .col-sm-offset-7{margin-left:58.333333333333336%;} .col-sm-offset-6{margin-left:50%;} .col-sm-offset-5{margin-left:41.66666666666667%;} .col-sm-offset-4{margin-left:33.33333333333333%;} .col-sm-offset-3{margin-left:25%;} .col-sm-offset-2{margin-left:16.666666666666664%;} .col-sm-offset-1{margin-left:8.333333333333332%;} .col-sm-offset-0{margin-left:0%;}}@media (min-width:992px){.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12{float:left;} .col-md-12{width:100%;} .col-md-11{width:91.66666666666666%;} .col-md-10{width:83.33333333333334%;} .col-md-9{width:75%;} .col-md-8{width:66.66666666666666%;} .col-md-7{width:58.333333333333336%;} .col-md-6{width:50%;} .col-md-5{width:41.66666666666667%;} .col-md-4{width:33.33333333333333%;} .col-md-3{width:25%;} .col-md-2{width:16.666666666666664%;} .col-md-1{width:8.333333333333332%;} .col-md-pull-12{right:100%;} .col-md-pull-11{right:91.66666666666666%;} .col-md-pull-10{right:83.33333333333334%;} .col-md-pull-9{right:75%;} .col-md-pull-8{right:66.66666666666666%;} .col-md-pull-7{right:58.333333333333336%;} .col-md-pull-6{right:50%;} .col-md-pull-5{right:41.66666666666667%;} .col-md-pull-4{right:33.33333333333333%;} .col-md-pull-3{right:25%;} .col-md-pull-2{right:16.666666666666664%;} .col-md-pull-1{right:8.333333333333332%;} .col-md-pull-0{right:0%;} .col-md-push-12{left:100%;} .col-md-push-11{left:91.66666666666666%;} .col-md-push-10{left:83.33333333333334%;} .col-md-push-9{left:75%;} .col-md-push-8{left:66.66666666666666%;} .col-md-push-7{left:58.333333333333336%;} .col-md-push-6{left:50%;} .col-md-push-5{left:41.66666666666667%;} .col-md-push-4{left:33.33333333333333%;} .col-md-push-3{left:25%;} .col-md-push-2{left:16.666666666666664%;} .col-md-push-1{left:8.333333333333332%;} .col-md-push-0{left:0%;} .col-md-offset-12{margin-left:100%;} .col-md-offset-11{margin-left:91.66666666666666%;} .col-md-offset-10{margin-left:83.33333333333334%;} .col-md-offset-9{margin-left:75%;} .col-md-offset-8{margin-left:66.66666666666666%;} .col-md-offset-7{margin-left:58.333333333333336%;} .col-md-offset-6{margin-left:50%;} .col-md-offset-5{margin-left:41.66666666666667%;} .col-md-offset-4{margin-left:33.33333333333333%;} .col-md-offset-3{margin-left:25%;} .col-md-offset-2{margin-left:16.666666666666664%;} .col-md-offset-1{margin-left:8.333333333333332%;} .col-md-offset-0{margin-left:0%;}}@media (min-width:1200px){.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12{float:left;} .col-lg-12{width:100%;} .col-lg-11{width:91.66666666666666%;} .col-lg-10{width:83.33333333333334%;} .col-lg-9{width:75%;} .col-lg-8{width:66.66666666666666%;} .col-lg-7{width:58.333333333333336%;} .col-lg-6{width:50%;} .col-lg-5{width:41.66666666666667%;} .col-lg-4{width:33.33333333333333%;} .col-lg-3{width:25%;} .col-lg-2{width:16.666666666666664%;} .col-lg-1{width:8.333333333333332%;} .col-lg-pull-12{right:100%;} .col-lg-pull-11{right:91.66666666666666%;} .col-lg-pull-10{right:83.33333333333334%;} .col-lg-pull-9{right:75%;} .col-lg-pull-8{right:66.66666666666666%;} .col-lg-pull-7{right:58.333333333333336%;} .col-lg-pull-6{right:50%;} .col-lg-pull-5{right:41.66666666666667%;} .col-lg-pull-4{right:33.33333333333333%;} .col-lg-pull-3{right:25%;} .col-lg-pull-2{right:16.666666666666664%;} .col-lg-pull-1{right:8.333333333333332%;} .col-lg-pull-0{right:0%;} .col-lg-push-12{left:100%;} .col-lg-push-11{left:91.66666666666666%;} .col-lg-push-10{left:83.33333333333334%;} .col-lg-push-9{left:75%;} .col-lg-push-8{left:66.66666666666666%;} .col-lg-push-7{left:58.333333333333336%;} .col-lg-push-6{left:50%;} .col-lg-push-5{left:41.66666666666667%;} .col-lg-push-4{left:33.33333333333333%;} .col-lg-push-3{left:25%;} .col-lg-push-2{left:16.666666666666664%;} .col-lg-push-1{left:8.333333333333332%;} .col-lg-push-0{left:0%;} .col-lg-offset-12{margin-left:100%;} .col-lg-offset-11{margin-left:91.66666666666666%;} .col-lg-offset-10{margin-left:83.33333333333334%;} .col-lg-offset-9{margin-left:75%;} .col-lg-offset-8{margin-left:66.66666666666666%;} .col-lg-offset-7{margin-left:58.333333333333336%;} .col-lg-offset-6{margin-left:50%;} .col-lg-offset-5{margin-left:41.66666666666667%;} .col-lg-offset-4{margin-left:33.33333333333333%;} .col-lg-offset-3{margin-left:25%;} .col-lg-offset-2{margin-left:16.666666666666664%;} .col-lg-offset-1{margin-left:8.333333333333332%;} .col-lg-offset-0{margin-left:0%;}}table{max-width:100%;background-color:transparent;}th{text-align:left;}.table{width:100%;margin-bottom:20px;}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.428571429;vertical-align:top;border-top:1px solid #dddddd;}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd;}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0;}.table>tbody+tbody{border-top:2px solid #dddddd;}.table .table{background-color:#ffffff;}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px;}.table-bordered{border:1px solid #dddddd;}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #dddddd;}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px;}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9;}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5;}table col[class*="col-"]{position:static;float:none;display:table-column;}table td[class*="col-"],table th[class*="col-"]{float:none;display:table-cell;}.table>thead>tr>.active,.table>tbody>tr>.active,.table>tfoot>tr>.active,.table>thead>.active>td,.table>tbody>.active>td,.table>tfoot>.active>td,.table>thead>.active>th,.table>tbody>.active>th,.table>tfoot>.active>th{background-color:#f5f5f5;}.table-hover>tbody>tr>.active:hover,.table-hover>tbody>.active:hover>td,.table-hover>tbody>.active:hover>th{background-color:#e8e8e8;}.table>thead>tr>.success,.table>tbody>tr>.success,.table>tfoot>tr>.success,.table>thead>.success>td,.table>tbody>.success>td,.table>tfoot>.success>td,.table>thead>.success>th,.table>tbody>.success>th,.table>tfoot>.success>th{background-color:#dff0d8;}.table-hover>tbody>tr>.success:hover,.table-hover>tbody>.success:hover>td,.table-hover>tbody>.success:hover>th{background-color:#d0e9c6;}.table>thead>tr>.danger,.table>tbody>tr>.danger,.table>tfoot>tr>.danger,.table>thead>.danger>td,.table>tbody>.danger>td,.table>tfoot>.danger>td,.table>thead>.danger>th,.table>tbody>.danger>th,.table>tfoot>.danger>th{background-color:#f2dede;}.table-hover>tbody>tr>.danger:hover,.table-hover>tbody>.danger:hover>td,.table-hover>tbody>.danger:hover>th{background-color:#ebcccc;}.table>thead>tr>.warning,.table>tbody>tr>.warning,.table>tfoot>tr>.warning,.table>thead>.warning>td,.table>tbody>.warning>td,.table>tfoot>.warning>td,.table>thead>.warning>th,.table>tbody>.warning>th,.table>tfoot>.warning>th{background-color:#fcf8e3;}.table-hover>tbody>tr>.warning:hover,.table-hover>tbody>.warning:hover>td,.table-hover>tbody>.warning:hover>th{background-color:#faf2cc;}@media (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd;-webkit-overflow-scrolling:touch;}.table-responsive>.table{margin-bottom:0;}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap;} .table-responsive>.table-bordered{border:0;}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0;} .table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0;} .table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0;}}fieldset{padding:0;margin:0;border:0;}label{display:inline-block;margin-bottom:5px;font-weight:bold;}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal;}select[multiple],select[size]{height:auto;}select optgroup{font-size:inherit;font-style:inherit;font-family:inherit;}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}input[type="number"]::-webkit-outer-spin-button,input[type="number"]::-webkit-inner-spin-button{height:auto;}output{display:block;padding-top:7px;font-size:14px;line-height:1.428571429;color:#555555;vertical-align:middle;}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.428571429;color:#555555;vertical-align:middle;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-webkit-transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s, box-shadow ease-in-out .15s;}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);}.form-control:-moz-placeholder{color:#999999;}.form-control::-moz-placeholder{color:#999999;opacity:1;}.form-control:-ms-input-placeholder{color:#999999;}.form-control::-webkit-input-placeholder{color:#999999;}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eeeeee;}textarea.form-control{height:auto;}.form-group{margin-bottom:15px;}.radio,.checkbox{display:block;min-height:20px;margin-top:10px;margin-bottom:10px;padding-left:20px;vertical-align:middle;}.radio label,.checkbox label{display:inline;margin-bottom:0;font-weight:normal;cursor:pointer;}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{float:left;margin-left:-20px;}.radio+.radio,.checkbox+.checkbox{margin-top:-5px;}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer;}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px;}input[type="radio"][disabled],input[type="checkbox"][disabled],.radio[disabled],.radio-inline[disabled],.checkbox[disabled],.checkbox-inline[disabled],fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"],fieldset[disabled] .radio,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox,fieldset[disabled] .checkbox-inline{cursor:not-allowed;}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;}select.input-sm{height:30px;line-height:30px;}textarea.input-sm{height:auto;}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px;}select.input-lg{height:46px;line-height:46px;}textarea.input-lg{height:auto;}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b;}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #c0a16b;}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3;}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442;}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #ce8483;}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede;}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d;}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #67b168;}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8;}.form-control-static{margin-bottom:0;}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373;}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle;} .form-inline .form-control{display:inline-block;} .form-inline select.form-control{width:auto;} .form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;} .form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:none;margin-left:0;}}.form-horizontal .control-label,.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px;}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px;}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px;}.form-horizontal .form-group:before,.form-horizontal .form-group:after{content:" ";display:table;}.form-horizontal .form-group:after{clear:both;}.form-horizontal .form-group:before,.form-horizontal .form-group:after{content:" ";display:table;}.form-horizontal .form-group:after{clear:both;}.form-horizontal .form-control-static{padding-top:7px;}@media (min-width:768px){.form-horizontal .control-label{text-align:right;}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 12px;font-size:14px;line-height:1.428571429;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;}.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;}.btn:hover,.btn:focus{color:#333333;text-decoration:none;}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;}.btn-default{color:#333333;background-color:#ffffff;border-color:#cccccc;}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{color:#333333;background-color:#ebebeb;border-color:#adadad;}.btn-default:active,.btn-default.active,.open .dropdown-toggle.btn-default{background-image:none;}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#ffffff;border-color:#cccccc;}.btn-default .badge{color:#ffffff;background-color:#fff;}.btn-primary{color:#ffffff;background-color:#428bca;border-color:#357ebd;}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{color:#ffffff;background-color:#3276b1;border-color:#285e8e;}.btn-primary:active,.btn-primary.active,.open .dropdown-toggle.btn-primary{background-image:none;}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd;}.btn-primary .badge{color:#428bca;background-color:#fff;}.btn-warning{color:#ffffff;background-color:#f0ad4e;border-color:#eea236;}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{color:#ffffff;background-color:#ed9c28;border-color:#d58512;}.btn-warning:active,.btn-warning.active,.open .dropdown-toggle.btn-warning{background-image:none;}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236;}.btn-warning .badge{color:#f0ad4e;background-color:#fff;}.btn-danger{color:#ffffff;background-color:#d9534f;border-color:#d43f3a;}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{color:#ffffff;background-color:#d2322d;border-color:#ac2925;}.btn-danger:active,.btn-danger.active,.open .dropdown-toggle.btn-danger{background-image:none;}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a;}.btn-danger .badge{color:#d9534f;background-color:#fff;}.btn-success{color:#ffffff;background-color:#5cb85c;border-color:#4cae4c;}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{color:#ffffff;background-color:#47a447;border-color:#398439;}.btn-success:active,.btn-success.active,.open .dropdown-toggle.btn-success{background-image:none;}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c;}.btn-success .badge{color:#5cb85c;background-color:#fff;}.btn-info{color:#ffffff;background-color:#5bc0de;border-color:#46b8da;}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{color:#ffffff;background-color:#39b3d7;border-color:#269abc;}.btn-info:active,.btn-info.active,.open .dropdown-toggle.btn-info{background-image:none;}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da;}.btn-info .badge{color:#5bc0de;background-color:#fff;}.btn-link{color:#428bca;font-weight:normal;cursor:pointer;border-radius:0;}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none;}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent;}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent;}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999999;text-decoration:none;}.btn-lg{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px;}.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-block{display:block;width:100%;padding-left:0;padding-right:0;}.btn-block+.btn-block{margin-top:5px;}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg');}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}.glyphicon:empty{width:1em;}.glyphicon-asterisk:before{content:"\2a";}.glyphicon-plus:before{content:"\2b";}.glyphicon-euro:before{content:"\20ac";}.glyphicon-minus:before{content:"\2212";}.glyphicon-cloud:before{content:"\2601";}.glyphicon-envelope:before{content:"\2709";}.glyphicon-pencil:before{content:"\270f";}.glyphicon-glass:before{content:"\e001";}.glyphicon-music:before{content:"\e002";}.glyphicon-search:before{content:"\e003";}.glyphicon-heart:before{content:"\e005";}.glyphicon-star:before{content:"\e006";}.glyphicon-star-empty:before{content:"\e007";}.glyphicon-user:before{content:"\e008";}.glyphicon-film:before{content:"\e009";}.glyphicon-th-large:before{content:"\e010";}.glyphicon-th:before{content:"\e011";}.glyphicon-th-list:before{content:"\e012";}.glyphicon-ok:before{content:"\e013";}.glyphicon-remove:before{content:"\e014";}.glyphicon-zoom-in:before{content:"\e015";}.glyphicon-zoom-out:before{content:"\e016";}.glyphicon-off:before{content:"\e017";}.glyphicon-signal:before{content:"\e018";}.glyphicon-cog:before{content:"\e019";}.glyphicon-trash:before{content:"\e020";}.glyphicon-home:before{content:"\e021";}.glyphicon-file:before{content:"\e022";}.glyphicon-time:before{content:"\e023";}.glyphicon-road:before{content:"\e024";}.glyphicon-download-alt:before{content:"\e025";}.glyphicon-download:before{content:"\e026";}.glyphicon-upload:before{content:"\e027";}.glyphicon-inbox:before{content:"\e028";}.glyphicon-play-circle:before{content:"\e029";}.glyphicon-repeat:before{content:"\e030";}.glyphicon-refresh:before{content:"\e031";}.glyphicon-list-alt:before{content:"\e032";}.glyphicon-lock:before{content:"\e033";}.glyphicon-flag:before{content:"\e034";}.glyphicon-headphones:before{content:"\e035";}.glyphicon-volume-off:before{content:"\e036";}.glyphicon-volume-down:before{content:"\e037";}.glyphicon-volume-up:before{content:"\e038";}.glyphicon-qrcode:before{content:"\e039";}.glyphicon-barcode:before{content:"\e040";}.glyphicon-tag:before{content:"\e041";}.glyphicon-tags:before{content:"\e042";}.glyphicon-book:before{content:"\e043";}.glyphicon-bookmark:before{content:"\e044";}.glyphicon-print:before{content:"\e045";}.glyphicon-camera:before{content:"\e046";}.glyphicon-font:before{content:"\e047";}.glyphicon-bold:before{content:"\e048";}.glyphicon-italic:before{content:"\e049";}.glyphicon-text-height:before{content:"\e050";}.glyphicon-text-width:before{content:"\e051";}.glyphicon-align-left:before{content:"\e052";}.glyphicon-align-center:before{content:"\e053";}.glyphicon-align-right:before{content:"\e054";}.glyphicon-align-justify:before{content:"\e055";}.glyphicon-list:before{content:"\e056";}.glyphicon-indent-left:before{content:"\e057";}.glyphicon-indent-right:before{content:"\e058";}.glyphicon-facetime-video:before{content:"\e059";}.glyphicon-picture:before{content:"\e060";}.glyphicon-map-marker:before{content:"\e062";}.glyphicon-adjust:before{content:"\e063";}.glyphicon-tint:before{content:"\e064";}.glyphicon-edit:before{content:"\e065";}.glyphicon-share:before{content:"\e066";}.glyphicon-check:before{content:"\e067";}.glyphicon-move:before{content:"\e068";}.glyphicon-step-backward:before{content:"\e069";}.glyphicon-fast-backward:before{content:"\e070";}.glyphicon-backward:before{content:"\e071";}.glyphicon-play:before{content:"\e072";}.glyphicon-pause:before{content:"\e073";}.glyphicon-stop:before{content:"\e074";}.glyphicon-forward:before{content:"\e075";}.glyphicon-fast-forward:before{content:"\e076";}.glyphicon-step-forward:before{content:"\e077";}.glyphicon-eject:before{content:"\e078";}.glyphicon-chevron-left:before{content:"\e079";}.glyphicon-chevron-right:before{content:"\e080";}.glyphicon-plus-sign:before{content:"\e081";}.glyphicon-minus-sign:before{content:"\e082";}.glyphicon-remove-sign:before{content:"\e083";}.glyphicon-ok-sign:before{content:"\e084";}.glyphicon-question-sign:before{content:"\e085";}.glyphicon-info-sign:before{content:"\e086";}.glyphicon-screenshot:before{content:"\e087";}.glyphicon-remove-circle:before{content:"\e088";}.glyphicon-ok-circle:before{content:"\e089";}.glyphicon-ban-circle:before{content:"\e090";}.glyphicon-arrow-left:before{content:"\e091";}.glyphicon-arrow-right:before{content:"\e092";}.glyphicon-arrow-up:before{content:"\e093";}.glyphicon-arrow-down:before{content:"\e094";}.glyphicon-share-alt:before{content:"\e095";}.glyphicon-resize-full:before{content:"\e096";}.glyphicon-resize-small:before{content:"\e097";}.glyphicon-exclamation-sign:before{content:"\e101";}.glyphicon-gift:before{content:"\e102";}.glyphicon-leaf:before{content:"\e103";}.glyphicon-fire:before{content:"\e104";}.glyphicon-eye-open:before{content:"\e105";}.glyphicon-eye-close:before{content:"\e106";}.glyphicon-warning-sign:before{content:"\e107";}.glyphicon-plane:before{content:"\e108";}.glyphicon-calendar:before{content:"\e109";}.glyphicon-random:before{content:"\e110";}.glyphicon-comment:before{content:"\e111";}.glyphicon-magnet:before{content:"\e112";}.glyphicon-chevron-up:before{content:"\e113";}.glyphicon-chevron-down:before{content:"\e114";}.glyphicon-retweet:before{content:"\e115";}.glyphicon-shopping-cart:before{content:"\e116";}.glyphicon-folder-close:before{content:"\e117";}.glyphicon-folder-open:before{content:"\e118";}.glyphicon-resize-vertical:before{content:"\e119";}.glyphicon-resize-horizontal:before{content:"\e120";}.glyphicon-hdd:before{content:"\e121";}.glyphicon-bullhorn:before{content:"\e122";}.glyphicon-bell:before{content:"\e123";}.glyphicon-certificate:before{content:"\e124";}.glyphicon-thumbs-up:before{content:"\e125";}.glyphicon-thumbs-down:before{content:"\e126";}.glyphicon-hand-right:before{content:"\e127";}.glyphicon-hand-left:before{content:"\e128";}.glyphicon-hand-up:before{content:"\e129";}.glyphicon-hand-down:before{content:"\e130";}.glyphicon-circle-arrow-right:before{content:"\e131";}.glyphicon-circle-arrow-left:before{content:"\e132";}.glyphicon-circle-arrow-up:before{content:"\e133";}.glyphicon-circle-arrow-down:before{content:"\e134";}.glyphicon-globe:before{content:"\e135";}.glyphicon-wrench:before{content:"\e136";}.glyphicon-tasks:before{content:"\e137";}.glyphicon-filter:before{content:"\e138";}.glyphicon-briefcase:before{content:"\e139";}.glyphicon-fullscreen:before{content:"\e140";}.glyphicon-dashboard:before{content:"\e141";}.glyphicon-paperclip:before{content:"\e142";}.glyphicon-heart-empty:before{content:"\e143";}.glyphicon-link:before{content:"\e144";}.glyphicon-phone:before{content:"\e145";}.glyphicon-pushpin:before{content:"\e146";}.glyphicon-usd:before{content:"\e148";}.glyphicon-gbp:before{content:"\e149";}.glyphicon-sort:before{content:"\e150";}.glyphicon-sort-by-alphabet:before{content:"\e151";}.glyphicon-sort-by-alphabet-alt:before{content:"\e152";}.glyphicon-sort-by-order:before{content:"\e153";}.glyphicon-sort-by-order-alt:before{content:"\e154";}.glyphicon-sort-by-attributes:before{content:"\e155";}.glyphicon-sort-by-attributes-alt:before{content:"\e156";}.glyphicon-unchecked:before{content:"\e157";}.glyphicon-expand:before{content:"\e158";}.glyphicon-collapse-down:before{content:"\e159";}.glyphicon-collapse-up:before{content:"\e160";}.glyphicon-log-in:before{content:"\e161";}.glyphicon-flash:before{content:"\e162";}.glyphicon-log-out:before{content:"\e163";}.glyphicon-new-window:before{content:"\e164";}.glyphicon-record:before{content:"\e165";}.glyphicon-save:before{content:"\e166";}.glyphicon-open:before{content:"\e167";}.glyphicon-saved:before{content:"\e168";}.glyphicon-import:before{content:"\e169";}.glyphicon-export:before{content:"\e170";}.glyphicon-send:before{content:"\e171";}.glyphicon-floppy-disk:before{content:"\e172";}.glyphicon-floppy-saved:before{content:"\e173";}.glyphicon-floppy-remove:before{content:"\e174";}.glyphicon-floppy-save:before{content:"\e175";}.glyphicon-floppy-open:before{content:"\e176";}.glyphicon-credit-card:before{content:"\e177";}.glyphicon-transfer:before{content:"\e178";}.glyphicon-cutlery:before{content:"\e179";}.glyphicon-header:before{content:"\e180";}.glyphicon-compressed:before{content:"\e181";}.glyphicon-earphone:before{content:"\e182";}.glyphicon-phone-alt:before{content:"\e183";}.glyphicon-tower:before{content:"\e184";}.glyphicon-stats:before{content:"\e185";}.glyphicon-sd-video:before{content:"\e186";}.glyphicon-hd-video:before{content:"\e187";}.glyphicon-subtitles:before{content:"\e188";}.glyphicon-sound-stereo:before{content:"\e189";}.glyphicon-sound-dolby:before{content:"\e190";}.glyphicon-sound-5-1:before{content:"\e191";}.glyphicon-sound-6-1:before{content:"\e192";}.glyphicon-sound-7-1:before{content:"\e193";}.glyphicon-copyright-mark:before{content:"\e194";}.glyphicon-registration-mark:before{content:"\e195";}.glyphicon-cloud-download:before{content:"\e197";}.glyphicon-cloud-upload:before{content:"\e198";}.glyphicon-tree-conifer:before{content:"\e199";}.glyphicon-tree-deciduous:before{content:"\e200";}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent;}.dropdown{position:relative;}.dropdown-toggle:focus{outline:0;}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0, 0, 0, 0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0, 0, 0, 0.175);box-shadow:0 6px 12px rgba(0, 0, 0, 0.175);background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5;}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429;color:#333333;white-space:nowrap;}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#f5f5f5;}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#428bca;}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999;}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);cursor:not-allowed;}.open>.dropdown-menu{display:block;}.open>a{outline:0;}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.428571429;color:#999999;}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990;}.pull-right>.dropdown-menu{right:0;left:auto;}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:"";}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto;}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle;}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left;}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2;}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:none;}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px;}.btn-toolbar:before,.btn-toolbar:after{content:" ";display:table;}.btn-toolbar:after{clear:both;}.btn-toolbar:before,.btn-toolbar:after{content:" ";display:table;}.btn-toolbar:after{clear:both;}.btn-toolbar .btn-group{float:left;}.btn-toolbar>.btn+.btn,.btn-toolbar>.btn-group+.btn,.btn-toolbar>.btn+.btn-group,.btn-toolbar>.btn-group+.btn-group{margin-left:5px;}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0;}.btn-group>.btn:first-child{margin-left:0;}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0;}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;}.btn-group>.btn-group{float:left;}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0;}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0;}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0;}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;}.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;}.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px;}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px;}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 5px rgba(0, 0, 0, 0.125);}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none;}.btn .caret{margin-left:0;}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0;}.dropup .btn-lg .caret{border-width:0 5px 5px;}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%;}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{content:" ";display:table;}.btn-group-vertical>.btn-group:after{clear:both;}.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after{content:" ";display:table;}.btn-group-vertical>.btn-group:after{clear:both;}.btn-group-vertical>.btn-group>.btn{float:none;}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0;}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0;}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:4px;border-top-right-radius:0;border-top-left-radius:0;}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0;}.btn-group-vertical>.btn-group:first-child>.btn:last-child,.btn-group-vertical>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0;}.btn-group-vertical>.btn-group:last-child>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0;}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate;}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%;}.btn-group-justified>.btn-group .btn{width:100%;}[data-toggle="buttons"]>.btn>input[type="radio"],[data-toggle="buttons"]>.btn>input[type="checkbox"]{display:none;}.input-group{position:relative;display:table;border-collapse:separate;}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0;}.input-group .form-control{width:100%;margin-bottom:0;}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px;}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px;}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto;}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px;}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px;}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto;}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell;}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0;}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle;}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555555;text-align:center;background-color:#eeeeee;border:1px solid #cccccc;border-radius:4px;}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px;}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px;}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0;}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0;}.input-group-addon:first-child{border-right:0;}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;}.input-group-addon:last-child{border-left:0;}.input-group-btn{position:relative;white-space:nowrap;}.input-group-btn:first-child>.btn{margin-right:-1px;}.input-group-btn:last-child>.btn{margin-left:-1px;}.input-group-btn>.btn{position:relative;}.input-group-btn>.btn+.btn{margin-left:-4px;}.input-group-btn>.btn:hover,.input-group-btn>.btn:active{z-index:2;}.nav{margin-bottom:0;padding-left:0;list-style:none;}.nav:before,.nav:after{content:" ";display:table;}.nav:after{clear:both;}.nav:before,.nav:after{content:" ";display:table;}.nav:after{clear:both;}.nav>li{position:relative;display:block;}.nav>li>a{position:relative;display:block;padding:10px 15px;}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee;}.nav>li.disabled>a{color:#999999;}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999999;text-decoration:none;background-color:transparent;cursor:not-allowed;}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#428bca;}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5;}.nav>li>a>img{max-width:none;}.nav-tabs{border-bottom:1px solid #dddddd;}.nav-tabs>li{float:left;margin-bottom:-1px;}.nav-tabs>li>a{margin-right:2px;line-height:1.428571429;border:1px solid transparent;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555555;background-color:#ffffff;border:1px solid #dddddd;border-bottom-color:transparent;cursor:default;}.nav-tabs.nav-justified{width:100%;border-bottom:0;}.nav-tabs.nav-justified>li{float:none;}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px;}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto;}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%;}.nav-tabs.nav-justified>li>a{margin-bottom:0;}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px;}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #dddddd;}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;border-radius:4px 4px 0 0;} .nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#ffffff;}}.nav-pills>li{float:left;}.nav-pills>li>a{border-radius:4px;}.nav-pills>li+li{margin-left:2px;}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#428bca;}.nav-stacked>li{float:none;}.nav-stacked>li+li{margin-top:2px;margin-left:0;}.nav-justified{width:100%;}.nav-justified>li{float:none;}.nav-justified>li>a{text-align:center;margin-bottom:5px;}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto;}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%;}.nav-justified>li>a{margin-bottom:0;}}.nav-tabs-justified{border-bottom:0;}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px;}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #dddddd;}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;border-radius:4px 4px 0 0;} .nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff;}}.tab-content>.tab-pane{display:none;}.tab-content>.active{display:block;}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0;}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent;}.navbar:before,.navbar:after{content:" ";display:table;}.navbar:after{clear:both;}.navbar:before,.navbar:after{content:" ";display:table;}.navbar:after{clear:both;}@media (min-width:768px){.navbar{border-radius:4px;}}.navbar-header:before,.navbar-header:after{content:" ";display:table;}.navbar-header:after{clear:both;}.navbar-header:before,.navbar-header:after{content:" ";display:table;}.navbar-header:after{clear:both;}@media (min-width:768px){.navbar-header{float:left;}}.navbar-collapse{max-height:340px;overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1);-webkit-overflow-scrolling:touch;}.navbar-collapse:before,.navbar-collapse:after{content:" ";display:table;}.navbar-collapse:after{clear:both;}.navbar-collapse:before,.navbar-collapse:after{content:" ";display:table;}.navbar-collapse:after{clear:both;}.navbar-collapse.in{overflow-y:auto;}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;box-shadow:none;}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important;} .navbar-collapse.in{overflow-y:visible;} .navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0;}}.container>.navbar-header,.container>.navbar-collapse{margin-right:-15px;margin-left:-15px;}@media (min-width:768px){.container>.navbar-header,.container>.navbar-collapse{margin-right:0;margin-left:0;}}.navbar-static-top{z-index:1000;border-width:0 0 1px;}@media (min-width:768px){.navbar-static-top{border-radius:0;}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0;}}.navbar-fixed-top{top:0;border-width:0 0 1px;}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0;}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none;}@media (min-width:768px){.navbar>.container .navbar-brand{margin-left:-15px;}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px;}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px;}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px;}@media (min-width:768px){.navbar-toggle{display:none;}}.navbar-nav{margin:7.5px -15px;}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px;}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;box-shadow:none;}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px;} .navbar-nav .open .dropdown-menu>li>a{line-height:20px;}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none;}}@media (min-width:768px){.navbar-nav{float:left;margin:0;}.navbar-nav>li{float:left;}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px;} .navbar-nav.navbar-right:last-child{margin-right:-15px;}}@media (min-width:768px){.navbar-left{float:left !important;} .navbar-right{float:right !important;}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.1),0 1px 0 rgba(255, 255, 255, 0.1);margin-top:8px;margin-bottom:8px;}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle;} .navbar-form .form-control{display:inline-block;} .navbar-form select.form-control{width:auto;} .navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;padding-left:0;} .navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{float:none;margin-left:0;}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px;}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none;}.navbar-form.navbar-right:last-child{margin-right:-15px;}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0;}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0;}.navbar-nav.pull-right>li>.dropdown-menu,.navbar-nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar-btn{margin-top:8px;margin-bottom:8px;}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px;}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px;}.navbar-text{margin-top:15px;margin-bottom:15px;}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px;}.navbar-text.navbar-right:last-child{margin-right:0;}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7;}.navbar-default .navbar-brand{color:#777777;}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent;}.navbar-default .navbar-text{color:#777777;}.navbar-default .navbar-nav>li>a{color:#777777;}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333333;background-color:transparent;}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555555;background-color:#e7e7e7;}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent;}.navbar-default .navbar-toggle{border-color:#dddddd;}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#dddddd;}.navbar-default .navbar-toggle .icon-bar{background-color:#cccccc;}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7;}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#e7e7e7;color:#555555;}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777777;}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333333;background-color:transparent;} .navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555555;background-color:#e7e7e7;} .navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent;}}.navbar-default .navbar-link{color:#777777;}.navbar-default .navbar-link:hover{color:#333333;}.navbar-inverse{background-color:#222222;border-color:#080808;}.navbar-inverse .navbar-brand{color:#999999;}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent;}.navbar-inverse .navbar-text{color:#999999;}.navbar-inverse .navbar-nav>li>a{color:#999999;}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent;}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#080808;}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent;}.navbar-inverse .navbar-toggle{border-color:#333333;}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333333;}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff;}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010;}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#080808;color:#ffffff;}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808;} .navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808;} .navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#999999;}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:transparent;} .navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#080808;} .navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444444;background-color:transparent;}}.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px;}.breadcrumb>li{display:inline-block;}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc;}.breadcrumb>.active{color:#999999;}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px;}.pagination>li{display:inline;}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;line-height:1.428571429;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px;}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px;}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px;}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{background-color:#eeeeee;}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#ffffff;background-color:#428bca;border-color:#428bca;cursor:default;}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999999;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed;}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px;}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px;}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px;}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px;}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center;}.pager:before,.pager:after{content:" ";display:table;}.pager:after{clear:both;}.pager:before,.pager:after{content:" ";display:table;}.pager:after{clear:both;}.pager li{display:inline;}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px;}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee;}.pager .next>a,.pager .next>span{float:right;}.pager .previous>a,.pager .previous>span{float:left;}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:#ffffff;cursor:not-allowed;}.label[href]:hover,.label[href]:focus{color:#ffffff;text-decoration:none;cursor:pointer;}.label:empty{display:none;}.btn .label{position:relative;top:-1px;}.label-default{background-color:#999999;}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080;}.label-primary{background-color:#428bca;}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9;}.label-success{background-color:#5cb85c;}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44;}.label-info{background-color:#5bc0de;}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5;}.label-warning{background-color:#f0ad4e;}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f;}.label-danger{background-color:#d9534f;}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c;}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#999999;border-radius:10px;}.badge:empty{display:none;}.btn .badge{position:relative;top:-1px;}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer;}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#ffffff;}.nav-pills>li>a>.badge{margin-left:3px;}.jumbotron{padding:30px;margin-bottom:30px;font-size:21px;font-weight:200;line-height:2.1428571435;color:inherit;background-color:#eeeeee;}.jumbotron h1,.jumbotron .h1{line-height:1;color:inherit;}.jumbotron p{line-height:1.4;}.container .jumbotron{border-radius:6px;}.jumbotron .container{max-width:100%;}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px;}.container .jumbotron{padding-left:60px;padding-right:60px;} .jumbotron h1,.jumbotron .h1{font-size:63px;}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.428571429;background-color:#ffffff;border:1px solid #dddddd;border-radius:4px;-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;}.thumbnail>img,.thumbnail a>img{display:block;max-width:100%;height:auto;margin-left:auto;margin-right:auto;}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca;}.thumbnail .caption{padding:9px;color:#333333;}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px;}.alert h4{margin-top:0;color:inherit;}.alert .alert-link{font-weight:bold;}.alert>p,.alert>ul{margin-bottom:0;}.alert>p+p{margin-top:5px;}.alert-dismissable{padding-right:35px;}.alert-dismissable .close{position:relative;top:-2px;right:-21px;color:inherit;}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d;}.alert-success hr{border-top-color:#c9e2b3;}.alert-success .alert-link{color:#2b542c;}.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#31708f;}.alert-info hr{border-top-color:#a6e1ec;}.alert-info .alert-link{color:#245269;}.alert-warning{background-color:#fcf8e3;border-color:#faebcc;color:#8a6d3b;}.alert-warning hr{border-top-color:#f7e1b5;}.alert-warning .alert-link{color:#66512c;}.alert-danger{background-color:#f2dede;border-color:#ebccd1;color:#a94442;}.alert-danger hr{border-top-color:#e4b9c0;}.alert-danger .alert-link{color:#843534;}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-transition:width 0.6s ease;transition:width 0.6s ease;}.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-size:40px 40px;}.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;}.progress-bar-success{background-color:#5cb85c;}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}.progress-bar-info{background-color:#5bc0de;}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}.progress-bar-warning{background-color:#f0ad4e;}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}.progress-bar-danger{background-color:#d9534f;}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);}.media,.media-body{overflow:hidden;zoom:1;}.media,.media .media{margin-top:15px;}.media:first-child{margin-top:0;}.media-object{display:block;}.media-heading{margin:0 0 5px;}.media>.pull-left{margin-right:10px;}.media>.pull-right{margin-left:10px;}.media-list{padding-left:0;list-style:none;}.list-group{margin-bottom:20px;padding-left:0;}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd;}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px;}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;}.list-group-item>.badge{float:right;}.list-group-item>.badge+.badge{margin-right:5px;}a.list-group-item{color:#555555;}a.list-group-item .list-group-item-heading{color:#333333;}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;background-color:#f5f5f5;}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#428bca;border-color:#428bca;}a.list-group-item.active .list-group-item-heading,a.list-group-item.active:hover .list-group-item-heading,a.list-group-item.active:focus .list-group-item-heading{color:inherit;}a.list-group-item.active .list-group-item-text,a.list-group-item.active:hover .list-group-item-text,a.list-group-item.active:focus .list-group-item-text{color:#e1edf7;}.list-group-item-heading{margin-top:0;margin-bottom:5px;}.list-group-item-text{margin-bottom:0;line-height:1.3;}.panel{margin-bottom:20px;background-color:#ffffff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:0 1px 1px rgba(0, 0, 0, 0.05);}.panel-body{padding:15px;}.panel-body:before,.panel-body:after{content:" ";display:table;}.panel-body:after{clear:both;}.panel-body:before,.panel-body:after{content:" ";display:table;}.panel-body:after{clear:both;}.panel>.list-group{margin-bottom:0;}.panel>.list-group .list-group-item{border-width:1px 0;}.panel>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0;}.panel>.list-group .list-group-item:last-child{border-bottom:0;}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0;}.panel>.table,.panel>.table-responsive>.table{margin-bottom:0;}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #dddddd;}.panel>.table>tbody:first-child th,.panel>.table>tbody:first-child td{border-top:0;}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0;}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0;}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0;}.panel>.table-bordered>thead>tr:last-child>th,.panel>.table-responsive>.table-bordered>thead>tr:last-child>th,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th,.panel>.table-bordered>thead>tr:last-child>td,.panel>.table-responsive>.table-bordered>thead>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0;}.panel>.table-responsive{border:0;margin-bottom:0;}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px;}.panel-heading>.dropdown .dropdown-toggle{color:inherit;}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit;}.panel-title>a{color:inherit;}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px;}.panel-group .panel{margin-bottom:0;border-radius:4px;overflow:hidden;}.panel-group .panel+.panel{margin-top:5px;}.panel-group .panel-heading{border-bottom:0;}.panel-group .panel-heading+.panel-collapse .panel-body{border-top:1px solid #dddddd;}.panel-group .panel-footer{border-top:0;}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd;}.panel-default{border-color:#dddddd;}.panel-default>.panel-heading{color:#333333;background-color:#f5f5f5;border-color:#dddddd;}.panel-default>.panel-heading+.panel-collapse .panel-body{border-top-color:#dddddd;}.panel-default>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#dddddd;}.panel-primary{border-color:#428bca;}.panel-primary>.panel-heading{color:#ffffff;background-color:#428bca;border-color:#428bca;}.panel-primary>.panel-heading+.panel-collapse .panel-body{border-top-color:#428bca;}.panel-primary>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#428bca;}.panel-success{border-color:#d6e9c6;}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6;}.panel-success>.panel-heading+.panel-collapse .panel-body{border-top-color:#d6e9c6;}.panel-success>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#d6e9c6;}.panel-warning{border-color:#faebcc;}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc;}.panel-warning>.panel-heading+.panel-collapse .panel-body{border-top-color:#faebcc;}.panel-warning>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#faebcc;}.panel-danger{border-color:#ebccd1;}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1;}.panel-danger>.panel-heading+.panel-collapse .panel-body{border-top-color:#ebccd1;}.panel-danger>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#ebccd1;}.panel-info{border-color:#bce8f1;}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1;}.panel-info>.panel-heading+.panel-collapse .panel-body{border-top-color:#bce8f1;}.panel-info>.panel-footer+.panel-collapse .panel-body{border-bottom-color:#bce8f1;}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}.well-lg{padding:24px;border-radius:6px;}.well-sm{padding:9px;border-radius:3px;}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50);}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;}.modal-open{overflow:hidden;}.modal{display:none;overflow:auto;overflow-y:scroll;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform 0.3s ease-out;-moz-transition:-moz-transform 0.3s ease-out;-o-transition:-o-transform 0.3s ease-out;transition:transform 0.3s ease-out;}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);transform:translate(0, 0);}.modal-dialog{position:relative;width:auto;margin:10px;z-index:1050;}.modal-content{position:relative;background-color:#ffffff;border:1px solid #999999;border:1px solid rgba(0, 0, 0, 0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0, 0, 0, 0.5);box-shadow:0 3px 9px rgba(0, 0, 0, 0.5);background-clip:padding-box;outline:none;}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1030;background-color:#000000;}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0);}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50);}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5;min-height:16.428571429px;}.modal-header .close{margin-top:-2px;}.modal-title{margin:0;line-height:1.428571429;}.modal-body{position:relative;padding:20px;}.modal-footer{margin-top:15px;padding:19px 20px 20px;text-align:right;border-top:1px solid #e5e5e5;}.modal-footer:before,.modal-footer:after{content:" ";display:table;}.modal-footer:after{clear:both;}.modal-footer:before,.modal-footer:after{content:" ";display:table;}.modal-footer:after{clear:both;}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;}.modal-footer .btn-group .btn+.btn{margin-left:-1px;}.modal-footer .btn-block+.btn-block{margin-left:0;}@media screen and (min-width:768px){.modal-dialog{width:600px;margin:30px auto;} .modal-content{-webkit-box-shadow:0 5px 15px rgba(0, 0, 0, 0.5);box-shadow:0 5px 15px rgba(0, 0, 0, 0.5);}}.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;font-size:12px;line-height:1.4;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.9;filter:alpha(opacity=90);}.tooltip.top{margin-top:-3px;padding:5px 0;}.tooltip.right{margin-left:3px;padding:0 5px;}.tooltip.bottom{margin-top:3px;padding:5px 0;}.tooltip.left{margin-left:-3px;padding:0 5px;}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;border-radius:4px;}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000000;}.tooltip.top-right .tooltip-arrow{bottom:0;right:5px;border-width:5px 5px 0;border-top-color:#000000;}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000000;}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000000;}.popover{position:absolute;top:0;left:0;z-index:1010;display:none;max-width:276px;padding:1px;text-align:left;background-color:#ffffff;background-clip:padding-box;border:1px solid #cccccc;border:1px solid rgba(0, 0, 0, 0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);white-space:normal;}.popover.top{margin-top:-10px;}.popover.right{margin-left:10px;}.popover.bottom{margin-top:10px;}.popover.left{margin-left:-10px;}.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0;}.popover-content{padding:9px 14px;}.popover .arrow,.popover .arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid;}.popover .arrow{border-width:11px;}.popover .arrow:after{border-width:10px;content:"";}.popover.top .arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#999999;border-top-color:rgba(0, 0, 0, 0.25);bottom:-11px;}.popover.top .arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff;}.popover.right .arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#999999;border-right-color:rgba(0, 0, 0, 0.25);}.popover.right .arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff;}.popover.bottom .arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999999;border-bottom-color:rgba(0, 0, 0, 0.25);top:-11px;}.popover.bottom .arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff;}.popover.left .arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999999;border-left-color:rgba(0, 0, 0, 0.25);}.popover.left .arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px;}.clearfix:before,.clearfix:after{content:" ";display:table;}.clearfix:after{clear:both;}.center-block{display:block;margin-left:auto;margin-right:auto;}.pull-right{float:right !important;}.pull-left{float:left !important;}.hide{display:none !important;}.show{display:block !important;}.invisible{visibility:hidden;}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0;}.hidden{display:none !important;visibility:hidden !important;}.affix{position:fixed;}
\ No newline at end of file diff --git a/app/assets/stylesheets/plugins/formtastic.css.scss b/app/assets/stylesheets/plugins/formtastic.css.scss new file mode 100644 index 000000000..bded68974 --- /dev/null +++ b/app/assets/stylesheets/plugins/formtastic.css.scss @@ -0,0 +1,34 @@ +fieldset.inputs { +     +    li.number input { width: 100px; } +    li.string input { width: 500px; }       + +    fieldset.inputs{ +        border: 2px groove threedface; +        margin-bottom: 20px; +        padding: 10px;        +         +        legend span{ +            font-weight: bold; +            padding: 5px; +        } + +        li.special {  +            display: inline-block;  +            width: 40%;        +             +            label.label {  +                width: 60%; +                margin-right: 10px; +            } +             +            input {          +                width: 20%; +            }  +             +        } +         +        a.action { float: right; } +         +    } +}
\ No newline at end of file diff --git a/app/assets/stylesheets/plugins/tipsy.css b/app/assets/stylesheets/plugins/tipsy.css new file mode 100644 index 000000000..f170fb710 --- /dev/null +++ b/app/assets/stylesheets/plugins/tipsy.css @@ -0,0 +1,25 @@ +.tipsy { font-size: 10px; position: absolute; padding: 5px; z-index: 100000; } +  .tipsy-inner { background-color: #000; color: #FFF; max-width: 200px; padding: 5px 8px 4px 8px; text-align: center; } + +  /* Rounded corners */ +  .tipsy-inner { border-radius: 3px; -moz-border-radius: 3px; -webkit-border-radius: 3px; } +   +  /* Uncomment for shadow */ +  /*.tipsy-inner { box-shadow: 0 0 5px #000000; -webkit-box-shadow: 0 0 5px #000000; -moz-box-shadow: 0 0 5px #000000; }*/ +   +  .tipsy-arrow { position: absolute; width: 0; height: 0; line-height: 0; border: 5px dashed #000; } +   +  /* Rules to colour arrows */ +  .tipsy-arrow-n { border-bottom-color: #000; } +  .tipsy-arrow-s { border-top-color: #000; } +  .tipsy-arrow-e { border-left-color: #000; } +  .tipsy-arrow-w { border-right-color: #000; } +   +	.tipsy-n .tipsy-arrow { top: 0px; left: 50%; margin-left: -5px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent; } +    .tipsy-nw .tipsy-arrow { top: 0; left: 10px; border-bottom-style: solid; border-top: none; border-left-color: transparent; border-right-color: transparent;} +    .tipsy-ne .tipsy-arrow { top: 0; right: 10px; border-bottom-style: solid; border-top: none;  border-left-color: transparent; border-right-color: transparent;} +  .tipsy-s .tipsy-arrow { bottom: 0; left: 50%; margin-left: -5px; border-top-style: solid; border-bottom: none;  border-left-color: transparent; border-right-color: transparent; } +    .tipsy-sw .tipsy-arrow { bottom: 0; left: 10px; border-top-style: solid; border-bottom: none;  border-left-color: transparent; border-right-color: transparent; } +    .tipsy-se .tipsy-arrow { bottom: 0; right: 10px; border-top-style: solid; border-bottom: none; border-left-color: transparent; border-right-color: transparent; } +  .tipsy-e .tipsy-arrow { right: 0; top: 50%; margin-top: -5px; border-left-style: solid; border-right: none; border-top-color: transparent; border-bottom-color: transparent; } +  .tipsy-w .tipsy-arrow { left: 0; top: 50%; margin-top: -5px; border-right-style: solid; border-left: none; border-top-color: transparent; border-bottom-color: transparent; } diff --git a/app/assets/stylesheets/referentials.css.scss b/app/assets/stylesheets/referentials.css.scss index 53200bf56..e7874711f 100644 --- a/app/assets/stylesheets/referentials.css.scss +++ b/app/assets/stylesheets/referentials.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the referentials controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.referentials.index  { diff --git a/app/assets/stylesheets/routes.css.scss b/app/assets/stylesheets/routes.css.scss index 756ddadfa..918f7c4fb 100644 --- a/app/assets/stylesheets/routes.css.scss +++ b/app/assets/stylesheets/routes.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the routes controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.lines.show  { diff --git a/app/assets/stylesheets/rule_parameter_sets.css.scss b/app/assets/stylesheets/rule_parameter_sets.css.scss new file mode 100644 index 000000000..8f9688d85 --- /dev/null +++ b/app/assets/stylesheets/rule_parameter_sets.css.scss @@ -0,0 +1,96 @@ +// Place all the styles related to the rule_parameter_sets controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ +@import "common/mixins"; + +#workspace.rule_parameter_sets.index +{ +    .rule_parameter_set:after { +        @include after_div_for_object; +    } + +    .rule_parameter_sets { +        margin-top: 20px; +    } + +    .rule_parameter_sets:after { +        @include content_to_clear; +    } + +    .rule_parameter_set { +        @include div_for_object; + +        /* to create multi-column index */ +        width: 350px; +        float: left; +        padding-right: 10px; +        position: relative; + +        .color { +            background-color: white; +            width: 64px; +            height: 64px; +            float: left; +            margin-right: 10px; +            border: 1px solid #999; + +            a { +                text-decoration: none; +            } +        } + +        .number { +            font-size: 16px; +            text-align: center; +            font-weight: bold; +            padding-top: 21px; +        } +        .name a { +            display: inline; +        } +    } +} + +#workspace.rule_parameter_sets.show, #workspace.compliance_check_tasks.rule_parameter_set +{ +    .summary label { +        font-weight: bold; +    } + +    div.attributes_group { +        margin: 15px 0 15px 0; + +        .title { font-weight: bold; } + +        .columns{ +            margin-left: 10px; + +            div { +                display: inline-block; + +                &.two_columns { width: 45%; } +                &.three_columns { width: 30%; } +                &.four_columns { width: 23%; } + +                label { +                    color: #616161; +                } + +                .value { margin-left: 5px; } +            } +        } +    } + +    div.rule_parameter_by_mode { +        margin: 20px 0 0 0 !important; + +        .mode_specific { +            display: none; +            margin: 0 0 0 10px; + +            p label { color: #616161; } +        } +    } +} + + diff --git a/app/assets/stylesheets/stop_areas.css.scss b/app/assets/stylesheets/stop_areas.css.scss index 3c0fd0479..8e5dc8fd9 100644 --- a/app/assets/stylesheets/stop_areas.css.scss +++ b/app/assets/stylesheets/stop_areas.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.stop_areas.index  { diff --git a/app/assets/stylesheets/stop_points.css.scss b/app/assets/stylesheets/stop_points.css.scss index 939ac1070..6f1ea505a 100644 --- a/app/assets/stylesheets/stop_points.css.scss +++ b/app/assets/stylesheets/stop_points.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.stop_points.index  { diff --git a/app/assets/stylesheets/subscriptions.css.scss b/app/assets/stylesheets/subscriptions.css.scss index ca94fd80a..e1877cb69 100644 --- a/app/assets/stylesheets/subscriptions.css.scss +++ b/app/assets/stylesheets/subscriptions.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.subscriptions.create, #workspace.subscriptions.new  { diff --git a/app/assets/stylesheets/time_tables.css.scss b/app/assets/stylesheets/time_tables.css.scss index f1ff7b3d2..ddd27b691 100644 --- a/app/assets/stylesheets/time_tables.css.scss +++ b/app/assets/stylesheets/time_tables.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.time_tables.index  { diff --git a/app/assets/stylesheets/users.css.scss b/app/assets/stylesheets/users.css.scss index e0fef9e5c..4ae0571ea 100644 --- a/app/assets/stylesheets/users.css.scss +++ b/app/assets/stylesheets/users.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the lines controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.users.edit, #workspace.lines.new  { diff --git a/app/assets/stylesheets/vehicle_journeys.css.scss b/app/assets/stylesheets/vehicle_journeys.css.scss index 76d78dd39..f11c6c1db 100644 --- a/app/assets/stylesheets/vehicle_journeys.css.scss +++ b/app/assets/stylesheets/vehicle_journeys.css.scss @@ -1,7 +1,7 @@  // Place all the styles related to the routes controller here.  // They will automatically be included in application.css.  // You can use Sass (SCSS) here: http://sass-lang.com/ -@import "common"; +@import "common/mixins";  #workspace.vehicle_journeys.edit, #workspace.vehicle_journeys.update, #workspace.vehicle_journeys.create, #workspace.vehicle_journeys.new  { diff --git a/app/controllers/compliance_check_results_controller.rb b/app/controllers/compliance_check_results_controller.rb new file mode 100644 index 000000000..a4ef40509 --- /dev/null +++ b/app/controllers/compliance_check_results_controller.rb @@ -0,0 +1,22 @@ +class ComplianceCheckResultsController < ChouetteController +  respond_to :json +  respond_to :js, :only => :index +  belongs_to :compliance_check_task + +  def index     +    index! do |format| +      format.html { render :layout => false } +    end +  end + +  def collection +    wheres = [:status, :severity].map{|key| params.has_key?(key) ? {key => params[key]} : {} }\ +      .inject({}){|hash, injected| hash.merge!(injected)} +    @compliance_check_results ||= end_of_association_chain.where(wheres).order(:rule_code) +  end + +  def rule_parameter_set +    @rule_parameter_set = RuleParameterSet.new.tap { |rps| rps.parameters = resource.parameter_set } +  end + +end diff --git a/app/controllers/compliance_check_tasks_controller.rb b/app/controllers/compliance_check_tasks_controller.rb new file mode 100644 index 000000000..45794199a --- /dev/null +++ b/app/controllers/compliance_check_tasks_controller.rb @@ -0,0 +1,41 @@ +class ComplianceCheckTasksController < ChouetteController +  respond_to :html, :js +  belongs_to :referential + +  def references +    @references = referential.send(params[:type]).where("name ilike ?", "%#{params[:q]}%") +    respond_to do |format| +      format.json do +        render json: @references.collect { |child| { id: child.id, name: child.name } } +      end +    end +  end + +  def rule_parameter_set +    @rule_parameter_set = compliance_check_task.rule_parameter_set_archived +    render "rule_parameter_sets/show" +  end + +  protected + +  alias_method :compliance_check_task, :resource + +  def create_resource( object ) +    if object.save +      object.delayed_validate +    end +  end + +  def build_resource +    super.tap do |export| +      compliance_check_task.assign_attributes referential_id: @referential.id, +        user_id: current_user.id, +        user_name: current_user.name +    end +  end + +  def collection +    @compliance_check_tasks ||= end_of_association_chain.order('created_at DESC').paginate(page: params[:page]) +  end + +end diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index 3b8fee566..2f14ab359 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -26,9 +26,9 @@ class ExportsController < ChouetteController    def references      @references = referential.send(params[:type]).where("name ilike ?", "%#{params[:q]}%") -    respond_to do |format|   +    respond_to do |format|        format.json do -        render :json => @references.collect { |child| { :id => child.id, :name => child.name } }  +        render :json => @references.collect { |child| { :id => child.id, :name => child.name } }        end      end    end @@ -53,7 +53,7 @@ class ExportsController < ChouetteController    end    def collection -    @exports ||= end_of_association_chain.paginate(:page => params[:page]) +    @exports ||= end_of_association_chain.order('created_at DESC').paginate(:page => params[:page])    end  end diff --git a/app/controllers/file_validations_controller.rb b/app/controllers/file_validations_controller.rb deleted file mode 100644 index 274d11f9f..000000000 --- a/app/controllers/file_validations_controller.rb +++ /dev/null @@ -1,45 +0,0 @@ -class FileValidationsController < InheritedResources::Base -  respond_to :html, :xml, :json - -  def index -    no_referential -    index! -  end - -  def show -    no_referential -    @toc = TestSheetPage.find("toc") -    show! -  end -   -  def new -    no_referential -    @toc = TestSheetPage.find("toc") -    new! -  end - -  def create -    no_referential -    create! do |success, failure| -      success.html { redirect_to file_validations_path } -    end -  end - -   -  protected -  def no_referential -    Apartment::Database.switch("public") -  end -   -  def resource -    @file_validation ||= current_organisation.file_validations.find_by_id(params[:id]) -  end -  def collection     -    @file_validations ||= current_organisation.file_validations.paginate(:page => params[:page]) -  end -  def create_resource(file_validation) -    file_validation.organisation = current_organisation -    super -  end -   -end diff --git a/app/controllers/import_tasks_controller.rb b/app/controllers/import_tasks_controller.rb new file mode 100644 index 000000000..36710bb69 --- /dev/null +++ b/app/controllers/import_tasks_controller.rb @@ -0,0 +1,67 @@ +class ImportTasksController < ChouetteController +  respond_to :html, :xml, :json +  respond_to :js, :only => :show +  belongs_to :referential + +  def new +    new! do +      available_imports +    end +  end + +  def show +    show! do +      if import_task.completed? +        @files_stats = import_task.result["files"]["stats"] +        @files_list = import_task.result["files"]["list"] +        @lines_stats = import_task.result["lines"]["stats"] +        @lines_list = import_task.result["lines"]["list"] +      end +    end +  end + +  def file_to_import +    send_file import_task.file_path, :type => "application/#{import_task.file_path_extension}", :disposition => "attachment" +  end + +  def create +    create! do |success, failure| +      available_imports +      success.html { redirect_to referential_import_tasks_path(@referential) } +    end +  end + +  protected + +  def create_resource( import ) +    if import_task.save +      import_task.delayed_import +    end +  end + +  alias_method :import_task, :resource + +  def available_imports +    @available_imports ||= ImportTask.formats.collect do |format| +      unless @import_task.format == format +        @referential.import_tasks.build :format => format +      else +        @import_task +      end +    end +  end + +  # FIXME why #resource_id is nil ?? +  def build_resource +    super.tap do |import_task| +      import_task.referential_id = @referential.id +      import_task.user_id = current_user.id +      import_task.user_name = current_user.name +    end +  end + +  def collection +    @import_tasks ||= end_of_association_chain.order('created_at DESC').paginate(:page => params[:page]) +  end + +end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb deleted file mode 100644 index 31af06c7d..000000000 --- a/app/controllers/imports_controller.rb +++ /dev/null @@ -1,47 +0,0 @@ -class ImportsController < ChouetteController -  respond_to :html, :xml, :json -  belongs_to :referential - -  def new -    new! do -      available_imports -    end -  end - -  def create -    create! do |success, failure| -      available_imports -      success.html { redirect_to referential_imports_path(@referential) } -    end -  end - -  def create_resource( import ) -    if import.save -      import.delayed_import -    end -  end - -  protected - -  def available_imports -    @available_imports ||= Import.types.collect do |type| -      unless @import.type == type -        @referential.imports.build :type => type -      else -        @import -      end -    end -  end - -  # FIXME why #resource_id is nil ?? -  def build_resource -    super.tap do |import| -      import.referential_id = @referential.id -    end -  end - -  def collection -    @imports ||= end_of_association_chain.paginate(:page => params[:page]) -  end - -end diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 447c48bc3..de0b209ca 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -2,8 +2,8 @@ class ReferentialsController < InheritedResources::Base    respond_to :html    respond_to :json, :only => :show    respond_to :js, :only => :show -   -  def show  + +  def show       resource.switch       show! do |format|         format.json { @@ -15,17 +15,23 @@ class ReferentialsController < InheritedResources::Base         }       end    end -   +    protected    def resource      @referential ||= current_organisation.referentials.find_by_id(params[:id])    end -  def collection     +  def collection      @referentials ||= current_organisation.referentials    end +  def build_resource +    super.tap do |referential| +      referential.user_id = current_user.id +      referential.user_name = current_user.name +    end +  end    def create_resource(referential)      referential.organisation = current_organisation      super    end -     +  end diff --git a/app/controllers/rule_parameter_sets_controller.rb b/app/controllers/rule_parameter_sets_controller.rb new file mode 100644 index 000000000..fbd5281c8 --- /dev/null +++ b/app/controllers/rule_parameter_sets_controller.rb @@ -0,0 +1,25 @@ +class RuleParameterSetsController < ChouetteController +  respond_to :html +  respond_to :js, :only => [ :mode ] + +  belongs_to :referential + +  def new +    @rule_parameter_set = RuleParameterSet.default( @referential) +    new! +  end + +  def destroy +    if @referential.rule_parameter_sets.count == 1 +      flash[:alert] = "Suppression impossible, le referentiel doit compter au minimum un jeu de parametre." +      redirect_to referential_rule_parameter_sets_path( @referential ) +    else +      destroy! +    end +  end + +  protected + +  alias_method :rule_parameter_set, :resource +end + diff --git a/app/helpers/compliance_check_tasks_helper.rb b/app/helpers/compliance_check_tasks_helper.rb new file mode 100644 index 000000000..3aab59452 --- /dev/null +++ b/app/helpers/compliance_check_tasks_helper.rb @@ -0,0 +1,5 @@ +module ComplianceCheckTasksHelper + +  include TypeIdsModelsHelper + +end diff --git a/app/helpers/creation_helper.rb b/app/helpers/creation_helper.rb deleted file mode 100644 index 167f2f01b..000000000 --- a/app/helpers/creation_helper.rb +++ /dev/null @@ -1,15 +0,0 @@ -module CreationHelper - -  def creation_tag(object) -    field_set_tag t("layouts.creation_tag.title") do -      content_tag :ul do -        [(content_tag :li do -          object.human_attribute_name('creation_time') + ' : ' + l(object.creation_time, :format => :short) -        end),  -        (content_tag :li do -          object.human_attribute_name('creator_id') + ' : ' + object.creator_id if  object.creator_id -        end)].join.html_safe -      end -    end -  end -end diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb index cd177b424..1ae59c190 100644 --- a/app/helpers/exports_helper.rb +++ b/app/helpers/exports_helper.rb @@ -10,76 +10,6 @@ module ExportsHelper      end    end -  @@export_references_type = {} -  def export_references_type(type) -    @@export_references_type[type] ||= ReferencesTypeHelper.new(type) -  end - -  class ReferencesTypeHelper -     -    attr_accessor :type - -    def initialize(type) -      @type = type.to_s -    end - -    def relation_name -      Export.references_relation(type) -    end - -    def input_id -      "export_reference_#{relation_name}_ids" -    end - -    def input_class -      "export_#{relation_name}_reference_ids" -    end - -  end - -  def export_references_input(form, export, type) -    ReferencesInput.new form, export, export_references_type(type) -  end - -  class ReferencesInput - -    attr_accessor :form, :export, :type_helper -    def initialize(form, export, type_helper) -      @form, @export, @type_helper = form, export, type_helper -    end - -    delegate :input_id, :type, :input_class, :to => :type_helper - -    def current? -      export.references_type == type -    end - -    def references_map -      references.collect { |child| { :id => child.id, :name => child.name } }  -    end - -    def wrapper_html_options -      {  -        :class => "export_reference_ids",  -        :id => "#{input_id}_input",  -        :"data-type" => type,  -        :style => ("display: none" unless current?)  -      } -    end - -    def input_html_options -      {  -        :id => input_id,  -        :class =>  input_class, -        :"data-pre" => ( references_map.to_json if current? ), -        :disabled => (true unless current?) -      } -    end -     -    def input -      form.input :reference_ids, :as => :text, :wrapper_html => wrapper_html_options, :input_html => input_html_options -    end - -  end +  include TypeIdsModelsHelper  end diff --git a/app/helpers/flash_helper.rb b/app/helpers/flash_helper.rb new file mode 100644 index 000000000..7f19e0566 --- /dev/null +++ b/app/helpers/flash_helper.rb @@ -0,0 +1,33 @@ +module FlashHelper + +  def bootstrap_class_for flash_type +    case flash_type +      when :success +        "alert-success" +      when :error +        "alert-danger" +      when :alert +        "alert-warning" +      when :notice +        "alert-info" +      else +        flash_type.to_s +    end +  end + +  def flash_message_for(flash_type, message) +    case flash_type +      when :success +        "<i class='fa fa-check-circle'></i>  #{message}".html_safe +      when :error +        "<i class='fa fa-minus-circle'></i> #{message}".html_safe +      when :alert +        "<i class='fa fa-exclamation-circle'></i> #{message}".html_safe  +      when :notice +        "<i class='fa fa-info-circle'></i> #{message}".html_safe +      else +        message +    end +  end +   +end diff --git a/app/helpers/history_helper.rb b/app/helpers/history_helper.rb new file mode 100644 index 000000000..a4f2df05c --- /dev/null +++ b/app/helpers/history_helper.rb @@ -0,0 +1,43 @@ +module HistoryHelper + +  def creation_tag(object) +    field_set_tag t("layouts.creation_tag.title") do +      content_tag :ul do +        [(content_tag :li do +          if object.has_attribute?(:creation_time)   +            object.human_attribute_name('creation_time') + ' : ' + l(object.creation_time, :format => :short) +          else             +            object.class.human_attribute_name('created_at') + ' : ' + l(object.created_at, :format => :short) +          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)].join.html_safe +      end +    end +  end +   +  def history_tag(object) +    field_set_tag t("layouts.history_tag.title") do +      content_tag :ul do +        [(content_tag :li do +          if object.has_attribute?(:created_at)     +            t('layouts.history_tag.created_at') + ' : ' + l(object.created_at, :format => :short) +          end +        end), +        (content_tag :li do +          if object.has_attribute?(:updated_at)     +            t('layouts.history_tag.updated_at') + ' : ' + l(object.updated_at, :format => :short) +          end +        end),   +        (content_tag :li do +           if object.has_attribute?(:user_name) +             t('layouts.history_tag.user_name') + ' : ' + object.user_name if  object.user_name +           end +        end)].join.html_safe +      end +    end +  end +end diff --git a/app/helpers/imports_helper.rb b/app/helpers/imports_helper.rb index 4b829fe98..2b94cfd1a 100644 --- a/app/helpers/imports_helper.rb +++ b/app/helpers/imports_helper.rb @@ -1,8 +1,8 @@  # -*- coding: utf-8 -*-  module ImportsHelper -  def fields_for_import_type(form) -    partial_name = "fields_#{form.object.type.underscore}" +  def fields_for_import_task_format(form) +    partial_name = "fields_#{form.object.format.underscore}_import"      begin        render :partial => partial_name, :locals => { :form => form } diff --git a/app/helpers/title_helper.rb b/app/helpers/title_helper.rb index 2203151a3..209cbc4a9 100644 --- a/app/helpers/title_helper.rb +++ b/app/helpers/title_helper.rb @@ -9,7 +9,7 @@ module TitleHelper    end    def title_tag(title, options = nil) -    content_tag :h2, title(title), options +    content_tag :h2, title(title).html_safe, options    end  end diff --git a/app/helpers/type_ids_models_helper.rb b/app/helpers/type_ids_models_helper.rb new file mode 100644 index 000000000..3d1c54a5b --- /dev/null +++ b/app/helpers/type_ids_models_helper.rb @@ -0,0 +1,75 @@ +module TypeIdsModelsHelper + +  def type_ids_model_references_type( type_ids_model_class, type) +    ReferencesTypeHelper.new( type_ids_model_class, type) +  end + +  class ReferencesTypeHelper + +    attr_accessor :type_ids_model_class, :type + +    def initialize( type_ids_model_class, type) +      @type_ids_model_class, @type = type_ids_model_class, type +    end +    def model_class +      type_ids_model_class.to_s.underscore +    end +    def input_id +      "#{model_class}_reference_#{relation_name}_ids" +    end +    def input_class +      "#{model_class}_#{relation_name}_reference_ids" +    end +    def relation_name +      type_ids_model_class.references_relation(type) +    end +  end + +  def type_ids_model_references_input( form, type_ids_model, model_class, type) +    cct_type_helper = type_ids_model_references_type( model_class, type) +    ReferencesInput.new form, type_ids_model, type, cct_type_helper +  end + +  class ReferencesInput + +    attr_accessor :form, :type_ids_model, :type, :type_helper +    def initialize(form, type_ids_model, type, type_helper) +      @form, @type_ids_model, @type, @type_helper = form, type_ids_model, type, type_helper +    end + +    delegate :input_id, :input_class, :model_class, :to => :type_helper + +    def current? +      type_ids_model.references_type == type +    end + +    def references_map +      references.collect { |child| { :id => child.id, :name => child.name } } +    end + +    def wrapper_html_options +      { +        :class => "#{model_class}_reference_ids", +        :id => "#{input_id}_input", +        :"data-type" => type, +        :style => ("display: none" unless current?) +      } +    end + +    def input_html_options +      { +        :id => input_id, +        :class =>  input_class, +        :"data-pre" => ( references_map.to_json if current? ), +        :disabled => (true unless current?) +      } +    end + +    def input +      form.input :reference_ids, :as => :text, :wrapper_html => wrapper_html_options, :input_html => input_html_options +    end + +  end + +end + diff --git a/app/maps/access_link_map.rb b/app/maps/access_link_map.rb index fcca1250f..35873a9b1 100644 --- a/app/maps/access_link_map.rb +++ b/app/maps/access_link_map.rb @@ -9,11 +9,11 @@ class AccessLinkMap < ApplicationMap    end    def customize_map(map, page) -    page.assign "access_points_layer", kml_layer([access_link.referential, access_link.access_point], :styleMap => StyleMap::AccessPointsStyleMap.new(helpers).style_map)  +    page.assign "access_points_layer", kml_layer([access_link.referential, access_link.access_point], :styleMap => Design::AccessPointsStyleMap.new(helpers).style_map)       page << map.add_layer(:access_points_layer) -    page.assign "stop_areas_layer", kml_layer([access_link.referential, access_link.stop_area], :styleMap => StyleMap::StopAreasStyleMap.new(helpers).style_map)  +    page.assign "stop_areas_layer", kml_layer([access_link.referential, access_link.stop_area], :styleMap => Design::StopAreasStyleMap.new(helpers).style_map)       page << map.add_layer(:stop_areas_layer) -    page << map.add_layer( kml_layer([access_link.referential, access_link.access_point, access_link], :styleMap => StyleMap::AccessLinkStyleMap.new(helpers).style_map)) +    page << map.add_layer( kml_layer([access_link.referential, access_link.access_point, access_link], :styleMap => Design::AccessLinkStyleMap.new(helpers).style_map))      page << map.add_control( hover_control_display_name([:access_points_layer,:stop_areas_layer]) )      page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds    end diff --git a/app/maps/access_point_map.rb b/app/maps/access_point_map.rb index c1fbd2a16..f31dcf5a3 100644 --- a/app/maps/access_point_map.rb +++ b/app/maps/access_point_map.rb @@ -10,9 +10,9 @@ class AccessPointMap < ApplicationMap    end    def customize_map(map, page) -    page.assign "parent_layer", kml_layer(access_point.stop_area,  :style_map => StyleMap::StopAreasStyleMap.new(helpers).style_map) +    page.assign "parent_layer", kml_layer(access_point.stop_area,  :style_map => Design::StopAreasStyleMap.new(helpers).style_map)      page << map.add_layer(:parent_layer) -    page.assign "edit_access_point_layer", kml_layer(access_point, { :default => editable? }, :style_map => StyleMap::EditAccessPointStyleMap.new(helpers).style_map) +    page.assign "edit_access_point_layer", kml_layer(access_point, { :default => editable? }, :style_map => Design::EditAccessPointStyleMap.new(helpers).style_map)      page << map.add_layer(:edit_access_point_layer) diff --git a/app/maps/connection_link_map.rb b/app/maps/connection_link_map.rb index 9318ec90f..82050c4da 100644 --- a/app/maps/connection_link_map.rb +++ b/app/maps/connection_link_map.rb @@ -9,9 +9,9 @@ class ConnectionLinkMap < ApplicationMap    end    def customize_map(map, page) -    page.assign "stop_areas_layer", kml_layer([connection_link.referential, connection_link, :stop_areas], :styleMap => StyleMap::StopAreasStyleMap.new(helpers).style_map)  +    page.assign "stop_areas_layer", kml_layer([connection_link.referential, connection_link, :stop_areas], :styleMap => Design::StopAreasStyleMap.new(helpers).style_map)       page << map.add_layer(:stop_areas_layer) -    page << map.add_layer( kml_layer([connection_link.referential, connection_link], :styleMap => StyleMap::ConnectionLinkStyleMap.new(helpers).style_map)) +    page << map.add_layer( kml_layer([connection_link.referential, connection_link], :styleMap => Design::ConnectionLinkStyleMap.new(helpers).style_map))      page << map.add_control( hover_control_display_name(:stop_areas_layer) )      page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds    end diff --git a/app/maps/style_map/access_link_style_map.rb b/app/maps/design/access_link_style_map.rb index 07ef5952b..742f7ed0e 100644 --- a/app/maps/style_map/access_link_style_map.rb +++ b/app/maps/design/access_link_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::AccessLinkStyleMap < StyleMap::GenericStyleMap +class Design::AccessLinkStyleMap < Design::GenericStyleMap    attr_accessor :style    def initialize(helpers,options = {}) diff --git a/app/maps/style_map/access_points_style_map.rb b/app/maps/design/access_points_style_map.rb index 57cf8dfb3..f7740006d 100644 --- a/app/maps/style_map/access_points_style_map.rb +++ b/app/maps/design/access_points_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::AccessPointsStyleMap < StyleMap::GenericStyleMap +class Design::AccessPointsStyleMap < Design::GenericStyleMap    attr_accessor :style, :context, :temporary    def default_style diff --git a/app/maps/style_map/connection_link_style_map.rb b/app/maps/design/connection_link_style_map.rb index 99393fc08..88eeb9457 100644 --- a/app/maps/style_map/connection_link_style_map.rb +++ b/app/maps/design/connection_link_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::ConnectionLinkStyleMap < StyleMap::GenericStyleMap +class Design::ConnectionLinkStyleMap < Design::GenericStyleMap    attr_accessor :style    def initialize(helpers,options = {}) diff --git a/app/maps/style_map/edit_access_point_style_map.rb b/app/maps/design/edit_access_point_style_map.rb index 83f9298e8..48c293470 100644 --- a/app/maps/style_map/edit_access_point_style_map.rb +++ b/app/maps/design/edit_access_point_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::EditAccessPointStyleMap < StyleMap::GenericStyleMap +class Design::EditAccessPointStyleMap < Design::GenericStyleMap    attr_accessor :style    def default_style diff --git a/app/maps/style_map/edit_stop_area_style_map.rb b/app/maps/design/edit_stop_area_style_map.rb index 38f18f04a..2431f8a0f 100644 --- a/app/maps/style_map/edit_stop_area_style_map.rb +++ b/app/maps/design/edit_stop_area_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::EditStopAreaStyleMap < StyleMap::GenericStyleMap +class Design::EditStopAreaStyleMap < Design::GenericStyleMap    attr_accessor :style    def default_style diff --git a/app/maps/style_map/generic_style_map.rb b/app/maps/design/generic_style_map.rb index c905cd00d..0056cc964 100644 --- a/app/maps/style_map/generic_style_map.rb +++ b/app/maps/design/generic_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::GenericStyleMap +class Design::GenericStyleMap    include MapLayers    include MapLayers::ViewHelpers diff --git a/app/maps/style_map/journey_pattern_style_map.rb b/app/maps/design/journey_pattern_style_map.rb index 5a06b5c18..1b5766f81 100644 --- a/app/maps/style_map/journey_pattern_style_map.rb +++ b/app/maps/design/journey_pattern_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::JourneyPatternStyleMap < StyleMap::GenericStyleMap +class Design::JourneyPatternStyleMap < Design::GenericStyleMap    attr_accessor :style    def initialize(helpers, options = {}) diff --git a/app/maps/style_map/line_style_map.rb b/app/maps/design/line_style_map.rb index acc307df4..e1d76078c 100644 --- a/app/maps/style_map/line_style_map.rb +++ b/app/maps/design/line_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::LineStyleMap < StyleMap::GenericStyleMap +class Design::LineStyleMap < Design::GenericStyleMap    attr_accessor :style, :line_priority, :line_color    def initialize(helpers,options = {}) diff --git a/app/maps/style_map/route_style_map.rb b/app/maps/design/route_style_map.rb index 1d9ab12f0..a8042c527 100644 --- a/app/maps/style_map/route_style_map.rb +++ b/app/maps/design/route_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::RouteStyleMap < StyleMap::GenericStyleMap +class Design::RouteStyleMap < Design::GenericStyleMap    attr_accessor :style    def initialize(helpers,options = {}) diff --git a/app/maps/style_map/stop_areas_style_map.rb b/app/maps/design/stop_areas_style_map.rb index f23b58136..f45c423e2 100644 --- a/app/maps/style_map/stop_areas_style_map.rb +++ b/app/maps/design/stop_areas_style_map.rb @@ -1,4 +1,4 @@ -class StyleMap::StopAreasStyleMap < StyleMap::GenericStyleMap +class Design::StopAreasStyleMap < Design::GenericStyleMap    attr_accessor :style, :context, :temporary    def default_style diff --git a/app/maps/group_of_line_map.rb b/app/maps/group_of_line_map.rb index df1708597..b9c174cb9 100644 --- a/app/maps/group_of_line_map.rb +++ b/app/maps/group_of_line_map.rb @@ -8,7 +8,7 @@ class GroupOfLineMap < ApplicationMap    end    def customize_map(map, page) -    page.assign "stop_areas_layer", kml_layer([group_of_line.referential, group_of_line], :styleMap => StyleMap::StopAreasStyleMap.new(helpers).style_map) +    page.assign "stop_areas_layer", kml_layer([group_of_line.referential, group_of_line], :styleMap => Design::StopAreasStyleMap.new(helpers).style_map)      page << map.add_layer(:stop_areas_layer)      page << map.add_control( hover_control_display_name(:stop_areas_layer) ) diff --git a/app/maps/journey_pattern_map.rb b/app/maps/journey_pattern_map.rb index 075019c79..e1cf54a6a 100644 --- a/app/maps/journey_pattern_map.rb +++ b/app/maps/journey_pattern_map.rb @@ -8,7 +8,7 @@ class JourneyPatternMap < ApplicationMap    end    def customize_map(map, page) -    layer = kml_layer([journey_pattern.referential, journey_pattern.route.line, journey_pattern.route, journey_pattern], :styleMap => StyleMap::JourneyPatternStyleMap.new(helpers).style_map) +    layer = kml_layer([journey_pattern.referential, journey_pattern.route.line, journey_pattern.route, journey_pattern], :styleMap => Design::JourneyPatternStyleMap.new(helpers).style_map)      page.assign "journeyPatternLayer", layer      selectFeature = OpenLayers::Control::SelectFeature.new( :journeyPatternLayer) diff --git a/app/maps/line_map.rb b/app/maps/line_map.rb index 3bc229555..8d79bfe0b 100644 --- a/app/maps/line_map.rb +++ b/app/maps/line_map.rb @@ -9,8 +9,8 @@ class LineMap < ApplicationMap    end    def customize_map(map, page) -    page << map.add_layer(kml_layer(line, :styleMap => StyleMap::LineStyleMap.new( :style => line_style).style_map)) -    page.assign "stop_areas_layer", kml_layer([line.referential, line], :styleMap => StyleMap::StopAreasStyleMap.new(helpers).style_map) +    page << map.add_layer(kml_layer(line, :styleMap => Design::LineStyleMap.new( :style => line_style).style_map)) +    page.assign "stop_areas_layer", kml_layer([line.referential, line], :styleMap => Design::StopAreasStyleMap.new(helpers).style_map)      page << map.add_layer(:stop_areas_layer) diff --git a/app/maps/network_map.rb b/app/maps/network_map.rb index ec23f62c9..109e390d0 100644 --- a/app/maps/network_map.rb +++ b/app/maps/network_map.rb @@ -8,7 +8,7 @@ class NetworkMap < ApplicationMap    end    def customize_map(map, page) -    page.assign "stop_areas_layer", kml_layer([network.referential, network], :styleMap => StyleMap::StopAreasStyleMap.new(helpers).style_map) +    page.assign "stop_areas_layer", kml_layer([network.referential, network], :styleMap => Design::StopAreasStyleMap.new(helpers).style_map)      page << map.add_layer(:stop_areas_layer)      page << map.add_control( hover_control_display_name(:stop_areas_layer) ) diff --git a/app/maps/route_map.rb b/app/maps/route_map.rb index fc1a7d93e..5acb1ad76 100644 --- a/app/maps/route_map.rb +++ b/app/maps/route_map.rb @@ -8,7 +8,7 @@ class RouteMap < ApplicationMap    end    def customize_map(map, page) -    layer = kml_layer([route.referential, route.line, route], :styleMap => StyleMap::RouteStyleMap.new(helpers).style_map) +    layer = kml_layer([route.referential, route.line, route], :styleMap => Design::RouteStyleMap.new(helpers).style_map)      page.assign "routeLayer", layer      selectFeature = OpenLayers::Control::SelectFeature.new( :routeLayer) diff --git a/app/maps/stop_area_map.rb b/app/maps/stop_area_map.rb index b2e04779a..6c3dd5feb 100644 --- a/app/maps/stop_area_map.rb +++ b/app/maps/stop_area_map.rb @@ -10,21 +10,21 @@ class StopAreaMap < ApplicationMap    end    def customize_map(map, page) -      page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => StyleMap::EditStopAreaStyleMap.new(helpers).style_map) +      page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map)        page << map.add_layer(:edit_stop_area_layer)        if stop_area.children.present? -        page.assign "children_layer", kml_layer(stop_area, { :children => true }, :style_map => StyleMap::StopAreasStyleMap.new(helpers).style_map) +        page.assign "children_layer", kml_layer(stop_area, { :children => true }, :style_map => Design::StopAreasStyleMap.new(helpers).style_map)          page << map.add_layer(:children_layer)        end        if stop_area.routing_stops.present? -        page.assign "routing_layer", kml_layer(stop_area, { :routing => true }, :style_map => StyleMap::StopAreasStyleMap.new(helpers).style_map) +        page.assign "routing_layer", kml_layer(stop_area, { :routing => true }, :style_map => Design::StopAreasStyleMap.new(helpers).style_map)          page << map.add_layer(:routing_layer)          page << map.add_control( hover_control_display_name(:routing_layer) )          page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds        else -        page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => StyleMap::EditStopAreaStyleMap.new(helpers).style_map) +        page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map)          page << map.add_layer(:edit_stop_area_layer)          if editable? diff --git a/app/models/compliance_check_result.rb b/app/models/compliance_check_result.rb new file mode 100644 index 000000000..6d4509676 --- /dev/null +++ b/app/models/compliance_check_result.rb @@ -0,0 +1,47 @@ +class ComplianceCheckResult < ActiveRecord::Base +  scope :warning, -> { where severity: 'warning' } +  scope :error, -> { where severity: 'error' } +  scope :improvment, -> { where severity: 'improvment' } + +  scope :ok, -> { where status: 'ok' } +  scope :nok, -> { where status: 'nok' } +  scope :na, -> { where status: 'na' }   + +  attr_accessible :violation_count +  belongs_to :compliance_check_task + +  validates_presence_of :rule_code +  validates_inclusion_of :severity, :in => %w{warning error improvment} +  validates_inclusion_of :status, :in => %w{na ok nok} + +  serialize :detail, JSON + +  def indice +    return nil unless rule_code + +    rule_code.match( /\d+-\w+-\w+-(\d+)/ )[1].to_i +  end + +  def data_type +    return nil unless rule_code + +    rule_code.match( /\d+-\w+-(\w+)-\d+/ )[1] +  end + +  def format +    return nil unless rule_code + +    rule_code.match( /\d+-(\w+)-\w+-\d+/ )[1] +  end + +  def level +    return nil unless rule_code + +    rule_code.match( /(\d+)-\w+-\w+-\d+/ )[1].to_i +  end + +  def rule_code_formatted +    rule_code.gsub("-", "_").downcase if rule_level +  end + +end diff --git a/app/models/compliance_check_task.rb b/app/models/compliance_check_task.rb new file mode 100644 index 000000000..756f4ba13 --- /dev/null +++ b/app/models/compliance_check_task.rb @@ -0,0 +1,95 @@ +class ComplianceCheckTask < ActiveRecord::Base +  attr_accessor :rule_parameter_set_id + +  belongs_to :referential +  belongs_to :import_task + +  validates_presence_of :referential +  validates_presence_of :user_id +  validates_presence_of :user_name +  validates_inclusion_of :status, :in => %w{ pending processing completed failed } + +  has_many :compliance_check_results, :order => :status + +  serialize :parameter_set, JSON + +  include ::TypeIdsModelable + +  def chouette_command +    Chouette::Command.new(:schema => referential.slug) +  end + +  before_validation :define_default_attributes, :on => :create +  def define_default_attributes +    self.status ||= "pending" +    if self.rule_parameter_set +      self.parameter_set = self.rule_parameter_set.parameters +      self.parameter_set_name = self.rule_parameter_set.name +    end +  end + +  @@references_types = [ Chouette::Line, Chouette::Network, Chouette::Company, Chouette::GroupOfLine ] +  cattr_reader :references_types + +  #validates_inclusion_of :references_type, :in => references_types.map(&:to_s), :allow_blank => true, :allow_nil => true + +  after_destroy :destroy_import_task +  def destroy_import_task +    import_task.destroy if import_task +  end + +  def delayed_validate +    delay.validate if import_task.blank? +  end + +  def name +    "#{self.class.model_name.human} #{id}" +  end + +  def levels +    [].tap do |l| +      l.concat( [1 , 2]) if self.import_task +      l << 3 if self.parameter_set +    end +  end + +  def level1? +    levels.include?( 1) +  end + +  def level2? +    levels.include?( 2) +  end + +  def level3? +    levels.include?( 3) +  end + +  def rule_parameter_set_archived +    return nil unless parameter_set +    RuleParameterSet.new( :name => parameter_set_name).tap do |rs| +      rs.parameters = parameter_set +    end +  end + +  def rule_parameter_set +    return nil if self.rule_parameter_set_id.blank? +    RuleParameterSet.find( self.rule_parameter_set_id) +  end + +  def chouette_command_args +    {:c => "validate", :id => id} +  end + +  def validate +    begin +      chouette_command.run! chouette_command_args +      update_attribute :status, "completed" +    rescue => e +      Rails.logger.error "Validation #{id} failed : #{e}, #{e.backtrace}" +      update_attribute :status, "failed" +    end +  end + + +end diff --git a/app/models/csv_import.rb b/app/models/csv_import.rb index be3c08743..69603b237 100644 --- a/app/models/csv_import.rb +++ b/app/models/csv_import.rb @@ -1,10 +1,6 @@ -class CsvImport < Import +class CsvImport < ImportTask -  validates_presence_of :objectid_prefix -  option :objectid_prefix - -  def import_options -    super.merge(:format => :csv, :objectid_prefix => objectid_prefix) -  end +  validates_presence_of :object_id_prefix +  option :object_id_prefix  end diff --git a/app/models/export.rb b/app/models/export.rb index 342e55738..f684ddef5 100644 --- a/app/models/export.rb +++ b/app/models/export.rb @@ -9,6 +9,8 @@ class Export < ActiveRecord::Base    serialize :options +  include ::TypeIdsModelable +    def self.option(name)      name = name.to_s @@ -74,7 +76,7 @@ class Export < ActiveRecord::Base      begin        # delayed job may repeat call -      ExportLogMessage.where(:export_id => self.id).delete_all  +      ExportLogMessage.where(:export_id => self.id).delete_all        log_messages.create :severity => "ok", :key => :started        exporter.export file, export_options @@ -94,54 +96,8 @@ class Export < ActiveRecord::Base    validates_inclusion_of :references_type, :in => references_types.map(&:to_s), :allow_blank => true, :allow_nil => true -  def references -    if references_relation.present? and reference_ids.present? -      referential.send(references_relation).find(reference_ids) -    else -      [] -    end -  end - -  def references=(references) -    unless references.blank? -      self.references_type = references.first.class.name -      self.reference_ids = references.map(&:id) -    else -      self.references_type = nil -      self.reference_ids = [] -    end -  end - -  def references_relation -    if references_type.present? -      relation = self.class.references_relation(references_type) -      relation if referential.respond_to?(relation) -    end -  end - -  def self.references_relation(type) -    type.to_s.demodulize.underscore.pluralize  -  end - -  def reference_ids -    if raw_reference_ids -      raw_reference_ids.split(',').map(&:to_i)  -    else -      [] -    end -  end - -  def reference_ids=(records) -    records = Array(records) -    write_attribute :reference_ids, (records.present? ? records.join(',') : nil) -  end - -  def raw_reference_ids -    read_attribute :reference_ids -  end -    def self.format_name(format) -    name_by_format = {  +    name_by_format = {        "NeptuneExport" => "Neptune",        "CsvExport" => "CSV",        "GtfsExport" => "GTFS", diff --git a/app/models/file_validation.rb b/app/models/file_validation.rb deleted file mode 100644 index e09a48113..000000000 --- a/app/models/file_validation.rb +++ /dev/null @@ -1,186 +0,0 @@ -class FileValidation < ActiveRecord::Base -  validates_presence_of :resources - -  validates_inclusion_of :status, :in => %w{ pending completed failed } - -  attr_accessor :resources,:uncheck_count,:ok_count,:warning_count,:error_count,:fatal_count,:log_message_tree -  attr_accessor :validator - -  belongs_to :organisation -  validates_presence_of :organisation - -  has_many :log_messages, :class_name => "FileValidationLogMessage", :order => :position, :dependent => :destroy - -  serialize :options - -  def self.option(name) -    name = name.to_s - -    define_method(name) do -      self.options and self.options[name] -    end - -    define_method("#{name}=") do |prefix| -      (self.options ||= {})[name] = prefix -    end -  end - -  option :test3_1_minimal_distance -  option :test3_2_minimal_distance -  option :test3_2_polygon_points -  option :test3_7_minimal_distance -  option :test3_7_maximal_distance -  option :test3_8a_minimal_speed -  option :test3_8a_maximal_speed -  option :test3_8b_minimal_speed -  option :test3_8b_maximal_speed -  option :test3_8c_minimal_speed -  option :test3_8c_maximal_speed -  option :test3_8d_minimal_speed -  option :test3_8d_maximal_speed -  option :test3_9_minimal_speed -  option :test3_9_maximal_speed -  option :test3_10_minimal_distance -  option :test3_15_minimal_time -  option :test3_16_1_maximal_time -  option :test3_16_3a_maximal_time -  option :test3_16_3b_maximal_time -  option :test3_21a_minimal_speed -  option :test3_21a_maximal_speed -  option :test3_21b_minimal_speed -  option :test3_21b_maximal_speed -  option :test3_21c_minimal_speed -  option :test3_21c_maximal_speed -  option :test3_21d_minimal_speed -  option :test3_21d_maximal_speed -  option :projection_reference - -  def validator -    @validator ||= ::Chouette::FileValidator.new("public") -  end - -  def with_original_filename -    Dir.mktmpdir do |tmp_dir| -      tmp_link = File.join(tmp_dir, resources.original_filename) -      FileUtils.ln_s resources.path, tmp_link -      yield tmp_link -    end -  end - -  before_validation :define_default_attributes, :on => :create -  def define_default_attributes -    self.status ||= "pending" -  end - -  after_validation :extract_file_type, :on => :create -  def extract_file_type -    if ! resources.nil?  -      if !resources.original_filename.nil? -        self.file_type = resources.original_filename.rpartition(".").last -        self.file_name = resources.original_filename -      end -    end -  end - -  after_create :delayed_validate -  def delayed_validate -    save_resources -    delay.validate -  end - -  @@root = "#{Rails.root}/tmp/validations" -  cattr_accessor :root - -  def save_resources -    FileUtils.mkdir_p root -    FileUtils.cp resources.path, saved_resources  -  end - -  after_destroy :destroy_resources -  def destroy_resources -    FileUtils.rm saved_resources if File.exists? saved_resources -  end - -  def saved_resources -    "#{root}/#{id}.#{file_type}" -  end - -  def name -    "#{FileValidation.model_name.humanize} #{id}" -  end - -  def validation_options -    hash = { :validation_id => self.id , -      :file_format => self.file_type} -    options.keys.each do |opt| -      hash.merge! opt.to_sym => self.send(opt.to_sym) -    end -    hash -  end - -  def validate -    begin -      # log_messages.create :key => :started -      if resources -        with_original_filename do |file| -          # chouette-command checks the file extension (and requires .zip) :( -          validator.validate file, validation_options -        end -      else -        validator.validate saved_resources, validation_options -      end -      update_attribute :status, "completed" -    rescue => e -      Rails.logger.error "Validation #{id} failed : #{e}, #{e.backtrace}" -      update_attribute :status, "failed" -    end -    # log_messages.create :key => status -  end - -  after_find :compute_tests -  def compute_tests -    if status == 'completed' -      self.uncheck_count = 0 -      self.ok_count = 0 -      self.warning_count = 0 -      self.error_count = 0 -      self.fatal_count = 0 -      self.log_message_tree = Array.new -      father1=nil -      father2=nil -      father3=nil -      log_messages.each do |message|  -        if message.level == 1 -          self.log_message_tree << message -          father1=message -        elsif message.level == 2 -          father1.add_child message -          father2=message -        elsif message.level == 3 -          father2.add_child message -          father3=message -          if message.severity == 'uncheck' -            self.uncheck_count += 1 -          end -          if message.severity == 'ok' -            self.ok_count += 1 -          end -          if message.severity == 'warning' -            self.warning_count += 1 -          end -          if message.severity == 'error' -            self.error_count += 1 -          end -          if message.severity == 'fatal' -            self.fatal_count += 1 -          end -        elsif message.level == 4 -          father3.add_child message -        end -      end -    end -     -  end -   - -end diff --git a/app/models/file_validation_log_message.rb b/app/models/file_validation_log_message.rb deleted file mode 100644 index 589327110..000000000 --- a/app/models/file_validation_log_message.rb +++ /dev/null @@ -1,68 +0,0 @@ -class FileValidationLogMessage < ActiveRecord::Base -  belongs_to :file_validation -  acts_as_list :scope => :file_validation -   -  attr_accessor :children -   -  validates_presence_of :key -  validates_inclusion_of :severity, :in => %w{info warning error ok uncheck fatal} - -  def arguments=(arguments) -    write_attribute :arguments, (arguments.to_json if arguments.present?) -  end - -  def arguments -    @decoded_arguments ||=  -      begin -        if (stored_arguments = raw_attributes).present? -          ActiveSupport::JSON.decode stored_arguments -        else -          {} -        end -      end -  end - -  def raw_attributes -    read_attribute(:arguments) -  end - -  before_validation :define_default_attributes, :on => :create -  def define_default_attributes -    self.severity ||= "info" -  end -  -  def level -    last_key=key.rpartition("|").last -    if last_key == 'TooMuchDetails'  -      4 -    else -      [last_key.count("_") + 1,4].min -    end -  end -  -  def full_message -    last_key=key.rpartition("|").last -    I18n.translate last_key, arguments.symbolize_keys.merge(:scope => "file_validation_log_messages.messages").merge(:default => :undefined).merge(:key => last_key) -  end -   -  def label -    last_key=key.rpartition("|").last -    label = "" -    last_key.split("_").each do |tag| -      if (tag.start_with?("Test"))  -        label = tag.delete("Test") -      else -        label += "."+tag.delete("Sheet").delete("Step") -      end -    end -    label -  end -   -  def add_child(child) -    if self.children.nil? -      self.children = Array.new -    end -    self.children << child -  end - -end diff --git a/app/models/gtfs_import.rb b/app/models/gtfs_import.rb index a332fe65e..af83d81a0 100644 --- a/app/models/gtfs_import.rb +++ b/app/models/gtfs_import.rb @@ -1,18 +1,10 @@ -class GtfsImport < Import +class GtfsImport < ImportTask -  validates_presence_of :objectid_prefix -  option :objectid_prefix +  validates_presence_of :object_id_prefix +  option :object_id_prefix    option :max_distance_for_commercial    option :ignore_last_word    option :ignore_end_chars    option :max_distance_for_connection_link -   -  def import_options -    super.merge(:format => :gtfs, :objectid_prefix => objectid_prefix, -     :max_distance_for_commercial => max_distance_for_commercial, -     :ignore_last_word => ignore_last_word, -     :ignore_end_chars => ignore_end_chars, -     :max_distance_for_connection_link => max_distance_for_connection_link) -  end  end diff --git a/app/models/import.rb b/app/models/import.rb deleted file mode 100644 index 629d54a42..000000000 --- a/app/models/import.rb +++ /dev/null @@ -1,127 +0,0 @@ -class Import < ActiveRecord::Base -  belongs_to :referential - -  validates_presence_of :referential_id -  validates_presence_of :resources - -  validates_inclusion_of :status, :in => %w{ pending completed failed } - -  attr_accessor :resources -  attr_accessor :loader - -  has_many :log_messages, :class_name => "ImportLogMessage", :order => :position, :dependent => :delete_all - -  serialize :options - -  def self.option(name) -    name = name.to_s - -    define_method(name) do -      self.options and self.options[name] -    end - -    define_method("#{name}=") do |prefix| -      (self.options ||= {})[name] = prefix -    end -  end - -  def self.format_name(format) -    name_by_format = { "NeptuneImport" => "Neptune", -                       "CsvImport" => "CSV", -                       "GtfsImport" => "GTFS", -                       "NetexImport" => "NeTEx"} -    name_by_format[format] -  end - -  def self.types -    # if Rails.env.development? and subclasses.blank? -    #   Dir[File.expand_path("../*_import.rb", __FILE__)].each do |f| -    #     require f -    #   end -    # end - -    unless Rails.env.development? -      subclasses.map(&:to_s) -    else -      # FIXME -      %w{NeptuneImport CsvImport GtfsImport NetexImport} -    end -  end - -  def loader -    @loader ||= ::Chouette::Loader.new(referential.slug) -  end - -  def with_original_filename -    Dir.mktmpdir do |tmp_dir| -      tmp_link = File.join(tmp_dir, resources.original_filename) -      FileUtils.ln_s resources.path, tmp_link -      yield tmp_link -    end -  end - -  before_validation :define_default_attributes, :on => :create -  def define_default_attributes -    self.status ||= "pending" -  end - -  before_validation :extract_file_type, :on => :create -  def extract_file_type -    if ! resources.nil? -      self.file_type = resources.original_filename.rpartition(".").last -    end -  end - -  def delayed_import -    save_resources -    delay.import -  end - -  @@root = "#{Rails.root}/tmp/imports" -  cattr_accessor :root - -  def save_resources -    FileUtils.mkdir_p root -    FileUtils.cp resources.path, saved_resources -  end - -  after_destroy :destroy_resources -  def destroy_resources -    FileUtils.rm saved_resources if File.exists? saved_resources -  end - -  def saved_resources -    "#{root}/#{id}.#{file_type}" -  end - -  def name -    "#{self.class.model_name.human} #{id}" -  end - -  def import_options -    { :import_id => self.id , :file_format => self.file_type } -  end - -  def import -    begin -      log_messages.create :key => :started - -      loader.import saved_resources, import_options - -      update_attribute :status, "completed" -    rescue => e -      Rails.logger.error "Import #{id} failed : #{e}, #{e.backtrace}" -      update_attribute :status, "failed" -    end -    log_messages.create :key => status -  end - -  def self.new(attributes = {}, options = {}, &block) -    if self == Import -      Object.const_get(attributes.delete(:type) || "NeptuneImport").new(attributes, options) -    else -      super -    end -  end - -end diff --git a/app/models/import_log_message.rb b/app/models/import_log_message.rb deleted file mode 100644 index 4b56f03bd..000000000 --- a/app/models/import_log_message.rb +++ /dev/null @@ -1,42 +0,0 @@ -class ImportLogMessage < ActiveRecord::Base -  belongs_to :import -  acts_as_list :scope => :import -   -  validates_presence_of :key -  validates_inclusion_of :severity, :in => %w{info warning error ok uncheck fatal} - -  def arguments=(arguments) -    write_attribute :arguments, (arguments.to_json if arguments.present?) -  end - -  def arguments -    @decoded_arguments ||=  -      begin -        if (stored_arguments = raw_attributes).present? -          ActiveSupport::JSON.decode stored_arguments -        else -          {} -        end -      end -  end - -  def raw_attributes -    read_attribute(:arguments) -  end - -  before_validation :define_default_attributes, :on => :create -  def define_default_attributes -    self.severity ||= "info" -  end -  -  def full_message -    last_key=key.rpartition("|").last -    begin -      I18n.translate last_key, arguments.symbolize_keys.merge(:scope => "import_log_messages.messages").merge(:default => :undefined).merge(:key => last_key) -    rescue => e -      Rails.logger.error "missing arguments for message "+last_key -      I18n.translate "WRONG_DATA",{"0"=>last_key}.symbolize_keys.merge(:scope => "import_log_messages.messages").merge(:default => :undefined).merge(:key => "WRONG_DATA") -    end -  end - -end diff --git a/app/models/import_task.rb b/app/models/import_task.rb new file mode 100644 index 000000000..6aca85821 --- /dev/null +++ b/app/models/import_task.rb @@ -0,0 +1,160 @@ +class ImportTask < ActiveRecord::Base +  attr_accessor :resources, :rule_parameter_set_id + +  belongs_to :referential + +  has_one :user +  has_one :compliance_check_task, :dependent => :delete + +  serialize :parameter_set, JSON +  serialize :result, JSON + +  validates_presence_of :referential_id +  validates_presence_of :resources +  validates_presence_of :user_id +  validates_presence_of :user_name +  validates_inclusion_of :status, :in => %w{ pending processing completed failed } + +  protected + +  def self.option(name, type=nil) +    name = name.to_s + +    define_method(name) do +      self.parameter_set and self.parameter_set[name] +    end + +    if type.to_s == "boolean" +      define_method("#{name}=") do |prefix| +        (self.parameter_set ||= {})[name] = (prefix=="1" || prefix==true) +      end +    else +      define_method("#{name}=") do |prefix| +        (self.parameter_set ||= {})[name] = prefix +      end +    end +  end + +  public + +  def self.formats +    %w{Neptune Csv Gtfs Netex} +  end + +  def delayed_import +    delay.import +  end + +  protected + +  option :no_save, :boolean +  option :format +  option :file_path + +  validates_inclusion_of :no_save, :in => [ true, false] +  validates_inclusion_of :format, :in => self.formats + +  def chouette_command +    Chouette::Command.new(:schema => referential.slug) +  end + +  before_validation :define_default_attributes, :on => :create +  def define_default_attributes +    self.status ||= "pending" +  end + +  @@root = "#{Rails.root}/tmp/imports" +  cattr_accessor :root + +  def compliance_check_task_attributes +    {:referential_id => referential.id, +     :user_id => user_id, +     :user_name => user_name, +     :rule_parameter_set_id => rule_parameter_set_id} +  end + +  after_create :update_info, :save_resources +  def update_info +    self.file_path = saved_resources +    self.update_attribute :parameter_set, self.parameter_set + +    self.create_compliance_check_task( self.compliance_check_task_attributes) +  end + +  def save_resources +    # resources is a required attribute +    FileUtils.mkdir_p root +    FileUtils.cp resources.path, saved_resources +  end + +  after_destroy :destroy_resources +  def destroy_resources +    FileUtils.rm file_path if File.exists? file_path +  end + +  def saved_resources +    raise Exception.new("Illegal call") if self.new_record? +    "#{root}/#{id}#{File.extname(resources.original_filename)}" +  end + +  def chouette_command_args +    {:c => "import", :id => id} +  end + +  public + +  def failed? +    status == "failed" +  end + +  def completed? +    status == "completed" +  end + +  def file_path_extension +    extension = File.extname( self.file_path ) +    if extension == ".xml" +      "xml" +    elsif extension == ".zip" +      "zip" +    else +      "basic" +    end +  end + +  def name +    "#{ImportTask.model_name.human} #{self.format} #{self.id}" +  end + +  def full_name +    return name unless no_save +    "#{name} - #{I18n.t('activerecord.attributes.import_task.no_save')}" +  end + +  # Create ImportTask and ComplianceCheckTask associated and give import id to Chouette Loader +  def import +    return nil if self.new_record? + +    begin +      chouette_command.run! chouette_command_args +      reload +      update_attribute :status, "completed" +      compliance_check_task.update_attribute :status, "completed" +    rescue => e +      Rails.logger.error "Import #{id} failed : #{e}, #{e.backtrace}" +      reload +      update_attribute :status, "failed" +      compliance_check_task.update_attribute :status, "failed" +    end +  end + +  def self.new(attributes = {}, parameter_set = {}, &block) +    if self == ImportTask +      attributes[:format] = "Neptune" unless attributes[:format] +      Object.const_get( attributes[:format] + "Import").new(attributes, parameter_set) +    else +      super +    end +  end + +end diff --git a/app/models/import_type.rb b/app/models/import_type.rb new file mode 100644 index 000000000..ecf226562 --- /dev/null +++ b/app/models/import_type.rb @@ -0,0 +1,6 @@ +class ImportType < ActiveEnum::Base +  value :id => 'Neptune', :name => 'Neptune' +  value :id => 'Csv', :name => 'Csv' +  value :id => 'Gtfs', :name => 'GTFS' +  value :id => 'Netex', :name => 'NeTEx' +end diff --git a/app/models/neptune_import.rb b/app/models/neptune_import.rb index 11282b306..24e3355d7 100644 --- a/app/models/neptune_import.rb +++ b/app/models/neptune_import.rb @@ -1,7 +1,6 @@ -class NeptuneImport < Import - -  def import_options -    super.merge(:format => :neptune) -  end +class NeptuneImport < ImportTask +  # def import_options +  #   super.merge() +  # end  end diff --git a/app/models/netex_import.rb b/app/models/netex_import.rb index 74e76e47c..cc09fd496 100644 --- a/app/models/netex_import.rb +++ b/app/models/netex_import.rb @@ -1,7 +1,7 @@ -class NetexImport < Import +class NetexImport < ImportTask -  def import_options -    super.merge(:format => :netex) -  end +  # def import_options +  #   super.merge(:format => :netex) +  # end  end diff --git a/app/models/referential.rb b/app/models/referential.rb index c759334b8..bc151b001 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -1,6 +1,6 @@  # -*- coding: utf-8 -*-  class Referential < ActiveRecord::Base -  validates_presence_of :name  +  validates_presence_of :name    validates_presence_of :slug    validates_presence_of :prefix    validates_presence_of :time_zone @@ -13,21 +13,24 @@ class Referential < ActiveRecord::Base    validates_format_of :upper_corner, :with => %r{\A-?[0-9]+\.?[0-9]*\,-?[0-9]+\.?[0-9]*\Z}    validates_format_of :lower_corner, :with => %r{\A-?[0-9]+\.?[0-9]*\,-?[0-9]+\.?[0-9]*\Z}    validate :slug_excluded_values -   +    attr_accessor :resources    attr_accessor :upper_corner    attr_accessor :lower_corner -  has_many :imports, :dependent => :destroy +  has_one :user +  has_many :rule_parameter_sets, :dependent => :destroy +  has_many :import_tasks, :dependent => :destroy +  has_many :compliance_check_tasks, :dependent => :destroy    has_many :exports, :dependent => :destroy    has_many :api_keys, :class_name => 'Api::V1::ApiKey', :dependent => :destroy -   +    belongs_to :organisation    validates_presence_of :organisation    def slug_excluded_values      if ! slug.nil? -      if slug.start_with? "pg_"  +      if slug.start_with? "pg_"          errors.add(:slug,I18n.t("referentials.errors.pg_excluded"))        end        if slug == 'public' @@ -74,7 +77,7 @@ class Referential < ActiveRecord::Base    def time_tables      Chouette::TimeTable.scoped    end -   +    def connection_links      Chouette::ConnectionLink.scoped    end @@ -122,7 +125,7 @@ class Referential < ActiveRecord::Base      ]    end -  def projection_type_label  +  def projection_type_label      self.class.available_srids.each do |a|        if a.last.to_s == projection_type          return a.first.split('(').first.rstrip @@ -141,9 +144,15 @@ class Referential < ActiveRecord::Base      Apartment::Database.drop slug    end -  after_create :import_resources   +  after_create :import_resources, :add_rule_parameter_set    def import_resources -    imports.create(:resources => resources) if resources +    import_tasks.create(:resources => resources, :no_save => false, +                        :format => "Neptune", :user_id => user_id, +                        :user_name => user_name) if resources +  end + +  def add_rule_parameter_set +    RuleParameterSet.default_for_all_modes( self).save    end    def upper_corner @@ -161,7 +170,7 @@ class Referential < ActiveRecord::Base      end    end -  def lower_corner     +  def lower_corner      envelope.lower_corner    end @@ -188,7 +197,7 @@ class Referential < ActiveRecord::Base  end  Rails.application.config.after_initialize do -   +    Chouette::TridentActiveRecord    class Chouette::TridentActiveRecord @@ -204,19 +213,19 @@ Rails.application.config.after_initialize do      end    end -   +    Chouette::StopArea -   +    class Chouette::StopArea -     +      attr_accessible :projection_x,:projection_y -     +      # override default_position method to add referential envelope when no stoparea is positioned -    def default_position  -      # for first StopArea ... the bounds is nil , set to referential center  +    def default_position +      # for first StopArea ... the bounds is nil , set to referential center        Chouette::StopArea.bounds ? Chouette::StopArea.bounds.center : self.referential.envelope.center      end -     +      # add projection_type set on pre-insert and pre_update action      before_validation :set_projections      def set_projections @@ -237,9 +246,9 @@ Rails.application.config.after_initialize do  #          self.y = nil  #      end      end -     +      def projection -      if self.referential.projection_type.nil? || self.referential.projection_type.empty?  +      if self.referential.projection_type.nil? || self.referential.projection_type.empty?          nil        else          self.referential.projection_type @@ -252,7 +261,7 @@ Rails.application.config.after_initialize do          nil        else          @point ||= GeoRuby::SimpleFeatures::Point::from_lat_lng(Geokit::LatLng.new(self.latitude,self.longitude)).project_to(self.projection.to_i) -         +          @point.x        end      end @@ -270,11 +279,11 @@ Rails.application.config.after_initialize do      def projection_y=(dummy)        # dummy method      end -  +    end    Chouette::AccessPoint -   +    class Chouette::AccessPoint      attr_accessible :projection_x,:projection_y @@ -298,9 +307,9 @@ Rails.application.config.after_initialize do  #          self.y = nil  #      end      end -     +      def projection -      if self.referential.projection_type.nil? || self.referential.projection_type.empty?  +      if self.referential.projection_type.nil? || self.referential.projection_type.empty?          nil        else          self.referential.projection_type @@ -313,7 +322,7 @@ Rails.application.config.after_initialize do          nil        else          @point ||= GeoRuby::SimpleFeatures::Point::from_lat_lng(Geokit::LatLng.new(self.latitude,self.longitude)).project_to(self.projection.to_i) -         +          @point.x        end      end @@ -332,5 +341,5 @@ Rails.application.config.after_initialize do        # dummy method      end    end -  +  end diff --git a/app/models/rule_parameter_set.rb b/app/models/rule_parameter_set.rb new file mode 100644 index 000000000..5177d6ecc --- /dev/null +++ b/app/models/rule_parameter_set.rb @@ -0,0 +1,225 @@ +class RuleParameterSet < ActiveRecord::Base +  belongs_to :referential + +  validates_presence_of :referential +  validates_presence_of :name + +  serialize :parameters, JSON + +  attr_accessible :name, :referential_id + +  def self.mode_attribute_prefixes +    %w( inter_stop_area_distance_min inter_stop_area_distance_max speed_max speed_min inter_stop_duration_variation_max) +  end +  def self.general_attributes +    %w( inter_stop_area_distance_min parent_stop_area_distance_max stop_areas_area inter_access_point_distance_min +      inter_connection_link_distance_max walk_default_speed_max +      walk_occasional_traveller_speed_max walk_frequent_traveller_speed_max walk_mobility_restricted_traveller_speed_max +      inter_access_link_distance_max inter_stop_duration_max facility_stop_area_distance_max) +  end +  def self.all_modes +    Chouette::TransportMode.all.map { |m| m.to_s} +  end + +  def self.mode_attribute?( method_name ) +    pattern = /(\w+)_mode_(\w+)/ +    return false unless method_name.match( pattern) + +    mode_attribute_prefixes.include?( $1) && self.class.all_modes.include?( $2) +  end +  def self.mode_of_mode_attribute( method_name ) +    method_name.match( /(\w+)_mode_(\w+)/) +    $2 +  end +  def self.attribute_of_mode_attribute( method_name ) +    method_name.match( /(\w+)_mode_(\w+)/) +    $1 +  end + +  def self.mode_parameter(name) +    name = name.to_s +    attr_accessible name + +    define_method(name) do +      attribute_name, mode = RuleParameterSet.attribute_of_mode_attribute( name), RuleParameterSet.mode_of_mode_attribute( name) +      self.parameters and self.parameters["mode_#{mode}"] and +        self.parameters["mode_#{mode}"][attribute_name] +    end + +    define_method("#{name}=") do |prefix| +      attribute_name, mode = RuleParameterSet.attribute_of_mode_attribute( name), RuleParameterSet.mode_of_mode_attribute( name) +      ((self.parameters ||= {})["mode_#{mode}"] ||= {})[attribute_name] = prefix +    end +  end +  def self.parameter(name) +    name = name.to_s +    attr_accessible name + +    define_method(name) do +        self.parameters and self.parameters[name] +    end + +    define_method("#{name}=") do |prefix| +        (self.parameters ||= {})[name] = prefix +    end +  end + +  def self.default_params(mode=nil) +    base = { :inter_stop_area_distance_min => 20, +      :parent_stop_area_distance_max => 300, +      :inter_access_point_distance_min => 20, +      :inter_connection_link_distance_max => 400, +      :walk_default_speed_max => 4, +      :walk_occasional_traveller_speed_max => 2, +      :walk_frequent_traveller_speed_max => 5, +      :walk_mobility_restricted_traveller_speed_max => 1, +      :inter_access_link_distance_max => 300, +      :inter_stop_duration_max => 40, +      :facility_stop_area_distance_max => 300 +    } +    if mode && self.mode_default_params[ mode.to_sym] +      base.merge!( self.mode_default_params[ mode.to_sym]) +    end +    base +  end +  def self.mode_default_params +    { +    :coach => { +      :inter_stop_area_distance_min_mode_coach => 500, +      :inter_stop_area_distance_max_mode_coach => 10000, +      :speed_max_mode_coach => 90, +      :speed_min_mode_coach => 40, +      :inter_stop_duration_variation_max_mode_coach => 20}, +    :air => { +      :inter_stop_area_distance_min_mode_air => 200, +      :inter_stop_area_distance_max_mode_air => 10000, +      :speed_max_mode_air => 800, +      :speed_min_mode_air => 700, +      :inter_stop_duration_variation_max_mode_air => 60}, +    :waterborne => { +      :inter_stop_area_distance_min_mode_waterborne => 200, +      :inter_stop_area_distance_max_mode_waterborne => 10000, +      :speed_max_mode_waterborne => 40, +      :speed_min_mode_waterborne => 5, +      :inter_stop_duration_variation_max_mode_waterborne => 60}, +    :bus => { +      :inter_stop_area_distance_min_mode_bus => 100, +      :inter_stop_area_distance_max_mode_bus => 10000, +      :speed_max_mode_bus => 60, +      :speed_min_mode_bus => 10, +      :inter_stop_duration_variation_max_mode_bus => 15}, +    :ferry => { +      :inter_stop_area_distance_min_mode_ferry => 200, +      :inter_stop_area_distance_max_mode_ferry => 10000, +      :speed_max_mode_ferry => 40, +      :speed_min_mode_ferry => 5, +      :inter_stop_duration_variation_max_mode_ferry => 60}, +    :walk => { +      :inter_stop_area_distance_min_mode_walk => 1, +      :inter_stop_area_distance_max_mode_walk => 10000, +      :speed_max_mode_walk => 6, +      :speed_min_mode_walk => 1, +      :inter_stop_duration_variation_max_mode_walk => 10}, +    :metro => { +      :inter_stop_area_distance_min_mode_metro => 300, +      :inter_stop_area_distance_max_mode_metro => 2000, +      :speed_max_mode_metro => 60, +      :speed_min_mode_metro => 30, +      :inter_stop_duration_variation_max_mode_metro => 30}, +    :shuttle => { +      :inter_stop_area_distance_min_mode_shuttle => 500, +      :inter_stop_area_distance_max_mode_shuttle => 10000, +      :speed_max_mode_shuttle => 80, +      :speed_min_mode_shuttle => 20, +      :inter_stop_duration_variation_max_mode_shuttle => 10}, +    :rapid_transit => { +      :inter_stop_area_distance_min_mode_rapid_transit => 2000, +      :inter_stop_area_distance_max_mode_rapid_transit => 500000, +      :speed_max_mode_rapid_transit => 300, +      :speed_min_mode_rapid_transit => 20, +      :inter_stop_duration_variation_max_mode_rapid_transit => 60}, +    :taxi => { +      :inter_stop_area_distance_min_mode_taxi => 500, +      :inter_stop_area_distance_max_mode_taxi => 300000, +      :speed_max_mode_taxi => 130, +      :speed_min_mode_taxi => 20, +      :inter_stop_duration_variation_max_mode_taxi => 60}, +    :local_train => { +      :inter_stop_area_distance_min_mode_local_train => 2000, +      :inter_stop_area_distance_max_mode_local_train => 500000, +      :speed_max_mode_local_train => 300, +      :speed_min_mode_local_train => 20, +      :inter_stop_duration_variation_max_mode_local_train => 60}, +    :train => { +      :inter_stop_area_distance_min_mode_train => 2000, +      :inter_stop_area_distance_max_mode_train => 500000, +      :speed_max_mode_train => 300, +      :speed_min_mode_train => 20, +      :inter_stop_duration_variation_max_mode_train => 60}, +    :long_distance_train => { +      :inter_stop_area_distance_min_mode_long_distance_train => 2000, +      :inter_stop_area_distance_max_mode_long_distance_train => 500000, +      :speed_max_mode_long_distance_train => 300, +      :speed_min_mode_long_distance_train => 20, +      :inter_stop_duration_variation_max_mode_long_distance_train => 60}, +    :tramway => { +      :inter_stop_area_distance_min_mode_tramway => 300, +      :inter_stop_area_distance_max_mode_tramway => 2000, +      :speed_max_mode_tramway => 50, +      :speed_min_mode_tramway => 20, +      :inter_stop_duration_variation_max_mode_tramway => 30}, +    :trolleybus => { +      :inter_stop_area_distance_min_mode_trolleybus => 300, +      :inter_stop_area_distance_max_mode_trolleybus => 2000, +      :speed_max_mode_trolleybus => 50, +      :speed_min_mode_trolleybus => 20, +      :inter_stop_duration_variation_max_mode_trolleybus => 30}, +    :private_vehicle => { +      :inter_stop_area_distance_min_mode_private_vehicle => 500, +      :inter_stop_area_distance_max_mode_private_vehicle => 300000, +      :speed_max_mode_private_vehicle => 130, +      :speed_min_mode_private_vehicle => 20, +      :inter_stop_duration_variation_max_mode_private_vehicle => 60}, +    :bicycle => { +      :inter_stop_area_distance_min_mode_bicycle => 300, +      :inter_stop_area_distance_max_mode_bicycle => 30000, +      :speed_max_mode_bicycle => 40, +      :speed_min_mode_bicycle => 10, +      :inter_stop_duration_variation_max_mode_bicycle => 10}, +    :other => { +      :inter_stop_area_distance_min_mode_other => 300, +      :inter_stop_area_distance_max_mode_other => 30000, +      :speed_max_mode_other => 40, +      :speed_min_mode_other => 10, +      :inter_stop_duration_variation_max_mode_other => 10}, +    } +    # :waterborne, :bus, :ferry, :walk, :metro, :shuttle, :rapidtransit, :taxi, :localtrain, :train, :longdistancetrain, :tramway, :trolleybus, :privatevehicle, :bicycle, :other +  end +  def self.default( referential) +    self.default_for_all_modes( referential).tap do |rps| +      rps.name = "" +    end +  end +  def self.default_for_all_modes( referential) +    mode_attributes = mode_default_params.values.inject(self.default_params){|memo, obj| memo.merge! obj} +    self.new( +      { :referential_id => referential.id, +        :stop_areas_area => referential.envelope.to_polygon.points.map(&:to_coordinates).to_json, +        :name => "valeurs par defaut" +      }.merge( mode_attributes)) +  end + +  all_modes.each do |mode| +    mode_attribute_prefixes.each do |prefix| +      mode_parameter "#{prefix}_mode_#{mode}".to_sym +    end +  end + +  general_attributes.each do |attribute| +    parameter attribute.to_sym +    unless attribute == "stop_areas_area" +      validates attribute.to_sym, :numericality => true, :allow_nil => true, :allow_blank => true +    end +  end + +end diff --git a/app/models/type_ids_modelable.rb b/app/models/type_ids_modelable.rb new file mode 100644 index 000000000..4d3de7a8f --- /dev/null +++ b/app/models/type_ids_modelable.rb @@ -0,0 +1,61 @@ +# The model table must have two columns : +#   - references_type +#   - reference_ids +# The model class should also define +# cattr :references_types with expected classes for references_type +module TypeIdsModelable +  def self.included(base) +    base.extend(Methods) +  end + +  def references +    if references_relation.present? and reference_ids.present? +      referential.send(references_relation).find(reference_ids) +    else +      [] +    end +  end + +  def references=(references) +    unless references.blank? +      self.references_type = references.first.class.name +      self.reference_ids = references.map(&:id) +    else +      self.references_type = nil +      self.reference_ids = [] +    end +  end + +  def references_relation +    if references_type.present? +      relation = self.class.references_relation(references_type) +      relation if referential.respond_to?(relation) +    end +  end + +  def reference_ids +    if raw_reference_ids +      raw_reference_ids.split(',').map(&:to_i) +    else +      [] +    end +  end + +  def reference_ids=(records) +    records = Array(records) +    write_attribute :reference_ids, (records.present? ? records.join(',') : nil) +  end + +  def raw_reference_ids +    read_attribute :reference_ids +  end + +  module Methods +    def type_ids_modelable_class? +      return true +    end +    def references_relation(type) +      type.to_s.demodulize.underscore.pluralize +    end +  end +end diff --git a/app/views/compliance_check_results/_compliance_check_result.erb b/app/views/compliance_check_results/_compliance_check_result.erb new file mode 100644 index 000000000..afd94f62e --- /dev/null +++ b/app/views/compliance_check_results/_compliance_check_result.erb @@ -0,0 +1,21 @@ + <div class="severity_<%= compliance_check_result.severity %> status_<%= compliance_check_result.status %>">  +   <div class="status_icon"> +     <%= image_tag "icons/status_#{compliance_check_result.status}.png", :class => "status" %>       +   </div>  +   <div class="status_text"> +   <div class="code"> +     <%= compliance_check_result.rule_code %> +   </div> +   <div class="severity"> +     [ <%= ComplianceCheckResult.human_attribute_name(:severity) %> : <%= t compliance_check_result.severity, :scope => "compliance_check_result.severities" %> ] +   </div> +   <div class="explanation"> +     <%= ComplianceCheckResult.human_attribute_name(compliance_check_result.rule_code) %> +   </div> +   <div class="attributes"> +     <% if compliance_check_result.violation_count > 0 %> +       <%= ComplianceCheckResult.human_attribute_name(:violation_count) %> :  +     <% end %> +   </div> +   </div> +</div> diff --git a/app/views/compliance_check_results/index.html.erb b/app/views/compliance_check_results/index.html.erb new file mode 100644 index 000000000..886664857 --- /dev/null +++ b/app/views/compliance_check_results/index.html.erb @@ -0,0 +1,56 @@ +<table class="table table-hover"> +  <thead> +    <tr> +      <th>#</th> +      <th><%= ComplianceCheckResult.human_attribute_name(:status) %></th> +      <th><%= ComplianceCheckResult.human_attribute_name(:severity) %></th> +      <th><%= ComplianceCheckResult.human_attribute_name(:rule_level) %></th> +      <th><%= ComplianceCheckResult.human_attribute_name(:rule_code) %></th> +      <% if @compliance_check_results && @compliance_check_results.first.status == "nok" %> +        <th><%= ComplianceCheckResult.human_attribute_name(:detail) %></th> +      <% end %> +    </tr> +  </thead> +  <tbody> +    <% @compliance_check_results.each_with_index do |compliance_check_result, index| %> +    <tr> +      <td><%= index + 1 %></td> +      <td><%= image_tag "icons/status_#{compliance_check_result.status}.png" %></td> +      <td><%= t compliance_check_result.severity, :scope => "compliance_check_result.severities" %></td> +      <td><%= compliance_check_result.rule_level %></td> +      <td> +        <%= image_tag "icons/notice.png", :"data-content" => ComplianceCheckResult.human_attribute_name(compliance_check_result.rule_code), :"data-title" => t("activerecord.attributes.compliance_check_result.detail"), :class =>"notice" %> +        <%= link_to compliance_check_result.rule_code, "#", :title => ComplianceCheckResult.human_attribute_name(compliance_check_result.rule_code) %></td> +      <% if @compliance_check_results && @compliance_check_results.first.status == "nok" %> +      <td class="td_error"> +        <% if compliance_check_result.detail.present? %> +        <span class="title_error"> +          <i class="fa fa-plus-square"></i><%= compliance_check_result.violation_count.to_s + " " + ComplianceCheckResult.human_attribute_name(:violation_count) %> +        </span> +        <div class="details_error"> +          <% compliance_check_result.detail["detail"].first(10).each do |error| %> +            <p class="detail_error"> +              <% if error["messageArgs"] %> +                |- <%= image_tag "icons/notice.png", :"data-content" => ComplianceCheckResult.human_attribute_name(compliance_check_result.rule_code) + "<br>" + t("compliance_check_result.details." + error["messageKey"], error["messageArgs"].symbolize_keys ), :"data-title" => t("activerecord.attributes.compliance_check_result.detail"), :class =>"notice" %> +              <% else %> +                |- <%= image_tag "icons/notice.png", :"data-content" => ComplianceCheckResult.human_attribute_name(compliance_check_result.rule_code) + "<br>" + t("compliance_check_result.details." + error["messageKey"]), :"data-title" => t("activerecord.attributes.compliance_check_result.detail"), :class =>"notice" %> +              <% end %> +              <% if error["location"]["url"].present? %> +                <%= link_to error["objectId"], referential_path(@referential) + "/" + error["location"]["url"] %> +              <% elsif error["location"]["filename"].present? %> +                <%= error["objectId"] %><br> +                <span class="file_error"> <%= File.basename(error["location"]["filename"]) %> +                <%= t("compliance_check_results.index.column") %>: <%= error["location"]["columnNumber"] %>, <%= t("compliance_check_results.index.line") %>: <%= error["location"]["lineNumber"] %></span> +              <% end %> +            </p>    +          <% end %>              +        </div> +        <% end %> +      </td> +      <% end %> +    </tr> +  <% end %> +  </tbody> +</table> +<%= javascript_include_tag referential_compliance_check_task_compliance_check_results_path(@compliance_check_task.referential, @compliance_check_task, :format => :js) %> + diff --git a/app/views/compliance_check_results/index.js.coffee b/app/views/compliance_check_results/index.js.coffee new file mode 100644 index 000000000..c73676d88 --- /dev/null +++ b/app/views/compliance_check_results/index.js.coffee @@ -0,0 +1,8 @@ +jQuery -> +  $("body").popover({ selector: '.notice', container: "body", trigger: "click", html: true, placement: "bottom" }) + +  # Hide and show error details +  $(".title_error").each ->      +    $( this ).click ->  +      $(this).next(".details_error").toggle()       +      $(this).children("i").toggleClass("fa-plus-square fa-minus-square")
\ No newline at end of file diff --git a/app/views/compliance_check_tasks/_compliance_check_task.erb b/app/views/compliance_check_tasks/_compliance_check_task.erb new file mode 100644 index 000000000..3c5388b00 --- /dev/null +++ b/app/views/compliance_check_tasks/_compliance_check_task.erb @@ -0,0 +1,22 @@ +<%= div_for(compliance_check_task, :class => :compliance_check_task) do %> +  <div class="icon"> +    <%= link_to image_tag("compliance_check_task-#{compliance_check_task.status}.png"), referential_compliance_check_task_path(@referential, compliance_check_task) %> +  </div> +  <div class="resume"> +    <ul class="header clearfix"> +      <li class="title"><%= link_to(compliance_check_task.name, referential_compliance_check_task_path(@referential, compliance_check_task)) %></li> +      <li class="remove"><%= link_to "<i class='fa fa-trash-o'></i>".html_safe, referential_compliance_check_task_path(@referential, compliance_check_task), :method => :delete, :class => "delete", :data => {:confirm =>  t('compliance_check_tasks.actions.destroy_confirm')} %></li> +    </ul> +    <div class="links"> +      <% if compliance_check_task.import_task.present? %> +      <p><%= link_to( image_tag('icons/link_page.png') + t("compliance_check_tasks.import_task"), referential_import_task_path(@referential, compliance_check_task.import_task)) %></p> +      <% end %> +      <% if compliance_check_task.parameter_set %> +      <p><%= link_to( image_tag('icons/link_page.png') + t("compliance_check_tasks.actions.rule_parameter_set"), rule_parameter_set_referential_compliance_check_task_path(@referential, compliance_check_task)) %></p> +      <% end %> +    </div> +    <div class="history"> +      <%= l  compliance_check_task.created_at, :format => "%d/%m/%Y %H:%M" %> | <%=  compliance_check_task.user_name %> +    </div> +  </div> +<% end %> diff --git a/app/views/file_validations/_test_sheet_toc.html.erb b/app/views/compliance_check_tasks/_test_sheet_toc.html.erb index 0605510b4..0605510b4 100644 --- a/app/views/file_validations/_test_sheet_toc.html.erb +++ b/app/views/compliance_check_tasks/_test_sheet_toc.html.erb diff --git a/app/views/compliance_check_tasks/index.html.erb b/app/views/compliance_check_tasks/index.html.erb new file mode 100644 index 000000000..e28d98f1a --- /dev/null +++ b/app/views/compliance_check_tasks/index.html.erb @@ -0,0 +1,18 @@ +<%= title_tag t('.title') %> +<div class="warning"><%= t('.warning') %> </div> +<div class="page_info"> +  <span class="search"> <%= t("will_paginate.page_entries_info.search") %></span> <%= page_entries_info @compliance_check_tasks %> +</div> +<div class="compliance_check_tasks paginated_content"> +  <%= render :partial => "compliance_check_task", :collection => @compliance_check_tasks %> +</div> +<div class="pagination"> +  <%= will_paginate @compliance_check_tasks, :container => false %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('compliance_check_tasks.actions.new'), new_referential_compliance_check_task_path(), :class => "add" %></li> +  <li><%= link_to t('rule_parameter_sets.actions.index'), referential_rule_parameter_sets_path(@referential), :class => "link" %></li> +</ul> +<% end %> diff --git a/app/views/compliance_check_tasks/new.html.erb b/app/views/compliance_check_tasks/new.html.erb new file mode 100644 index 000000000..1d15377e4 --- /dev/null +++ b/app/views/compliance_check_tasks/new.html.erb @@ -0,0 +1,22 @@ +<%= title_tag t(".title") %> + +<%= semantic_form_for [@referential, @compliance_check_task] do |form| %> +  <%= form.inputs do %> +    <%= form.input :rule_parameter_set_id, :as => :select, +          :collection => @referential.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => false %> + +    <%= form.input :references_type, :as => :select, :collection => ComplianceCheckTask.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %> + +    <% ComplianceCheckTask.references_types.each do |type| %> +      <%= type_ids_model_references_input(form, @compliance_check_task, ComplianceCheckTask, type).input %> +    <% end %> +  <% end %> + +   <%= form.actions do %> +     <%= form.action :submit, :as => :button , :label => t( 'formtastic.validate' ) %> +     <%= form.action :cancel, :as => :link %> +   <% end %> +<% end %> + +<%= javascript_include_tag new_referential_compliance_check_task_path(@referential, :format => :js) %> + diff --git a/app/views/compliance_check_tasks/new.js.coffee b/app/views/compliance_check_tasks/new.js.coffee new file mode 100644 index 000000000..f8f60ac79 --- /dev/null +++ b/app/views/compliance_check_tasks/new.js.coffee @@ -0,0 +1,4 @@ +jQuery -> +    <% ComplianceCheckTask.references_types.map { |type| type_ids_model_references_type( ComplianceCheckTask, type)}.each do |rt| %> +       $("textarea.<%= rt.input_class %>").tokenInput('<%= references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1 }); +    <% end %> diff --git a/app/views/compliance_check_tasks/show.html.erb b/app/views/compliance_check_tasks/show.html.erb new file mode 100644 index 000000000..239cea7dc --- /dev/null +++ b/app/views/compliance_check_tasks/show.html.erb @@ -0,0 +1,38 @@ +<%= title_tag "#{@compliance_check_task.name} <span class='status status_#{@compliance_check_task.status}'>#{ t('compliance_check_tasks.show.'+@compliance_check_task.status) }</span>" %> + +<div class="compliance_check_task_show"> +   <div class="links"> +     <% if @compliance_check_task.import_task %> +       <%= link_to t("compliance_check_tasks.import_task"), referential_import_task_path(@compliance_check_task.referential, @compliance_check_task.import_task), :class => "btn btn-default"  %> +     <% end %> +     <% if @compliance_check_task.rule_parameter_set_archived %> +       <%= link_to t("compliance_check_tasks.rule_parameter_set"), rule_parameter_set_referential_compliance_check_task_path(@compliance_check_task.referential, @compliance_check_task), :class => "btn btn-default" %> +     <% end %> +   </div> +  <% if @compliance_check_task.status == 'completed'%> +   <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="order" style="display: none;"> +     Filtre : <%= select_tag "order", ("<option value='severity'>" + ComplianceCheckResult.human_attribute_name(:severity) +"</option><option value='status'>" + ComplianceCheckResult.human_attribute_name(:status) + "</option>").html_safe, :include_blank => false %> +   </div> + +   <div class="report"></div> +   <% end %> +  <%= javascript_include_tag referential_compliance_check_task_path(@compliance_check_task.referential, @compliance_check_task,:format => :js) %> +</div> +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to  t('compliance_check_tasks.actions.destroy'), referential_compliance_check_task_path(@referential, @compliance_check_task), :method => :delete,  :data => {:confirm =>  t('compliance_check_tasks.actions.destroy_confirm')}, :class => "remove" %></li> +</ul> + +<%= history_tag(@compliance_check_task) %> + +<% end %> diff --git a/app/views/compliance_check_tasks/show.js.coffee b/app/views/compliance_check_tasks/show.js.coffee new file mode 100644 index 000000000..ffcc6dc5b --- /dev/null +++ b/app/views/compliance_check_tasks/show.js.coffee @@ -0,0 +1,62 @@ +jQuery -> + +  get_compliance_check_results = (html_container, status, severity) -> +    h = new Object() +    h["status"] = status if status +    h["severity"] = severity if severity +    $.get( +        "<%= @compliance_check_task.id %>/compliance_check_results", +        h, +        update = (data) ->     +             html_container.append(data) +    ) + +  order_change = (event) ->  +    console.log "order change" + +  $('.compliance_check_tasks.show .order').change(order_change) + +  Morris.Donut({ +    element: 'error', +    data: [ +      {label: "<%= t 'nok', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.nok.error.count %>}, +      {label: "<%= t 'na', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.na.error.count %>}, +      {label: "<%= t 'ok', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.ok.error.count %>} +    ] +    colors: [ "#e22b1b", "#ffbd2b", "#8fc861" ] +  }).on('click', update = (i, row) -> +    $(".report").empty() +    switch i +      when 0 then get_compliance_check_results( $(".report"), "nok", "error") +      when 1 then get_compliance_check_results( $(".report"), "na", "error") +      when 2 then get_compliance_check_results( $(".report"), "ok", "error") +      else console.log "Error no other value for donut chart") + +  Morris.Donut({ +    element: 'warning', +    data: [ +      {label: "<%= t 'nok', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.nok.warning.count %>}, +      {label: "<%= t 'na', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.na.warning.count %>}, +      {label: "<%= t 'ok', :scope => 'compliance_check_result.statuses' %>", value: <%= @compliance_check_task.compliance_check_results.ok.warning.count %>} +    ] +    colors: [ "#e22b1b", "#ffbd2b", "#8fc861" ] +  }).on('click', update = (i, row) -> +    $(".report").empty() +    switch i +      when 0 then get_compliance_check_results( $(".report"), "nok", "warning") +      when 1 then get_compliance_check_results( $(".report"), "na", "warning") +      when 2 then get_compliance_check_results( $(".report"), "ok", "warning") +      else console.log "Error no other value for donut chart") + +  $(".resume .col1 .caption").click -> +    $(".report").empty() +    get_compliance_check_results( $(".report"), null, "error") + +  $(".resume .col2 .caption").click -> +    $(".report").empty() +    get_compliance_check_results( $(".report"), null, "warning") + +  $('img[title]').tipsy({gravity: 'w'}) +  $('a[title]').tipsy({gravity: 'w'}) + +                                       diff --git a/app/views/connection_links/_connection_link.erb b/app/views/connection_links/_connection_link.erb index 01128051a..0cdcd6f34 100644 --- a/app/views/connection_links/_connection_link.erb +++ b/app/views/connection_links/_connection_link.erb @@ -1,21 +1,21 @@  <%= div_for(connection_link) do %> -  <%= link_to truncate(connection_link.name, :length => 30), [@referential, connection_link], :title => "#{Chouette::TimeTable.model_name.human} #{connection_link.name}" %> +  <%= link_to truncate(connection_link.name, :length => 35), [@referential, connection_link], :title => "#{Chouette::TimeTable.model_name.human} #{connection_link.name}" %>    <div class="info">      <%= t('.from') %> -    <% if connection_link.departure.present? %>  -        <%= link_to_if connection_link.departure, connection_link.departure.name, referential_stop_area_path(@referential, connection_link.departure), :title => "#{connection_link.human_attribute_name('departure')} #{connection_link.departure.name}" %> +    <% if connection_link.departure.present? %> +      <%= link_to_if connection_link.departure, truncate(connection_link.departure.name, :length => 15) , referential_stop_area_path(@referential, connection_link.departure), :title => "#{connection_link.human_attribute_name('departure')} #{connection_link.departure.name}" %>      <% else %> -  	<%= connection_link.human_attribute_name('undefined') %>  +  	<%= connection_link.human_attribute_name('undefined') %>      <% end %>      <%= t('.to') %> -    <% if connection_link.arrival.present? %>  -        <%= link_to_if( connection_link.arrival, connection_link.arrival.name, referential_stop_area_path(@referential, connection_link.arrival), :title => "#{connection_link.human_attribute_name('arrival')} #{connection_link.arrival.name}" )  %> +    <% if connection_link.arrival.present? %> +      <%= link_to_if( connection_link.arrival, truncate(connection_link.arrival.name, :length => 15), referential_stop_area_path(@referential, connection_link.arrival), :title => "#{connection_link.human_attribute_name('arrival')} #{connection_link.arrival.name}" )  %>      <% else %>          <%= connection_link.human_attribute_name("undefined") %> -    <% end %> -  -    <%= connection_link.human_attribute_name('default_duration').capitalize %>: <%= connection_link.default_duration ? connection_link.default_duration.strftime('%Mm %Ss') : connection_link.human_attribute_name("undefined") %>  +    <% end %> - +    <%= connection_link.human_attribute_name('default_duration').capitalize %>: <%= connection_link.default_duration ? connection_link.default_duration.strftime('%Mm %Ss') : connection_link.human_attribute_name("undefined") %> -    <div class="actions">   +    <div class="actions">        <%= link_to t("actions.edit"), edit_referential_connection_link_path(@referential, connection_link), :class => "edit" %> |        <%= link_to t("actions.destroy"), referential_connection_link_path(@referential, connection_link), :method => :delete,  :data => {:confirm =>  t('connection_links.actions.destroy_confirm')}, :class => "remove" %>      </div> diff --git a/app/views/exports/new.html.erb b/app/views/exports/new.html.erb index 60c1cff48..553ebe4a2 100644 --- a/app/views/exports/new.html.erb +++ b/app/views/exports/new.html.erb @@ -8,7 +8,7 @@  <% @available_exports.each do |export| %>  <%= semantic_form_for [@referential, export], :as => :export, :url => referential_exports_path(@referential), :html => { :id => "#{export.type}_new",  :style => ('display: none' unless @export == export)} do |form| %> -    <%= form.inputs do %>  +    <%= form.inputs do %>        <%= fields_for_export_type form %>      <% end %>    <%= form.inputs do %> @@ -17,7 +17,7 @@      <%= form.input :references_type, :as => :select, :collection => Export.references_types.map { |c| [ c.model_name.human.capitalize.pluralize, c.name ] }, :include_blank => t(".all") %>      <% Export.references_types.each do |type| %> -      <%= export_references_input(form, @export, type).input %> +      <%= type_ids_model_references_input(form, @export, Export, type).input %>      <% end %>    <% end %> diff --git a/app/views/exports/new.js.coffee b/app/views/exports/new.js.coffee index f3d815d82..01835f404 100644 --- a/app/views/exports/new.js.coffee +++ b/app/views/exports/new.js.coffee @@ -1,4 +1,4 @@  jQuery -> -    <% Export.references_types.each do |type| %> -       $("textarea.<%= export_references_type(type).input_class %>").tokenInput('<%= references_referential_exports_path(@referential, :type => export_references_type(type).relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1 }); +    <% Export.references_types.map { |type| type_ids_model_references_type( Export, type)}.each do |rt| %> +       $("textarea.<%= rt.input_class %>").tokenInput('<%= references_referential_compliance_check_tasks_path(@referential, :type => rt.relation_name, :format => :json) %>', { prePopulate: $('#').data('pre'), minChars: 1 });      <% end %> diff --git a/app/views/file_validations/_file_validation.erb b/app/views/file_validations/_file_validation.erb deleted file mode 100644 index 7ffed1417..000000000 --- a/app/views/file_validations/_file_validation.erb +++ /dev/null @@ -1,13 +0,0 @@ -<%= div_for(file_validation, :class => :file_validation) do %> -  <%= link_to(file_validation_path(file_validation), :class => "preview") do %> -    <%= image_tag "file-validation-#{file_validation.status}.png" %> -  <% end %> -  <%= link_to(file_validation.name, file_validation_path(file_validation)) %> -  <div class="info"> -    <%= l file_validation.created_at %><br/> -    <%= file_validation.file_name %> -    <div class="actions">   -      <%= link_to t("actions.destroy"), file_validation_path(file_validation), :method => :delete,  :data => {:confirm =>  t('file_validations.actions.destroy_confirm')}, :class => "remove" %> -    </div> -  </div> -<% end %> diff --git a/app/views/file_validations/index.html.erb b/app/views/file_validations/index.html.erb deleted file mode 100644 index 2e0cefbe8..000000000 --- a/app/views/file_validations/index.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -<%= title_tag t('.title') %>  -<div class="warning"><%= t('.warning') %> </div>  -<div class="pagination"> -  <div class="page_info"> -    <%= page_entries_info @file_validations %> -  </div> -  <%= will_paginate @file_validations, :container => false %> -</div> -<div class="file_validations paginated_content"> -  <%= render :partial => "file_validation", :collection => @file_validations %> -</div> -<div class="pagination"> -  <%= will_paginate @file_validations, :container => false %> -</div> - -<% content_for :sidebar do %> -<ul class="actions"> -  <li><%= link_to t('file_validations.actions.new'), new_file_validation_path(), :class => "add" %></li>  -</ul> -<% end %> diff --git a/app/views/file_validations/new.html.erb b/app/views/file_validations/new.html.erb deleted file mode 100644 index 3a86cfac9..000000000 --- a/app/views/file_validations/new.html.erb +++ /dev/null @@ -1,51 +0,0 @@ -<%= title_tag t(".title") %> - -<%= semantic_form_for @file_validation do |form| %> -  <%= form.inputs do %> -      <%= form.input :resources, :as => :file %> -      <%= form.input :test3_1_minimal_distance, :as => :number,:input_html => { :value => '10.0' }, :wrapper_html => { :class => 'fl' } %> -      <%= form.input :test3_2_minimal_distance, :as => :number,:input_html => { :value => '10.0' }, :wrapper_html => { :class => 'fl' } %> -      <%= form.input :test3_2_polygon_points , :as => :text ,:input_html => { :rows => '4', :value => '2.303466,51.399206 8.411865,49.05227 7.950439,43.34116 3.138427,41.869561 -2.376709,43.2932 -5.848389,48.705463' }%> -      <%= form.input :test3_7_minimal_distance, :as => :number ,:input_html => { :value => '50.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_7_maximal_distance, :as => :number ,:input_html => { :value => '15000.0' },:wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_8a_minimal_speed, :as => :number ,:input_html => { :value => '3.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_8a_maximal_speed, :as => :number ,:input_html => { :value => '6.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_8b_minimal_speed, :as => :number ,:input_html => { :value => '4.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_8b_maximal_speed, :as => :number ,:input_html => { :value => '7.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_8c_minimal_speed, :as => :number ,:input_html => { :value => '2.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_8c_maximal_speed, :as => :number ,:input_html => { :value => '5.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_8d_minimal_speed, :as => :number ,:input_html => { :value => '1.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_8d_maximal_speed, :as => :number ,:input_html => { :value => '4.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_9_minimal_speed, :as => :number ,:input_html => { :value => '5.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_9_maximal_speed, :as => :number ,:input_html => { :value => '45.0' }, :wrapper_html => { :class => 'fl2' } %> -  <% end %> -  <%= form.inputs do %>  -      <%= form.input :test3_10_minimal_distance, :as => :number ,:input_html => { :value => '50.0' }, :wrapper_html => { :class => 'fl' } %> -      <%= form.input :test3_15_minimal_time, :as => :number,:input_html => { :value => '1' }, :wrapper_html => { :class => 'fl' }  %> -      <%= form.input :test3_16_1_maximal_time, :as => :number,:input_html => { :value => '120' }, :wrapper_html => { :class => 'fl' }  %> -      <%= form.input :test3_16_3a_maximal_time, :as => :number ,:input_html => { :value => '600' }, :wrapper_html => { :class => 'fl' } %> -      <%= form.input :test3_16_3b_maximal_time, :as => :number ,:input_html => { :value => '300' }, :wrapper_html => { :class => 'fl' } %> -      <%= form.input :test3_21a_minimal_speed, :as => :number ,:input_html => { :value => '3.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_21a_maximal_speed, :as => :number ,:input_html => { :value => '6.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_21b_minimal_speed, :as => :number ,:input_html => { :value => '4.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_21b_maximal_speed, :as => :number ,:input_html => { :value => '7.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_21c_minimal_speed, :as => :number ,:input_html => { :value => '2.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_21c_maximal_speed, :as => :number ,:input_html => { :value => '2.0' }, :wrapper_html => { :class => 'fl2' } %> -      <%= form.input :test3_21d_minimal_speed, :as => :number ,:input_html => { :value => '1.0' }, :wrapper_html => { :class => 'fl1' } %> -      <%= form.input :test3_21d_maximal_speed, :as => :number ,:input_html => { :value => '4.0' }, :wrapper_html => { :class => 'fl2' } %> -   <% end %> -  <%= form.inputs do %>  -      <%= form.input :projection_reference ,:input_html => { :value => 'WGS84' }, :wrapper_html => { :class => 'fl' } %> -  <% end %> - -   <%= form.actions do %> -     <%= form.action :submit, :as => :button , :label => t( 'formtastic.validate' ) %> -     <%= form.action :cancel, :as => :link %> -   <% end %> -<% end %> - -<% content_for :sidebar do %> -<%= render :partial => "test_sheet_toc" %> -<% end %> - - diff --git a/app/views/file_validations/show.html.erb b/app/views/file_validations/show.html.erb deleted file mode 100644 index d3d53fde5..000000000 --- a/app/views/file_validations/show.html.erb +++ /dev/null @@ -1,151 +0,0 @@ -<%= title_tag @file_validation.name %> - -<div class="file_validation_show"> -  <div class="panelDataSection"><%= t(".summary") %></div> -     -  <div class="neptune-panel"> -      <label><%= FileValidation.human_attribute_name(:created_at) %>: </label> -      <%= l @file_validation.created_at %><br/> -      <label><%= FileValidation.human_attribute_name(:status) %>: </label> -      <%= t @file_validation.status, :scope => "file_validations.statuses" %><br/> -      <label><%= FileValidation.human_attribute_name(:file_name) %>: </label> -      <%= @file_validation.file_name %><br/> -      <br/> -      <br/> -      <% if @file_validation.status == 'completed' %> -      <table> -         <tbody> -            <tr> -               <td><%= image_tag "severity-uncheck.png" , :alt => t("uncheck", :scope => "file_validation_log_messages.severities") %> -               	<%= t( "file_validations.uncheck_count" , :count => @file_validation.uncheck_count )%> -               </td> -               <td><%= image_tag "severity-ok.png" , :alt => t("ok", :scope => "file_validation_log_messages.severities") %> -               	<%= t( "file_validations.ok_count" , :count => @file_validation.ok_count )%> -               </td> -               <td><%= image_tag "severity-warning.png" , :alt => t("warning", :scope => "file_validation_log_messages.severities") %> -               	<%= t( "file_validations.warning_count" , :count => @file_validation.warning_count )%> -               </td> -               <td><%= image_tag "severity-error.png" , :alt => t("error", :scope => "file_validation_log_messages.severities") %> -               	<%= t( "file_validations.error_count" , :count => @file_validation.error_count )%> -               </td> -               <td><%= image_tag "severity-fatal.png" , :alt => t("fatal", :scope => "file_validation_log_messages.severities") %> -               	<%= t( "file_validations.fatal_count" , :count => @file_validation.fatal_count )%> -               </td> -            </tr> -         </tbody> -      </table> -      <% end %> -  </div>    	 		 -<% if @file_validation.status == 'completed' %> -  <h3><%= t(".details") %></h3> -    <% @file_validation.log_message_tree.each do |message1| %> -       <label class="category"><%= message1.full_message %></label> -       <div id="<%= message1.key %>" style="margin-left: 40px;"> -       <% message1.children.each do  |message2| %> -          <div class="panelDataSection"><%= message2.full_message %></div> -          <div id="<%= message2.severity %>" class="neptune-panel"> -          <% message2.children.each do  |message3| %> -	          <div class="<%= message3.severity %>"> -				<div> -				<label id=""><%= message3.label %></label> -				</div> -				<div id="" class="step"> -					<%= message3.full_message %> -	            </div> -	          </div> -	          <% if !message3.children.nil? %> -	          <div id="" class="detail"> </div> -	          <div id="detail_0_4_0" class="neptune-panel-inSide"> -				<ol> -		          <% message3.children.each do  |message4| %> -					<li> <%= message4.full_message %> </li> -					<br> -				  <% end %> -				</ol> -	          </div> -	          <% end %> -	      <% end %> -	      </div> -       <% end %> -       </div> -    <% end %> -    <div class="panelDataSection"><%= t(".parameters") %></div> -    <div class="neptune-panel"> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_1_minimal_distance") %> :</label> -        <label><%= @file_validation.test3_1_minimal_distance %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_2_minimal_distance") %> :</label> -        <label><%= @file_validation.test3_2_minimal_distance %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_2_polygon_points") %> :</label> -        <label><%= @file_validation.test3_2_polygon_points %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_7_minimal_distance") %> :</label> -        <label><%= @file_validation.test3_7_minimal_distance %></label> /  -        <label><%= @file_validation.test3_7_maximal_distance %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_8a_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_8a_minimal_speed %></label> /  -        <label><%= @file_validation.test3_8a_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_8b_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_8b_minimal_speed %></label> /  -        <label><%= @file_validation.test3_8b_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_8c_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_8c_minimal_speed %></label> /  -        <label><%= @file_validation.test3_8c_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_8d_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_8d_minimal_speed %></label> /  -        <label><%= @file_validation.test3_8d_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_9_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_9_minimal_speed %></label> /  -        <label><%= @file_validation.test3_9_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_10_minimal_distance") %> :</label> -        <label><%= @file_validation.test3_10_minimal_distance %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_15_minimal_time") %> :</label> -        <label><%= @file_validation.test3_15_minimal_time %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_16_1_maximal_time") %> :</label> -        <label><%= @file_validation.test3_16_1_maximal_time %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_16_3a_maximal_time") %> :</label> -        <label><%= @file_validation.test3_16_3a_maximal_time %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_16_3b_maximal_time") %> :</label> -        <label><%= @file_validation.test3_16_3b_maximal_time %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_21a_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_21a_minimal_speed %></label> /  -        <label><%= @file_validation.test3_21a_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_21b_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_21b_minimal_speed %></label> /  -        <label><%= @file_validation.test3_21b_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_21c_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_21c_minimal_speed %></label> /  -        <label><%= @file_validation.test3_21c_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.test3_21d_minimal_speed") %> :</label> -        <label><%= @file_validation.test3_21d_minimal_speed %></label> /  -        <label><%= @file_validation.test3_21d_maximal_speed %></label> -        <br> -    	<label class="label"><%= t("activerecord.attributes.file_validation.projection_reference") %> :</label> -        <label><%= @file_validation.projection_reference %></label> - -    </div> - -  <% end %> -</div> -<% content_for :sidebar do %> -<ul class="actions"> -  <li><%= link_to  t('file_validations.actions.destroy'), file_validation_path(@file_validation), :method => :delete,  :data => {:confirm =>  t('file_validations.actions.destroy_confirm')}, :class => "remove" %></li> -</ul> -<%= render :partial => "test_sheet_toc" %> - -<% end %> diff --git a/app/views/import_tasks/_fields_csv_import.erb b/app/views/import_tasks/_fields_csv_import.erb new file mode 100644 index 000000000..b4ae719a5 --- /dev/null +++ b/app/views/import_tasks/_fields_csv_import.erb @@ -0,0 +1 @@ +<%= form.input :object_id_prefix, :input_html => { :value => @referential.prefix } %> diff --git a/app/views/import_tasks/_fields_gtfs_import.erb b/app/views/import_tasks/_fields_gtfs_import.erb new file mode 100644 index 000000000..842a24ab7 --- /dev/null +++ b/app/views/import_tasks/_fields_gtfs_import.erb @@ -0,0 +1,7 @@ +<%= form.input :object_id_prefix, :input_html => { :value => @referential.prefix } %> +<%= form.input :max_distance_for_commercial , :as => :number , :input_html => { :title => t("tipsy.hints.import_task.max_distance_for_commercial"), :value => 50 } %> +<%= form.input :ignore_last_word , :as => :boolean , :input_html => { :title => t("tipsy.hints.import_task.ignore_last_word"), :value => false }%> +<%= form.input :ignore_end_chars  , :as => :number , :input_html => { :title => t("tipsy.hints.import_task.ignore_end_chars"), :value => 0 }%> +<%= form.input :max_distance_for_connection_link  , :as => :number , :input_html => { :title => t("tipsy.hints.import_task.max_distance_for_connection_link"), :value => 100 }%> + + diff --git a/app/views/import_tasks/_import_task.erb b/app/views/import_tasks/_import_task.erb new file mode 100644 index 000000000..afa235d4d --- /dev/null +++ b/app/views/import_tasks/_import_task.erb @@ -0,0 +1,20 @@ +<%= div_for import_task do %> +  <div class="icon">  +    <%= link_to image_tag("import_task-#{import_task.status}.png"), referential_import_task_path(@referential, import_task) %> +  </div> +  <div class="resume"> +    <ul class="header clearfix"> +      <li class="title"><%= link_to(import_task.name, referential_import_task_path(@referential, import_task)) %></li> +      <li class="remove"><%= link_to "<i class='fa fa-trash-o'></i>".html_safe, referential_import_task_path(@referential, import_task), :method => :delete, :class => "delete", :data => {:confirm =>  t('import_tasks.actions.destroy_confirm')} %></li> +    </ul> +    <div class="links"> +      <p><%= link_to image_tag("icons/file_#{import_task.file_path_extension}.png") + t("import_tasks.index.imported_file"), file_to_import_referential_import_task_path(@referential, import_task) %></p> +      <% if import_task.compliance_check_task.present? %> +        <p><%= link_to image_tag('icons/link_page.png') + t("import_tasks.compliance_check_task"), referential_compliance_check_task_path(@referential, import_task.compliance_check_task) %></p> +      <% end %>       +    </div> +    <div class="history"> +      <%= l import_task.created_at, :format => "%d/%m/%Y %H:%M" %> | <%= import_task.user_name %> +    </div>   +  </div> +<% end %> diff --git a/app/views/import_tasks/_results_dashboard.html.erb b/app/views/import_tasks/_results_dashboard.html.erb new file mode 100644 index 000000000..d1e674964 --- /dev/null +++ b/app/views/import_tasks/_results_dashboard.html.erb @@ -0,0 +1,67 @@ + <div class="resume"> +   <div class="col1"> +     <% file_title = (@import_task.file_path_extension=="zip") ? t( "import_tasks.show.graph.files.title_zip") : t( "import_tasks.show.graph.files.title_default", :extension => @import_task.file_path_extension)%> +     <div class="caption"><%= file_title %></div> +     <div id="files_statistics"></div> +   </div> +   <div class="col2"> +     <div class="caption"><%= t "import_tasks.show.graph.lines.title" %></div> +     <div id="objects_statistics"></div> +   </div> + </div> + <div class="report"> +   <div class="files files_error"> +     <% @files_list["error"].each_with_index do |error, index| %> +       <% index += 1 %> +       <%= image_tag "icons/file_xml_md.png" %><span class="file_name"><%= truncate(error["name"], :length => 20) %></span> <% if index%4 == 0 %><br><% end %> +     <% end %> +   </div> +   <div class="files files_ignored"> +     <% @files_list["ignored"].each_with_index do |ignored, index| %> +       <% index += 1 %> +       <%= image_tag "icons/file_xml_md.png" %><span class="file_name"><%= truncate(ignored["name"], :length => 20) %></span> <% if index%4 == 0 %><br><% end %> +     <% end %> +   </div> +   <div class="files files_ok"> +     <% @files_list["ok"].each_with_index do |ok, index| %> +       <% index += 1 %> +       <%= image_tag "icons/file_xml_md.png" %><span class="file_name"><%= truncate(ok["name"], :length => 20) %></span> <% if index%4 == 0 %><br><% end %> +     <% end %> +   </div> +   <div class="lines"> +     <table class="table table-hover"> +       <thead> +         <tr> +           <th>#</th> +           <th><%= t("import_tasks.show.table.line.name") %></th> +           <th><%= t("import_tasks.show.table.line.save") %></th> +           <th><%= t("import_tasks.show.table.line.routes") %></th> +           <th><%= t("import_tasks.show.table.line.connection_links") %></th> +           <th><%= t("import_tasks.show.table.line.time_tables") %></th> +           <th><%= t("import_tasks.show.table.line.stop_areas") %></th> +           <th><%= t("import_tasks.show.table.line.access_points") %></th> +           <th><%= t("import_tasks.show.table.line.vehicle_journeys") %></th> +           <th><%= t("import_tasks.show.table.line.journey_patterns") %></th> +         </tr> +       </thead> +       <tbody> +         <% @lines_list.each_with_index do |line, index| %> +         <tr> +           <td><%= index + 1 %></td> +           <td><%= line["name"] %></td> +           <td><%= t("import_tasks.show.table.line." + line["status"] ) %></td> +           <td><%= line["stats"]["route_count"] %></td> +           <td><%= line["stats"]["connection_link_count"] %></td> +           <td><%= line["stats"]["time_table_count"] %></td> +           <td><%= line["stats"]["stop_area_count"] %></td> +           <td><%= line["stats"]["acces_point_count"] %></td> +           <td><%= line["stats"]["vehicle_journey_count"] %></td> +           <td><%= line["stats"]["journey_pattern_count"] %></td> +         </tr> +         <% end %> +       </tbody> +     </table> +   </div> + </div> + <%= javascript_include_tag referential_import_task_path(@import_task.referential, @import_task,:format => :js) %> + diff --git a/app/views/import_tasks/index.html.erb b/app/views/import_tasks/index.html.erb new file mode 100644 index 000000000..df70120b5 --- /dev/null +++ b/app/views/import_tasks/index.html.erb @@ -0,0 +1,18 @@ +<%= title_tag t('.title') %> +<div class="warning"><%= t('.warning') %> </div> +<div class="page_info"> +  <span class="search"> <%= t("will_paginate.page_entries_info.search") %></span> <%= page_entries_info @import_tasks %> +</div> +<div class="import_tasks paginated_content"> +  <%= render :partial => "import_task", :collection => @import_tasks %> +</div> +<div class="pagination"> +  <%= will_paginate @import_tasks, :container => false %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('import_tasks.actions.new'), new_referential_import_task_path(@referential), :class => "add" %></li> +  <li><%= link_to t('rule_parameter_sets.actions.index'), referential_rule_parameter_sets_path(@referential), :class => "link" %></li> +</ul> +<% end %> diff --git a/app/views/import_tasks/new.html.erb b/app/views/import_tasks/new.html.erb new file mode 100644 index 000000000..13888ad39 --- /dev/null +++ b/app/views/import_tasks/new.html.erb @@ -0,0 +1,31 @@ +<%= title_tag t(".title") %> + +<%= semantic_form_for([@referential, @import_task], :as => :import_task, :url => new_referential_import_task_path(@referential), :method => :get) do |form| %> +  <%= form.inputs do %> +    <%= form.input :format, :as => :radio, :collection => ImportTask.formats, :required => true, :include_blank => false %> +  <% end %> +<% end %> + +<% @available_imports.each do |import_task| %> +  <%= semantic_form_for [@referential, import_task], :as => :import_task, :url => referential_import_tasks_path(@referential), :html => { :id => "#{import_task.format}_new",  :style => ('display: none' unless @import_task == import_task)} do |form| %> + +    <%= form.inputs do %> +      <%= fields_for_import_task_format form %> +    <% end %> + +    <%= form.inputs do %> +      <%= form.input :format, :as => :hidden %> +      <%= form.input :no_save, :as => :boolean, :collection => [true, false] %> +      <%= form.input :rule_parameter_set_id, :as => :select, +          :collection =>  @referential.rule_parameter_sets.map { |rps| [ rps.name, rps.id ] }, :include_blank => true %> +      <%= form.input :resources, :as => :file %> +    <% end %> + +    <%= form.actions do %> +     <%= form.action :submit, :as => :button , :label => t( 'formtastic.import' ) %> +     <%= form.action :cancel, :as => :link %> +   <% end %> +  <% end %> +<% end %> + + diff --git a/app/views/import_tasks/show.html.erb b/app/views/import_tasks/show.html.erb new file mode 100644 index 000000000..781b9b07e --- /dev/null +++ b/app/views/import_tasks/show.html.erb @@ -0,0 +1,20 @@ +<%= title_tag "#{@import_task.full_name} <span class='status status_#{@import_task.status}'>#{ t('import_tasks.show.'+@import_task.status) }</span>" %> + +<div class="import_task_show"> +  <div class="links"> +    <%= link_to t("import_tasks.show.imported_file"), file_to_import_referential_import_task_path(@import_task.referential, @import_task), :class => "btn btn-default" %> +    <% if @import_task.compliance_check_task %> +      <%= link_to t("import_tasks.compliance_check_task"), referential_compliance_check_task_path(@import_task.referential, @import_task.compliance_check_task), :class => "btn btn-default"  %> +    <% end %> +  </div> +  <%= render( :partial => "results_dashboard") if @import_task.completed? %> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to  t('import_tasks.actions.destroy'), referential_import_task_path(@referential, @import_task), :method => :delete,  :data => {:confirm =>  t('import_tasks.actions.destroy_confirm')}, :class => "remove" %></li> +</ul> + +<%= history_tag(@import_task) %> + +<% end %> diff --git a/app/views/import_tasks/show.js.coffee b/app/views/import_tasks/show.js.coffee new file mode 100644 index 000000000..accd8e720 --- /dev/null +++ b/app/views/import_tasks/show.js.coffee @@ -0,0 +1,41 @@ +jQuery -> + +  get_import_results = (html_container, html_element) -> +    html_container.children().each -> +      if( $( this ).is(html_element) ) +        $( this ).show() +      else +        $( this ).hide() + +  Morris.Donut({ +    element: 'files_statistics', +    data: [ +      {label: "<%= t 'import_tasks.show.graph.files.error' %>", value: <%= @files_stats["error_count"] %> }, +      {label: "<%= t 'import_tasks.show.graph.files.ignored' %>", value: <%= @files_stats["ignored_count"] %> }, +      {label: "<%= t 'import_tasks.show.graph.files.ok' %>", value: <%= @files_stats["ok_count"] %> } +    ] +    colors: [ "#e22b1b", "#ffbd2b", "#8fc861" ] +  }).on('click', update = (i, row) -> +    switch i +      when 0 then get_import_results( $(".report"), $(".files_error")) +      when 1 then get_import_results( $(".report"), $(".files_ignored")) +      when 2 then get_import_results( $(".report"), $(".files_ok")) +      else console.log "Error no other value for donut chart") + +  Morris.Bar({ +    element: 'objects_statistics', +    data: [ +      { object: "<%= t("import_tasks.show.graph.lines.lines_stats") %>", value: <%= @lines_stats["line_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.routes_stats") %>", value: <%= @lines_stats["route_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.connection_links_stats") %>", value: <%= @lines_stats["connection_link_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.time_tables_stats") %>", value: <%= @lines_stats["time_table_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.stop_areas_stats") %>", value: <%= @lines_stats["stop_area_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.access_points_stats") %>", value: <%= @lines_stats["access_point_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.vehicle_journeys_stats") %>", value: <%= @lines_stats["vehicle_journey_count"] %> }, +      { object: "<%= t("import_tasks.show.graph.lines.journey_patterns_stats") %>", value: <%= @lines_stats["journey_pattern_count"] %> },  +    ], +    xkey: 'object', +    ykeys: ['value'], +    labels: ['<%= t "import_tasks.show.graph.lines.objects_label" %>'] +  }).on('click', update = (i, row) -> +    get_import_results( $(".report"), $(".lines")) )
\ No newline at end of file diff --git a/app/views/imports/_fields_csv_import.erb b/app/views/imports/_fields_csv_import.erb deleted file mode 100644 index 2ab96acf7..000000000 --- a/app/views/imports/_fields_csv_import.erb +++ /dev/null @@ -1 +0,0 @@ -<%= form.input :objectid_prefix, :input_html => { :value => @referential.prefix } %> diff --git a/app/views/imports/_fields_gtfs_import.erb b/app/views/imports/_fields_gtfs_import.erb deleted file mode 100644 index dd75a41a5..000000000 --- a/app/views/imports/_fields_gtfs_import.erb +++ /dev/null @@ -1,7 +0,0 @@ -<%= form.input :objectid_prefix, :input_html => { :value => @referential.prefix } %> -<%= form.input :max_distance_for_commercial , :as => :number , :input_html => { :value => 50 } %> -<%= form.input :ignore_last_word , :as => :boolean , :input_html => { :value => false }%> -<%= form.input :ignore_end_chars  , :as => :number , :input_html => { :value => 0 }%> -<%= form.input :max_distance_for_connection_link  , :as => :number , :input_html => { :value => 100 }%> - - diff --git a/app/views/imports/_import.erb b/app/views/imports/_import.erb deleted file mode 100644 index 87e7c3190..000000000 --- a/app/views/imports/_import.erb +++ /dev/null @@ -1,13 +0,0 @@ -<%= div_for(import, :class => :import) do %> -  <%= link_to(referential_import_path(@referential, import), :class => "preview") do %> -    <%= image_tag "import-#{import.status}.png" %> -  <% end %> -  <%= link_to(import.name, referential_import_path(@referential, import)) %> -  <div class="info"> -    <%= l import.created_at %> - -    <div class="actions">   -      <%= link_to t("actions.destroy"), referential_import_path(@referential, import), :method => :delete,  :data => {:confirm =>  t('imports.actions.destroy_confirm')}, :class => "remove" %> -    </div> -  </div> -<% end %> diff --git a/app/views/imports/index.html.erb b/app/views/imports/index.html.erb deleted file mode 100644 index 8469fbd7b..000000000 --- a/app/views/imports/index.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<%= title_tag t('.title') %>  -<div class="warning"><%= t('.warning') %> </div>  -<div class="page_info"> -  <span class="search"> <%= t("will_paginate.page_entries_info.search") %></span> <%= page_entries_info @imports %> -</div> -<div class="imports paginated_content"> -  <%= render :partial => "import", :collection => @imports %> -</div> -<div class="pagination"> -  <%= will_paginate @imports, :container => false %> -</div> - -<% content_for :sidebar do %> -<ul class="actions"> -  <li><%= link_to t('imports.actions.new'), new_referential_import_path(@referential), :class => "add" %></li>  -</ul> -<% end %> diff --git a/app/views/imports/new.html.erb b/app/views/imports/new.html.erb deleted file mode 100644 index f99ca9062..000000000 --- a/app/views/imports/new.html.erb +++ /dev/null @@ -1,26 +0,0 @@ -<%= title_tag t(".title") %> - -<%= semantic_form_for([@referential, @import], :as => :import, :url => new_referential_import_path(@referential), :method => :get) do |form| %>   -  <%= form.inputs do %> -    <%= form.input :type, :as => :radio, :collection => Import.types.map { |format| [ Import.format_name(format), format]}, :required => true, :include_blank => false %> -  <% end %> -<% end %> - -<% @available_imports.each do |import| %> -  <%= semantic_form_for [@referential, import], :as => :import, :url => referential_imports_path(@referential), :html => { :id => "#{import.type}_new",  :style => ('display: none' unless @import == import)} do |form| %> - -    <%= form.inputs do %>  -      <%= fields_for_import_type form %> -    <% end %> - -    <%= form.inputs do %>  -      <%= form.input :type, :as => :hidden %> -      <%= form.input :resources, :as => :file %> -    <% end %> - -    <%= form.actions do %> -     <%= form.action :submit, :as => :button , :label => t( 'formtastic.import' ) %> -     <%= form.action :cancel, :as => :link %> -   <% end %> -  <% end %> -<% end %> diff --git a/app/views/imports/show.html.erb b/app/views/imports/show.html.erb deleted file mode 100644 index 15c595e95..000000000 --- a/app/views/imports/show.html.erb +++ /dev/null @@ -1,42 +0,0 @@ -<%= title_tag @import.name %> - -<div class="import_show"> -  <div class="summary"> -    <p> -      <label><%= Import.human_attribute_name(:created_at) %>: </label> -      <%= l @import.created_at %> -    </p> -    <p> -      <label><%= Import.human_attribute_name(:status) %>: </label> -      <%= t @import.status, :scope => "imports.statuses" %> -    </p> -  </div> - -  <% if @import.log_messages.empty? %> -  	  <p> <%= t(".not_yet_started") %> </p> -  <% else %> -	  <h3><%= t(".report") %></h3> -	  <table> -	    <tr> -	      <th class="severity"></th> -	      <th class="created_at"><%= ImportLogMessage.human_attribute_name(:created_at) %></th> -	      <th class="position"><%= ImportLogMessage.human_attribute_name(:position) %></th> -	      <th class="message"><%= ImportLogMessage.human_attribute_name(:full_message) %></th> -	    </tr> -	    <% @import.log_messages.each do |message| %> -	    <tr> -	      <td class="severity"><%= image_tag "severity-#{message.severity}.png", :alt => t(message.severity, :scope => "import_log_messages.severities") %></td> -	      <td class="created_at"><%= l message.created_at, :format => :short %></td> -	      <td class="position"><%= message.position %></td> -	      <td class="message"><%= message.full_message %></td> -	    </tr> -	    <% end %> -	  </table> -  <% end %> -</div> - -<% content_for :sidebar do %> -<ul class="actions"> -  <li><%= link_to  t('imports.actions.destroy'), referential_import_path(@referential, @import), :method => :delete,  :data => {:confirm =>  t('imports.actions.destroy_confirm')}, :class => "remove" %></li> -</ul> -<% end %> diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 81a87f5ae..e13a130e8 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -44,7 +44,6 @@            <% elsif ! selected_referential? %>              <% if  user_signed_in? %>                <li><%= link_to Referential.model_name.human(:count=>2), referentials_path, :class => ("current" if current_page?(referentials_path) || current_page?(root_url)) %></li> -              <li><%= tab_link_to FileValidation.model_name.human(:count=>2), file_validations_path %></li>                <li class="admin"><%= tab_link_to Organisation.model_name.human, organisation_path %></li>              <% end %>            <% else %> @@ -56,18 +55,16 @@              <li><%= tab_link_to Chouette::StopArea, referential_stop_areas_path(@referential) %></li>              <li><%= tab_link_to Chouette::ConnectionLink, referential_connection_links_path(@referential) %></li>              <li><%= tab_link_to Chouette::TimeTable, referential_time_tables_path(@referential) %></li> - -            <li><%= tab_link_to Import, referential_imports_path(@referential) %></li> +            <li><%= tab_link_to ImportTask, referential_import_tasks_path(@referential) %></li>              <li><%= tab_link_to Export, referential_exports_path(@referential) %></li> +            <li><%= tab_link_to ComplianceCheckTask, referential_compliance_check_tasks_path(@referential) %></li>            <% end %>          </ul>        </div>      </div>      <div id="body"> -      <div id="flash"> -        <%= flash_tag flash %> -      </div>        <div id="workspace" class="<%= controller_name %> <%= action_name %>"> +        <%= render partial: "shared/flash_messages", flash: flash %>          <%= yield %>        </div>        <div id="sidebar"> diff --git a/app/views/lines/_line.erb b/app/views/lines/_line.erb index 88e222686..69baacd75 100644 --- a/app/views/lines/_line.erb +++ b/app/views/lines/_line.erb @@ -1,5 +1,5 @@  <%= div_for(line) do %> -  <%= link_to([@referential, line], :class => "preview", :title => "#{Chouette::Line.model_name.human.capitalize} #{line.number}") do %> +  <div><%= link_to([@referential, line], :class => "preview", :title => "#{Chouette::Line.model_name.human.capitalize} #{line.number}") do %></div>      <div class="color">        <% if line.number and line.number.length <= 3 %>          <div class="number"><%= line.number %></div> @@ -14,7 +14,7 @@    	<% if line.network.nil? %>    	   <%= line.human_attribute_name('network') %> <%=  t('lines.index.unset') %>     	<% else %> -       <%= line.human_attribute_name('network') %> <%= link_to_if line.network, line.network.name, referential_network_path(@referential, line.network), :title => "#{line.human_attribute_name('network')} #{line.network.name}" %> - +       <%= line.human_attribute_name('network') %> <%= link_to_if line.network, line.network.name, referential_network_path(@referential, line.network), :title => "#{line.human_attribute_name('network')} #{line.network.name}" %><br>      <% end %>    	<% if line.company.nil? %>    	   <%= line.human_attribute_name('company') %> <%=  t('lines.index.unset') %>  diff --git a/app/views/lines/index.html.erb b/app/views/lines/index.html.erb index ff14e8749..0eed3e63b 100644 --- a/app/views/lines/index.html.erb +++ b/app/views/lines/index.html.erb @@ -45,10 +45,6 @@    <li><%= link_to t('lines.actions.new'), new_referential_line_path(@referential), :class => "add" %></li>   </ul> -<ul class="actions"> -  <li><%= link_to t('lines.actions.import'), new_referential_import_path(@referential), :class => "import" %></li>  -</ul> -  <h3><%= t(".selection") %></h3>  <h4><%= Chouette::Company.model_name.human.pluralize %></h4> diff --git a/app/views/rule_parameter_sets/_form.html.erb b/app/views/rule_parameter_sets/_form.html.erb new file mode 100644 index 000000000..1f12d6b14 --- /dev/null +++ b/app/views/rule_parameter_sets/_form.html.erb @@ -0,0 +1,27 @@ +<%= semantic_form_for [@referential, @rule_parameter_set] do |form| %> +  <%= form.inputs do %> +    <%= form.input :name %> +    <%= form.input :inter_stop_area_distance_min, :as => :number %> +    <%= form.input :parent_stop_area_distance_max, :as => :number %> +    <%= form.input :stop_areas_area %> +    <%= form.input :inter_access_point_distance_min, :as => :number %> +    <%= form.input :inter_connection_link_distance_max, :as => :number %> +    <%= form.input :walk_default_speed_max, :as => :number %> +    <%= form.input :walk_occasional_traveller_speed_max, :as => :number %> +    <%= form.input :walk_frequent_traveller_speed_max, :as => :number %> +    <%= form.input :walk_mobility_restricted_traveller_speed_max, :as => :number %> + +    <%= form.input :inter_access_link_distance_max, :as => :number %> +    <%= form.input :inter_stop_duration_max, :as => :number %> +    <%= form.input :facility_stop_area_distance_max, :as => :number %> + +    <% Chouette::Line.transport_modes.map(&:to_s).each do |mode| %> +      <%= render :partial => "mode_fields", :locals => { :f => form, :mode => mode} %> +    <% end %> +  <% end %> + +   <%= form.actions do %> +     <%= form.action :submit, :as => :button %> +     <%= form.action :cancel, :as => :link %> +   <% end %> +<% end %> diff --git a/app/views/rule_parameter_sets/_mode_fields.html.erb b/app/views/rule_parameter_sets/_mode_fields.html.erb new file mode 100644 index 000000000..0a17b4d82 --- /dev/null +++ b/app/views/rule_parameter_sets/_mode_fields.html.erb @@ -0,0 +1,5 @@ +<%= f.inputs t("transport_modes.label.#{mode}"), :id => "specific_parameters_#{mode}" do %> +  <% RuleParameterSet.mode_attribute_prefixes.each do |prefix| %> +    <%= f.input "#{prefix}_mode_#{mode}".to_sym, :as => :number, :label => RuleParameterSet.human_attribute_name(prefix), :wrapper_html => { :class => "special"} %> +  <% end %> +<% end %> diff --git a/app/views/rule_parameter_sets/_mode_selection.html.erb b/app/views/rule_parameter_sets/_mode_selection.html.erb new file mode 100644 index 000000000..56d1c05bb --- /dev/null +++ b/app/views/rule_parameter_sets/_mode_selection.html.erb @@ -0,0 +1,6 @@ +<select class="undescribed_modes"> +  <% Chouette::TransportMode.all.map { |m| m.name.downcase}.each do |mode| %> +  <option value='<%= mode %>'><%= t("transport_modes.label.#{mode}") %></option> +  <% end %> +</select> + diff --git a/app/views/rule_parameter_sets/_transport_mode_parameter_set_fields.html.erb b/app/views/rule_parameter_sets/_transport_mode_parameter_set_fields.html.erb new file mode 100644 index 000000000..3d2bcd3d2 --- /dev/null +++ b/app/views/rule_parameter_sets/_transport_mode_parameter_set_fields.html.erb @@ -0,0 +1,10 @@ +<%= f.inputs :class => 'transport_mode_parameter_sets nested-fields' do %> +  <%= f.input :transport_mode, :as => :select, :collection => Chouette::TransportMode.all, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }, :label => "transport_mode", :wrapper_html => { :class => 'fl1' } %> +  <%= f.input :inter_stop_area_distance_min, :as => :number, :label => "inter_stop_area_distance_min", :wrapper_html => { :class => 'fl1' } %> +  <%= f.input :inter_stop_area_distance_max, :as => :number, :label => "inter_stop_area_distance_max", :wrapper_html => { :class => 'fl2' } %> +  <%= f.input :speed_min, :as => :number, :label => "speed_min", :wrapper_html => { :class => 'fl2' } %> +  <%= f.input :speed_max, :as => :number, :label => "speed_max", :wrapper_html => { :class => 'fl2' } %> +  <%= f.input :inter_stop_duration_variation_max, :as => :number, :label => "inter_stop_duration_variation_max", :wrapper_html => { :class => 'fl2' } %> +  <%= link_to_remove_association t('actions.destroy'), f %> +<% end %> + diff --git a/app/views/rule_parameter_sets/edit.html.erb b/app/views/rule_parameter_sets/edit.html.erb new file mode 100644 index 000000000..eb2ca466f --- /dev/null +++ b/app/views/rule_parameter_sets/edit.html.erb @@ -0,0 +1,4 @@ +<%= title_tag t('rule_parameter_sets.edit.title', :rule_parameter_set => @rule_parameter_set.name ) %> + +<%= render "form" %> + diff --git a/app/views/rule_parameter_sets/index.html.erb b/app/views/rule_parameter_sets/index.html.erb new file mode 100644 index 000000000..c03ff0d15 --- /dev/null +++ b/app/views/rule_parameter_sets/index.html.erb @@ -0,0 +1,21 @@ +<%= title_tag t('rule_parameter_sets.index.title') %> + +<% @rule_parameter_sets.each do |rule_parameter_set| %> +  <%= div_for(rule_parameter_set) do %> +    <%= link_to( rule_parameter_set.name, [@referential, rule_parameter_set]) %> +    <div class="info"> +      <div class="actions"> +        <%= link_to t("actions.edit"), edit_referential_rule_parameter_set_path(@referential, rule_parameter_set), :class => "edit" %> +        <% if @referential.rule_parameter_sets.size > 1 %> +        | <%= link_to t("actions.destroy"), referential_rule_parameter_set_path(@referential, rule_parameter_set), :method => :delete, :data => {:confirm =>  t('rule_parameter_sets.actions.destroy_confirm')}, :class => "remove" %> +        <% end %> +      </div> +    </div> +  <% end %> +<% end %> + +<% content_for :sidebar do %> +<ul class="actions"> +  <li><%= link_to t('rule_parameter_sets.actions.new'), new_referential_rule_parameter_set_path(@referential), :class => "add" %></li> +</ul> +<% end %> diff --git a/app/views/rule_parameter_sets/mode.js.erb b/app/views/rule_parameter_sets/mode.js.erb new file mode 100644 index 000000000..22b70830e --- /dev/null +++ b/app/views/rule_parameter_sets/mode.js.erb @@ -0,0 +1,13 @@ +if ( $('#specific_parameters_<%= @mode %>').length == 0) { +  <% form_content = "" %> +  <% semantic_form_for [@referential, @rule_parameter_set] do |form| %> +    <% form_content += render(:partial => 'mode_fields', :locals => { :mode => @mode, :f => form }) %> +  <% end %> +  $('#added_mode_parameter_set').before('<%= escape_javascript( form_content).html_safe %>'); +} +else { +  $('#_destroy_mode_<%= @mode %>').attr( "value", false); +  $('#specific_parameters_<%= @mode %>').toggle(); +} + + diff --git a/app/views/rule_parameter_sets/new.html.erb b/app/views/rule_parameter_sets/new.html.erb new file mode 100644 index 000000000..228a2da7a --- /dev/null +++ b/app/views/rule_parameter_sets/new.html.erb @@ -0,0 +1,4 @@ +<%= title_tag  t('rule_parameter_sets.new.title') %> + +<%= render "form" %> + diff --git a/app/views/rule_parameter_sets/show.html.erb b/app/views/rule_parameter_sets/show.html.erb new file mode 100644 index 000000000..f2427e36e --- /dev/null +++ b/app/views/rule_parameter_sets/show.html.erb @@ -0,0 +1,109 @@ +<%= title_tag t('rule_parameter_sets.show.title', :rule_parameter_set => @rule_parameter_set.name ) %> + +<div class="rule_parameter_set_show"> + +  <div class="summary"> +    <p> +      <label><%= RuleParameterSet.human_attribute_name("name") %>: </label> +      <%= @rule_parameter_set.name %> +    </p> +    <p> +      <label><%= RuleParameterSet.human_attribute_name("stop_areas_area") %>: </label> +      <%= @rule_parameter_set.stop_areas_area %> +    </p> +    <div class="attributes_group" > +      <span class="title"><%= t(".min_distance") %></span> +      <div class="columns"> +        <div class="two_columns"> +          <label><%= t(".inter_stop_area_distance_min") %> : </label> +          <span class="value"><%= @rule_parameter_set.inter_stop_area_distance_min %></span> +        </div> +        <div class="two_columns"> +          <label><%= t(".inter_access_point_distance_min") %> : </label> +          <span class="value"><%= @rule_parameter_set.inter_access_point_distance_min %></span> +        </div> +      </div> +    </div> +    <div class="attributes_group" > +      <span class="title"><%= t(".max_distance") %></span> +      <div class="columns"> +        <div class="two_columns"> +          <label><%= t(".parent_stop_area_distance_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.parent_stop_area_distance_max %></span> +        </div> +        <div class="two_columns"> +          <label><%= t(".inter_connection_link_distance_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.inter_connection_link_distance_max %></span> +        </div> +      </div> +      <div class="columns"> +        <div class="two_columns"> +          <label><%= t(".inter_access_link_distance_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.inter_access_link_distance_max %></span> +        </div> +        <div class="two_columns"> +          <label><%= t(".facility_stop_area_distance_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.facility_stop_area_distance_max %></span> +        </div> +      </div> +    </div> +    <div class="attributes_group" > +      <span class="title"><%= t(".walk_speed") %></span> +      <div class="columns"> +        <div class="four_columns"> +          <label><%= t(".walk_default_speed_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.walk_default_speed_max %></span> +        </div> +        <div class="four_columns"> +          <label><%= t(".walk_occasional_traveller_speed_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.walk_occasional_traveller_speed_max %></span> +        </div> +        <div class="four_columns"> +          <label><%= t(".walk_frequent_traveller_speed_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.walk_frequent_traveller_speed_max %></span> +        </div> +        <div class="four_columns"> +          <label><%= t(".walk_mobility_restricted_traveller_speed_max") %>: </label> +          <span class="value"><%= @rule_parameter_set.walk_mobility_restricted_traveller_speed_max %></span> +        </div> +      </div> +    </div> +    <p> +      <label><%= t(".inter_stop_duration_max") %>: </label> +      <%= @rule_parameter_set.inter_stop_duration_max %> +    </p> +    <div class="rule_parameter_by_mode"> +      <label><%= t(".rule_parameter_by_mode") %>: </label> +      <select id="mode" > +        <%= options_for_select( Chouette::Line.transport_modes.map(&:to_s).map { |s| [ I18n.t("transport_modes.label.#{s}"), s]}, 1) %> +      </select> +      <% Chouette::Line.transport_modes.map(&:to_s).each_with_index do |mode, index| %> +        <% selected_class = (index==0) ? 'selected' : '' %> +        <% style = (index==0) ? "style='display: block;'" : '' %> +        <div class='<%= "#{mode} mode_specific #{selected_class}" %>' <%= style %> > +        <% RuleParameterSet.mode_attribute_prefixes.each do |prefix| %> +          <% unless @rule_parameter_set.send("#{prefix}_mode_#{mode}" ).blank? %> +            <p> +              <label><%= RuleParameterSet.human_attribute_name( prefix) %>: </label> +              <%= @rule_parameter_set.send  "#{prefix}_mode_#{mode}" %> +            </p> +          <% end %> +        <% end %> +      </div> +      <% end %> +    </div> +  </div> +</div> + +<% content_for :sidebar do %> +<ul class="actions"> +  <% if @rule_parameter_set.persisted? %> +  <li><%= link_to t('rule_parameter_sets.actions.index'), referential_rule_parameter_sets_path(@referential), :class => "link" %></li> +  <li><%= link_to t('rule_parameter_sets.actions.edit'), edit_referential_rule_parameter_set_path(@referential, @rule_parameter_set), :class => "edit" %></li> +  <% if @referential.rule_parameter_sets.size > 1 %> +  <li><%= link_to  t('rule_parameter_sets.actions.destroy'), referential_rule_parameter_set_path(@referential, @rule_parameter_set), :method => :delete, :data => {:confirm =>  t('rule_parameter_sets.actions.destroy_confirm')}, :class => "remove" %></li> +  <% end %> +  <li><%= link_to t('rule_parameter_sets.actions.new'), new_referential_rule_parameter_set_path(@referential), :class => "add" %></li> +  <% end %> +</ul> +<% end %> diff --git a/app/views/shared/_flash_messages.erb b/app/views/shared/_flash_messages.erb new file mode 100644 index 000000000..bad859aa9 --- /dev/null +++ b/app/views/shared/_flash_messages.erb @@ -0,0 +1,6 @@ +<% flash.each do |type, message| %> +  <div class="alert <%= bootstrap_class_for(type) %> fade in"> +    <button class="close" data-dismiss="alert">×</button>    +    <%= flash_message_for type, message %> +  </div> +<% end %> diff --git a/config/environment.rb b/config/environment.rb index 7d362d262..296970388 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -6,4 +6,4 @@ require File.expand_path('../application', __FILE__)  ChouetteIhm::Application.initialize!  # Fix version -APP_VERSION = '2.1.1' +APP_VERSION = '2.2.0' diff --git a/config/initializers/active_enum.rb b/config/initializers/active_enum.rb new file mode 100644 index 000000000..cabf0bf7b --- /dev/null +++ b/config/initializers/active_enum.rb @@ -0,0 +1,24 @@ +# Form helper integration +# require 'active_enum/form_helpers/formtastic'  # for Formtastic <2 +require 'active_enum/form_helpers/formtastic2' # for Formtastic 2.x + +ActiveEnum.setup do |config| + +  # Extend classes to add enumerate method +  # config.extend_classes = [ ActiveRecord::Base ] + +  # Return name string as value for attribute method +  # config.use_name_as_value = false + +  # Storage of values (:memory, :i18n) +  # config.storage = :memory + +end + +# ActiveEnum.define do +#  +#   enum(:enum_name) do +#     value 1 => 'Name' +#   end +#  +# end diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index b9873db1b..095ee9aff 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -1,6 +1,6 @@  Apartment.configure do |config|    # set your options (described below) here -  config.excluded_models = ["Referential", "Organisation", "User", "Import", "ImportLogMessage", "Export", "ExportLogMessage","FileValidation", "FileValidationLogMessage", "Delayed::Backend::ActiveRecord::Job", "Api::V1::ApiKey"]        # these models will not be multi-tenanted, but remain in the global (public) namespace +  config.excluded_models = ["Referential", "Organisation", "User", "ImportTask", "Export", "ExportLogMessage","ComplianceCheckTask", "ComplianceCheckResult", "Delayed::Backend::ActiveRecord::Job", "Api::V1::ApiKey", "RuleParameterSet"]        # these models will not be multi-tenanted, but remain in the global (public) namespace    # Dynamically get database names to migrate    config.database_names = lambda{ Referential.pluck(:slug) } diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index d77e42f46..bf423a2f5 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -92,18 +92,18 @@ Devise.setup do |config|    # this period, the invited resource won't be able to accept the invitation.    # When invite_for is 0 (the default), the invitation won't expire.    # config.invite_for = 2.weeks -   +    # Number of invitations users can send.    # If invitation_limit is nil, users can send unlimited invitations.    # If invitation_limit is 0, users can't send invitations.    # If invitation_limit n > 0, users can send n invitations.    # Default: nil    # config.invitation_limit = 5 -   +    # The key to be used to check existing users when sending an invitation    # config.invite_key = :email -   -  # Flag that force a record to be valid before being actually invited  + +  # Flag that force a record to be valid before being actually invited    # Default: false    # config.validate_on_invite = true @@ -242,3 +242,25 @@ Devise.setup do |config|    #   manager.default_strategies(:scope => :user).unshift :some_external_strategy    # end  end + +class Devise::FailureApp +    def return_to_root_path? +      root_path == session["#{scope}_return_to"] +    end +    def redirect +      store_location! +      if flash[:timedout] && flash[:alert] +        flash.keep(:timedout) +        flash.keep(:alert) +      else +        Rails.logger.debug "A" * 30 +        Rails.logger.debug i18n_message +        Rails.logger.debug redirect_url +        Rails.logger.debug scope +        Rails.logger.debug root_path +        Rails.logger.debug session["#{scope}_return_to"] +        flash[:alert] = i18n_message unless return_to_root_path? +      end +      redirect_to redirect_url +    end +end diff --git a/config/initializers/formtastic.rb b/config/initializers/formtastic.rb index 7aee33df5..c1f7f972f 100644 --- a/config/initializers/formtastic.rb +++ b/config/initializers/formtastic.rb @@ -1,6 +1,5 @@    Formtastic::FormBuilder.i18n_lookups_by_default = true -  module Formtastic    module Inputs      class CheckBoxesInput diff --git a/config/locales/compliance_check_results.yml b/config/locales/compliance_check_results.yml new file mode 100644 index 000000000..b523275c2 --- /dev/null +++ b/config/locales/compliance_check_results.yml @@ -0,0 +1,265 @@ +en: +  compliance_check_result: +    severities: +      error: "Obligatory Tests" +      warning: "Optionnal Tests" +    statuses: +      nok: "Error" +      na: "Unavailable" +      ok: "Success" +  activerecord: +    models: +      compliance_check_result:  +        zero: "Validation" +        one: "Validation" +        other: "Validation" +    attributes: +      compliance_check_result: +         violation_count: "Violation count" + +fr: +  compliance_check_results: +    index: +      line: "Li" +      column: "Col" +  compliance_check_result: +    severities: +      error: "Tests Obligatoires" +      warning: "Tests Optionnels" +    statuses: +      nok: "Erreur" +      na: "Absent" +      ok: "Succès" +    details: +      #### level 1 +      ## NEPTUNE +      detail_1_neptune_xml_1: "%{xmlKey} : %{message}" +      detail_1_neptune_xml_2: "%{xmlKey} : %{message}" +      #### level 2 +      ## NEPTUNE  +      detail_2_neptune_common_1: "" +      detail_2_neptune_common_2: "RegistrationNumber = %{RegistrationNumber}" +      detail_2_neptune_network_1: "La ligne %{lineId} est absente de la liste des lignes du réseau %{objectId}" +      detail_2_neptune_groupofline_1: "lineId = %{lineId}" +      detail_2_neptune_stoparea_1: "contains = %{contains}" +      detail_2_neptune_stoparea_2: "contains = %{contains}" +      detail_2_neptune_stoparea_3: "contains = %{contains}" +      detail_2_neptune_stoparea_4: "contains = %{contains}" +      detail_2_neptune_stoparea_5: "centroidOfArea = %{centroidOfArea}" +      detail_2_neptune_stoparea_6: "centroidOfArea = %{centroidOfArea}" +      detail_2_neptune_itl_1: "contains = %{contains}" +      detail_2_neptune_itl_2: "" +      detail_2_neptune_itl_3: "areaId = %{areaId}" +      detail_2_neptune_itl_4: "areaId = %{areaId}" +      detail_2_neptune_itl_5: "lineIdShortCut = %{lineIdShortCut}" +      detail_2_neptune_areacentroid_1: "containedIn = %{containedIn}" +      detail_2_neptune_areacentroid_2: "longLatType = %{longLatType}" +      detail_2_neptune_connectionlink_1: "" +      detail_2_neptune_accesspoint_1: "containedIn = %{containedIn}" +      detail_2_neptune_accesspoint_2: "containedIn = %{containedIn}" +      detail_2_neptune_accesspoint_3: "" +      detail_2_neptune_accesspoint_4: "" +      detail_2_neptune_accesspoint_5: "" +      detail_2_neptune_accesspoint_6: "" +      detail_2_neptune_accesspoint_7: "longLatType = %{longLatType}" +      detail_2_neptune_accesslink_1: "%{link} = %{target}" +      detail_2_neptune_accesslink_2: "startOfLink = %{startOfLink} et endOfLink = %{endOfLink} ; type = %{type}" +      detail_2_neptune_line_1: "ptNetworkIdShortcut = %{ptNetworkIdShortcut}" +      detail_2_neptune_line_2: "lineEnd = %{lineEnd}" +      detail_2_neptune_line_3: "lineEnd = %{lineEnd}" +      detail_2_neptune_line_4: "routeId = %{routeId}" +      detail_2_neptune_line_5: "routeId = %{routeId}" +      detail_2_neptune_route_1: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_route_2: "ptLinkId = %{ptLinkId}" +      detail_2_neptune_route_3: "waybackRouteId = %{waybackRouteId}" +      detail_2_neptune_route_4: "ptLinkId = %{ptLinkId}" +      detail_2_neptune_route_5: "%{link} = %{target}" +      detail_2_neptune_route_6: "ptLinkId = %{ptLinkId}" +      detail_2_neptune_route_7: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_route_8: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_route_9: "L'arrêt (stopPointId = %{stopPointId}) de la séquence d'arrêts %{objectId} n'est utilisé dans aucune mission" +      detail_2_neptune_route_10: "waybackRouteId = %{waybackRouteId}" +      detail_2_neptune_route_11: "Le sens (%{waybackValue}) de la séquence d'arrêt %{objectId} n'est pas compatible avec celui (%{oppositeWaybackValue}) de la séquence opposée %{waybackRouteId}" +      detail_2_neptune_route_12: "Le départ (stopPointId = %{stopPointId}) de la séquence d'arrêts %{objectId} n'est pas dans la même zone que l'arrivée (stopPointId = %{waybackStopPointId} de la séquence retour %{waybackRouteId}" +      detail_2_neptune_ptlink_1: "%{link} = %{target}" +      detail_2_neptune_journeypattern_1: "routeId = %{routeId}" +      detail_2_neptune_journeypattern_2: "stopPointId = %{stopPointId}" +      detail_2_neptune_journeypattern_3: "lineIdShortcut = %{lineIdShortcut}" +      detail_2_neptune_stoppoint_1: "lineIdShortcut = %{lineIdShortcut}" +      detail_2_neptune_stoppoint_2: "ptNetworkIdShortcut = %{ptNetworkIdShortcut}" +      detail_2_neptune_stoppoint_3: "containedIn = %{containedIn}" +      detail_2_neptune_stoppoint_4: "longLatType = %{longLatType}" +      detail_2_neptune_timetable_1: "" +      detail_2_neptune_timetable_2: "La course %{objectId} n'est référencée dans aucun objet <Timetable>" +      detail_2_neptune_vehiclejourney_1: "routeId = %{routeId}" +      detail_2_neptune_vehiclejourney_2: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_vehiclejourney_3: "lineIdShortcut = %{lineIdShortcut}" +      detail_2_neptune_vehiclejourney_4: "L'opérateur (operatorId = %{operatorId}) de la course %{objectId} n'existe pas" +      detail_2_neptune_vehiclejourney_5: "timeSlotId = %{timeSlotId}" +      detail_2_neptune_vehiclejourney_6: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_vehiclejourney_7: "" +      detail_2_neptune_vehiclejourneyatstop_1: "stopPointId = %{stopPointId}" +      detail_2_neptune_vehiclejourneyatstop_2: "vehicleJourneyId = %{vehicleJourneyId}" +      detail_2_neptune_vehiclejourneyatstop_3: "routeId = %{routeId}" +      detail_2_neptune_vehiclejourneyatstop_4: "journeyPatternId = %{journeyPatternId}" +      detail_2_neptune_facility_1: "containedId = %{containedId}" +      detail_2_neptune_facility_2: "stopAreaId = %{stopAreaId}" +      detail_2_neptune_facility_3: "lineId = %{lineId}" +      detail_2_neptune_facility_4: "connectionLinkId = %{connectionLinkId}" +      detail_2_neptune_facility_5: "stopPointId = %{stopPointId}" +      detail_2_neptune_facility_6: "longLatType = %{longLatType}" +      #### level 3 +      detail_3_stoparea_1: "" +      detail_3_stoparea_2: "" +      detail_3_stoparea_3: "" +      detail_3_stoparea_4: "" +      detail_3_stoparea_5: "" +      detail_3_accesspoint_1: "" +      detail_3_accesspoint_2: "" +      detail_3_accesspoint_3: "" +      detail_3_connectionlink_1: "" +      detail_3_connectionlink_2: "" +      detail_3_connectionlink_3: "" +      detail_3_accesslink_1: "" +      detail_3_accesslink_2: "" +      detail_3_accesslink_3: "" +      detail_3_line_1: "" +      detail_3_line_2: "" +      detail_3_route_1: "" +      detail_3_route_2: "" +      detail_3_route_3: "Entre les arrêts de rang %{firstStopRank} (%{firstStop} et %{nextStopRank} (%{nextStop}, distance %{distance} %{orientation} %{distanceLimit} " +      detail_3_route_4: "" +      detail_3_route_5: "" +      detail_3_route_6: "" +      detail_3_route_7: "" +      detail_3_route_8: "%{count} arrêts non utilisés par des missions : %{names}" +      detail_3_route_9: "" +      detail_3_journeypattern_1: "Nombre d'arrêts = %{count}" +      detail_3_vehiclejourney_1: "Arrêt n° %{stopRank} (%{stopName}) : durée d'arrêt mesurée %{diffTime} > %{maxDiffTime}" +      detail_3_vehiclejourney_2: "" +      detail_3_vehiclejourney_3: "" +      detail_3_vehiclejourney_4: "" +      detail_3_vehiclejourney_5: "" +      detail_3_facility_1: "" +      detail_3_facility_2: "" +     +  activerecord: +    models: +      compliance_check_result:  +        zero:  "Validation" +        one:   "Validation" +        other: "Validations" +    attributes: +      compliance_check_result: +        1-NEPTUNE-XML-1: "Conformité à la syntaxe XML suivant les recommandations du W3C." +        1-NEPTUNE-XML-2: "Conformité au schéma défini par la XSD du profil TRIDENT/NEPTUNE." +        2-NEPTUNE-Common-1: "Unicité des éléments objectId des différents objets d'un lot de fichiers Neptune." +        2-NEPTUNE-Common-2: "Unicité des éléments regitrationNumber des différents objets d'un lot de fichiers Neptune." +        2-NEPTUNE-Network-1: "Correcte référence à des lignes <Line> dans version du réseau <PTNetwork>." +        2-NEPTUNE-GroupOfLine-1: "Correcte référence à des lignes <Line> dans groupe de lignes <GroupOfLine>." +        2-NEPTUNE-StopArea-1: "Correcte référence à des arrêts <StopArea> et/ou à des points d'arrêt sur parcours <StopPoint> dans les arrêts <StopArea>." +        2-NEPTUNE-StopArea-2: "Correcte référence à des arrêts <StopArea> dans les arrêts <StopArea> de type StopPlace." +        2-NEPTUNE-StopArea-3: "Correcte référence à des arrêts <StopArea> dans les arrêts <StopArea> de type CommercialStopPoint." +        2-NEPTUNE-StopArea-4: "Correcte référence à des points d'arrêt sur parcours <StopPoint> dans les arrêts <StopArea> de type BoardingPosition ou Quay." +        2-NEPTUNE-StopArea-5: "Correcte référence à une position géographique <AreaCentroid> dans les arrêts <StopArea> de tout type StopPlace, CommercialStopPoint, BoardingPosition et Quay." +        2-NEPTUNE-StopArea-6: "référenceréciproque d'une position géographique <AreaCentroid> dans les arrêts <StopArea> de tout type StopPlace, CommercialStopPoint, BoardingPosition et Quay." +        2-NEPTUNE-ITL-1: "Correcte référence à des arrêts <StopArea> dans les arrêts <StopArea> de type ITL." +        2-NEPTUNE-ITL-2: "Correcte référence à des arrêts <StopArea> de type ITL dans la classe d’objets <ITL>." +        2-NEPTUNE-ITL-3: "Correcte référence à des arrêts <StopArea> dans la classe d’objets <ITL>." +        2-NEPTUNE-ITL-4: "Vérification du type de référence à des arrêts <StopArea> type ITL dans la classe d’objets <ITL>." +        2-NEPTUNE-ITL-5: "Bonne référence à la ligne <Line> dans la classe d’objets <ITL>." +        2-NEPTUNE-AreaCentroid-1: "Correcte référence à des arrêts <StopArea> dans la classe d’objets <AreaCentroid>." +        2-NEPTUNE-AreaCentroid-2: "Vérification du modèle de projection de référence utilisé." +        2-NEPTUNE-ConnectionLink-1: "Correcte référence aux arrêts <StopArea> définissant des tronçons de correspondance <ConnectionLink>." +        2-NEPTUNE-AccessPoint-1: "Correcte référence à un arrêt <StopArea> dans les accès <AccessPoint>." +        2-NEPTUNE-AccessPoint-2: "Correcte référence à un arrêt <StopArea> dans les accès <AccessPoint>." +        2-NEPTUNE-AccessPoint-3: "Existence de liens d'accès <AccessLink> sur les accès <AccessPoint>." +        2-NEPTUNE-AccessPoint-4: "Existence de liens d'accès <AccessLink> sur les accès <AccessPoint> de type 'in'." +        2-NEPTUNE-AccessPoint-5: "Existence de liens d'accès <AccessLink> sur les accès <AccessPoint> sur les accès de type 'out'." +        2-NEPTUNE-AccessPoint-6: "Existence de liens d'accès <AccessLink> sur les accès <AccessPoint>  sur les accès de type 'inout'." +        2-NEPTUNE-AccessPoint-7: "Vérification du modèle de projection de référence utilisé." +        2-NEPTUNE-AccessLink-1: "Correcte référence aux arrêts <StopArea> et accès «AccessPoint> définissant des liens d'accès <AccessLink>." +        2-NEPTUNE-AccessLink-2: "Correcte référence aux arrêts <StopArea> et accès «AccessPoint> définissant des liens d'accès <AccessLink>." +        2-NEPTUNE-Line-1: "Correcte référence au réseau dans l'objet ligne <Line>." +        2-NEPTUNE-Line-2: "Correcte référence à un point d'arrêt sur parcours <StopPoint> comme terminus de ligne <Line>." +        2-NEPTUNE-Line-3: "Correcte référence à un point d'arrêt sur parcours <StopPoint> comme terminus de ligne <Line>." +        2-NEPTUNE-Line-4: "Correcte référence  aux séquences d'arrêts <ChouetteRoute> dans l'objet ligne <Line>." +        2-NEPTUNE-Line-5: "Correcte référence aux séquences d'arrêts <ChouetteRoute> dans l'objet ligne <Line>." +        2-NEPTUNE-Route-1: "Existence des missions <JourneyPattern> référencées par la séquence d'arrêt <ChouetteRoute>." +        2-NEPTUNE-Route-2: "Existence des tronçons commerciaux <PtLink> référencés par la séquence d'arrêt <ChouetteRoute>." +        2-NEPTUNE-Route-3: "Existence de la séquence opposée <ChouetteRoute> référencée par la séquence d'arrêt <ChouetteRoute>." +        2-NEPTUNE-Route-4: "Correcte référence à un tronçon commercial <PtLink> dans une séquence d'arrêts <ChouetteRoute>." +        2-NEPTUNE-Route-5: "Vérification que tous les points d'arrêts sur parcours sont rattachés à une séquence d'arrêts <ChouetteRoute> au départ d'un tronçon commercial <PtLink> et/ou à l'arrivée d'un autre tronçon commercial <PtLink> de la même séquence d'arrêts." +        2-NEPTUNE-Route-6: "Vérification du correct ordonnancement des points d'arrêts sur parcours <StopPoint> dans le chainage des tronçons <PtLink> d'une séquence d'arrêts <ChouetteRoute>." +        2-NEPTUNE-Route-7: "référence mutuelle des missions <JourneyPattern> et des séquences d'arrêts <ChouetteRoute>." +        2-NEPTUNE-Route-8: "Cohérence des références aux points d'arrêt des missions <JourneyPattern> et des séquences d'arrêts <ChouetteRoute>." +        2-NEPTUNE-Route-9: "Utilité des points d'arrêts sur parcours des séquences d'arrêts <ChouetteRoute>." +        2-NEPTUNE-Route-10: "référence d'une séquence d'arrêts <ChouetteRoute> à une séquence d'arrêts opposée." +        2-NEPTUNE-Route-11: "Cohérence des sens de la référence d'une séquence d'arrêts <ChouetteRoute> à une séquence d'arrêts opposée." +        2-NEPTUNE-Route-12: "Cohérence des terminus de la référence d'une séquence d'arrêts <ChouetteRoute> à une séquence d'arrêts opposée." +        2-NEPTUNE-PtLink-1: "Existence des  arrêts <StopPoint> référencés par les  tronçons commerciaux <PTLink>." +        2-NEPTUNE-JourneyPattern-1: "Existence de la séquence d'arrêt <ChouetteRoute> référencée par la mission <JourneyPattern>." +        2-NEPTUNE-JourneyPattern-2: "Existence des arrêts <StopPoint> référencés par la mission <JourneyPattern>." +        2-NEPTUNE-JourneyPattern-3: "Existence de la ligne <Line> référencée par la mission <JourneyPattern>." +        2-NEPTUNE-StopPoint-1: "Existence de la ligne <Line> référencée par l'arrêt <StopPoint>." +        2-NEPTUNE-StopPoint-2: "Existence du réseau <PTNetwork> référence par l'arrêt <StopPoint>." +        2-NEPTUNE-StopPoint-3: "Existence de l'arrêt   <StopArea> référencé par l'arrêt <StopPoint>." +        2-NEPTUNE-StopPoint-4: "Vérification du modèle de projection de référence utilisé." +        2-NEPTUNE-Timetable-1: "Utilité des calendriers." +        2-NEPTUNE-Timetable-2: "Utilité des calendriers." +        2-NEPTUNE-VehicleJourney-1: "Existence de la séquence d'arrêt <ChouetteRoute> référencée par la course <VehicleJourney>." +        2-NEPTUNE-VehicleJourney-2: "Existence de la mission <JourneyPattern> référencée par la course <VehicleJourney>." +        2-NEPTUNE-VehicleJourney-3: "Existence de la ligne <Line> référencée par la course <VehicleJourney>." +        2-NEPTUNE-VehicleJourney-4: "Existence de l'opérateur <Company> référencé par la course <VehicleJourney>." +        2-NEPTUNE-VehicleJourney-5: "Existence de la tranche horaire <TimeSlot> référencée par la course <VehicleJourney>." +        2-NEPTUNE-VehicleJourney-6: "Cohérence entre la course, la mission et la séquence d'arrêts." +        2-NEPTUNE-VehicleJourney-7: "Utilité des missions" +        2-NEPTUNE-VehicleJourneyAtStop-1: "Existence de l'arrêt <StopPoint> référencé par l'horaire <VehicleJourneyAtStop>." +        2-NEPTUNE-VehicleJourneyAtStop-2: "Existence de la course <VehicleJourney> référenceé par l'horaire <VehicleJourneyAtStop>." +        2-NEPTUNE-VehicleJourneyAtStop-3: "adéquation des horaires de la course à la séquence d'arrêts." +        2-NEPTUNE-VehicleJourneyAtStop-4: "adéquation des horaires de la course à la mission." +        2-NEPTUNE-Facility-1: "Existence de l'arrêt <StopArea> référencé par l'équipement <Facility>." +        2-NEPTUNE-Facility-2: "Existence de l'arrêt <StopArea> référencé par l'équipement <Facility>." +        2-NEPTUNE-Facility-3: "Existence de la ligne <Line> référencée par l'équipement <Facility>." +        2-NEPTUNE-Facility-4: "Existence de la correspondance <ConnectionLink> référencée par l'équipement <Facility>." +        2-NEPTUNE-Facility-5: "Existence de l'arrêt <StopPoint> référencé par l'équipement <Facility>." +        2-NEPTUNE-Facility-6: "Vérification du modèle de projection de référence utilisé." +        3-StopArea-1:	"Vérification de la géolocalisation de tous les arrêts hors ITL" +        3-StopArea-2: "Vérification que 2 arrêts de noms différents en dehors d'un même regroupement d'arrêts ne sont pas trop proches" +        3-StopArea-3:	"Vérification de l'unicité des arrêts" +        3-StopArea-4:	"Vérification de la géolocalisation des arrêts" +        3-StopArea-5:	"Vérification de la position relative des arrêts et de leur parent" +        3-AccessPoint-1: "Vérification de la géolocalisation de tous les accès" +        3-AccessPoint-2: "Vérification que deux accès de nom différents ne sont pas trop proches" +        3-AccessPoint-3: "Vérification de la proximité entre les accès et leur arrêt de rattachement" +        3-ConnectionLink-1:	"Vérification de la proximité entre les deux arrêts d'une correspondance" +        3-ConnectionLink-2:	"Vérification de la cohérence entre la distance fournie sur la correspondance et la distance géographique entre les deux arrêts de la correspondance" +        3-ConnectionLink-3:	"Vérification de la vitesse de parcours entre les deux arrêts d'une correspondance" +        3-AccessLink-1:	"Vérification de la proximité entre les deux extrémités d'un lien d'accès" +        3-AccessLink-2:	"Vérification de la cohérence entre la distance fournie sur le lien d'accès et la distance géographique entre les deux extrémités du lien d'accès" +        3-AccessLink-3:	"Vérification de la vitesse de parcours entre les deux extrémités d'un lien d'accès" +        3-Line-1:	"Vérification de la non homonymie des lignes" +        3-Route-1: "Vérification de la succession des arrêts de la séquence" +        3-Route-2: "Vérification de la séquence inverse" +        3-Route-3: "Vérification de la distance entre deux arrêts successifs de la séquence" +        3-Route-4: "Vérification de double définition de séquences" +        3-Route-5: "Vérification de séquences sans séquence opposée" +        3-JourneyPattern-1:	"Vérification de l'utilisation des arrêts par les missions" +        3-JourneyPattern-2:	"Vérification de l’existence d’une mission passant par tous les arrêts de la séquence" +        3-JourneyPattern-3:	"Vérification de double définition de missions"	 +        3-VehicleJourney-1:	"Vérification de la chronologie des horaires de passage à un arrêt" +        3-VehicleJourney-2:	"Vérification de la chronologie des horaires de passage entre deux arrêts" +        3-VehicleJourney-3:	"Vérification de la vitesse de transfert entre deux arrêts" +        3-VehicleJourney-4:	"Vérification de la cohérence des courses successives desservant deux mêmes arrêts" +        3-VehicleJourney-5:	"Vérification de l'affectation des courses à un calendrier" +        3-Facility-1:	"Vérification de la géolocalisation de tous les accès" +        3-Facility-2:	"Vérification de la proximité entre les équipements et leur arrêt de rattachement" +        severity: "Sévérité" +        status: "Statut" +        rule_level: "Niveau" +        rule_target: "Objet" +        rule_number: "Etape" +        rule_code: "Code" +        violation_count: "Violations" +        detail: "Détail" +         diff --git a/config/locales/compliance_check_tasks.yml b/config/locales/compliance_check_tasks.yml new file mode 100644 index 000000000..c9472136a --- /dev/null +++ b/config/locales/compliance_check_tasks.yml @@ -0,0 +1,143 @@ +en: +  compliance_check_tasks: +    index: +      title: "Validation" +      warning: "" +    edit: +      title: "Edit the Validation" +    show: +      title: "Neptune Validation" +      summary: "Rapport de conformité à la norme NEPTUNE" +      completed: "[ Completed ]" +      failed: "[ Failed ]" +      pending: "[ In the treatment queue ]" +      processing: "[ In progress... ]" +    new: +      title: "Create a new validation" +      submit: "Create a validation" +      all: "All" +    actions: +      new: "Add a validation" +      destroy_confirm: "Do you confirm to destroy this validation ?" +      destroy: "Destroy this validation" +      edit: "Edit this validation" +      rule_parameter_set: "Rule parameter set" +    statuses: +      pending: "Pending" +      completed: "Completed" +      failed: "Failed" +  file_validation_log_messages: +    messages: +      undefined: "%{key} undefined" +      TooMuchDetails: ( %{0} erreurs / warnings supplémentaires ) +      ONE: "Catégorie 1 : Syntaxe" +    severities: +      uncheck: "Unchecked" +      ok: "Ok" +      warning: "Warning" +      error: "Error" +      fatal: "Fatal" +    import_task: "Import Report" +    rule_parameter_set: "Rule Parameter Set" +  activerecord: +    models: +      file_validation: +        zero: "Validation" +        one: "Validation" +        other: "Validation" +    attributes: +      file_validation: +        created_at: "Executed at" +        references_type: "Associated Data Type" +        reference_ids: "Associated Data" +        rule_parameter_set_id: "Rule parameters set" +        resources: "File to validate" +        status: "Status" +        file_name: "Tested data" +        projection_reference: "Système de projection de référence" +      file_validation_log_message: +        created_at: "Date" +        position: "N." +        full_message: "Message" + +fr: +  compliance_check_tasks: +    index: +      title: "Validation" +      warning: "" +    edit: +      title: "Editer la validation" +    show: +      title: "Validation Neptune" +      summary: "Rapport de conformité à la norme NEPTUNE" +      details: "Détails" +      parameters: "Paramètres des tests" +      completed: "[ Terminé ]" +      failed: "[ Echoué ]" +      pending: "[ En file d'attente ]" +      processing: "[ En progression... ]" +    new: +      title: "Démarrer une nouvelle validation" +      submit: "Lancer la validation" +      all: "Toutes" +    actions: +      new: "Ajouter une validation" +      destroy_confirm: "Voulez-vous supprimer ce résultat de validation ?" +      destroy: "Supprimer cette validation" +      edit: "Editer cette validation" +      rule_parameter_set: "Jeu de paramètres" +    statuses: +      pending: "En cours" +      completed: "Achevé" +      failed: "Echoué" +    uncheck_count: +      zero: "aucun inapplicable" +      one: "un inapplicable" +      other: "%{count} inapplicables" +    ok_count: +      zero: "aucun test réussi" +      one: "un test réussi" +      other: "%{count} tests réussis" +    warning_count: +      zero: "aucun warning" +      one: "un warning" +      other: "%{count} warnings" +    error_count: +      zero: "aucune erreur" +      one: "une erreur" +      other: "%{count} erreurs" +    fatal_count: +      zero: "aucune erreur fatale" +      one: "une erreur fatale" +      other: "%{count} erreurs fatales" +    import_task: "Import" +    rule_parameter_set: "Jeu de paramètres" +  file_validation_log_messages: +    messages: +      undefined: "%{key} non défini" +      TooMuchDetails: "( %{0} erreurs / warnings supplémentaires )" +    severities: +      uncheck: "Non testé" +      ok: "Ok" +      warning: "Alerte" +      error: "Erreur" +      fatal: "Fatal" +  activerecord: +    models: +      compliance_check_task: +        zero:  "Validation" +        one:   "Validation" +        other: "Validations" +    attributes: +      compliance_check_task: +        created_at: "Exécuté le" +        references_type: "Type de données incluses" +        reference_ids: "Données incluses" +        rule_parameter_set_id: "Jeu de paramètres" +        resources: "Fichier à valider" +        status: "Status" +        file_name: "Jeu de données" +      compliance_check_task_log_message: +        created_at: "Date" +        position: "N." +        full_message: "Message" diff --git a/config/locales/file_validations.yml b/config/locales/file_validations.yml deleted file mode 100644 index c252796a6..000000000 --- a/config/locales/file_validations.yml +++ /dev/null @@ -1,595 +0,0 @@ -en: -  file_validations: -    index: -      title: "Neptune Validation" -      warning: "" -    edit: -      title: "Edit the Validation" -    show: -      title: "Neptune Validation" -      summary: "Rapport de conformité à la norme NEPTUNE" -    new: -      title: "Create a new validation" -      submit: "Create a validation" -    actions: -      new: "Add a validation" -      destroy_confirm: "Do you confirm to destroy this validation ?" -      destroy: "Destroy this validation" -      edit: "Edit this validation" -    statuses: -      pending: "Pending" -      completed: "Completed" -      failed: "Failed" -  file_validation_log_messages: -    messages: -      undefined: "%{key} undefined" -      TooMuchDetails: ( %{0} erreurs / warnings supplémentaires ) -      ONE: "Catégorie 1 : Syntaxe" -      Test1_Sheet1: 'Fiche n° 1.1 : Conformité à la syntaxe XML suivant les recommandations du W3C' -      Test1_Sheet1_Step1: "Conformité à la syntaxe XML" -      Test1_Sheet1_Step2: "Conformité au schéma XML du profil NEPTUNE" -      Test1_Sheet1_Step0_fatal: "Erreur fatale : Impossible d'ouvrir le fichier %{0}" -      Test1_Sheet1_Step0_error: "Impossible d'importer cette entrée %{0} du zip" -      Test1_Sheet1_Step0_warning: "Cette entrée %{0} du zip n'est pas un fichier xml et a été ignoré" -      Test1_Sheet1_Step1_error: "le fichier %{0} n'est pas correctement formé selon les recommandations du W3C" -      Test1_Sheet1_Step2_error: "le fichier %{0} ne respecte pas le modèle NEPTUNE" -      Test1_Sheet1_Step2_encoding: "le fichier %{0} ne respecte pas le codage de caractères du modèle NEPTUNE (ISO-8859-1)" -      Test1_Sheet1_Step2_fatal: "Erreur fatale : Aucune entrée valide trouvée dans le fichier" -      Test1_Sheet2: 'Fiche n° 1.2 : Conformité au schéma XML du profil NEPTUNE' -      Test1_Sheet2_Step1: Conformité au schéma XML du profil NEPTUNE -      Test1_Sheet2_Step1_error: "le fichier %{0} ne respecte pas le modèle NEPTUNE" -      Test1_Sheet2_Step1_encoding: "le fichier %{0} ne respecte pas le codage de caractères du modèle NEPTUNE (ISO-8859-1)" -      Test1_Sheet2_Step1_fatal: "Erreur fatale : Aucune entrée valide trouvée dans le fichier" -      TWO: "Catégorie 2 : Complétude, cohérence et intégrité des données" -      Test2_Sheet1: "Fiche n° 2.1 : Cohérence entre le réseau et ses composants" -      Test2_Sheet1_fatal: "La ligne %{0} n'a pas de réseau" -      Test2_Sheet1_Step1: "Correcte réference à des LIGNEs/Chouette(<Line>)" -      Test2_Sheet1_Step1_error: "La ligne %{1} n'est pas dans la liste des identifiants de ligne de %{0}" -      Test2_Sheet1_Step2: "Correcte référence  à la  VERSION DU RÉSEAU(< PTNetwork >) dans LIGNEs/Chouette (< Line >)" -      Test2_Sheet1_Step2a_error: "Le réseau %{0} n'est pas celui lié à la ligne %{1} dont le raccourci est %{2}." -      Test2_Sheet1_Step2b_error: "Le raccourci du réseau %{0} dans la ligne %{1} ne correspond à aucun réseau de la ligne" -      Test2_Sheet2: "Fiche n° 2.2 : Cohérence entre le regroupement de lignes et ses composants" -      Test2_Sheet2_Step1: "Correcte référence  à des LIGNEs/Chouette ( < Line >) dans GROUPE DE LIGNES ( < GroupOfLine >)" -      Test2_Sheet2_Step1_error: "la valeur de l'élément < lineId > : %{0} de la classe d'objets < GroupOfLine > n'a pas été repérée dans l'élément < objectId > de la classe d'objets < Line >" -      Test2_Sheet3: "Fiche n° 2.3 : Cohérence entre les arrêts et leurs composants" -      Test2_Sheet3_Step1: "Correcte référence  à  des ARRÊTs/Chouette ( < StopArea >)  et/ou à des POINTs D''ARRÊT SUR PARCOURS ( < StopPoint >) dans les ARRÊTs/Chouette ( < StopArea >)  " -      Test2_Sheet3_Step1_unchecked: "non implémenté" -      Test2_Sheet3_Step1_error: "une ou plusieurs valeurs de l'élément < contains > de l'objet < StopArea > %{0} n'est pas repérée dans la classe d'objets correspondant < StopPoint > ou < StopArea >. >" -      Test2_Sheet4: "Fiche n° 2.4 : Définition des correspondances" -      Test2_Sheet4_Step1: "Correcte référence aux ARRÊTs/Chouette ( < StopArea >) définissant des TronçonsDeCorrespondance/Chouette  ( < ConnectionLink >)" -      Test2_Sheet4_Step1_unchecked: "non implémenté" -      Test2_Sheet4_Step1_error: "L'objet < ConnectionLink > %{0} a des < StartOfLink >  %{1} et < EndOfLink >  %{2} qui pointent vers le même < StopArea >" -      Test2_Sheet4_Step1_error_a: "a : il manque au moins un identifiant d'arrêt < StartOfLink > et < EndOfLink > dans  l'objet < ConnectionLink > %{0}" -      Test2_Sheet4_Step1_error_b: "b : un identifiant d'arrêt < StartOfLink > ou < EndOfLink > de l'objet < ConnectionLink> %{0} n'est pas repéré dans un objet < StopArea >" -      Test2_Sheet5: "Fiche n° 2.5 : Cohérence entre les courses et les horaires" -      Test2_Sheet5_Step1: "Correcte référence aux COURSES COMMERCIALES ( < VehicleJourney > ) dans les VERSIONs DES HORAIRES/Chouette ( < Timetable >)" -      Test2_Sheet5_Step1_error: "un identifiant de course, situé dans l'objet < Timetable >, n'est pas référencé dans un objet < VehicleJourney >" -      Test2_Sheet5_Step2: "Chaque COURSE COMMERCIALE ( < VehicleJourney > ) est référencée dans une VERSION DES HORAIRES/Chouette  ( < Timetable >)" -      Test2_Sheet5_Step2_error: "une course n'est pas référencée dans aucun < TimeTable >" -      Test2_Sheet6: "Fiche n° 2.6 : Définition des terminus" -      Test2_Sheet6_Step1: "Correcte définition du terminus de LIGNE/Chouette  < Line >" -      Test2_Sheet6_Step1_unchecked: "non implémenté" -      Test2_Sheet6_Step1_error: "un identifiant de point d'arrêt de fin de trajet n'est pas repéré dans un objet < StopPoint>" -      Test2_Sheet6_Step2: "Caractère terminus des points de fin de trajet des LIGNEs/Chouette  < Line >" -      Test2_Sheet6_Step2_error: "un identifiant de point d'arrêt de fin de trajet n'est pas repéré comme début ou comme fin d'un trajet" -      Test2_Sheet7: "Fiche n° 2.7 : Cohérence entre les Itinéraires/Chouette et les LIGNEs/Chouette" -      Test2_Sheet7_Step1: "Correcte référence aux Itinéraires/Chouette ( < ChouetteRoute >) pour chaque LIGNE/Chouette ( < Line >)" -      Test2_Sheet7_Step1_unchecked: "non implémenté" -      Test2_Sheet7_Step1_error: "un identifiant d'Itinéraire < RouteId > situé dans l'objet < Line > n'est pas identifié dans l'objet < ChouetteRoute >" -      Test2_Sheet8: "Fiche n° 2.8 : Cohérence entre les missions commerciales et les itinéraires" -      Test2_Sheet8_Step1: "Correcte référence des MISSIONs COMMERCIALEs ( < JourneyPattern >)  par les Itinéraires/Chouette ( < ChouetteRoute >)" -      Test2_Sheet8_Step1_error: "un élément < journeyPatternId > dans un objet d'Itinéraire < ChouetteRoute > n'a pas d'identifiant < ObjectId > dans un objet < JourneyPattern>" -      Test2_Sheet8_Step2: "Correcte référence des Itinéraires/Chouette ( < ChouetteRoute >) que référencent les MISSIONs COMMERCIALEs ( < JourneyPattern >)" -      Test2_Sheet8_Step2_error: "l'élément d'Itinéraire < routeId >, référencé dans un objet < JourneyPattern >, n'a pas d'identifiant < objectId > dans l'objet d'Itinéraire < ChouetteRoute >" -      Test2_Sheet8_Step3: "Cohérence de la séquence des POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint >)  d'une mission commerciale et celle de l'Itinéraire/Chouette ( < ChouetteRoute >) correspondant" -      Test2_Sheet8_Step3_a_error: "a : l'identifiant du < %{0} > détecté dans l'objet < StopPoint > ne figure pas dans la liste des points d'arrêt de l'objet < JourneyPattern >" -      Test2_Sheet8_Step3_b_error: "b : l'identifiant du  %{0} < StopPoint >  ne figure pas dans l'un des éléments < startOfLink > ou < endOfLink > du tronçon < PtLink >" -      Test2_Sheet8_Step3_c_error: "c : l'identifiant du tronçon < PtLink > : %{0} , détecté dans le test b, n'est pas intégré dans un Itinéraire < ChouetteRoute >" -      Test2_Sheet8_Step3_d_error: "d : les <PTLinks> de l'Itinéraire < ChouetteRoute > : %{0} ne sont pas cohérents avec les <StopPoints> du < JourneyPattern > %{1}" -      Test2_Sheet9: "Fiche n° 2.9 : Définition de l'itinéraire retour" -      Test2_Sheet9_Step1: "Correcte référence  à un Itinéraire/Chouette ( < ChouetteRoute >) dans le cas d'un Itinéraire de retour" -      Test2_Sheet9_Step1_error: "un élément d'Itinéraire de retour < wayBackRouteId > dans un objet d'Itinéraire < ChouetteRoute > n'a pas d'identifiant < ObjectId > dans un autre objet d'Itinéraire <  ChouetteRoute >" -      Test2_Sheet10: "Fiche n° 2.10 : Référence à une ligne pour un point d'arrêt" -      Test2_Sheet10_Step1: "Correcte référence à une LIGNE/Chouette ( < Line >) pour les POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint > )" -      Test2_Sheet10_Step1_error: "Le point d'arrêt  (< StopPoint >)  fait référence à une ligne inexistante>" -      Test2_Sheet11: "Fiche n° 2.11 : Référence à un réseau au point d'arrêt" -      Test2_Sheet11_Step1: "Correcte référence à la VERSION DU RÉSEAU   ( < PTNetwork >) pour  chaque POINT D'ARRÊT SUR PARCOURS  \n( < StopPoint >)" -      Test2_Sheet11_Step1_error: "Le point d'arrêt  (< StopPoint >)  fait référence à un réseau inexistant>" -      Test2_Sheet12: "Fiche n° 2.12 : Définition de  l''Interdiction de Trafic Local" -      Test2_Sheet12_Step1: "Cohérence entre les objets  <  ITL >  et les ARRÊTs/Chouette ( < StopArea >)" -      Test2_Sheet12_Step1_error: "Un objet d'interdiction de trafic local  < ITL > %{0} fait référence à un arrêt du réseau < StopArea > %{1} inexistant" -      Test2_Sheet13: "Fiche n° 2.13 : Référence à une ligne des arrêts ITL" -      Test2_Sheet13_Step1: "Correcte référence à la LIGNE/Chouette ( < Line >) pour chaque  < ITL >" -      Test2_Sheet13_Step1_error: "Un objet d'interdiction de trafic local  < ITL >  fait référence à une ligne inexistante" -      Test2_Sheet14: "Fiche n° 2.14 : Association points d'arrêt, tronçons, itinéraire" -      Test2_Sheet14_Step1: "Tout POINT D'ARRÊT SUR PARCOURS  ( < StopPoint >) est associé à un Itinéraire/Chouette (ChouetteRoute >)" -      Test2_Sheet14_Step1a_error: "a : le point d'arrêt  (< StopPoint >)  %{0} n'appartient à aucune extrémité de tronçon" -      Test2_Sheet14_Step1b_error: "b : le tronçon %{0} fait référence à un itinéraire inexistant" -      Test2_Sheet14_Step2: "Continuité des tronçons COMMERCIAUX/Chouette ( < PtLink >) au sein d'un Itinéraire/Chouette ( < ChouetteRoute >)" -      Test2_Sheet14_Step2_error: "l'analyse des tronçons d'un itinéraire fait apparaître que la valeur de l'attribut de l'élément < endOfLink > d'un premier tronçon < PtLink > n'est pas identique à la valeur de l'attribut de l'élément < startOfLink > du deuxième tronçon < PtLink >" -      Test2_Sheet15: "Fiche n° 2.15 : Cohérence entre points d'arrêt et missions commerciales" -      Test2_Sheet15_Step1: "Existence de définition des POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint >)  d'une mission commerciale  ( < JourneyPattern >)" -      Test2_Sheet15_Step1_error: "La liste de l'objet < JourneyPattern > %{0} fait référence à des points d'arrêt  inexistants" -      Test2_Sheet15_Step2: "Tout POINT D'ARRÊT SUR PARCOURS  ( < StopPoint >)  appartient à une mission commerciale  ( < JourneyPattern >)" -      Test2_Sheet15_Step2_error: "un point d'arrêt  (< StopPoint >)  n'est pas rattaché à une mission commerciale" -      Test2_Sheet16: "Fiche n° 2.16 : Référence à une ligne des  missions commerciales" -      Test2_Sheet16_Step1: "Correcte référence à une une LIGNE/Chouette ( < Ligne >)  pour une MISSION COMMERCIALE  ( < JourneyPattern >)" -      Test2_Sheet16_Step1_error: "Un objet < JourneyPattern > fait référence à une ligne inexistante" -      Test2_Sheet17: "Fiche n° 2.17 : Cohérence entre itinéraires et courses" -      Test2_Sheet17_Step1: "Correcte référence à l'Itinéraire/Chouette ( < ChouetteRoute) pour chaque COURSE COMMERCIALE  ( < VehicleJourney > )" -      Test2_Sheet17_Step1_error: "la course  %{0} fait référence à un itinéraire inexistant %{1}" -      Test2_Sheet18: "Fiche n° 2.18 : Cohérence entre les  missions commerciales et les courses" -      Test2_Sheet18_Step1: "Existence d'une MISSION COMMERCIALE ( < JourneyPattern  < ) pour chaque COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet18_Step1_error: "la course %{0} fait référence à une mission commerciale inexistante" -      Test2_Sheet18_Step2: "Cohérence de points entre MISSION COMMERCIALE ( < JourneyPattern  < ) et COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet18_Step2_error_a: "a : l'identifiant (< StopPoint >)  détecté dans un objet < StopPoint >  ne figure pas dans la liste des points d'arrêts < stopPointList > de < JourneyPattern >" -      Test2_Sheet18_Step2_error_b: "b : l'identifiant (< StopPoint >)  ne figure pas dans l'élément < stopPointId > d'un objet  < vehicleJourneyAtStop >" -      Test2_Sheet19: "Fiche n° 2.19 : Référence à une ligne pour chaque course" -      Test2_Sheet19_Step1: "Référence à une LIGNE/Chouette ( < Line >)  pour une COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet19_Step1_error: "le raccourci de ligne d'une course %{0} fait référence à une ligne inexistante" -      Test2_Sheet20: "Fiche n° 2.20 : Vérification des identifiants d''exploitants que référencent les courses" -      Test2_Sheet20_Step1: "Correcte référence à l'EXPLOITANT/Chouette ( < Company >) dans une COURSE COMMERCIALE ( < VehicleJourney > )" -      Test2_Sheet20_Step1_error: "la course %{0} fait référence à un exploitant inexistant" -      Test2_Sheet21: "Fiche n° 2.21 : Référence à une tranche horaire  pour  les courses" -      Test2_Sheet21_Step1: "Correcte référence des COURSEs COMMERCIALEs ( < VehicleJourney > ) à des TRANCHEs HORAIREs ( < TimeSlot >)" -      Test2_Sheet21_Step1_error: "la course %{0} fait référence à une tranche horaire inexistante" -      Test2_Sheet22: "Fiche n° 2.22 : Cohérence entre les points d'arrêts et les heures de passage" -      Test2_Sheet22_Step1: "Correcte référence à un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) pour les HEUREs DE PASSAGE GRAPHIQUées/Chouette ( < VehicleJourneyAtStop >)" -      Test2_Sheet22_Step1_error: "une heure de passage %{0} fait référence à un point d'arrêt  (< StopPoint >)  inexistant" -      Test2_Sheet23: "Fiche n° 2.23 : Cohérence entre les courses et  des heures de passage" -      Test2_Sheet23_Step1: "Correcte référence à une COURSE COMMERCIALE \n( < VehicleJourney >) dans HEURE DE PASSAGE GRAPHIQUEE/Chouette ( < VehicleJourneyAtStop >)" -      Test2_Sheet23_Step1_error: "une heure de passage %{0} fait référence à une course inexistante" -      Test2_Sheet24: "Fiche n° 2.24 : Cohérence entre la mission commerciale de la course et l''itinéraire de la course" -      Test2_Sheet24_Step1: "Cohérence de la référence un Itinéraire/Chouette pour une COURSE COMMERCIALE ( < VehicleJourney >) et la MISSION COMMERCIALE ( < JourneyPattern >) correspondante" -      Test2_Sheet24_Step1_error: "un objet < vehicleJourney > possède une valeur de l'attribut de l'élément < RouteId >. Cette valeur ne se retrouve dans un élément < RouteId > d'un objet < JourneyPattern > " -      Test2_Sheet25: "Fiche n° 2.25 : Définition des liens d'accès" -      Test2_Sheet25_Step1: "Correcte référence aux ARRÊTs/Chouette ( < StopArea >) et ACCES/NEPTUNE ( <AccessPoint >) définissant des LiensAccèsZoneArrêt/NEPTUNE  ( < AccessLink >)" -      Test2_Sheet25_Step1_error_a: "a : les objets < StartOfLink > et < EndOfLink > de  l'objet < AccessLink > sont identiques" -      Test2_Sheet25_Step1_error_b: "b : un identifiant d'arrêt ou d'accès < StartOfLink > ou < EndOfLink > de l'objet < AccessLink> n'est pas repéré dans un objet < StopArea > ou < AccessPoint >" -      Test2_Sheet26: "Fiche n° 2.26 : Cohérence entre les accès et leurs composants" -      Test2_Sheet26_Step1: "Correcte référence à des ARRÊTs/Chouette ( < StopArea >) et/ou à des LiensAccèsZoneArrêt/NEPTUNE  ( < AccessLink >) dans les ACCES/NEPTUNE ( < AccessPoint >)  " -      Test2_Sheet26_Step1_error: "une ou plusieurs valeurs de l'élément < containedIn> de la classe d'objets < AccessPoint> n'est pas repérée dans la classe d'objets correspondante < StopArea > ou < AccessLink >" -      Test2_Sheet27: "Fiche n° 2.27 : Référence aux arrêts dans les équipements" -      Test2_Sheet27_Step1: "Correcte référence à des ARRÊTs/Chouette ( < StopArea >) dans les EQUIPEMENTs /NEPTUNE  ( <Facility>)" -      Test2_Sheet27_Step1_error: "une valeur de l'élément < containedIn> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondante < StopArea >" -      Test2_Sheet28: "Fiche n° 2.28 : Référencement correct des composants dans les équipements" -      Test2_Sheet28_Step1: "Correcte référence à un ARRÊT/Chouette ( < StopArea >) ou  à une LIGNE/Chouette ( < Line >)  ou à un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) ou à un TronçonsDeCorrespondance/Chouette  ( < ConnectionLink >) dans les FACILITYs /NEPTUNE  ( <Facility>)" -      Test2_Sheet28_Step1_error: "une valeur de l'élément < stopAreaId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < StopArea >" -      Test2_Sheet28_Step2_error: "une valeur de l'élément < lineId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < Line>" -      Test2_Sheet28_Step3_error: "une valeur de l'élément < connectionLinkId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < ConnectionLink >" -      Test2_Sheet28_Step4_error: "une valeur de l'élément < stopPointId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < StopPoint >" -      THREE: "Catégorie 3 : Contenu" -      Test3_Sheet1: "Fiche n° 3.1 : Points d'arrêt de dénomination différente et très proches" -      Test3_Sheet1_Step1: "2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) très proches porte le même nom/même adresse" -      Test3_Sheet1_Step1_warning: "deux points d'arrêt séparés par une distance  %{3} inférieure à une valeur paramétrable %{0} ne portent pas le même nom , premier : %{1} , deuxième : %{2} " -      Test3_Sheet2: "Fiche n° 3.2 : Points d'arrêt très proches regroupés au sein d'une zone d'arrêt" -      Test3_Sheet2_Step1: "2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) très proches appartiennent à un même ARRÊT1/Chouette ( < StopArea >)" -      Test3_Sheet2_Step1_warning: "la distance calculée %{0} entre un point d'arrêt et les autres points d'arrêt est inférieure à une valeur paramétrable %{1} mais la valeur de l'attribut de l'élément < containedIn > de ces deux points d'arrêt < StopPoint > n'est pas identique, premier : %{2} , deuxième : %{3}"  -      Test3_Sheet3: "Fiche n° 3.3 : Unicité des noms de points d'arrêt " -      Test3_Sheet3_Step1: "Différentiation de nom pour les POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet3_Step1_warning: "deux points d'arrêt < StopPoint > : %{0} et %{1} de même nom ne sont pas suffisamment renseignés pour avoir des propriétés uniques" -      Test3_Sheet4: "Fiche n° 3.4 :  Unicité des noms de ligne" -      Test3_Sheet4_Step1: "Chaque LINE/Chouette ( < Line >) possède des valeurs d'attributs uniques" -      Test3_Sheet4_Step1_error: "les éléments < name > et < number > d'une ligne ne constituent pas un identifiant unique pour la ligne < Line > référencée par l'élément < %{0} >" -      Test3_Sheet5: "Fiche n° 3.5 : Modèle de représentation des coordonnées des points d'arrêt" -      Test3_Sheet5_Step1: "Coordonnées géographiques de chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) par rapport à un modèle de projection de référence" -      Test3_Sheet5_Step1_warning: "le point d'arrêt d'identifiant < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulle ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet6: "Fiche n° 3.6 : Localisation des points d'arrêt à l'intérieur d'un périmètre défini" -      Test3_Sheet6_Step1: "Les coordonnées de chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet6_Step1_warning_a: "a : le point d'arrêt d'identifiant < %{0} > n'est pas dans le bon système de projection " -      Test3_Sheet6_Step1_error_b: "b :  le point d'arrêt d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte" -      Test3_Sheet7: "Fiche n° 3.7 : Caractérisation des distances entre les points d'arrêt" -      Test3_Sheet7_Step1: "La distance entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs" -      Test3_Sheet7_Step1_warning: "la distance spatiale entre deux points d'arrêt consécutifs ne se situe pas dans une fourchette autorisée (entre %{0} pour sa valeur minimale et %{1} pour sa valeur supérieure" -      Test3_Sheet8: "Fiche n° 3.8 : Cohérence entre le temps et la distance pour chaque correspondance" -      Test3_Sheet8_Step1: " Les vitesses calculées à partir des attributs du TronçonDeCorrespondance/Chouette ( < ConnectionLink >) suivant les paramètres fixés" -      Test3_Sheet8_Step1_error_a: "a : la vitesse fixée par l'élément < DefaultDuration > n'est pas conforme à la valeur paramétrable : Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_b: "b : la vitesse fixée par l'élément < FrequentTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_c: "c : la vitesse fixée par l'élément < OccasionalTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_d: "d : la vitesse fixée par l'élément < MobilityRestrictedTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet9: "Fiche n° 3.9 : Cohérence entre le temps et la distance pour chaque tronçon" -      Test3_Sheet9_Step1: "La vitesse entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs se situe dans une fourchette autorisée" -      Test3_Sheet9_Step1_warning: "la vitesse déterminée par la distance et le temps entre 2 points d'arrêt consécutifs (entre deux objets < %{0} > et < %{1} > ) ne se situe pas une fourchette autorisée entre %{2} et %{3}" -      Test3_Sheet10: "Fiche n° 3.10 : Détection des boucles" -      Test3_Sheet10_Step1: "Utilisation unique dans un Itinéraire/Chouette ( < ChouetteRoute >) d'un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet10_Step1_error_a: "a : le point d'arrêt d'identifiant < %{0} > est défini de manière unique et ne retrouve pas dans au moins deux tronçons" -      Test3_Sheet10_Step1_error_b: "b : les identifiants de tronçon identifiés dans le 3.10.1 a ne sont pas présents dans un même itinéraire" -      Test3_Sheet10_Step2: "Boucle dans un itinéraire/Chouette" -      Test3_Sheet10_Step2_warning: "des tronçons < PtLink > utilisent des points d'arrêt < StopPoint > ayant la même valeur d'attribut que l'élément <  containedIn  > pour la route %{0} " -      Test3_Sheet10_Step3: "La distance entre points d'arrêt d'un même itinéraire/Chouette" -      Test3_Sheet10_Step3_warning: "des points d'arrêt < StopPoint > utilisés par des tronçons d'itinéraire, sont proches les uns des autres d'une distance %{0} inférieure à une valeur paramétrable %{1} " -      Test3_Sheet11: "Fiche n° 3.11 : Détection des retours en arrière" -      Test3_Sheet11_Step1: "Utilisation répétitive de POINTs D'ARRÊT SUR PARCOURS  d'un Itinéraire/Chouette ( < ChouetteRoute >)" -      Test3_Sheet11_Step1_warning: "les tronçons < PtLink > d'un itinéraire utilisent des points d'arrêt < StopPoint > identiques plus de deux fois" -      Test3_Sheet12: "Fiche n° 3.12 : Connexité du graphe des lignes et des points d'arrêt" -      Test3_Sheet12_Step1: "Construction d'un graphe à partir de chaque POINTs D'ARRÊT SUR PARCOURS" -      Test3_Sheet15: "Fiche n° 3.15 : Cohérence des horaires" -      Test3_Sheet15_Step1: "Cohérence des HEUREs DE PASSAGE GRAPHIQUEEs/Chouette ( < VehicleJourneyAtStop >)  d'une COURSE ( < VehicleJourney >) pour chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet15_Step1_error: "la différence absolue entre la valeur de l'attribut de l'élément < arrivalTime > et la valeur de l'attribut de l'élément < departureTime > est supérieure à une valeur paramétrable %{0}" -      Test3_Sheet16: "Fiche n° 3.16 : Cohérence des courses" -      Test3_Sheet16_Step1: "Cohérence horaire pour 2 COURSEs ( < VehicleJourney >) utilisant le même couple de POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet16_Step1_error: "pour deux courses qui utilisent le même couple de points  A -> B, les temps de parcours : %{2} entre le point A : %{0} et le point B : %{1} ne sont pas  cohérents" -      Test3_Sheet16_Step2: "La VERSION DES HORAIREs/Chouette ( < Timetable >) contient des COURSEs ( < VehicleJourney >)" -      Test3_Sheet16_Step2_warning: "La course < vehicleJourney > dont l'identifiant est < %{0} > n'est pas référencée dans l'objet < TimeTable >" -      Test3_Sheet16_Step3: "Cohérence des HEUREs DE PASSAGE GRAPHIQUEEs/Chouette ( < VehicleJourneyAtStop >) entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs dans une COURSE ( < VehicleJourney >)" -      Test3_Sheet16_Step3_error_a: "a :  entre deux éléments < vehicleJourneyAtStop > successifs, la différence absolue entre la valeur de l'attribut de l'élément < departureTime > du premier point d'arrêt et la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt : %{0} est supérieure à une valeur paramétrable %{1} " -      Test3_Sheet16_Step3_error_b: "b : entre deux éléments < vehicleJourneyAtStop > successifs, la valeur de l'attribut de l'élément < departureTime > du premier point d'arrêt est inférieure à la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt ou la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt  : %{0} est supérieure à une valeur paramétrable %{1}" -      Test3_Sheet17: "Fiche n° 3.17 : Modèle de représentation des coordonnées des points d'accès" -      Test3_Sheet17_Step1: " Les coordonnées géographiques de chaque POINT D'ACCES ( < AccessPoint >) par rapport à un modèle de projection de référence" -      Test3_Sheet17_Step1_warning: "le point d'accès d'identifiant < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulles ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet18: "Fiche n° 3.18 : Localisation des points d'accès à l'intérieur d'un périmètre défini" -      Test3_Sheet18_Step1: " Les coordonnées de chaque POINT D'ACCES ( < AccessPoint >) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet18_Step1_warning_a: "a : le point d'accès d'identifiant < %{0} > n'est pas dans le bon système de projection" -      Test3_Sheet18_Step1_error_b: "b :  le point d'accès d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte" -      Test3_Sheet19: "Fiche n° 3.19 : Modèle de représentation des coordonnées des équipements" -      Test3_Sheet19_Step1: " Test des coordonnées géographiques de chaque EQUIPEMENT ( < Facility >) par rapport à un modèle de projection de référence" -      Test3_Sheet19_Step1_warning: "l'equipement < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulle ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet20: "Fiche n° 3.20 : Localisation des équipements à l'intérieur d'un périmètre défini" -      Test3_Sheet20_Step1: " Les coordonnées de chaque EQUIPEMENT ( < Facility>) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet20_Step1_warning_a: "a : l'equipement d'identifiant < %{0} > n'est pas dans le bon système de projection " -      Test3_Sheet20_Step1_error_b: "b :  l'equipement d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte " -      Test3_Sheet21: "Fiche n° 3.21 : Cohérence entre le temps et la distance pour chaque lien accès-zone d'arrêt" -      Test3_Sheet21_Step1: " Les vitesses calculées à partir des attributs du LiensAccèsZoneArrêt /NEPTUNE ( < AccessLink >) suivant les paramètres fixés" -      Test3_Sheet21_Step1_error_a: "a : la vitesse fixée par l'élément < DefaultDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_b: "b : la vitesse fixée par l'élément < FrequentTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_c: "c : la vitesse fixée par l'élément < OccasionalTravellerDuration > n'est pas conforme à la valeur paramétrable %{Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_d: "d : la vitesse fixée par l'élément < MobilityRestrictedTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -    severities: -      uncheck: "Unchecked" -      ok: "Ok" -      warning: "Warning" -      error: "Error" -      fatal: "Fatal" -  activerecord: -    models: -      file_validation:  -        zero: "Neptune Validation" -        one: "Neptune Validation" -        other: "Neptune Validation" -    attributes: -      file_validation: -        resources: "File to validate" -        status: "Status" -        file_name: "Tested data" -        test3_1_minimal_distance: "Distance minimale (test 3.1)" -        test3_2_minimal_distance: "Distance minimale (test 3.2)" -        test3_2_polygon_points: "Polygone (long lat) (test 3.6)" -        test3_7_minimal_distance: "Distance minimale / maximale (test 3.7)" -        test3_7_maximal_distance: " / " -        test3_8a_minimal_speed: "Vitesse minimale / maximale (test 3.8a)" -        test3_8a_maximal_speed: " / " -        test3_8b_minimal_speed: "Vitesse minimale / maximale (test 3.8b)" -        test3_8b_maximal_speed: " / " -        test3_8c_minimal_speed: "Vitesse minimale / maximale (test 3.8c)" -        test3_8c_maximal_speed: " / " -        test3_8d_minimal_speed: "Vitesse minimale / maximale (test 3.8d)" -        test3_8d_maximal_speed: " / " -        test3_9_minimal_speed: "Vitesse minimale / maximale (test 3.9)" -        test3_9_maximal_speed: " / " -        test3_10_minimal_distance: "Distance minimale (test 3.10)" -        test3_15_minimal_time: "Temps minimal (test 3.15)" -        test3_16_1_maximal_time: "Ecart maximal de durée entre deux desserte d'un même tronçon (test 3.16.1)" -        test3_16_3a_maximal_time: "Durée maximale du parcours entre 2 arrêts successifs (test 3.16.3a)" -        test3_16_3b_maximal_time: "Heure maximale de départ au premier arrêt après minuit sur une course franchissant minuit (test 3.16.3b)" -        test3_21a_minimal_speed: "Vitesse minimale / maximale (test 3.21a)" -        test3_21a_maximal_speed: " / " -        test3_21b_minimal_speed: "Vitesse minimale / maximale (test 3.21b)" -        test3_21b_maximal_speed: " / " -        test3_21c_minimal_speed: "Vitesse minimale / maximale (test 3.21c)" -        test3_21c_maximal_speed: " / " -        test3_21d_minimal_speed: "Vitesse minimale / maximale (test 3.21d)" -        test3_21d_maximal_speed: " / " -        projection_reference: "Système de projection de référence" -      file_validation_log_message: -        created_at: "Date" -        position: "N." -        full_message: "Message" - -fr: -  file_validations: -    index: -      title: "Validation Neptune" -      warning: "" -    edit: -      title: "Editer la validation" -    show: -      title: "Validation Neptune" -      summary: "Rapport de conformité à la norme NEPTUNE" -      details: "Détails" -      parameters: "Paramètres des tests" -    new: -      title: "Démarrer une nouvelle validation" -      submit: "Lancer la validation" -    actions: -      new: "Ajouter une validation" -      destroy_confirm: "Voulez-vous supprimer ce résultat de validation ?" -      destroy: "Supprimer cette validation" -      edit: "Editer cette validation" -    statuses: -      pending: "En cours" -      completed: "Achevé" -      failed: "Echoué" -    uncheck_count:  -      zero: "aucun inapplicable" -      one: "un inapplicable" -      other: "%{count} inapplicables" -    ok_count:  -      zero: "aucun test réussi" -      one: "un test réussi" -      other: "%{count} tests réussis" -    warning_count:  -      zero: "aucun warning" -      one: "un warning" -      other: "%{count} warnings" -    error_count:  -      zero: "aucune erreur" -      one: "une erreur" -      other: "%{count} erreurs" -    fatal_count:  -      zero: "aucune erreur fatale" -      one: "une erreur fatale" -      other: "%{count} erreurs fatales" -  file_validation_log_messages: -    messages: -      undefined: "%{key} non défini" -      TooMuchDetails: "( %{0} erreurs / warnings supplémentaires )" -      ONE: "Catégorie 1 : Syntaxe" -      Test1_Sheet1: 'Fiche n° 1.1 : Conformité à la syntaxe XML suivant les recommandations du W3C' -      Test1_Sheet1_Step1: "Conformité à la syntaxe XML" -      Test1_Sheet1_Step2: "Conformité au schéma XML du profil NEPTUNE" -      Test1_Sheet1_Step0_fatal: "Erreur fatale : Impossible d'ouvrir le fichier %{0}" -      Test1_Sheet1_Step0_error: "Impossible d'importer cette entrée %{0} du zip" -      Test1_Sheet1_Step0_warning: "Cette entrée %{0} du zip n'est pas un fichier xml et a été ignoré" -      Test1_Sheet1_Step1_error: "le fichier %{0} n'est pas correctement formé selon les recommandations du W3C" -      Test1_Sheet1_Step2_error: "le fichier %{0} ne respecte pas le modèle NEPTUNE" -      Test1_Sheet1_Step2_encoding: "le fichier %{0} ne respecte pas le codage de caractères du modèle NEPTUNE (ISO-8859-1)" -      Test1_Sheet1_Step2_fatal: "Erreur fatale : Aucune entrée valide trouvée dans le fichier" -      Test1_Sheet2: 'Fiche n° 1.2 : Conformité au schéma XML du profil NEPTUNE' -      Test1_Sheet2_Step1: Conformité au schéma XML du profil NEPTUNE -      Test1_Sheet2_Step1_error: "le fichier %{0} ne respecte pas le modèle NEPTUNE" -      Test1_Sheet2_Step1_encoding: "le fichier %{0} ne respecte pas le codage de caractères du modèle NEPTUNE (ISO-8859-1)" -      Test1_Sheet2_Step1_fatal: "Erreur fatale : Aucune entrée valide trouvée dans le fichier" -      TWO: "Catégorie 2 : Complétude, cohérence et intégrité des données" -      Test2_Sheet1: "Fiche n° 2.1 : Cohérence entre le réseau et ses composants" -      Test2_Sheet1_fatal: "La ligne %{0} n'a pas de réseau" -      Test2_Sheet1_Step1: "Correcte réference à des LIGNEs/Chouette(<Line>)" -      Test2_Sheet1_Step1_error: "La ligne %{1} n'est pas dans la liste des identifiants de ligne de %{0}" -      Test2_Sheet1_Step2: "Correcte référence  à la  VERSION DU RÉSEAU(< PTNetwork >) dans LIGNEs/Chouette (< Line >)" -      Test2_Sheet1_Step2a_error: "Le réseau %{0} n'est pas celui lié à la ligne %{1} dont le raccourci est %{2}." -      Test2_Sheet1_Step2b_error: "Le raccourci du réseau %{0} dans la ligne %{1} ne correspond à aucun réseau de la ligne" -      Test2_Sheet2: "Fiche n° 2.2 : Cohérence entre le regroupement de lignes et ses composants" -      Test2_Sheet2_Step1: "Correcte référence  à des LIGNEs/Chouette ( < Line >) dans GROUPE DE LIGNES ( < GroupOfLine >)" -      Test2_Sheet2_Step1_error: "la valeur de l'élément < lineId > : %{0} de la classe d'objets < GroupOfLine > n'a pas été repérée dans l'élément < objectId > de la classe d'objets < Line >" -      Test2_Sheet3: "Fiche n° 2.3 : Cohérence entre les arrêts et leurs composants" -      Test2_Sheet3_Step1: Conformité au schéma XML du profil NEPTUNE"Correcte référence  à  des ARRÊTs/Chouette ( < StopArea >)  et/ou à des POINTs D''ARRÊT SUR PARCOURS ( < StopPoint >) dans les ARRÊTs/Chouette ( < StopArea >)  " -      Test2_Sheet3_Step1_unchecked: "non implémenté" -      Test2_Sheet3_Step1_error: "une ou plusieurs valeurs de l'élément < contains > de l'objet < StopArea > %{0} n'est pas repérée dans la classe d'objets correspondant < StopPoint > ou < StopArea >. >" -      Test2_Sheet4: "Fiche n° 2.4 : Définition des correspondances" -      Test2_Sheet4_Step1: "Correcte référence aux ARRÊTs/Chouette ( < StopArea >) définissant des TronçonsDeCorrespondance/Chouette  ( < ConnectionLink >)" -      Test2_Sheet4_Step1_unchecked: "non implémenté" -      Test2_Sheet4_Step1_error: "L'objet < ConnectionLink > %{0} a des < StartOfLink >  %{1} et < EndOfLink >  %{2} qui pointent vers le même < StopArea >" -      Test2_Sheet4_Step1_error_a: "a : il manque au moins un identifiant d'arrêt < StartOfLink > et < EndOfLink > dans  l'objet < ConnectionLink > %{0}" -      Test2_Sheet4_Step1_error_b: "b : un identifiant d'arrêt < StartOfLink > ou < EndOfLink > de l'objet < ConnectionLink> %{0} n'est pas repéré dans un objet < StopArea >" -      Test2_Sheet5: "Fiche n° 2.5 : Cohérence entre les courses et les horaires" -      Test2_Sheet5_Step1: "Correcte référence aux COURSES COMMERCIALES ( < VehicleJourney > ) dans les VERSIONs DES HORAIRES/Chouette ( < Timetable >)" -      Test2_Sheet5_Step1_error: "un identifiant de course, situé dans l'objet < Timetable >, n'est pas référencé dans un objet < VehicleJourney >" -      Test2_Sheet5_Step2: "Chaque COURSE COMMERCIALE ( < VehicleJourney > ) est référencée dans une VERSION DES HORAIRES/Chouette  ( < Timetable >)" -      Test2_Sheet5_Step2_error: "une course n'est pas référencée dans aucun < TimeTable >" -      Test2_Sheet6: "Fiche n° 2.6 : Définition des terminus" -      Test2_Sheet6_Step1: "Correcte définition du terminus de LIGNE/Chouette  < Line >" -      Test2_Sheet6_Step1_unchecked: "non implémenté" -      Test2_Sheet6_Step1_error: "un identifiant de point d'arrêt de fin de trajet n'est pas repéré dans un objet < StopPoint>" -      Test2_Sheet6_Step2: "Caractère terminus des points de fin de trajet des LIGNEs/Chouette  < Line >" -      Test2_Sheet6_Step2_error: "un identifiant de point d'arrêt de fin de trajet n'est pas repéré comme début ou comme fin d'un trajet" -      Test2_Sheet7: "Fiche n° 2.7 : Cohérence entre les Itinéraires/Chouette et les LIGNEs/Chouette" -      Test2_Sheet7_Step1: "Correcte référence aux Itinéraires/Chouette ( < ChouetteRoute >) pour chaque LIGNE/Chouette ( < Line >)" -      Test2_Sheet7_Step1_unchecked: "non implémenté" -      Test2_Sheet7_Step1_error: "un identifiant d'Itinéraire < RouteId > situé dans l'objet < Line > n'est pas identifié dans l'objet < ChouetteRoute >" -      Test2_Sheet8: "Fiche n° 2.8 : Cohérence entre les missions commerciales et les itinéraires" -      Test2_Sheet8_Step1: "Correcte référence des MISSIONs COMMERCIALEs ( < JourneyPattern >)  par les Itinéraires/Chouette ( < ChouetteRoute >)" -      Test2_Sheet8_Step1_error: "un élément < journeyPatternId > dans un objet d'Itinéraire < ChouetteRoute > n'a pas d'identifiant < ObjectId > dans un objet < JourneyPattern>" -      Test2_Sheet8_Step2: "Correcte référence des Itinéraires/Chouette ( < ChouetteRoute >) que référencent les MISSIONs COMMERCIALEs ( < JourneyPattern >)" -      Test2_Sheet8_Step2_error: "l'élément d'Itinéraire < routeId >, référencé dans un objet < JourneyPattern >, n'a pas d'identifiant < objectId > dans l'objet d'Itinéraire < ChouetteRoute >" -      Test2_Sheet8_Step3: "Cohérence de la séquence des POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint >)  d'une mission commerciale et celle de l'Itinéraire/Chouette ( < ChouetteRoute >) correspondant" -      Test2_Sheet8_Step3_a_error: "a : l'identifiant du < %{0} > détecté dans l'objet < StopPoint > ne figure pas dans la liste des points d'arrêt de l'objet < JourneyPattern >" -      Test2_Sheet8_Step3_b_error: "b : l'identifiant du  %{0} < StopPoint >  ne figure pas dans l'un des éléments < startOfLink > ou < endOfLink > du tronçon < PtLink >" -      Test2_Sheet8_Step3_c_error: "c : l'identifiant du tronçon < PtLink > : %{0} , détecté dans le test b, n'est pas intégré dans un Itinéraire < ChouetteRoute >" -      Test2_Sheet8_Step3_d_error: "d : les <PTLinks> de l'Itinéraire < ChouetteRoute > : %{0} ne sont pas cohérents avec les <StopPoints> du < JourneyPattern > %{1}" -      Test2_Sheet9: "Fiche n° 2.9 : Définition de l'itinéraire retour" -      Test2_Sheet9_Step1: "Correcte référence  à un Itinéraire/Chouette ( < ChouetteRoute >) dans le cas d'un Itinéraire de retour" -      Test2_Sheet9_Step1_error: "un élément d'Itinéraire de retour < wayBackRouteId > dans un objet d'Itinéraire < ChouetteRoute > n'a pas d'identifiant < ObjectId > dans un autre objet d'Itinéraire <  ChouetteRoute >" -      Test2_Sheet10: "Fiche n° 2.10 : Référence à une ligne pour un point d'arrêt" -      Test2_Sheet10_Step1: "Correcte référence à une LIGNE/Chouette ( < Line >) pour les POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint > )" -      Test2_Sheet10_Step1_error: "Le point d'arrêt  (< StopPoint >)  fait référence à une ligne inexistante>" -      Test2_Sheet11: "Fiche n° 2.11 : Référence à un réseau au point d'arrêt" -      Test2_Sheet11_Step1: "Correcte référence à la VERSION DU RÉSEAU   ( < PTNetwork >) pour  chaque POINT D'ARRÊT SUR PARCOURS  \n( < StopPoint >)" -      Test2_Sheet11_Step1_error: "Le point d'arrêt  (< StopPoint >)  fait référence à un réseau inexistant>" -      Test2_Sheet12: "Fiche n° 2.12 : Définition de  l''Interdiction de Trafic Local" -      Test2_Sheet12_Step1: "Cohérence entre les objets  <  ITL >  et les ARRÊTs/Chouette ( < StopArea >)" -      Test2_Sheet12_Step1_error: "Un objet d'interdiction de trafic local  < ITL > %{0} fait référence à un arrêt du réseau < StopArea > %{1} inexistant" -      Test2_Sheet13: "Fiche n° 2.13 : Référence à une ligne des arrêts ITL" -      Test2_Sheet13_Step1: "Correcte référence à la LIGNE/Chouette ( < Line >) pour chaque  < ITL >" -      Test2_Sheet13_Step1_error: "Un objet d'interdiction de trafic local  < ITL >  fait référence à une ligne inexistante" -      Test2_Sheet14: "Fiche n° 2.14 : Association points d'arrêt, tronçons, itinéraire" -      Test2_Sheet14_Step1: "Tout POINT D'ARRÊT SUR PARCOURS  ( < StopPoint >) est associé à un Itinéraire/Chouette (ChouetteRoute >)" -      Test2_Sheet14_Step1a_error: "a : le point d'arrêt  (< StopPoint >)  %{0} n'appartient à aucune extrémité de tronçon" -      Test2_Sheet14_Step1b_error: "b : le tronçon %{0} fait référence à un itinéraire inexistant" -      Test2_Sheet14_Step2: "Continuité des tronçons COMMERCIAUX/Chouette ( < PtLink >) au sein d'un Itinéraire/Chouette ( < ChouetteRoute >)" -      Test2_Sheet14_Step2_error: "l'analyse des tronçons d'un itinéraire fait apparaître que la valeur de l'attribut de l'élément < endOfLink > d'un premier tronçon < PtLink > n'est pas identique à la valeur de l'attribut de l'élément < startOfLink > du deuxième tronçon < PtLink >" -      Test2_Sheet15: "Fiche n° 2.15 : Cohérence entre points d'arrêt et missions commerciales" -      Test2_Sheet15_Step1: "Existence de définition des POINTs D'ARRÊT SUR PARCOURS  ( < StopPoint >)  d'une mission commerciale  ( < JourneyPattern >)" -      Test2_Sheet15_Step1_error: "La liste de l'objet < JourneyPattern > %{0} fait référence à des points d'arrêt  inexistants" -      Test2_Sheet15_Step2: "Tout POINT D'ARRÊT SUR PARCOURS  ( < StopPoint >)  appartient à une mission commerciale  ( < JourneyPattern >)" -      Test2_Sheet15_Step2_error: "un point d'arrêt  (< StopPoint >)  n'est pas rattaché à une mission commerciale" -      Test2_Sheet16: "Fiche n° 2.16 : Référence à une ligne des  missions commerciales" -      Test2_Sheet16_Step1: "Correcte référence à une une LIGNE/Chouette ( < Ligne >)  pour une MISSION COMMERCIALE  ( < JourneyPattern >)" -      Test2_Sheet16_Step1_error: "Un objet < JourneyPattern > fait référence à une ligne inexistante" -      Test2_Sheet17: "Fiche n° 2.17 : Cohérence entre itinéraires et courses" -      Test2_Sheet17_Step1: "Correcte référence à l'Itinéraire/Chouette ( < ChouetteRoute) pour chaque COURSE COMMERCIALE  ( < VehicleJourney > )" -      Test2_Sheet17_Step1_error: "la course  %{0} fait référence à un itinéraire inexistant %{1}" -      Test2_Sheet18: "Fiche n° 2.18 : Cohérence entre les  missions commerciales et les courses" -      Test2_Sheet18_Step1: "Existence d'une MISSION COMMERCIALE ( < JourneyPattern  < ) pour chaque COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet18_Step1_error: "la course %{0} fait référence à une mission commerciale inexistante" -      Test2_Sheet18_Step2: "Cohérence de points entre MISSION COMMERCIALE ( < JourneyPattern  < ) et COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet18_Step2_error_a: "a : l'identifiant (< StopPoint >)  détecté dans un objet < StopPoint >  ne figure pas dans la liste des points d'arrêts < stopPointList > de < JourneyPattern >" -      Test2_Sheet18_Step2_error_b: "b : l'identifiant (< StopPoint >)  ne figure pas dans l'élément < stopPointId > d'un objet  < vehicleJourneyAtStop >" -      Test2_Sheet19: "Fiche n° 2.19 : Référence à une ligne pour chaque course" -      Test2_Sheet19_Step1: "Référence à une LIGNE/Chouette ( < Line >)  pour une COURSE COMMERCIALE ( < VehicleJourney >)" -      Test2_Sheet19_Step1_error: "le raccourci de ligne d'une course %{0} fait référence à une ligne inexistante" -      Test2_Sheet20: "Fiche n° 2.20 : Vérification des identifiants d''exploitants que référencent les courses" -      Test2_Sheet20_Step1: "Correcte référence à l'EXPLOITANT/Chouette ( < Company >) dans une COURSE COMMERCIALE ( < VehicleJourney > )" -      Test2_Sheet20_Step1_error: "la course %{0} fait référence à un exploitant inexistant" -      Test2_Sheet21: "Fiche n° 2.21 : Référence à une tranche horaire  pour  les courses" -      Test2_Sheet21_Step1: "Correcte référence des COURSEs COMMERCIALEs ( < VehicleJourney > ) à des TRANCHEs HORAIREs ( < TimeSlot >)" -      Test2_Sheet21_Step1_error: "la course %{0} fait référence à une tranche horaire inexistante" -      Test2_Sheet22: "Fiche n° 2.22 : Cohérence entre les points d'arrêts et les heures de passage" -      Test2_Sheet22_Step1: "Correcte référence à un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) pour les HEUREs DE PASSAGE GRAPHIQUées/Chouette ( < VehicleJourneyAtStop >)" -      Test2_Sheet22_Step1_error: "une heure de passage %{0} fait référence à un point d'arrêt  (< StopPoint >)  inexistant" -      Test2_Sheet23: "Fiche n° 2.23 : Cohérence entre les courses et  des heures de passage" -      Test2_Sheet23_Step1: "Correcte référence à une COURSE COMMERCIALE \n( < VehicleJourney >) dans HEURE DE PASSAGE GRAPHIQUEE/Chouette ( < VehicleJourneyAtStop >)" -      Test2_Sheet23_Step1_error: "une heure de passage %{0} fait référence à une course inexistante" -      Test2_Sheet24: "Fiche n° 2.24 : Cohérence entre la mission commerciale de la course et l''itinéraire de la course" -      Test2_Sheet24_Step1: "Cohérence de la référence un Itinéraire/Chouette pour une COURSE COMMERCIALE ( < VehicleJourney >) et la MISSION COMMERCIALE ( < JourneyPattern >) correspondante" -      Test2_Sheet24_Step1_error: "un objet < vehicleJourney > possède une valeur de l'attribut de l'élément < RouteId >. Cette valeur ne se retrouve dans un élément < RouteId > d'un objet < JourneyPattern > " -      Test2_Sheet25: "Fiche n° 2.25 : Définition des liens d'accès" -      Test2_Sheet25_Step1: "Correcte référence aux ARRÊTs/Chouette ( < StopArea >) et ACCES/NEPTUNE ( <AccessPoint >) définissant des LiensAccèsZoneArrêt/NEPTUNE  ( < AccessLink >)" -      Test2_Sheet25_Step1_error_a: "a : les objets < StartOfLink > et < EndOfLink > de  l'objet < AccessLink > sont identiques" -      Test2_Sheet25_Step1_error_b: "b : un identifiant d'arrêt ou d'accès < StartOfLink > ou < EndOfLink > de l'objet < AccessLink> n'est pas repéré dans un objet < StopArea > ou < AccessPoint >" -      Test2_Sheet26: "Fiche n° 2.26 : Cohérence entre les accès et leurs composants" -      Test2_Sheet26_Step1: "Correcte référence à des ARRÊTs/Chouette ( < StopArea >) et/ou à des LiensAccèsZoneArrêt/NEPTUNE  ( < AccessLink >) dans les ACCES/NEPTUNE ( < AccessPoint >)  " -      Test2_Sheet26_Step1_error: "une ou plusieurs valeurs de l'élément < containedIn> de la classe d'objets < AccessPoint> n'est pas repérée dans la classe d'objets correspondante < StopArea > ou < AccessLink >" -      Test2_Sheet27: "Fiche n° 2.27 : Référence aux arrêts dans les équipements" -      Test2_Sheet27_Step1: "Correcte référence à des ARRÊTs/Chouette ( < StopArea >) dans les EQUIPEMENTs /NEPTUNE  ( <Facility>)" -      Test2_Sheet27_Step1_error: "une valeur de l'élément < containedIn> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondante < StopArea >" -      Test2_Sheet28: "Fiche n° 2.28 : Référencement correct des composants dans les équipements" -      Test2_Sheet28_Step1: "Correcte référence à un ARRÊT/Chouette ( < StopArea >) ou  à une LIGNE/Chouette ( < Line >)  ou à un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) ou à un TronçonsDeCorrespondance/Chouette  ( < ConnectionLink >) dans les FACILITYs /NEPTUNE  ( <Facility>)" -      Test2_Sheet28_Step1_error: "une valeur de l'élément < stopAreaId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < StopArea >" -      Test2_Sheet28_Step2_error: "une valeur de l'élément < lineId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < Line>" -      Test2_Sheet28_Step3_error: "une valeur de l'élément < connectionLinkId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < ConnectionLink >" -      Test2_Sheet28_Step4_error: "une valeur de l'élément < stopPointId> de la classe d'objets < Facility> n'est pas repérée dans la classe d'objets correspondant < StopPoint >" -      THREE: "Catégorie 3 : Contenu" -      Test3_Sheet1: "Fiche n° 3.1 : Points d'arrêt de dénomination différente et très proches" -      Test3_Sheet1_Step1: "2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) très proches porte le même nom/même adresse" -      Test3_Sheet1_Step1_warning: "deux points d'arrêt séparés par une distance  %{3} inférieure à une valeur paramétrable %{0} ne portent pas le même nom , premier : %{1} , deuxième : %{2} " -      Test3_Sheet2: "Fiche n° 3.2 : Points d'arrêt très proches regroupés au sein d'une zone d'arrêt" -      Test3_Sheet2_Step1: "2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) très proches appartiennent à un même ARRÊT1/Chouette ( < StopArea >)" -      Test3_Sheet2_Step1_warning: "la distance calculée %{0} entre un point d'arrêt et les autres points d'arrêt est inférieure à une valeur paramétrable %{1} mais la valeur de l'attribut de l'élément < containedIn > de ces deux points d'arrêt < StopPoint > n'est pas identique, premier : %{2} , deuxième : %{3}"  -      Test3_Sheet3: "Fiche n° 3.3 : Unicité des noms de points d'arrêt " -      Test3_Sheet3_Step1: "Différentiation de nom pour les POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet3_Step1_warning: "deux points d'arrêt < StopPoint > : %{0} et %{1} de même nom ne sont pas suffisamment renseignés pour avoir des propriétés uniques" -      Test3_Sheet4: "Fiche n° 3.4 :  Unicité des noms de ligne" -      Test3_Sheet4_Step1: "Chaque LINE/Chouette ( < Line >) possède des valeurs d'attributs uniques" -      Test3_Sheet4_Step1_error: "les éléments < name > et < number > d'une ligne ne constituent pas un identifiant unique pour la ligne < Line > référencée par l'élément < %{0} >" -      Test3_Sheet5: "Fiche n° 3.5 : Modèle de représentation des coordonnées des points d'arrêt" -      Test3_Sheet5_Step1: "Coordonnées géographiques de chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) par rapport à un modèle de projection de référence" -      Test3_Sheet5_Step1_warning: "le point d'arrêt d'identifiant < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulle ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet6: "Fiche n° 3.6 : Localisation des points d'arrêt à l'intérieur d'un périmètre défini" -      Test3_Sheet6_Step1: "Les coordonnées de chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet6_Step1_warning_a: "a : le point d'arrêt d'identifiant < %{0} > n'est pas dans le bon système de projection " -      Test3_Sheet6_Step1_error_b: "b :  le point d'arrêt d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte" -      Test3_Sheet7: "Fiche n° 3.7 : Caractérisation des distances entre les points d'arrêt" -      Test3_Sheet7_Step1: "La distance entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs" -      Test3_Sheet7_Step1_warning: "la distance spatiale entre deux points d'arrêt consécutifs ne se situe pas dans une fourchette autorisée (entre %{0} pour sa valeur minimale et %{1} pour sa valeur supérieure" -      Test3_Sheet8: "Fiche n° 3.8 : Cohérence entre le temps et la distance pour chaque correspondance" -      Test3_Sheet8_Step1: " Les vitesses calculées à partir des attributs du TronçonDeCorrespondance/Chouette ( < ConnectionLink >) suivant les paramètres fixés" -      Test3_Sheet8_Step1_error_a: "a : la vitesse fixée par l'élément < DefaultDuration > n'est pas conforme à la valeur paramétrable : Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_b: "b : la vitesse fixée par l'élément < FrequentTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_c: "c : la vitesse fixée par l'élément < OccasionalTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet8_Step1_error_d: "d : la vitesse fixée par l'élément < MobilityRestrictedTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale  %{0} (+/- delta) et Vitesse maximale %{1} fixée pour la correspondance dont l'identifiant est < %{2} >" -      Test3_Sheet9: "Fiche n° 3.9 : Cohérence entre le temps et la distance pour chaque tronçon" -      Test3_Sheet9_Step1: "La vitesse entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs se situe dans une fourchette autorisée" -      Test3_Sheet9_Step1_warning: "la vitesse déterminée par la distance et le temps entre 2 points d'arrêt consécutifs (entre deux objets < %{0} > et < %{1} > ) ne se situe pas une fourchette autorisée entre %{2} et %{3}" -      Test3_Sheet10: "Fiche n° 3.10 : Détection des boucles" -      Test3_Sheet10_Step1: "Utilisation unique dans un Itinéraire/Chouette ( < ChouetteRoute >) d'un POINT D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet10_Step1_error_a: "a : le point d'arrêt d'identifiant < %{0} > est défini de manière unique et ne retrouve pas dans au moins deux tronçons" -      Test3_Sheet10_Step1_error_b: "b : les identifiants de tronçon identifiés dans le 3.10.1 a ne sont pas présents dans un même itinéraire" -      Test3_Sheet10_Step2: "Boucle dans un itinéraire/Chouette" -      Test3_Sheet10_Step2_warning: "des tronçons < PtLink > utilisent des points d'arrêt < StopPoint > ayant la même valeur d'attribut que l'élément <  containedIn  > pour la route %{0} " -      Test3_Sheet10_Step3: "La distance entre points d'arrêt d'un même itinéraire/Chouette" -      Test3_Sheet10_Step3_warning: "des points d'arrêt < StopPoint > utilisés par des tronçons d'itinéraire, sont proches les uns des autres d'une distance %{0} inférieure à une valeur paramétrable %{1} " -      Test3_Sheet11: "Fiche n° 3.11 : Détection des retours en arrière" -      Test3_Sheet11_Step1: "Utilisation répétitive de POINTs D'ARRÊT SUR PARCOURS  d'un Itinéraire/Chouette ( < ChouetteRoute >)" -      Test3_Sheet11_Step1_warning: "les tronçons < PtLink > d'un itinéraire utilisent des points d'arrêt < StopPoint > identiques plus de deux fois" -      Test3_Sheet12: "Fiche n° 3.12 : Connexité du graphe des lignes et des points d'arrêt" -      Test3_Sheet12_Step1: "Construction d'un graphe à partir de chaque POINTs D'ARRÊT SUR PARCOURS" -      Test3_Sheet15: "Fiche n° 3.15 : Cohérence des horaires" -      Test3_Sheet15_Step1: "Cohérence des HEUREs DE PASSAGE GRAPHIQUEEs/Chouette ( < VehicleJourneyAtStop >)  d'une COURSE ( < VehicleJourney >) pour chaque POINT D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet15_Step1_error: "la différence absolue entre la valeur de l'attribut de l'élément < arrivalTime > et la valeur de l'attribut de l'élément < departureTime > est supérieure à une valeur paramétrable %{0}" -      Test3_Sheet16: "Fiche n° 3.16 : Cohérence des courses" -      Test3_Sheet16_Step1: "Cohérence horaire pour 2 COURSEs ( < VehicleJourney >) utilisant le même couple de POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >)" -      Test3_Sheet16_Step1_error: "pour deux courses qui utilisent le même couple de points  A -> B, les temps de parcours : %{2} entre le point A : %{0} et le point B : %{1} ne sont pas  cohérents" -      Test3_Sheet16_Step2: "La VERSION DES HORAIREs/Chouette ( < Timetable >) contient des COURSEs ( < VehicleJourney >)" -      Test3_Sheet16_Step2_warning: "La course < vehicleJourney > dont l'identifiant est < %{0} > n'est pas référencée dans l'objet < TimeTable >" -      Test3_Sheet16_Step3: "Cohérence des HEUREs DE PASSAGE GRAPHIQUEEs/Chouette ( < VehicleJourneyAtStop >) entre 2 POINTs D'ARRÊT SUR PARCOURS ( < StopPoint >) consécutifs dans une COURSE ( < VehicleJourney >)" -      Test3_Sheet16_Step3_error_a: "a :  entre deux éléments < vehicleJourneyAtStop > successifs, la différence absolue entre la valeur de l'attribut de l'élément < departureTime > du premier point d'arrêt et la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt : %{0} est supérieure à une valeur paramétrable %{1} " -      Test3_Sheet16_Step3_error_b: "b : entre deux éléments < vehicleJourneyAtStop > successifs, la valeur de l'attribut de l'élément < departureTime > du premier point d'arrêt est inférieure à la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt ou la valeur de l'attribut de l'élément < arrivalTime > du second point d'arrêt  : %{0} est supérieure à une valeur paramétrable %{1}" -      Test3_Sheet17: "Fiche n° 3.17 : Modèle de représentation des coordonnées des points d'accès" -      Test3_Sheet17_Step1: " Les coordonnées géographiques de chaque POINT D'ACCES ( < AccessPoint >) par rapport à un modèle de projection de référence" -      Test3_Sheet17_Step1_warning: "le point d'accès d'identifiant < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulles ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet18: "Fiche n° 3.18 : Localisation des points d'accès à l'intérieur d'un périmètre défini" -      Test3_Sheet18_Step1: " Les coordonnées de chaque POINT D'ACCES ( < AccessPoint >) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet18_Step1_warning_a: "a : le point d'accès d'identifiant < %{0} > n'est pas dans le bon système de projection" -      Test3_Sheet18_Step1_error_b: "b :  le point d'accès d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte" -      Test3_Sheet19: "Fiche n° 3.19 : Modèle de représentation des coordonnées des équipements" -      Test3_Sheet19_Step1: " Test des coordonnées géographiques de chaque EQUIPEMENT ( < Facility >) par rapport à un modèle de projection de référence" -      Test3_Sheet19_Step1_warning: "l'equipement < %{0} > n'est pas dans le bon système de projection ou ses coordonnées géographiques sont nulle ou il est situé hors d'une zone dont le périmètre ou le contour est à définir" -      Test3_Sheet20: "Fiche n° 3.20 : Localisation des équipements à l'intérieur d'un périmètre défini" -      Test3_Sheet20_Step1: " Les coordonnées de chaque EQUIPEMENT ( < Facility>) sont inscrites dans une zone déterminée et qu'elles sont dans le bon système de projection" -      Test3_Sheet20_Step1_warning_a: "a : l'equipement d'identifiant < %{0} > n'est pas dans le bon système de projection " -      Test3_Sheet20_Step1_error_b: "b :  l'equipement d'identifiant < %{0} > a des coordonnées qui sont hors du polygone de la zone couverte " -      Test3_Sheet21: "Fiche n° 3.21 : Cohérence entre le temps et la distance pour chaque lien accès-zone d'arrêt" -      Test3_Sheet21_Step1: " Les vitesses calculées à partir des attributs du LiensAccèsZoneArrêt /NEPTUNE ( < AccessLink >) suivant les paramètres fixés" -      Test3_Sheet21_Step1_error_a: "a : la vitesse fixée par l'élément < DefaultDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_b: "b : la vitesse fixée par l'élément < FrequentTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_c: "c : la vitesse fixée par l'élément < OccasionalTravellerDuration > n'est pas conforme à la valeur paramétrable %{Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -      Test3_Sheet21_Step1_error_d: "d : la vitesse fixée par l'élément < MobilityRestrictedTravellerDuration > n'est pas conforme à la valeur paramétrable Vitesse minimale %{0} et Vitesse maximale %{1} fixée pour le lien d'accès dont l'identifiant est < %{2} >" -    severities: -      uncheck: "Non testé" -      ok: "Ok" -      warning: "Alerte" -      error: "Erreur" -      fatal: "Fatal" -  activerecord: -    models: -      file_validation:  -        zero:  "Validation Neptune" -        one:   "Validation Neptune"  -        other: "Validations Neptune" -    attributes: -      file_validation: -        resources: "Fichier à valider" -        status: "Status" -        file_name: "Jeu de données" -        test3_1_minimal_distance: "Distance minimale (test 3.1)" -        test3_2_minimal_distance: "Distance minimale (test 3.2)" -        test3_2_polygon_points: "Polygone (long lat) (test 3.6)" -        test3_7_minimal_distance: "Distance minimale / maximale (test 3.7)" -        test3_7_maximal_distance: " / " -        test3_8a_minimal_speed: "Vitesse minimale / maximale (test 3.8a)" -        test3_8a_maximal_speed: " / " -        test3_8b_minimal_speed: "Vitesse minimale / maximale (test 3.8b)" -        test3_8b_maximal_speed: " / " -        test3_8c_minimal_speed: "Vitesse minimale / maximale (test 3.8c)" -        test3_8c_maximal_speed: " / " -        test3_8d_minimal_speed: "Vitesse minimale / maximale (test 3.8d)" -        test3_8d_maximal_speed: " / " -        test3_9_minimal_speed: "Vitesse minimale / maximale (test 3.9)" -        test3_9_maximal_speed: " / " -        test3_10_minimal_distance: "Distance minimale (test 3.10)" -        test3_15_minimal_time: "Temps minimal (test 3.15)" -        test3_16_1_maximal_time: "Ecart maximal de durée entre deux desserte d'un même tronçon (test 3.16.1)" -        test3_16_3a_maximal_time: "Durée maximale du parcours entre 2 arrêts successifs (test 3.16.3a)" -        test3_16_3b_maximal_time: "Heure maximale de départ au premier arrêt après minuit sur une course franchissant minuit (test 3.16.3b)" -        test3_21a_minimal_speed: "Vitesse minimale / maximale (test 3.21a)" -        test3_21a_maximal_speed: " / " -        test3_21b_minimal_speed: "Vitesse minimale / maximale (test 3.21b)" -        test3_21b_maximal_speed: " / " -        test3_21c_minimal_speed: "Vitesse minimale / maximale (test 3.21c)" -        test3_21c_maximal_speed: " / " -        test3_21d_minimal_speed: "Vitesse minimale / maximale (test 3.21d)" -        test3_21d_maximal_speed: " / " -        projection_reference: "Système de projection de référence" -      file_validation_log_message: -        created_at: "Date" -        position: "N." -        full_message: "Message" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 31075abe5..e2632152c 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -225,16 +225,4 @@ fr:        <<: *errors  # FIN: https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/fr.yml -  "true": "oui" -  "false": "non" -  or: "ou" -  back: "Revenir" -  today: "Aujourd'hui" -  yesterday: "Hier" -  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/config/locales/import_tasks.yml b/config/locales/import_tasks.yml new file mode 100644 index 000000000..94134188f --- /dev/null +++ b/config/locales/import_tasks.yml @@ -0,0 +1,195 @@ +en: +  import_tasks: +    actions: +      new: "New import" +      destroy: "Destroy" +      destroy_confirm: "Are you sure you want destroy this import?" +    new: +      title: "New import" +    index: +      title: "Imports" +      warning: "" +    show: +      report: "Report" +      not_yet_started: "On queue" +      imported_file: "Imported file" +      completed: "[ Completed ]" +      failed: "[ Failed ]" +      pending: "[ In the treatment queue ]" +      processing: "[ In progress... ]" +      graph: +        files: +          title_zip: "Import results for files in zip" +          title_default: "Import result for %{extension} file" +          error: "Errors" +          ignored: "Ignored" +          ok: "Success" +        lines: +          title: "Imported objects" +          objects_label: "Objects count" +          lines_stats: "Lines" +          routes_stats: "Routes" +          connection_links_stats: "Connection Links" +          time_tables_stats: "Timetables" +          stop_areas_stats: "Stop Areas" +          access_points_stats: "Access Points" +          vehicle_journeys_stats: "Vehicle Journeys" +          journey_patterns_stats: "Journey Patterns" +    statuses: +      pending: "Pending" +      completed: "Completed" +      failed: "Failed" +    compliance_check_task: "Validate Report" +    severities: +      info: "Information" +      uncheck: "Unchecked" +      ok: "Ok" +      warning: "Warning" +      error: "Error" +      fatal: "Fatal" +  activerecord: +    models: +      import_task: +        zero:  "import" +        one:   "import" +        other: "imports" +      neptune_import: +        zero:  "import" +        one:   "Neptune import" +        other: "imports" +      csv_import: +        zero:  "import" +        one:   "CSV import" +        other: "imports" +      gtfs_import: +        zero:  "import" +        one:   "GTFS import" +        other: "imports" +      netex_import: +        zero:  "import" +        one:   "NeTEx import" +        other: "imports" +    attributes: +      import_task: +        resources: "File to import" +        created_at: "Created on" +        status: "Status" +        no_save: "No save" +        rule_parameter_set_id: "Rule parameter set for compliance check" +        object_id_prefix: "Neptune Id prefix" +        max_distance_for_commercial: "Max distance for commercial stop" +        max_distance_for_connection_link: "Max distance for connection link" +        ignore_last_word: "ignore last word" +        ignore_end_chars: "ignore last chars" +  tipsy: +    hints: +      import_task: +        max_distance_for_commercial: "Maximal distance to merge homonymous stops in commercial stop in meter" +        max_distance_for_connection_link: "Maximal distance to link stops by connection link stop in meter" +        ignore_last_word: "ignore last word on stop name in homonymous detection (inappliable when just one word occurs)" +        ignore_end_chars: "ignore some chars at the end of stop names in homonymous detection" +fr: +  import_tasks: +    actions: +      new: "Nouvel import" +      destroy: "Supprimer cet import" +      destroy_confirm: "Etes vous sûr de détruire cet import ?" +    new: +      title: "Nouvel import" +    index: +      title: "Imports" +      warning: "" +      imported_file: "Fichier importé" +    show: +      report: "Rapport" +      not_yet_started: "En file d'attente" +      imported_file: "Fichier importé" +      completed: "[ Terminé ]" +      failed: "[ Echoué ]" +      pending: "[ En file d'attente ]" +      processing: "[ En progression... ]" +      graph: +        files: +          title_zip: "Résultat d'import des fichiers du zip" +          title_default: "Résultat d'import 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" +          lines_stats: "Lignes" +          routes_stats: "Séquences d'arrêts" +          connection_links_stats: "Correspondances" +          time_tables_stats: "Calendriers" +          stop_areas_stats: "Zones d'arrèt" +          access_points_stats: "Accès" +          vehicle_journeys_stats: "Courses" +          journey_patterns_stats: "Missions" +      table: +        line: +          name: "Nom" +          save: "Sauvegarde" +          routes: "Séquences d'arrêts" +          connection_links: "Correspondances" +          time_tables: "Calendriers" +          stop_areas: "Zones d'arrèt" +          access_points: "Accès" +          vehicle_journeys: "Courses" +          journey_patterns: "Missions" +          not_saved: "Non Sauvé" +          saved: "Sauvé" +          save_error: "Sauvegarde en erreur" +    statuses: +      pending: "En cours" +      completed: "Achevé" +      failed: "Echoué" +    compliance_check_task: "Validation" +    severities: +      info: "Information" +      uncheck: "Non testé" +      ok: "Ok" +      warning: "Alerte" +      error: "Erreur" +      fatal: "Fatal" +  activerecord: +    models: +      import_task: +        zero:  "import" +        one:   "import" +        other: "imports" +      neptune_import: +        zero:  "import" +        one:   "import Neptune" +        other: "imports" +      csv_import: +        zero:  "import" +        one:   "import CSV" +        other: "imports" +      gtfs_import: +        zero:  "import" +        one:   "import GTFS" +        other: "imports" +      netex_import: +        zero:  "import" +        one:   "import NeTEx" +        other: "imports" +    attributes: +      import_task: +        resources: "Fichier à importer" +        created_at: "Créé le" +        status: "Status" +        no_save: "Pas de sauvegarde" +        rule_parameter_set_id: "Jeu de paramètres pour validation" +        object_id_prefix: "Préfixe d'identifiants" +        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" +  tipsy: +    hints: +      import_task: +        max_distance_for_commercial: "Distance maximale entre deux arrêts homonymes pour créer les zones d'arrêt (en mètre)" +        max_distance_for_connection_link: "Distance maximale entre deux arrêts pour créer les correspondances (en mètre)" +        ignore_last_word: "Ignorer le dernier mot pour détecter l'homonymie des noms d'arrêt (inapplicable quand le nom ne comporte qu'un mot)" +        ignore_end_chars: "Ignorer les n derniers caractères du nom de l'arrêt pour détecter l'homonymie" diff --git a/config/locales/imports.yml b/config/locales/imports.yml deleted file mode 100644 index d9e51fac4..000000000 --- a/config/locales/imports.yml +++ /dev/null @@ -1,292 +0,0 @@ -en: -  imports: -    actions: -      new: "New import" -      destroy: "Destroy" -      destroy_confirm: "Are you sure you want destroy this import?" -    new: -      title: "New import" -    index: -      title: "Imports" -      warning: "" -    show: -      report: "Report" -      not_yet_started: "On queue" -    statuses: -      pending: "Pending" -      completed: "Completed" -      failed: "Failed" -  import_log_messages: -    messages: -      started: "Started import" -      completed: "Completed import" -      failed: "Failed import" -      undefined: "%{key} undefined" -      IMPORT: "Import on %{0} format" -      ZIP_FILE: "ZIP File %{0}" -      ZIP_ERROR: "Error %{0}" -      ZIP_ENTRY: "ZIP Entry %{0}" -      ZIP_MISSING_ENTRY: "Missing ZIP entry %{0}" -      FILE: "File %{0}" -      FILE_ERROR: "Error %{0}" -      FILE_IGNORED: "Unknown file %{0} ignored" -      VALIDATION_ERROR: "Wrong grammar : %{0}" -      VALIDATION_CAUSE: "%{0}" -      IMPORTED_LINE: "Imported Line : %{0}" -      LINE_COUNT: "Line count : %{0}" -      TIME_TABLE_COUNT: "Timetable count : %{0}" -      ROUTE_COUNT: "Route count : %{0}" -      JOURNEY_PATTERN_COUNT: "Journey pattern count : %{0}" -      VEHICLE_JOURNEY_COUNT: "Vehicle journey count : %{0}" -      STOP_AREA_COUNT: "Stop area count : %{0}" -      CONNECTION_LINK_COUNT: "Connection link count : %{0}" -      ACCES_POINT_COUNT: "Access Point count : %{0}" -      MANDATORY_TAG: "Mandatory tag : %{0} " -      MANDATORY_DATA: "Mandatory data on line %{0} : %{1}" -      IGNORED_DATA: "%{0} line %{1} : invalid field %{2} (%{3}) ignored" -      DUPLICATE_ID: "%{0} line %{1} : duplicate id %{2}" -      UNKNOWN_ENUM: "Unknown enum vaule for %{0} : %{1} " -      EMPTY_TAG: "Empty value : %{0}" -      BAD_REFERENCE: "%{0} %{1} missing reference %{2}, id = %{3}" -      BAD_REFERENCE_IN_FILE: "%{0} line %{1} missing reference %{2}, id = %{3}" -      NETWORK_ANALYSE: "Analysing networks" -      COMPANY_ANALYSE: "Analysing networks" -      GROUP_OF_LINES_ANALYSE: "Analysing networks" -      LINE_ANALYSE: "Analysing lines" -      ROUTE_ANALYSE: "Analysing routes" -      STOP_ANALYSE: "Analysing stops" -      VEHICLE_JOURNEY_ANALYSE: "Analysing vehicle journeys" -      TIME_TABLE_ANALYSE: "Analysing timetables" -      CONNECTION_LINK_ANALYSE: "Analysing connection links" -      EMPTY_LINE: "Empty Line %{0} " -      EMPTY_ROUTE: "Empty Route {0} " -      EMPTY_JOURNEY_PATTERN: "Empty Journey pattern %{0}" -      EMPTY_VEHICLE_JOURNEY: "Empty Vehicle journey %{0} " -      EMPTY_TIMETABLE: "Empty Timetable %{0} " -      SAVE_OK: "%{0} saved" -      SAVE_ERROR: "%{0} save failed : %{1}" -      IMPORT_ERROR: "Import Error" -      EXCEPTION: "Problem : %{0}" -      WRONG_DATA: "Missing arguments to produce log message %{0}" -      COUNT_MORE_ITEMS: "%{0} similar problems" -      # old Import reports (before 2.0.3) -      SAVE: "Save"  -      CSV_IMPORT: "Import CVS file" -      CSV_OK_LINE: "line %{0} imported" -      CSV_OK_TIMETABLE: "timetables %{0} (%{1}) imported" -      CSV_OK_PTNETWORK: "network %{0} : %{1} imported" -      CSV_OK_COMPANY: "company %{0} imported" -      CSV_FILE_NOT_FOUND: "file %{0} : error %{1}" -      CSV_FILE_IGNORED: "file %{0} ignored (not XML) " -      CSV_VALIDATION_ERROR: "XML file don't agree with Neptune XSD : %{0}" -      CSV_VALIDATION_CAUSE: "%{0}" -      CSV_PARSE_OBJECT: "Analyse %{0}" -      CSV_MANDATORY_TAG: "missing or empty mandatory tag : %{0}" -      CSV_UNKNOWN_ENUM: "Unknown %{0} enumaration value : %{1}" -      CSV_EMPTY_TAG: "empty tag : %{0}" -      CSV_TIMETABLE_COUNT: "timetable count : %{0}" -      CSV_LINE_COUNT: "line count : %{0}" -      CSV_END_OF_FILE: "Unexpected end of file" -      CSV_BAD_TIMETABLE_PERIODS: "Bad timetable periods" -      CSV_INVALID_LINE: "invalid line : %{0}" -      CSV_STOP_WITHOUT_COORDS: "Stop without coords : %{0}" -      CSV_VJ_MISSING_TIMETABLE: "Unable to find timetable of vehicle journey : %{0}" -      CSV_FILE_FORMAT: "Invalid or deprecated CSV format" -      CSV_BAD_ID: "Invalid built Neptune Object ID : %{1} for %{0} " -      CSV_UNUSED_TIMETABLE: "Unused timetable %{0} (%{1})" -    severities: -      info: "Information" -      uncheck: "Unchecked" -      ok: "Ok" -      warning: "Warning" -      error: "Error" -      fatal: "Fatal" -  activerecord:         -    models:         -      import: -        zero:  "import" -        one:   "import" -        other: "imports" -      neptune_import: -        zero:  "import" -        one:   "Neptune import" -        other: "imports" -      csv_import: -        zero:  "import" -        one:   "CSV import" -        other: "imports" -      gtfs_import: -        zero:  "import" -        one:   "GTFS import" -        other: "imports" -      netex_import: -        zero:  "import" -        one:   "NeTEx import" -        other: "imports" -    attributes: -      import: -        resources: "File to import" -        created_at: "Created on" -        status: "Status" -        objectid_prefix: "Neptune Id prefix" -        max_distance_for_commercial: "Max distance for commercial stop" -        max_distance_for_connection_link: "Max distance for connection link" -        ignore_last_word: "ignore last word" -        ignore_end_chars: "ignore last chars" -      import_log_message: -        created_at: "Date" -        position: "N." -        full_message: "Message" -  formtastic: -    hints: -      import: -        max_distance_for_commercial: "Maximal distance to merge homonymous stops in commercial stop in meter" -        max_distance_for_connection_link: "Maximal distance to link stops by connection link stop in meter" -        ignore_last_word: "ignore last word on stop name in homonymous detection (inappliable when just one word occurs)" -        ignore_end_chars: "ignore some chars at the end of stop names in homonymous detection" -fr: -  imports: -    actions: -      new: "Nouvel import" -      destroy: "Supprimer cet import" -      destroy_confirm: "Etes vous sûr de détruire cet import ?" -    new: -      title: "Nouvel import" -    index: -      title: "Imports" -      warning: "" -    show: -      report: "Rapport" -      not_yet_started: "En file d'attente" -    statuses: -      pending: "En cours" -      completed: "Achevé" -      failed: "Echoué" -  import_log_messages: -    messages: -      started: "Import démarré" -      completed: "Import achevé avec succès" -      failed: "Import interrompu" -      undefined: "%{key} non défini" -      IMPORT: "Import au format %{0}" -      ZIP_FILE: "Fichier ZIP %{0}" -      ZIP_ERROR: "Erreur %{0}" -      ZIP_ENTRY: "Entrée de ZIP  %{0}" -      ZIP_MISSING_ENTRY: "Entrée de ZIP %{0} absente" -      FILE: "Fichier %{0}" -      FILE_ERROR: "Erreur %{0}" -      FILE_IGNORED: "Format non traité %{0}" -      VALIDATION_ERROR: "Le fichier ne respecte pas la grammaire : %{0}" -      VALIDATION_CAUSE: "%{0}" -      IMPORTED_LINE: "Ligne importée %{0}" -      LINE_COUNT: "Nombre de lignes extraites : %{0}" -      TIME_TABLE_COUNT: "Nombre de calendriers extraits : %{0}" -      ROUTE_COUNT: "Nombre de séquences d'arrêts extraites : %{0}" -      JOURNEY_PATTERN_COUNT: "Nombre de missions extraites : %{0}" -      VEHICLE_JOURNEY_COUNT: "Nombre de courses extraites : %{0}" -      STOP_AREA_COUNT: "Nombre d'arrêts extraits : %{0}" -      CONNECTION_LINK_COUNT: "Nombre de correspondances extraites : %{0}" -      ACCES_POINT_COUNT: "Nombre de points d'accès extraits : %{0}" -      MANDATORY_TAG: "Valeur obligatoire absente ou vide : %{0} " -      MANDATORY_DATA: "Ligne %{0} : il manque les données %{1}" -      IGNORED_DATA: "%{0} ligne %{1} : champ %{2} invalide (%{3}) ignoré" -      DUPLICATE_ID: "%{0} ligne %{1} : identifiant en double %{2}" -      UNKNOWN_ENUM: "Valeur de l'enum %{0} inconnue : %{1} " -      EMPTY_TAG: "Valeur vide : %{0}" -      BAD_REFERENCE: "%{0} %{1} Référence %{2} d'identifiant %{3} manquant" -      BAD_REFERENCE_IN_FILE: "%{0} ligne %{1} Référence %{2} d'identifiant %{3} manquant" -      NETWORK_ANALYSE: "Analyse des réseaux" -      COMPANY_ANALYSE: "Analyse des  networks" -      GROUP_OF_LINES_ANALYSE: "Analyse des  networks" -      LINE_ANALYSE: "Analyse des lignes" -      ROUTE_ANALYSE: "Analyse des séquences d'arrêts" -      STOP_ANALYSE: "Analyse des arrêts" -      VEHICLE_JOURNEY_ANALYSE: "Analyse des courses" -      TIME_TABLE_ANALYSE: "Analyse des calendriers" -      CONNECTION_LINK_ANALYSE: "Analyse des correspondances" -      EMPTY_LINE: "Ligne %{0} sans séquence d'arrêt" -      EMPTY_ROUTE: "Séquence d'arrêts %{0} sans mission ou arrêt" -      EMPTY_JOURNEY_PATTERN: "Mission %{0} sans arrêt ou course" -      EMPTY_VEHICLE_JOURNEY: "Course %{0} sans horaire" -      EMPTY_TIMETABLE: "Calendrier %{0} sans jours ni période" -      SAVE_OK: "%{0} enregistré" -      SAVE_ERROR: "Echec de l'enregistrement de %{0} : %{1}" -      IMPORT_ERROR: "Erreur d'import" -      EXCEPTION: "Problème : %{0}" -      WRONG_DATA: "Il manque des données pour afficher le message de log %{0}" -      COUNT_MORE_ITEMS: "%{0} problèmes similaires" -      # old Import reports (before 2.0.3) -      SAVE: "Sauvegarde"  -      CSV_IMPORT: "Import de fichier au format CSV" -      CSV_OK_LINE: "Ligne %{0} importée" -      CSV_OK_TIMETABLE: "Tableau de marche %{0} (%{1}) importé" -      CSV_OK_PTNETWORK: "Réseau %{0} : %{1} importé" -      CSV_OK_COMPANY: "Transporteur %{0} importé" -      CSV_FILE_ERROR: "Fichier %{0} : erreur %{1}" -      CSV_FILE_IGNORED: "Fichier %{0} ignoré (non CSV) " -      CSV_VALIDATION_ERROR: "Fichier CSV ne respecte pas le format Chouette : %{0}" -      CSV_VALIDATION_CAUSE: "%{0}" -      CSV_PARSE_OBJECT: "Analyse %{0}" -      CSV_MANDATORY_TAG: "Tag obligatoire absent ou vide : %{0}" -      CSV_UNKNOWN_ENUM: "Valeur de l'enum %{0} inconnue : %{1}" -      CSV_EMPTY_TAG: "Tag vide : %{0}" -      CSV_TIMETABLE_COUNT: "Nombre de tableaux de marche : %{0}" -      CSV_LINE_COUNT: "Nombre de lignes : %{0}" -      CSV_END_OF_FILE: "Fichier tronqué" -      CSV_BAD_TIMETABLE_PERIODS: "Mauvaises périodes dans le tableau de marche" -      CSV_INVALID_LINE: "ligne invalide : %{0}" -      CSV_STOP_WITHOUT_COORDS: "Arret sans coordonnées : %{0}" -      CSV_VJ_MISSING_TIMETABLE: "Impossible de trouver le tableau de marche de la course : %{0}" -      CSV_FILE_FORMAT: "Format CSV invalide ou obsolète" -      CSV_BAD_ID: "Identifiant Neptune produit invalide : %{1} pour %{0} " -      CSV_UNUSED_TIMETABLE: "Tableau de marche %{0} (%{1}) inutilisé" -    severities: -      info: "Information" -      uncheck: "Non testé" -      ok: "Ok" -      warning: "Alerte" -      error: "Erreur" -      fatal: "Fatal" -  activerecord:         -    models:         -      import: -        zero:  "import" -        one:   "import" -        other: "imports" -      neptune_import: -        zero:  "import" -        one:   "import Neptune" -        other: "imports" -      csv_import: -        zero:  "import" -        one:   "import CSV" -        other: "imports" -      gtfs_import: -        zero:  "import" -        one:   "import GTFS" -        other: "imports" -      netex_import: -        zero:  "import" -        one:   "import NeTEx" -        other: "imports" -    attributes: -      import: -        resources: "Fichier à importer" -        created_at: "Créé le" -        status: "Status" -        objectid_prefix: "Préfixe d'identifiants" -        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" -      import_log_message: -        created_at: "Date" -        position: "No" -        full_message: "Message" -  formtastic: -    hints: -      import: -        max_distance_for_commercial: "Distance maximale entre deux arrêts homonymes pour créer les zones d'arrêt (en mètre)" -        max_distance_for_connection_link: "Distance maximale entre deux arrêts pour créer les correspondances (en mètre)" -        ignore_last_word: "ignorer le dernier mot pour détecter l'homonymie des noms d'arrêt (inapplicable quand le nom ne comporte qu'un mot)" -        ignore_end_chars: "ignorer les n derniers caractères du nom de l'arrêt pour détecter l'homonymie" diff --git a/config/locales/layouts.yml b/config/locales/layouts.yml index 6c9165bf2..6efd519c7 100644 --- a/config/locales/layouts.yml +++ b/config/locales/layouts.yml @@ -10,6 +10,17 @@ en:        dashboard: "dashboard"      creation_tag:        title: "Create" +    history_tag: +      title: "History"   +      created_at: "Created at" +      updated_at: "Updated at" +      user_name: "User" +    flash_messages: +      success: "Success" +      error: "Error" +      alert: "Alert" +      notice: "Info"       +          fr:    layouts:      back_to_dashboard: "Retour au Tableau de Bord" @@ -22,3 +33,27 @@ fr:        dashboard: "Tableau de bord"      creation_tag:        title: "Création" +    history_tag: +      title: "Historique"     +      created_at: "Créé le" +      updated_at: "Mise à jour le" +      user_name: "Auteur" +    flash_messages: +      success: "Succès" +      error: "Erreur" +      alert: "Alerte" +      notice: "Info" +       +  true: "oui" +  false: "non" +  or: "ou" +  back: "Revenir" +  today: "Aujourd'hui" +  yesterday: "Hier" +  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/config/locales/rule_parameter_sets.yml b/config/locales/rule_parameter_sets.yml new file mode 100644 index 000000000..421322f07 --- /dev/null +++ b/config/locales/rule_parameter_sets.yml @@ -0,0 +1,113 @@ +en: +  rule_parameter_sets: +    actions: +      new: "Add a new parameter set" +      edit: "Edit this parameter set" +      index: "Rule parameter sets" +      destroy: "Remove this rule parameter set" +      destroy_confirm: "Are you sure you want destroy this rule parameter set ?" +    new: +      title: "Add a new parameter set" +    edit: +      title: "Update parameter set %{rule_parameter_set}" +    form: +      add_mode_parameter_set: "Add mode specific parameter set" +    show: +      title: "Parameter Set %{rule_parameter_set}" +      max_distance: "Maximum distance" +      min_distance: "Minimum distance" +      walk_speed: "Maximum walk speed for" +      inter_stop_area_distance_min: "between 2 stop areas having different parent" +      parent_stop_area_distance_max: "between a stop area and its own parent" +      inter_access_point_distance_min: "between 2 access having different name for a commun stop area" +      inter_connection_link_distance_max: "between stop area departure and stop area arrival in a connection link" +      walk_default_speed_max: "a regular traveller" +      walk_occasional_traveller_speed_max: "an occasional traveller" +      walk_frequent_traveller_speed_max: "a frequent traveller" +      walk_mobility_restricted_traveller_speed_max: "for a mobility restricted traveller" +      inter_access_link_distance_max: "Access link maximum distance" +      inter_stop_duration_max: "Maximum duration between the moment when a vehicle is arriving at a stop and the moment when the vehicle is leaving" +      facility_stop_area_distance_max: "between a stop area and a facility" +    index: +      title: "Parameter sets" +  activerecord: +    models: +      rule_parameter_set:  "Parameter Set for Conformity Rules" +    attributes: +      rule_parameter_set: +        name: "Name" +        inter_stop_area_distance_min: "Minimum distance between 2 stop areas having different parent" +        parent_stop_area_distance_max: "Maximum distance between a stop area and its own parent" +        stop_areas_area: "Geographic stop area envelop" +        inter_access_point_distance_min: "Minimum distance between 2 access having different name for a commun stop area" +        inter_connection_link_distance_max: "Maximum distance between stop area departure and stop area arrival in a connection link" +        walk_default_speed_max: "Maximum walk speed for a regular traveller" +        walk_occasional_traveller_speed_max: "Maximum walk speed for an occasional traveller" +        walk_frequent_traveller_speed_max: "Maximum walk speed for a frequent traveller" +        walk_mobility_restricted_traveller_speed_max: "Maximum walk speed for a mobility restricted traveller" +        inter_access_link_distance_max: "Access link maximum distance" +        inter_stop_duration_max: "Maximum duration for a stopping time" +        facility_stop_area_distance_max: "Maximum distance between a stop area and a facility" +        inter_stop_area_distance_min: "Maximum distance between a stop areas" +        inter_stop_area_distance_max: "Maximum distance between a stop areas" +        speed_min: "Minimum speed" +        speed_max: "Maximum speed" +        inter_stop_duration_variation_max: "Maximum duration gap between 2 vehicle journeys and between 2 folowing stops" + +fr: +  rule_parameter_sets: +    actions: +      new: "Ajouter un jeu de paramètres" +      edit: "Modifier ce jeu de paramètres" +      index: "Jeux de paramètres" +      destroy: "Supprimer ce jeu de paramètres" +      destroy_confirm: "Etes vous sûr de détruire ce jeu de paramètres ?" +    new: +      title: "Ajouter un jeu de paramètres" +    form: +      add_mode_parameter_set: "Ajouter les paramètres spécifiques à un mode" +    edit: +      title: "Modifier le jeu de paramètres %{rule_parameter_set}" +    show: +      title: "Jeu de paramètres %{rule_parameter_set}" +      max_distance: "Distance maximum entre : " +      min_distance: "Distance minimum entre : " +      walk_speed: "Vitesse de marche maximum d'un voyageur : " +      inter_stop_area_distance_min: "2 arrêts n'ayant pas le même parent" +      parent_stop_area_distance_max: "un arrêt et son parent" +      inter_access_point_distance_min: "2 accès de noms différents pour un même arrêt" +      inter_connection_link_distance_max: "les arrêts en correspondance" +      walk_default_speed_max: "ordinaire" +      walk_occasional_traveller_speed_max: "occasionnel" +      walk_frequent_traveller_speed_max: "habituel" +      walk_mobility_restricted_traveller_speed_max: "à mobilité réduite" +      inter_access_link_distance_max: "liaison accès - arrêt" +      facility_stop_area_distance_max: "un arrêt et un équipement" +      inter_stop_duration_max: "Durée maximum de stationnement à un arrêt" +      rule_parameter_by_mode: "Jeu de paramètres pour un mode de transport" +    index: +      title: "Jeux de paramètres" +  activerecord: +    models: +      rule_parameter_set: "Jeu de paramètres pour le contrôle de qualité des données" +    attributes: +      rule_parameter_set: +        name: "Nom" +        inter_stop_area_distance_min: Distance minimum entre 2 arrêts n'ayant pas le même parent +        parent_stop_area_distance_max: Distance maximum entre un arrêt et son parent +        stop_areas_area: Délimitation géographique des arrêts +        inter_access_point_distance_min: Distance minimum entre 2 accès de noms différents pour un même arrêt +        inter_connection_link_distance_max: Distance maximum entre les arrêts en correspondance +        walk_default_speed_max: Vitesse de marche maximum pour un voyageur ordinaire +        walk_occasional_traveller_speed_max: Vitesse de marche maximum pour un voyageur occasionnel +        walk_frequent_traveller_speed_max: Vitesse de marche maximum pour un voyageur habituel +        walk_mobility_restricted_traveller_speed_max: Vitesse de marche maximum pour un voyageur à mobilité réduite +        inter_access_link_distance_max: Distance maximum d'un liaison accès - arrêt +        inter_stop_duration_max: Durée maximum entre les horaires d'arrivée et de départ à un arrêt +        facility_stop_area_distance_max: Distance maximum entre un arrêt et un équipement +        inter_stop_area_distance_min: Distance minimum entre 2 arrêts +        inter_stop_area_distance_max: Distance maximum entre 2 arrêts +        speed_min: Vitesse minimum +        speed_max: Vitesse maximum +        inter_stop_duration_variation_max: Ecart maximum de durée de trajet entre 2 arrêts successifs pour les différentes courses + diff --git a/config/locales/transport_modes.yml b/config/locales/transport_modes.yml index 3c89e4524..9ed0745f7 100644 --- a/config/locales/transport_modes.yml +++ b/config/locales/transport_modes.yml @@ -15,13 +15,13 @@ en:        waterborne: "Waterborne"        private_vehicle: "Private vehicle"        walk: "Walk" -      trolley_bus: "Trolleybus" +      trolleybus: "Trolleybus"        bicycle: "Bicycle"        shuttle: "Shuttle"        taxi: "Taxi"        val: "VAL"        other: "Other" -       +  fr:    transport_modes:      label: @@ -29,8 +29,8 @@ fr:        air: "Air"        train: "Train"        long_distance_train: "Train Grande Ligne" -      local_train: "TER"  -      rapid_transit: "RER"  +      local_train: "TER" +      rapid_transit: "RER"        metro: "Métro"        tramway: "Tramway"        coach: "Autocar" @@ -39,7 +39,7 @@ fr:        waterborne: "Bac"        private_vehicle: "Voiture particulière"        walk: "Marche à pied" -      trolley_bus: "Trolleybus" +      trolleybus: "Trolleybus"        bicycle: "Vélo"        shuttle: "Navette"        taxi: "Taxi" diff --git a/config/routes.rb b/config/routes.rb index 238217099..a0e91cf7f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -28,7 +28,7 @@ ChouetteIhm::Application.routes.draw do        resources :vehicle_journeys, :only => :show      end    end -   +    resource :subscription @@ -36,10 +36,9 @@ ChouetteIhm::Application.routes.draw do      resources :users    end -  resources :file_validations -    resources :referentials do      resources :api_keys +    resources :rule_parameter_sets      resources :stop_point_areas      match 'lines' => 'lines#destroy_all', :via => :delete      resources :group_of_lines do @@ -55,7 +54,7 @@ ChouetteIhm::Application.routes.draw do            get 'add_routing_lines'            get 'add_routing_stops'          end -      end        +      end        resources :lines        collection do          get :name_filter @@ -81,7 +80,7 @@ ChouetteIhm::Application.routes.draw do            get 'add_routing_lines'            get 'add_routing_stops'          end -      end         +      end        resources :routes do          resources :journey_patterns do            member do @@ -101,15 +100,30 @@ ChouetteIhm::Application.routes.draw do        end      end -    resources :imports +    resources :import_tasks do +      member do +        get 'file_to_import' +      end +    end +      resources :exports do        collection do          get 'references'        end      end +    resources :compliance_check_tasks do +      member do +        get 'rule_parameter_set' +      end +      collection do +        get 'references' +      end + +      resources :compliance_check_results +    end      resources :companies -     +      resources :time_tables do        collection do          get :comment_filter @@ -123,7 +137,7 @@ ChouetteIhm::Application.routes.draw do      end      resources :stop_areas do -      resources :access_points  +      resources :access_points        resources :stop_area_parents        resources :stop_area_children        resources :stop_area_routing_lines @@ -135,13 +149,13 @@ ChouetteIhm::Application.routes.draw do          get 'add_routing_stops'          get 'access_links'        end -      collection do  +      collection do          put 'default_geometry'        end      end      resources :connection_links do -      resources :connection_link_areas  +      resources :connection_link_areas        member do          get 'select_areas'        end @@ -157,12 +171,12 @@ ChouetteIhm::Application.routes.draw do            get 'add_routing_lines'            get 'add_routing_stops'          end -      end         +      end      end      resources :clean_ups -     -  end  + +  end    match '/help/(*slug)' => 'help#show'    match '/test_sheet/(*slug)' => 'test_sheet#show' diff --git a/db/migrate/20120531070108_add_type_and_options_to_import.rb b/db/migrate/20120531070108_add_type_and_options_to_import.rb index 490427c8a..0488fb6d4 100644 --- a/db/migrate/20120531070108_add_type_and_options_to_import.rb +++ b/db/migrate/20120531070108_add_type_and_options_to_import.rb @@ -3,6 +3,6 @@ class AddTypeAndOptionsToImport < ActiveRecord::Migration      change_table :imports do |t|        t.string :type, :options      end -    Import.update_all :type => "NeptuneImport" +    # Import.update_all :type => "NeptuneImport"    end  end diff --git a/db/migrate/20120612071936_add_file_type_to_import.rb b/db/migrate/20120612071936_add_file_type_to_import.rb index fccd91cce..8eacab40d 100644 --- a/db/migrate/20120612071936_add_file_type_to_import.rb +++ b/db/migrate/20120612071936_add_file_type_to_import.rb @@ -3,6 +3,6 @@ class AddFileTypeToImport < ActiveRecord::Migration      change_table :imports do |t|        t.string :file_type      end -    Import.update_all :file_type => "zip" +    #Import.update_all :file_type => "zip"    end  end diff --git a/db/migrate/20120905125251_add_organisation_id_to_file_validation.rb b/db/migrate/20120905125251_add_organisation_id_to_file_validation.rb index 996bf8dba..79929414f 100644 --- a/db/migrate/20120905125251_add_organisation_id_to_file_validation.rb +++ b/db/migrate/20120905125251_add_organisation_id_to_file_validation.rb @@ -4,9 +4,9 @@ class AddOrganisationIdToFileValidation < ActiveRecord::Migration        f.belongs_to :organisation      end -    FileValidation.reset_column_information -    organisation = Organisation.find_or_create_by_name!("Chouette") -    FileValidation.update_all :organisation_id => organisation.id +    #FileValidation.reset_column_information +    #organisation = Organisation.find_or_create_by_name!("Chouette") +    #FileValidation.update_all :organisation_id => organisation.id    end  end diff --git a/db/migrate/20131028153043_add_bounds_to_referentials.rb b/db/migrate/20131028153043_add_bounds_to_referentials.rb new file mode 100644 index 000000000..013852e3f --- /dev/null +++ b/db/migrate/20131028153043_add_bounds_to_referentials.rb @@ -0,0 +1,7 @@ +class AddBoundsToReferentials < ActiveRecord::Migration +  def change +    change_table :referentials do |t| +      t.text :geographical_bounds +    end +  end +end diff --git a/db/migrate/20131029092608_drop_import_log_messages.rb b/db/migrate/20131029092608_drop_import_log_messages.rb new file mode 100644 index 000000000..98b17a42e --- /dev/null +++ b/db/migrate/20131029092608_drop_import_log_messages.rb @@ -0,0 +1,24 @@ +class DropImportLogMessages < ActiveRecord::Migration +  def up +    if table_exists? :import_log_messages +      execute "DROP TABLE import_log_messages" # fix Foreigner bug < 1.5.0 +      # drop_table :import_log_messages +    end +  end + +  def down +    unless table_exists? :import_log_messages +      create_table :import_log_messages do |t| +        t.belongs_to :import +        t.string :key +        t.string :arguments,:limit => 1000 +        t.integer :position +        t.string :severity +        t.timestamps +      end +      add_index :import_log_messages, :import_id +    end +  end +   + +end diff --git a/db/migrate/20131029105107_drop_imports.rb b/db/migrate/20131029105107_drop_imports.rb new file mode 100644 index 000000000..12677fa1f --- /dev/null +++ b/db/migrate/20131029105107_drop_imports.rb @@ -0,0 +1,23 @@ +class DropImports < ActiveRecord::Migration +  def up +    if table_exists? :imports +      execute "DROP TABLE imports" # fix Foreigner bug < 1.5.0 +      # drop_table :imports +    end +  end + +  def down +    unless table_exists? :imports +      create_table :imports do |t| +        t.belongs_to :referential +        t.string :status +        t.string :type +        t.string :options +        t.string :file_type +        t.timestamps +      end +      add_index :imports, :referential_id +    end +  end +   +end diff --git a/db/migrate/20131029110239_create_import_tasks.rb b/db/migrate/20131029110239_create_import_tasks.rb new file mode 100644 index 000000000..fa2faec37 --- /dev/null +++ b/db/migrate/20131029110239_create_import_tasks.rb @@ -0,0 +1,27 @@ +class CreateImportTasks < ActiveRecord::Migration +  def up +    unless table_exists? :import_tasks +      create_table :import_tasks do |t| +        t.belongs_to :referential ,:limit => 8 +        t.string :status        # pending processing completed failed +        t.string :format        # NEPTUNE, CSV, NETEX, GTFS +        t.boolean :no_save      # processing no save on database (exclude level 3 conformity testing) +        t.text :parameter_set   # all parameters needed to execute the import operation +        t.integer :user_id ,:limit => 8     # id to the user who has requested this task (may be nil) +        t.string :user_name     # name of the user who has requested this task +        t.string  :file_path    # saved file +        t.text :result          # import report : objects statistics +        t.text :progress_info   # percentage of progress and step code +        t.timestamps +        t.foreign_key :referentials, :dependent => :delete +      end +    end +  end + +  def down +    if table_exists? :import_tasks +      execute "drop table import_tasks" +      # drop_table :import_tasks +    end +  end +end diff --git a/db/migrate/20131029115751_create_compliance_check_tasks.rb b/db/migrate/20131029115751_create_compliance_check_tasks.rb new file mode 100644 index 000000000..9195556b2 --- /dev/null +++ b/db/migrate/20131029115751_create_compliance_check_tasks.rb @@ -0,0 +1,26 @@ +class CreateComplianceCheckTasks < ActiveRecord::Migration +  def up +    unless table_exists? :compliance_check_tasks +      create_table :compliance_check_tasks do |t| +        t.belongs_to :referential, :null => :no ,:limit => 8 +        t.belongs_to :import_task ,:limit => 8 # optional +        t.string :status      # global status of conformity checking +        t.string :parameter_set_name       # name of parameter set used for testing +        t.text :parameter_set   # all parameters needed to execute the import operation +        t.integer :user_id  ,:limit => 8    # id to the user who has requested this task (may be nil) +        t.string :user_name     # name of the user who has requested this task +        t.text :progress_info # percentage of progress and step code +        t.timestamps +        t.foreign_key :referentials, :dependent => :delete +        t.foreign_key :import_tasks, :dependent => :delete +      end +    end +  end + +  def down +    if table_exists? :compliance_check_tasks +      execute "drop table compliance_check_tasks" +      # drop_table :compliance_check_tasks +    end +  end +end diff --git a/db/migrate/20131029115820_create_compliance_check_results.rb b/db/migrate/20131029115820_create_compliance_check_results.rb new file mode 100644 index 000000000..8b72aa4c0 --- /dev/null +++ b/db/migrate/20131029115820_create_compliance_check_results.rb @@ -0,0 +1,23 @@ +class CreateComplianceCheckResults < ActiveRecord::Migration +  def up +    unless table_exists? :compliance_check_results +      create_table :compliance_check_results do |t| +        t.belongs_to :compliance_check_task , :null => :no ,:limit => 8 +        t.string :rule_code      # rule code value +        t.string :severity      # warning, error, improvement +        t.string :status      # NA, OK, NOK +        t.integer :violation_count # number of violation occurences +        t.text :detail # detail of violation location +        t.timestamps +        t.foreign_key :compliance_check_tasks, :dependent => :delete +      end +    end +  end + +  def down +    if table_exists? :compliance_check_results +      execute "drop table compliance_check_results" +      # drop_table :compliance_check_results +    end +  end +end diff --git a/db/migrate/20131104110509_create_rule_parameter_sets.rb b/db/migrate/20131104110509_create_rule_parameter_sets.rb new file mode 100644 index 000000000..b2ceb0dbb --- /dev/null +++ b/db/migrate/20131104110509_create_rule_parameter_sets.rb @@ -0,0 +1,19 @@ +class CreateRuleParameterSets < ActiveRecord::Migration +  def up +    unless table_exists? :rule_parameter_sets +      create_table :rule_parameter_sets do |a| +        a.belongs_to :referential ,:limit => 8 +        a.text :parameters +        a.string :name +        a.timestamps +      end +    end +  end + +  def down +    if table_exists? :rule_parameter_sets +      execute "drop table rule_parameter_sets" +      # drop_table :rule_parameter_sets +    end +  end +end diff --git a/db/migrate/20131105063323_create_transport_mode_parameter_sets.rb b/db/migrate/20131105063323_create_transport_mode_parameter_sets.rb new file mode 100644 index 000000000..307a7f4db --- /dev/null +++ b/db/migrate/20131105063323_create_transport_mode_parameter_sets.rb @@ -0,0 +1,20 @@ +class CreateTransportModeParameterSets < ActiveRecord::Migration +  def up +    unless table_exists? :transport_mode_parameter_sets +      create_table :transport_mode_parameter_sets do |a| +	a.belongs_to :rule_parameter_set  ,:limit => 8 +	a.string :transport_mode +	a.text :parameters +	a.timestamps +      end +    end +  end + +  def down +    if table_exists? :transport_mode_parameter_sets +      execute "drop table transport_mode_parameter_sets" +      # drop_table :transport_mode_parameter_sets +    end +     +  end +end diff --git a/db/migrate/20131220083200_drop_file_validation.rb b/db/migrate/20131220083200_drop_file_validation.rb new file mode 100644 index 000000000..ff774310c --- /dev/null +++ b/db/migrate/20131220083200_drop_file_validation.rb @@ -0,0 +1,14 @@ +class DropFileValidation < ActiveRecord::Migration +  def change +    if table_exists? :file_validation_log_messages +      execute "drop table file_validation_log_messages" +      # drop_table :file_validation_log_messages +    end + +    if table_exists? :file_validations +      execute "drop table file_validations" +      # drop_table :file_validations +    end +     +  end +end diff --git a/db/migrate/20131220215103_add_reference_to_compliance_check_task.rb b/db/migrate/20131220215103_add_reference_to_compliance_check_task.rb new file mode 100644 index 000000000..225c1a974 --- /dev/null +++ b/db/migrate/20131220215103_add_reference_to_compliance_check_task.rb @@ -0,0 +1,7 @@ +class AddReferenceToComplianceCheckTask < ActiveRecord::Migration +  def change +    change_table :compliance_check_tasks do |t| +      t.string :references_type, :reference_ids +    end +  end +end diff --git a/db/migrate/20140106084920_add_rule_code_parts_to_compilance_check_results.rb b/db/migrate/20140106084920_add_rule_code_parts_to_compilance_check_results.rb new file mode 100644 index 000000000..f494a0428 --- /dev/null +++ b/db/migrate/20140106084920_add_rule_code_parts_to_compilance_check_results.rb @@ -0,0 +1,8 @@ +class AddRuleCodePartsToCompilanceCheckResults < ActiveRecord::Migration +  def change +    change_table :compliance_check_results do |t| +      t.string  :rule_target, :rule_format +      t.integer :rule_level, :rule_number +    end +  end +end diff --git a/db/migrate/20140107084816_insert_rule_parameter_sets.rb b/db/migrate/20140107084816_insert_rule_parameter_sets.rb new file mode 100644 index 000000000..fd951c765 --- /dev/null +++ b/db/migrate/20140107084816_insert_rule_parameter_sets.rb @@ -0,0 +1,10 @@ +class InsertRuleParameterSets < ActiveRecord::Migration +  def up +    Referential.all.each do |referential| +      RuleParameterSet.default_for_all_modes( referential).save if referential.rule_parameter_sets.empty? +    end +  end + +  def down +  end +end diff --git a/db/migrate/20140110090743_add_user_id_name_to_referential.rb b/db/migrate/20140110090743_add_user_id_name_to_referential.rb new file mode 100644 index 000000000..127ba5937 --- /dev/null +++ b/db/migrate/20140110090743_add_user_id_name_to_referential.rb @@ -0,0 +1,6 @@ +class AddUserIdNameToReferential < ActiveRecord::Migration +  def change +    add_column :referentials, :user_id, :integer, :limit => 8 +    add_column :referentials, :user_name, :string +  end +end diff --git a/db/migrate/20140113094406_move_options_to_parameter_set_import_task.rb b/db/migrate/20140113094406_move_options_to_parameter_set_import_task.rb new file mode 100644 index 000000000..cb12aa3c4 --- /dev/null +++ b/db/migrate/20140113094406_move_options_to_parameter_set_import_task.rb @@ -0,0 +1,19 @@ +class MoveOptionsToParameterSetImportTask < ActiveRecord::Migration +  def up +    ImportTask.all.each do |import| +      import.parameter_set.tap do |parameter_set| +        parameter_set = {} if parameter_set.nil? +        import.resources = "dummy" +        import.update_attribute :format, "Neptune" +        import.update_attribute :no_save, false +        result = import.update_attribute( :parameter_set, {  :no_save => import.attributes[ "no_save"], +                                                      :file_path => import.attributes[ "file_path"], +                                                      :format => import.attributes[ "format"]}.merge( parameter_set)) +        raise Exception.new("Echec id=#{import.id}, import.valid? #{import.valid?}, import.erros #{import.errors.inspect}") unless result +      end +    end +  end + +  def down +  end +end diff --git a/db/migrate/20140113103544_remove_format_no_save_file_path_from_import_task.rb b/db/migrate/20140113103544_remove_format_no_save_file_path_from_import_task.rb new file mode 100644 index 000000000..f1548e5b4 --- /dev/null +++ b/db/migrate/20140113103544_remove_format_no_save_file_path_from_import_task.rb @@ -0,0 +1,13 @@ +class RemoveFormatNoSaveFilePathFromImportTask < ActiveRecord::Migration +  def up +    remove_column :import_tasks, :no_save +    remove_column :import_tasks, :file_path +    remove_column :import_tasks, :format +  end + +  def down +    add_column :import_tasks, :no_save, :boolean +    add_column :import_tasks, :file_path, :datatype +    add_column :import_tasks, :format, :datatype +  end +end diff --git a/db/schema.rb b/db/schema.rb index f6e27009d..f6203e6d7 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -1,3 +1,4 @@ +# encoding: UTF-8  # This file is auto-generated from the current state of the database. Instead  # of editing this file, please use the migrations feature of Active Record to  # incrementally modify your database, and then regenerate this schema definition. @@ -10,7 +11,7 @@  #  # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130710123351) do +ActiveRecord::Schema.define(:version => 20140113103544) do    create_table "access_links", :force => true do |t|      t.integer  "access_point_id",                        :limit => 8 @@ -87,6 +88,36 @@ ActiveRecord::Schema.define(:version => 20130710123351) do    add_index "companies", ["objectid"], :name => "companies_objectid_key", :unique => true    add_index "companies", ["registration_number"], :name => "companies_registration_number_key", :unique => true +  create_table "compliance_check_results", :force => true do |t| +    t.integer  "compliance_check_task_id", :limit => 8 +    t.string   "rule_code" +    t.string   "severity" +    t.string   "status" +    t.integer  "violation_count" +    t.text     "detail" +    t.datetime "created_at",                            :null => false +    t.datetime "updated_at",                            :null => false +    t.string   "rule_target" +    t.string   "rule_format" +    t.integer  "rule_level" +    t.integer  "rule_number" +  end + +  create_table "compliance_check_tasks", :force => true do |t| +    t.integer  "referential_id",     :limit => 8 +    t.integer  "import_task_id",     :limit => 8 +    t.string   "status" +    t.string   "parameter_set_name" +    t.text     "parameter_set" +    t.integer  "user_id",            :limit => 8 +    t.string   "user_name" +    t.text     "progress_info" +    t.datetime "created_at",                      :null => false +    t.datetime "updated_at",                      :null => false +    t.string   "references_type" +    t.string   "reference_ids" +  end +    create_table "connection_links", :force => true do |t|      t.integer  "departure_id",                           :limit => 8      t.integer  "arrival_id",                             :limit => 8 @@ -182,28 +213,6 @@ ActiveRecord::Schema.define(:version => 20130710123351) do      t.integer "choice_code"    end -  create_table "file_validation_log_messages", :force => true do |t| -    t.integer  "file_validation_id", :limit => 8 -    t.string   "key" -    t.string   "arguments",          :limit => 1000 -    t.integer  "position" -    t.string   "severity" -    t.datetime "created_at",                         :null => false -    t.datetime "updated_at",                         :null => false -  end - -  add_index "file_validation_log_messages", ["file_validation_id"], :name => "index_file_validation_log_messages_on_file_validation_id" - -  create_table "file_validations", :force => true do |t| -    t.string   "status" -    t.string   "options",         :limit => 2000 -    t.string   "file_name" -    t.string   "file_type" -    t.datetime "created_at",                      :null => false -    t.datetime "updated_at",                      :null => false -    t.integer  "organisation_id", :limit => 8 -  end -    create_table "group_of_lines", :force => true do |t|      t.string   "objectid",       :null => false      t.integer  "object_version" @@ -220,30 +229,18 @@ ActiveRecord::Schema.define(:version => 20130710123351) do      t.integer "line_id",          :limit => 8    end -  create_table "import_log_messages", :force => true do |t| -    t.integer  "import_id",  :limit => 8 -    t.string   "key" -    t.string   "arguments",  :limit => 1000 -    t.integer  "position" -    t.string   "severity" -    t.datetime "created_at",                 :null => false -    t.datetime "updated_at",                 :null => false -  end - -  add_index "import_log_messages", ["import_id"], :name => "index_import_log_messages_on_import_id" - -  create_table "imports", :force => true do |t| +  create_table "import_tasks", :force => true do |t|      t.integer  "referential_id", :limit => 8      t.string   "status" +    t.text     "parameter_set" +    t.integer  "user_id",        :limit => 8 +    t.string   "user_name" +    t.text     "result" +    t.text     "progress_info"      t.datetime "created_at",                  :null => false      t.datetime "updated_at",                  :null => false -    t.string   "type" -    t.string   "options" -    t.string   "file_type"    end -  add_index "imports", ["referential_id"], :name => "index_imports_on_referential_id" -    create_table "journey_patterns", :force => true do |t|      t.integer  "route_id",                :limit => 8      t.string   "objectid",                             :null => false @@ -329,13 +326,16 @@ ActiveRecord::Schema.define(:version => 20130710123351) do    create_table "referentials", :force => true do |t|      t.string   "name"      t.string   "slug" -    t.datetime "created_at",                   :null => false -    t.datetime "updated_at",                   :null => false +    t.datetime "created_at",                       :null => false +    t.datetime "updated_at",                       :null => false      t.string   "prefix"      t.string   "projection_type"      t.string   "time_zone"      t.string   "bounds" -    t.integer  "organisation_id", :limit => 8 +    t.integer  "organisation_id",     :limit => 8 +    t.text     "geographical_bounds" +    t.integer  "user_id",             :limit => 8 +    t.string   "user_name"    end    create_table "routes", :force => true do |t| @@ -360,6 +360,14 @@ ActiveRecord::Schema.define(:version => 20130710123351) do      t.integer "line_id",      :limit => 8    end +  create_table "rule_parameter_sets", :force => true do |t| +    t.integer  "referential_id", :limit => 8 +    t.text     "parameters" +    t.string   "name" +    t.datetime "created_at",                  :null => false +    t.datetime "updated_at",                  :null => false +  end +    create_table "stop_areas", :force => true do |t|      t.integer  "parent_id",                       :limit => 8      t.string   "objectid",                                                                     :null => false @@ -456,6 +464,14 @@ ActiveRecord::Schema.define(:version => 20130710123351) do    add_index "time_tables_vehicle_journeys", ["time_table_id"], :name => "index_time_tables_vehicle_journeys_on_time_table_id"    add_index "time_tables_vehicle_journeys", ["vehicle_journey_id"], :name => "index_time_tables_vehicle_journeys_on_vehicle_journey_id" +  create_table "transport_mode_parameter_sets", :force => true do |t| +    t.integer  "rule_parameter_set_id", :limit => 8 +    t.string   "transport_mode" +    t.text     "parameters" +    t.datetime "created_at",                         :null => false +    t.datetime "updated_at",                         :null => false +  end +    create_table "users", :force => true do |t|      t.string   "email",                                :default => "", :null => false      t.string   "encrypted_password",                   :default => "" @@ -532,12 +548,19 @@ ActiveRecord::Schema.define(:version => 20130710123351) do    add_foreign_key "access_points", "stop_areas", :name => "access_area_fkey", :dependent => :delete +  add_foreign_key "compliance_check_results", "compliance_check_tasks", :name => "compliance_check_results_compliance_check_task_id_fk", :dependent => :delete + +  add_foreign_key "compliance_check_tasks", "import_tasks", :name => "compliance_check_tasks_import_task_id_fk", :dependent => :delete +  add_foreign_key "compliance_check_tasks", "referentials", :name => "compliance_check_tasks_referential_id_fk", :dependent => :delete +    add_foreign_key "connection_links", "stop_areas", :name => "colk_endarea_fkey", :column => "arrival_id", :dependent => :delete    add_foreign_key "connection_links", "stop_areas", :name => "colk_startarea_fkey", :column => "departure_id", :dependent => :delete    add_foreign_key "group_of_lines_lines", "group_of_lines", :name => "groupofline_group_fkey", :dependent => :delete    add_foreign_key "group_of_lines_lines", "lines", :name => "groupofline_line_fkey", :dependent => :delete +  add_foreign_key "import_tasks", "referentials", :name => "import_tasks_referential_id_fk", :dependent => :delete +    add_foreign_key "journey_patterns", "routes", :name => "jp_route_fkey", :dependent => :delete    add_foreign_key "journey_patterns", "stop_points", :name => "arrival_point_fkey", :column => "arrival_stop_point_id", :dependent => :nullify    add_foreign_key "journey_patterns", "stop_points", :name => "departure_point_fkey", :column => "departure_stop_point_id", :dependent => :nullify diff --git a/lib/tasks/demo.rake b/lib/tasks/demo.rake index 7d964b894..da9f6c024 100644 --- a/lib/tasks/demo.rake +++ b/lib/tasks/demo.rake @@ -14,7 +14,7 @@ namespace :demo do      referential = organisation.referentials.create( :name => "Tatrobus", :slug => "tatrobus", :prefix => "TAT")      resource = Rack::Test::UploadedFile.new( Rails.application.config.demo_data, 'application/zip', false) -    import_instance = referential.imports.create( :resources => resource, :referential_id => referential.id) +    import_instance = referential.import_tasks.create( :resources => resource, :referential_id => referential.id)      import_instance.save_resources      import_instance.import      puts "Restore demo environment complete" diff --git a/spec/controllers/exports_controller_spec.rb b/spec/controllers/exports_controller_spec.rb index e7a49a8e8..fd7b182d7 100644 --- a/spec/controllers/exports_controller_spec.rb +++ b/spec/controllers/exports_controller_spec.rb @@ -1,6 +1,6 @@  require 'spec_helper' -describe ImportsController do +describe ExportsController do    login_user    describe "GET 'new'" do diff --git a/spec/controllers/import_tasks_controller_spec.rb b/spec/controllers/import_tasks_controller_spec.rb new file mode 100644 index 000000000..d9b8b7660 --- /dev/null +++ b/spec/controllers/import_tasks_controller_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe ImportTasksController do +  login_user +  shared_examples_for "referential dependant" do +    it "assigns referential as @referential" do +      assigns[:referential].should == referential +    end +  end + +  describe "GET /new" do +    before(:each) do +      get :new, +          :referential_id => referential.id +    end +    it_behaves_like "referential dependant" +    it "should assign import_task with NeptuneImport instance" do +      assigns[:import_task].class.should == NeptuneImport +    end +    it "should assign import_task with Neptune format" do +      assigns[:import_task].format.should == ImportTask.new.format +    end +    it "should assign import_task with refrential.id" do +      assigns[:import_task].referential_id.should == referential.id +    end +    it "should assign import_task with logged in user id" do +      assigns[:import_task].user_id.should == referential.organisation.users.first.id +    end +    it "should assign import_task with logged in user name" do +      assigns[:import_task].user_name.should == referential.organisation.users.first.name +    end +  end + +end diff --git a/spec/controllers/imports_controller_spec.rb b/spec/controllers/imports_controller_spec.rb deleted file mode 100644 index 8e2582a99..000000000 --- a/spec/controllers/imports_controller_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'spec_helper' - -describe ImportsController do -  login_user - -  describe "GET 'new'" do -    it "returns http success" do -      pending -      get 'new' -      response.should be_success -    end -  end - -  describe "POST 'create'" do -    before(:each) do -      post :create, -          :referential_id => referential.id, -          :import => { :resources => Rack::Test::UploadedFile.new( "spec/fixtures/neptune.zip", 'application/zip', false)} -    end - -    it "assigns import.referential as @referential" do -      assigns[:import].referential.should == referential -    end - -    it "assigns referential as @referential" do -      assigns[:referential].should == referential -    end -    it "shoud redirect to imports" do -      response.should redirect_to referential_imports_path(referential) -    end -  end - -  describe "GET 'index'" do -    it "returns http success" do -      pending -      get 'index' -      response.should be_success -    end -  end - -end diff --git a/spec/controllers/rule_parameter_sets_controller_spec.rb b/spec/controllers/rule_parameter_sets_controller_spec.rb new file mode 100644 index 000000000..99a522581 --- /dev/null +++ b/spec/controllers/rule_parameter_sets_controller_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe RuleParameterSetsController do +  login_user +  let(:mode){"air"} + +  shared_examples_for "referential dependant" do +    it "assigns referential as @referential" do +      assigns[:referential].should == referential +    end +  end + +  describe "GET /index" do +    before(:each) do +      get :index, +          :referential_id => referential.id +    end +    it_behaves_like "referential dependant" +  end + +  describe "GET /new" do +    before(:each) do +      get :new, +          :referential_id => referential.id +    end +    it_behaves_like "referential dependant" +    it "should assign rule_parameter_set with default params" do +      RuleParameterSet.default_params.each do |k,v| +        assigns[:rule_parameter_set].send( k ).should == v +      end +      assigns[:rule_parameter_set].referential_id.should == referential.id +    end +  end +end diff --git a/spec/factories.rb b/spec/factories.rb index 681400443..205f020bb 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -13,6 +13,14 @@ FactoryGirl.define do      f.time_zone "Europe/Paris"    end +  factory :rule_parameter_set do |f| +    f.sequence(:name) { |n| "Test #{n}" } +    f.association :referential +    f.after_create do |rsp| +      rsp.parameters = RuleParameterSet.default_for_all_modes( rsp.referential).parameters +    end +  end +    factory :user do |f|      f.association :organisation      f.sequence(:name) { |n| "chouette#{n}" } @@ -21,16 +29,15 @@ FactoryGirl.define do      f.password_confirmation "secret"    end -  factory :import do |f| +  factory :import_task do |f| +    f.user_name "dummy" +    f.user_id 123 +    f.no_save false +    f.format "Neptune"      f.resources { Rack::Test::UploadedFile.new 'spec/fixtures/neptune.zip', 'application/zip', false }      f.referential { Referential.find_by_slug("first") }    end -  factory :import_log_message do |f| -    f.association :import -    f.sequence(:key) { "key_#{n}" } -  end -    factory :kml_export do |f|      f.referential { Referential.find_by_slug("first") }    end @@ -49,9 +56,18 @@ FactoryGirl.define do      f.duration 1    end -  factory :file_validation do |f| -    f.resources { Rack::Test::UploadedFile.new 'spec/fixtures/neptune.zip', 'application/zip', false } -    f.association :organisation +  factory :compliance_check_result do |f| +    f.association :compliance_check_task +    f.rule_code "2-NEPTUNE-StopArea-6" +    f.severity "warning" +    f.status "nok" +  end + +  factory :compliance_check_task do |f| +    f.user_id 1 +    f.user_name "Dummy" +    f.status "pending" +    f.referential { Referential.find_by_slug("first") }    end    factory :file_validation_log_message do |f| diff --git a/spec/models/compliance_check_result_spec.rb b/spec/models/compliance_check_result_spec.rb new file mode 100644 index 000000000..4d73d8ad3 --- /dev/null +++ b/spec/models/compliance_check_result_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' + +describe ComplianceCheckResult do + +  subject { Factory( :compliance_check_result)} + +  describe "#indice" do +    context "when 1-NEPTUNE-XML-1 result" do +      before(:each) do +        subject.rule_code = "1-NEPTUNE-XML-1" +      end +      its(:indice) { should == 1 } +    end +    context "when 2-NETEX-AccessLink-2 result" do +      before(:each) do +        subject.rule_code = "2-NETEX-AccessLink-2" +      end +      its(:indice) { should == 2 } +    end +  end + +  describe "#data_type" do +    context "when 1-NEPTUNE-XML-1 result" do +      before(:each) do +        subject.rule_code = "1-NEPTUNE-XML-1" +      end +      its(:data_type) { should == "XML" } +    end +    context "when 2-NETEX-AccessLink-2 result" do +      before(:each) do +        subject.rule_code = "2-NETEX-AccessLink-2" +      end +      its(:data_type) { should == "AccessLink" } +    end +  end + +  describe "#format" do +    context "when 1-NEPTUNE-XML-1 result" do +      before(:each) do +        subject.rule_code = "1-NEPTUNE-XML-1" +      end +      its(:format) { should == "NEPTUNE" } +    end +    context "when 2-NETEX-AccessLink-2 result" do +      before(:each) do +        subject.rule_code = "2-NETEX-AccessLink-2" +      end +      its(:format) { should == "NETEX" } +    end +  end + +  describe "#level" do +    context "when 1-NEPTUNE-XML-1 result" do +      before(:each) do +        subject.rule_code = "1-NEPTUNE-XML-1" +      end +      its(:level) { should == 1 } +    end +    context "when 2-NEPTUNE-AccessLink-2 result" do +      before(:each) do +        subject.rule_code = "2-NEPTUNE-AccessLink-2" +      end +      its(:level) { should == 2 } +    end +  end + +end + diff --git a/spec/models/compliance_check_task_spec.rb b/spec/models/compliance_check_task_spec.rb new file mode 100644 index 000000000..e06554fe4 --- /dev/null +++ b/spec/models/compliance_check_task_spec.rb @@ -0,0 +1,283 @@ +require 'spec_helper' + +describe ComplianceCheckTask do + +  subject { Factory( :compliance_check_task ) } + +  RSpec::Matchers.define :be_log_message do |expected| +    match do |actual| +      actual and expected.all? { |k,v| actual[k.to_s] == v } +    end +  end + +  describe "#destroy" do +    let(:import_task){ Factory( :import_task )} +    context "with an import_task" do +        before(:each) do +          subject.import_task = import_task +        end +        it "should destroy import_task" do +          subject.destroy +          ImportTask.exists?( import_task.id).should be_false +        end +    end +    context "without any import_task" do +        before(:each) do +          subject.import_task = nil +        end +        it "should not raise exception" do +          subject.destroy +          subject.should be_destroyed +        end +    end +  end + +  describe "#levels" do +    let(:import_task){ Factory( :import_task )} +    context "when validation is without import" do +      it "should not return levels 1 and 2" do +        subject.levels.include?(1).should be_false +        subject.levels.include?(2).should be_false +      end +      context "when parameter_set is defined" do +        before(:each) do +          subject.parameter_set = "dummy" +        end +        it "should return level 3" do +          subject.levels.include?(3).should be_true +        end +      end +      context "when parameter_set is not defined" do +        before(:each) do +          subject.parameter_set = nil +        end +        it "should not return level 3" do +          subject.levels.include?(3).should_not be_true +        end +      end +    end +    context "when validation is done with an import" do +      before(:each) do +        subject.import_task = import_task +      end +      it "should return levels 1 and 2" do +        subject.levels.include?(1).should be_true +        subject.levels.include?(2).should be_true +      end +      context "when parameter_set is defined" do +        before(:each) do +          subject.parameter_set = "dummy" +        end +        it "should return level 3" do +          subject.levels.include?(3).should be_true +        end +      end +      context "when parameter_set is not defined" do +        before(:each) do +          subject.parameter_set = nil +        end +        it "should not return level 3" do +          subject.levels.include?(3).should_not be_true +        end +      end +    end + +  end + +  describe "#chouette_command" do +    it "should be a Chouette::Command instance" do +      subject.send( :chouette_command).class.should == Chouette::Command +    end +    it "should have schema same as referential.slug" do +      subject.send( :chouette_command).schema.should == subject.referential.slug +    end +  end + +  describe "#validate" do +    let(:compliance_check_task){ Factory(:compliance_check_task) } +    let(:chouette_command) { "dummy" } +    context "for failing validation" do +      before(:each) do +        chouette_command.stub!( :run!).and_raise( "dummy") +        compliance_check_task.stub!( :chouette_command => chouette_command) +      end +      it "should have status 'failed'" do +        compliance_check_task.validate +        compliance_check_task.status.should == "failed" +      end +    end +    context "for successful validation" do +      before(:each) do +        compliance_check_task.stub!( :chouette_command => mock( :run! => true )) +      end +      it "should have status 'completed'" do +        compliance_check_task.validate +        compliance_check_task.status.should == "completed" +      end +    end +  end + +  describe "#validate" do +    let(:compliance_check_task){ Factory(:compliance_check_task) } +    let(:command_args){ "dummy" } +    before(:each) do +      compliance_check_task.stub!( :chouette_command => mock( :run! => true )) +      compliance_check_task.stub!( :chouette_command_args => command_args) +    end +    it "should call chouette_command.run! with :c => 'import', :id => id" do +      compliance_check_task.send( :chouette_command).should_receive( :run! ).with(  command_args) +      compliance_check_task.validate +    end +  end + +  describe "#delayed_validate" do +    let( :import_task){ Factory.build(:import_task) } +    before(:each) do +      subject.stub!( :delay => mock( :validate => true)) +    end +    it "should not call delay#validate if import_task defined" do +      subject.import_task = import_task +      subject.delay.should_not_receive( :validate) +      subject.delayed_validate +    end +    it "should call delay#validate if import_task blank" do +      subject.import_task = nil +      subject.delay.should_receive( :validate) +      subject.delayed_validate +    end + +  end + +  describe "#define_default_attributes" do +    it "should keep status if defined" do +      subject.status = "dummy" +      subject.define_default_attributes +      subject.status.should == "dummy" +    end +    it "should set status to pending if not defined" do +      subject.status = nil +      subject.define_default_attributes +      subject.status.should == "pending" +    end +    context "when rule_parameter_set is nil" do +      before(:each) do +        subject.stub!( :rule_parameter_set => nil) +        subject.parameter_set = "dummy" +        subject.parameter_set_name = "dummy" +      end +      it "should keep parameter_set_name" do +        subject.define_default_attributes +        subject.parameter_set_name.should == "dummy" +      end +      it "should keep parameter_set" do +        subject.define_default_attributes +        subject.parameter_set.should == "dummy" +      end +    end +    context "when rule_parameter_set is defined" do +      let( :rule_parameter_set ){ Factory( :rule_parameter_set ) } +      before(:each) do +        subject.stub!( :rule_parameter_set => rule_parameter_set) +        subject.parameter_set = "dummy" +        subject.parameter_set_name = "dummy" +      end +      it "should set parameter_set_name to rule_parameter_set.name" do +        subject.define_default_attributes +        subject.parameter_set_name.should == rule_parameter_set.name +      end +      it "should keep set parameter_set to rule_parameter_set.parameters" do +        subject.define_default_attributes +        subject.parameter_set.should == rule_parameter_set.parameters +      end +    end +  end + +  describe "#rule_parameter_set" do +    context "when rule_parameter_set_id is blank" do +      before(:each) do +        subject.rule_parameter_set_id = "" +      end +      it "should return nil" do +        subject.rule_parameter_set.should be_nil +      end +    end +    context "when rule_parameter_set_id is not blank" do +      let( :rule_parameter_set ){ Factory( :rule_parameter_set ) } +      before(:each) do +        subject.rule_parameter_set_id = rule_parameter_set.id +      end +      it "should return rule_parameter_set instance" do +        subject.rule_parameter_set.should == rule_parameter_set +      end +    end +  end + +  describe "#rule_parameter_set_archived" do +    context "when parameter_set is blank" do +      before(:each) do +        subject.parameter_set = nil +      end +      it "should return nil" do +        subject.rule_parameter_set_archived.should be_nil +      end +    end +    context "when parameter_set is blank" do +      before(:each) do +        subject.parameter_set = { :speed => 30, :distance => 5 } +      end +      it "should return RuleParameterSet#parameters same as parameter_set" do +        subject.rule_parameter_set_archived.parameters.should == subject.parameter_set +      end +      it "should return RuleParameterSet#name same as parameter_set_name" do +        subject.rule_parameter_set_archived.name.should == subject.parameter_set_name +      end +    end + +  end + +#  describe "#validate" do +# +#    before(:each) do +#      subject.stub :validator => mock(:validate => true) +#    end +# +#    it "should create a ComplianceCheckResult :started when started" do +#      subject.validate +#      subject.compliance_check_results.first.should be_log_message(:key => "started") +#    end +# +#    it "should create a ComplianceCheckResult :completed when completed" do +#      subject.validate +#      subject.compliance_check_results.last.should be_log_message(:key => "completed") +#    end +# +#    it "should create a ComplianceCheckResult :failed when failed" do +#      pending +#      # subject.loader.stub(:export).and_raise("export failed") +#      subject.validate +#      subject.compliance_check_results.last.should be_log_message(:key => "failed") +#    end +# +#  end + +  describe ".create" do +    let( :new_compliance_check_task){ Factory.build( :compliance_check_task) } + +    it "should call #define_default_attributes" do +      new_compliance_check_task.should_receive( :define_default_attributes) +      new_compliance_check_task.save +    end + +    it "should call #delayed_validate" do +      new_compliance_check_task.should_not_receive( :delayed_validate) +      new_compliance_check_task.save +    end + +  end + +  it_behaves_like TypeIdsModelable do +    let(:type_ids_model) { subject} +  end + +end + diff --git a/spec/models/csv_import_spec.rb b/spec/models/csv_import_spec.rb index e169afb5f..3dad39aeb 100644 --- a/spec/models/csv_import_spec.rb +++ b/spec/models/csv_import_spec.rb @@ -2,18 +2,13 @@ require 'spec_helper'  describe CsvImport do -  describe "#objectid_prefix" do + describe "#object_id_prefix" do -    it "should be included in options" do -      subject.objectid_prefix = "dummy" -      subject.options.should include "objectid_prefix" => "dummy" -    end +   it "should be included in import_options" do +     subject.object_id_prefix = "dummy" +     subject.parameter_set["object_id_prefix"].should == "dummy" +   end -    it "should be included in import_options" do -      subject.objectid_prefix = "dummy" -      subject.import_options.should include :objectid_prefix => "dummy" -    end -     -  end + end  end diff --git a/spec/models/export_spec.rb b/spec/models/export_spec.rb index fb83236b0..cc8c045f1 100644 --- a/spec/models/export_spec.rb +++ b/spec/models/export_spec.rb @@ -9,7 +9,7 @@ describe Export do        actual and expected.all? { |k,v| actual[k.to_s] == v }      end    end -   +    describe "#export" do      before(:each) do @@ -36,7 +36,7 @@ describe Export do    end    describe "#options" do -     +      it "should be empty by default" do        subject.options.should be_empty      end @@ -44,7 +44,7 @@ describe Export do    end    describe ".types" do -     +      it "should return available Export implementations" do        Export.types.should =~ %w{NeptuneExport CsvExport GtfsExport NetexExport KmlExport}      end @@ -52,99 +52,15 @@ describe Export do    end    describe ".new" do -     +      it "should use type attribute to create a subclass" do        Export.new(:type => "NeptuneExport").should be_an_instance_of(NeptuneExport)      end    end -  describe "#references" do - -    it "should be empty if references_type is nil" do -      subject.references_type = nil -      subject.references.should be_empty -    end - -    it "should be empty if reference_ids is blank" do -      subject.reference_ids = "" -      subject.references.should be_empty -    end - -  end - -  describe "#references=" do - -    context "with Lines" do - -      let(:lines) { create_list :line, 3 } - -      before(:each) do -        subject.references = lines -      end - -      it "should use 'Chouette::Line' as references_type" do -        subject.references_type.should == 'Chouette::Line' -      end - -      it "should use line identifiers as raw reference_ids" do -        subject.raw_reference_ids.should == lines.map(&:id).join(',') -      end -                         -    end - -  end - -  describe "#references_relation" do -     -    it "should be 'lines' when relation_type is 'Chouette::Line'" do -      subject.references_type = "Chouette::Line" -      subject.references_relation.should == "lines" -    end - -    it "should be 'networks' when relation_type is 'Chouette::Network'" do -      subject.references_type = "Chouette::Network" -      subject.references_relation.should == "networks" -    end - -    it "should be nil when relation_type is blank" do -      subject.references_type = "" -      subject.references_relation.should be_nil -    end - -    it "should be nil when relation_type is 'dummy'" do -      subject.references_type = "dummy" -      subject.references_relation.should be_nil -    end - -  end - -  describe "#reference_ids" do -     -    it "should parse raw_reference_ids and returns ids" do -      subject.stub :raw_reference_ids => "1,2,3" -      subject.reference_ids.should == [1,2,3] -    end - -    it "should be empty if raw_reference_ids is blank" do -      subject.stub :raw_reference_ids => "" -      subject.reference_ids.should be_empty -    end - -  end - -  describe "#reference_ids=" do -     -    it "should join ids with comma" do -      subject.reference_ids = [1,2,3] -      subject.raw_reference_ids.should == "1,2,3" -    end - -    it "should be nil if records is blank" do -      subject.reference_ids = [] -      subject.raw_reference_ids.should be_nil -    end - +  it_behaves_like TypeIdsModelable do +    let(:type_ids_model) { subject}    end  end diff --git a/spec/models/gtfs_import_spec.rb b/spec/models/gtfs_import_spec.rb index f22a2d20d..e1a1ac48e 100644 --- a/spec/models/gtfs_import_spec.rb +++ b/spec/models/gtfs_import_spec.rb @@ -2,74 +2,49 @@ require 'spec_helper'  describe GtfsImport do -  describe "#objectid_prefix" do - -    it "should be included in options" do -      subject.objectid_prefix = "dummy" -      subject.options.should include "objectid_prefix" => "dummy" -    end - -    it "should be included in import_options" do -      subject.objectid_prefix = "dummy" -      subject.import_options.should include :objectid_prefix => "dummy" -    end -     -  end - -  describe "#max_distance_for_commercial" do - -    it "should be included in options" do -      subject.max_distance_for_commercial = 300 -      subject.options.should include "max_distance_for_commercial" => 300 -    end - -    it "should be included in import_options" do -      subject.max_distance_for_commercial = 300 -      subject.import_options.should include :max_distance_for_commercial => 300 -    end -     -  end -   -  describe "#max_distance_for_connection_link" do - -    it "should be included in options" do -      subject.max_distance_for_connection_link = 300 -      subject.options.should include "max_distance_for_connection_link" => 300 -    end - -    it "should be included in import_options" do -      subject.max_distance_for_connection_link = 300 -      subject.import_options.should include :max_distance_for_connection_link => 300 -    end -     -  end - -  describe "#ignore_last_word" do - -    it "should be included in options" do -      subject.ignore_last_word = true -      subject.options.should include "ignore_last_word" => true -    end - -    it "should be included in import_options" do -      subject.ignore_last_word = true -      subject.import_options.should include :ignore_last_word => true -    end -     -  end -   -  describe "#ignore_end_chars" do - -    it "should be included in options" do -      subject.ignore_end_chars = 2 -      subject.options.should include "ignore_end_chars" => 2 -    end - -    it "should be included in import_options" do -      subject.ignore_end_chars = 2 -      subject.import_options.should include :ignore_end_chars => 2 -    end -     -  end + describe "#object_id_prefix" do + +   it "should be included in import_options" do +     subject.object_id_prefix = "dummy" +     subject.parameter_set["object_id_prefix"].should  == "dummy" +   end + + end + + describe "#max_distance_for_commercial" do + +   it "should be included in import_options" do +     subject.max_distance_for_commercial = 300 +     subject.parameter_set["max_distance_for_commercial"].should == 300 +   end + + end + + describe "#max_distance_for_connection_link" do + +   it "should be included in import_options" do +     subject.max_distance_for_connection_link = 300 +     subject.parameter_set["max_distance_for_connection_link"].should == 300 +   end + + end + + describe "#ignore_last_word" do + +   it "should be included in import_options" do +     subject.ignore_last_word = true +     subject.parameter_set["ignore_last_word"].should == true +   end + + end + + describe "#ignore_end_chars" do + +   it "should be included in import_options" do +     subject.ignore_end_chars = 2 +     subject.parameter_set["ignore_end_chars"].should == 2 +   end + + end  end diff --git a/spec/models/import_log_message_spec.rb b/spec/models/import_log_message_spec.rb deleted file mode 100644 index dab951255..000000000 --- a/spec/models/import_log_message_spec.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'spec_helper' - -describe ImportLogMessage do - -  describe "#attributes" do - -    subject { create :import_log_message } - -    it "should read json stored in database" do -      subject.update_attribute :arguments, { "key" => "value"} -      subject.raw_attributes.should == { "key" => "value"}.to_json -    end - -  end - -end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb deleted file mode 100644 index bbf6725d7..000000000 --- a/spec/models/import_spec.rb +++ /dev/null @@ -1,61 +0,0 @@ -require 'spec_helper' - -describe Import do - -  subject { create :import } - -  RSpec::Matchers.define :be_log_message do |expected| -    match do |actual| -      actual and expected.all? { |k,v| actual[k.to_s] == v } -    end -  end -   -  describe "#import" do - -    before(:each) do -      subject.stub :loader => mock(:import => true) -    end - -    it "should create a ImportLogmessage :started when started" do -      subject.import -      subject.log_messages.first.should be_log_message(:key => "started") -    end - -    it "should create a ImportLogmessage :completed when completed" do -      subject.import -      subject.log_messages.last.should be_log_message(:key => "completed") -    end - -    it "should create a ImportLogmessage :failed when failed" do -      subject.loader.stub(:import).and_raise("import failed") -      subject.import -      subject.log_messages.last.should be_log_message(:key => "failed") -    end - -  end - -  describe "#options" do -     -    it "should be nil by default" do -      subject.options.should be_nil -    end - -  end - -  describe ".types" do -     -    it "should return available Import implementations" do -      Import.types.should =~ %w{NeptuneImport CsvImport GtfsImport NetexImport} -    end - -  end - -  describe ".new" do -     -    it "should use type attribute to create a subclass" do -      Import.new(:type => "NeptuneImport").should be_an_instance_of(NeptuneImport) -    end - -  end - -end diff --git a/spec/models/import_task_spec.rb b/spec/models/import_task_spec.rb new file mode 100644 index 000000000..542ccd739 --- /dev/null +++ b/spec/models/import_task_spec.rb @@ -0,0 +1,196 @@ +require 'spec_helper' + +describe ImportTask do + +  subject { build :import_task } + +  describe ".new" do + +    it "should use type attribute to create a subclass" do +      ImportTask.new(:format => "Neptune").should be_an_instance_of(NeptuneImport) +      ImportTask.new(:format => "Gtfs").should be_an_instance_of(GtfsImport) +      ImportTask.new(:format => "Netex").should be_an_instance_of(NetexImport) +      ImportTask.new(:format => "Csv").should be_an_instance_of(CsvImport) + +      NeptuneImport.new.should be_an_instance_of(NeptuneImport) +      GtfsImport.new.should be_an_instance_of(GtfsImport) +      NetexImport.new.should be_an_instance_of(NetexImport) +      CsvImport.new.should be_an_instance_of(CsvImport) +    end + +  end + +  describe "#delayed_import" do +    before(:each) do +      subject.stub!( :delay => mock( :import => true)) +    end +    it "should call delay#import" do +      subject.delay.should_receive( :import) +      subject.send :delayed_import +    end +  end + +  describe ".create" do +    before(:each) do +      subject.stub!( :save_resources => true ) +    end +    it "should call save_resource" do +      subject.should_receive( :save_resources) +      subject.send :save +    end +    it "should update file_path with #saved_resources" do +      subject.send :save +      ImportTask.find( subject.id).file_path.should == subject.send( :saved_resources) +    end +    it "should have a compliance_check_task" do +      subject.send :save +      ImportTask.find( subject.id).compliance_check_task.should_not be_nil +    end +  end + +  describe "#compliance_check_task" do +    let(:rule_parameter_set){ Factory( :rule_parameter_set) } +    let(:import_task){ Factory(:import_task, :rule_parameter_set_id => rule_parameter_set.id) } +    let(:compliance_check_task){ import_task.compliance_check_task } + +    it "should have same #referential as import_task" do +      compliance_check_task.referential.should == import_task.referential +    end + +    it "should have same #rule_parameter_set_id as import_task" do +      compliance_check_task.rule_parameter_set_id.should == import_task.rule_parameter_set_id +    end + +    it "should have same #user_id as import_task" do +      compliance_check_task.user_id.should == import_task.user_id +    end + +    it "should have same #user_name as import_task" do +      compliance_check_task.user_name.should == import_task.user_name +    end +  end + +  describe "#file_path_extension" do +    let(:import_task){ Factory(:import_task) } +    context "zip file to import" do +      before(:each) do +        import_task.file_path = "aaa/bbb.zip" +      end +      it "should return zip" do +        import_task.file_path_extension.should == "zip" +      end +    end +    context "xml file to import" do +      before(:each) do +        import_task.file_path = "aaa/bbb.xml" +      end +      it "should return xml" do +        import_task.file_path_extension.should == "xml" +      end +    end +    context "csv file to import" do +      before(:each) do +        import_task.file_path = "aaa/bbb.csv" +      end +      it "should return csv" do +        import_task.file_path_extension.should == "basic" +      end +    end + +  end + +  context "options attributes" do +    let(:import_task){ Factory(:import_task) } +    describe "#no_save" do +      it "should read parameter_set['no_save']" do +        import_task.parameter_set[ "no_save"] = "dummy" +        import_task.no_save.should == "dummy" +      end +    end +    describe "#format" do +      it "should read parameter_set['format']" do +        import_task.parameter_set[ "format"] = "dummy" +        import_task.format.should == "dummy" +      end +    end +    describe "#file_path" do +      it "should read parameter_set['file_path']" do +        import_task.parameter_set[ "file_path"] = "dummy" +        import_task.file_path.should == "dummy" +      end +    end +    describe "#no_save=" do +      it "should read parameter_set['no_save']" do +        import_task.no_save = "dummy" +        import_task.parameter_set[ "no_save"].should == false +      end +    end +    describe "#format=" do +      it "should read parameter_set['format']" do +        import_task.format = "dummy" +        import_task.parameter_set[ "format"].should == "dummy" +      end +    end +    describe "#file_path=" do +      it "should read parameter_set['file_path']" do +        import_task.file_path = "dummy" +        import_task.parameter_set[ "file_path"].should == "dummy" +      end +    end +  end + +  describe "#chouette_command" do +    it "should be a Chouette::Command instance" do +      subject.send( :chouette_command).class.should == Chouette::Command +    end +    it "should have schema same as referential.slug" do +      subject.send( :chouette_command).schema.should == subject.referential.slug +    end +  end + +  describe "#import" do +    let(:import_task){ Factory(:import_task) } +    let(:chouette_command) { "dummy" } +    context "for failing import" do +      before(:each) do +        chouette_command.stub!( :run!).and_raise( "dummy") +        import_task.stub!( :chouette_command => chouette_command) +      end +      it "should have status 'failed'" do +        import_task.import +        import_task.status.should == "failed" +      end +      it "should have status 'failed' for compliance_check_task" do +        import_task.import +        import_task.compliance_check_task.status.should == "failed" +      end +    end +    context "for successful import" do +      before(:each) do +        import_task.stub!( :chouette_command => mock( :run! => true )) +      end +      it "should have status 'completed'" do +        import_task.import +        import_task.status.should == "completed" +      end +      it "should have status 'completed' for compliance_check_task" do +        import_task.import +        import_task.status.should == "completed" +      end +    end +  end + +  describe "#import" do +    let(:import_task){ Factory(:import_task) } +    let(:command_args){ "dummy" } +    before(:each) do +      import_task.stub!( :chouette_command => mock( :run! => true )) +      import_task.stub!( :chouette_command_args => command_args) +    end +    it "should call chouette_command.run! with :c => 'import', :id => id" do +      import_task.send( :chouette_command).should_receive( :run! ).with(  command_args) +      import_task.import +    end +  end + +end diff --git a/spec/models/rule_parameter_set_spec.rb b/spec/models/rule_parameter_set_spec.rb new file mode 100644 index 000000000..bf785d6f7 --- /dev/null +++ b/spec/models/rule_parameter_set_spec.rb @@ -0,0 +1,49 @@ +require 'spec_helper' + +describe RuleParameterSet do + +  describe ".mode_of_mode_attribute" do +    it "should retreive attribute name" do +      subject.class.attribute_of_mode_attribute("dummy1_mode_dummy2").should == "dummy1" +    end +    it "should retreive mode" do +      subject.class.mode_of_mode_attribute("dummy1_mode_dummy2").should == "dummy2" +    end +  end + +  RuleParameterSet.mode_attribute_prefixes.each do |prefix| +    RuleParameterSet.all_modes.map do |mode| +      "#{prefix}_mode_#{mode}".tap do |attribute| +        describe "##{attribute}=" do +          it "should store value on parameters hash" do +            subject.send( "#{attribute}=".to_sym, 1234) +            subject.send( attribute.to_sym).should == 1234 +            subject.parameters["mode_#{mode}"][ prefix].should == 1234 +          end +        end +        it { should allow_mass_assignment_of attribute.to_sym} +      end +    end +  end + +  RuleParameterSet.general_attributes.each do |attribute| +    describe "##{attribute}=" do +      it "should store value on parameters hash" do +        subject.send( "#{attribute}=".to_sym, 1234) +        subject.send( attribute.to_sym).should == 1234 +        subject.parameters[ attribute].should == 1234 +      end +    end +    it { should allow_mass_assignment_of attribute.to_sym} +  end + +  describe "#referential" do +    it { should validate_presence_of(:referential) } +    it { should allow_mass_assignment_of :referential_id } +  end + +  describe "#name" do +    it { should validate_presence_of(:name) } +    it { should allow_mass_assignment_of :name } +  end +end diff --git a/spec/requests/companies_spec.rb b/spec/requests/companies_spec.rb index dbacd4a71..fdcff4cab 100644 --- a/spec/requests/companies_spec.rb +++ b/spec/requests/companies_spec.rb @@ -4,12 +4,11 @@ require 'spec_helper'  describe "Companies" do    login_user -  let(:companies) { Array.new(2) { create :company } } +  let!(:companies) { Array.new(2) { create :company } }    subject { companies.first }    describe "list" do      it "display companies" do -      pending        visit referential_companies_path(referential)        page.should have_content(companies.first.name)        page.should have_content(companies.last.name) @@ -19,7 +18,6 @@ describe "Companies" do    describe "show" do            it "display company" do -      pending        visit referential_companies_path(referential)        click_link "#{companies.first.name}"        page.should have_content(companies.first.name) @@ -29,7 +27,6 @@ describe "Companies" do    describe "new" do            it "creates company and return to show" do -      pending        visit referential_companies_path(referential)        click_link "Ajouter un transporteur"        fill_in "Nom", :with => "Company 1" @@ -42,7 +39,6 @@ describe "Companies" do    describe "edit and return to show" do            it "edit company" do -      pending        visit referential_company_path(referential, subject)        click_link "Modifier ce transporteur"        fill_in "Nom", :with => "Company Modified" diff --git a/spec/requests/connection_links_spec.rb b/spec/requests/connection_links_spec.rb index 48b5aa41d..74fe17c2e 100644 --- a/spec/requests/connection_links_spec.rb +++ b/spec/requests/connection_links_spec.rb @@ -4,12 +4,11 @@ require 'spec_helper'  describe "ConnectionLinks" do    login_user -  let(:connection_links) { Array.new(2) { create(:connection_link) } } +  let!(:connection_links) { Array.new(2) { create(:connection_link) } }    subject { connection_links.first }    describe "list" do      it "display connection_links" do -      pending        visit referential_connection_links_path(referential)        page.should have_content(connection_links.first.name)        page.should have_content(connection_links.last.name) @@ -19,14 +18,12 @@ describe "ConnectionLinks" do    describe "show" do            it "display connection_link" do -      pending        visit referential_connection_links_path(referential)        click_link "#{connection_links.first.name}"        page.should have_content(connection_links.first.name)      end      it "display map" do -      pending ": map not yet implemented"        subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_connection_links_path(referential)        click_link "#{connection_links.first.name}" @@ -37,7 +34,6 @@ describe "ConnectionLinks" do    describe "new" do           it "creates connection_link and return to show" do -      pending        visit referential_connection_links_path(referential)        click_link "Ajouter une correspondance"        fill_in "Nom", :with => "ConnectionLink 1" @@ -49,7 +45,6 @@ describe "ConnectionLinks" do    describe "edit and return to show" do            it "edit connection_link" do -      pending        visit referential_connection_link_path(referential, subject)        click_link "Modifier cette correspondance"        fill_in "Nom", :with => "ConnectionLink Modified" diff --git a/spec/requests/lines_spec.rb b/spec/requests/lines_spec.rb index 10d653f30..b851f522a 100644 --- a/spec/requests/lines_spec.rb +++ b/spec/requests/lines_spec.rb @@ -4,14 +4,13 @@ require 'spec_helper'  describe "Lines" do    login_user -  let(:network) { Factory(:network) } -  let(:company) { Factory(:company) } -  let(:lines) { referential; Array.new(2) { Factory(:line, :network => network, :company => company) } } +  let!(:network) { Factory(:network) } +  let!(:company) { Factory(:company) } +  let!(:lines) { Array.new(2) { Factory(:line_with_stop_areas, :network => network, :company => company) } }    subject { lines.first }    describe "list" do      it "display lines" do -      pending        visit referential_lines_path(referential)        page.should have_content(lines.first.name)        page.should have_content(lines.last.name) @@ -22,16 +21,12 @@ describe "Lines" do    describe "show" do            it "display line" do -      pending -      subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_lines_path(referential)        click_link "#{lines.first.name}"        page.should have_content(lines.first.name)      end      it "display map" do -      pending -      subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_lines_path(referential)        click_link "#{lines.first.name}"        page.should have_selector("#map", :class => 'line') @@ -41,13 +36,11 @@ describe "Lines" do    describe "new" do            it "creates line and return to show" do -      pending -      subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_lines_path(referential)        click_link "Ajouter une ligne"        fill_in "Nom", :with => "Line 1" -      fill_in "Numéro d'enregistrement", :with => "test-1" -      fill_in "Identifiant Neptune", :with => "test:Line:1"         +      fill_in "Numéro d'enregistrement", :with => "1" +      fill_in "Identifiant Neptune", :with => "test:Line:999"                click_button("Créer ligne")        page.should have_content("Line 1")      end @@ -55,8 +48,6 @@ describe "Lines" do    describe "edit and return to show" do            it "edit line" do -      pending -      subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_line_path(referential, subject)        click_link "Modifier cette ligne"        fill_in "Nom", :with => "Line Modified" diff --git a/spec/requests/networks_spec.rb b/spec/requests/networks_spec.rb index ff020dca6..662e5e830 100644 --- a/spec/requests/networks_spec.rb +++ b/spec/requests/networks_spec.rb @@ -4,13 +4,11 @@ require 'spec_helper'  describe "Networks" do    login_user -  let(:networks) { Array.new(2) { Factory(:network) } } +  let!(:networks) { Array.new(2) { Factory(:network) } }    subject { networks.first }    describe "list" do      it "display networks" do -      pending -        visit referential_networks_path(referential)        page.should have_content(networks.first.name)        page.should have_content(networks.last.name) @@ -20,8 +18,6 @@ describe "Networks" do    describe "show" do            it "display network" do -      pending -        subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_networks_path(referential)        click_link "#{networks.first.name}" @@ -29,8 +25,6 @@ describe "Networks" do      end      it "display map" do -      pending -        subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_networks_path(referential)        click_link "#{networks.first.name}" @@ -41,8 +35,6 @@ describe "Networks" do    describe "new" do            it "creates network and return to show" do -      pending -        subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_networks_path(referential)        click_link "Ajouter un réseau" @@ -56,8 +48,6 @@ describe "Networks" do    describe "edit and return to show" do            it "edit network" do -      pending -        subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })        visit referential_network_path(referential, subject)        click_link "Modifier ce réseau" @@ -68,23 +58,15 @@ describe "Networks" do      end    end -  describe "delete", :js => true do       -    it "delete network and return to the list" do -      # subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) }) -       -      # visit referential_networks_path(referential) -      # click_link "#{networks.first.name}" -      # click_link "Modifier ce réseau" -      # fill_in "Nom", :with => "Network 1" -      # fill_in "Numéro d'enregistrement", :with => "test-1" -      # click_button("Modifier Réseau") -      # page.should have_content("Network 1") -      # visit referential_network_path(referential, subject) -      # click_link "Supprimer ce réseau" -      # page.evaluate_script('window.confirm = function() { return true; }') -      # click_button "Valider" -      # page.should have_no_content("Network 1") -    end +  # describe "delete", :js => true do       +  #   it "delete network and return to the list" do +  #     subject.stub(:stop_areas).and_return(Array.new(2) { Factory(:stop_area) })      +  #     visit referential_network_path(referential, subject) +  #     click_link "Supprimer ce réseau" +  #     page.evaluate_script('window.confirm = function() { return true; }') +  #     click_button "Valider" +  #     page.should have_no_content(subject.name) +  #   end -  end +  # end  end diff --git a/spec/requests/referentials_spec.rb b/spec/requests/referentials_spec.rb index 9203de16d..c57192d9b 100644 --- a/spec/requests/referentials_spec.rb +++ b/spec/requests/referentials_spec.rb @@ -22,8 +22,6 @@ describe "Referentials" do                                retrieve_referential_by_slug("bb")] }          it "should show n referentials" do -        pending -          visit referentials_path          page.should have_content(referentials.first.name)          page.should have_content(referentials.last.name) diff --git a/spec/requests/routes_spec.rb b/spec/requests/routes_spec.rb index 3ba1985eb..5e24b8492 100644 --- a/spec/requests/routes_spec.rb +++ b/spec/requests/routes_spec.rb @@ -4,9 +4,9 @@ require 'spec_helper'  describe "Routes" do    login_user -  let(:line) { Factory(:line) } -  let(:route) { Factory(:route, :line => line) } -  let(:route2) { Factory(:route, :line => line) } +  let!(:line) { Factory(:line) } +  let!(:route) { Factory(:route, :line => line) } +  let!(:route2) { Factory(:route, :line => line) }    describe "from lines page to a line page" do      it "display line's routes" do diff --git a/spec/requests/stop_areas_spec.rb b/spec/requests/stop_areas_spec.rb index 5d4e3afb3..ef3ca9275 100644 --- a/spec/requests/stop_areas_spec.rb +++ b/spec/requests/stop_areas_spec.rb @@ -4,30 +4,25 @@ require 'spec_helper'  describe "StopAreas" do    login_user -  let(:stop_areas) { Array.new(2) { Factory(:stop_area) } } +  let!(:stop_areas) { Array.new(2) { Factory(:stop_area) } }    subject { stop_areas.first }    describe "list" do      it "display stop_areas" do -      pending        visit referential_stop_areas_path(referential)        page.should have_content(stop_areas.first.name)        page.should have_content(stop_areas.last.name) -    end -     +    end        end -      describe "show" do            it "display stop_area" do -      pending        visit referential_stop_areas_path(referential)        click_link "#{stop_areas.first.name}"        page.should have_content(stop_areas.first.name)      end      it "display map" do -      pending        visit referential_stop_areas_path(referential)        click_link "#{stop_areas.first.name}"        page.should have_selector("#map", :class => 'stop_area') @@ -37,12 +32,11 @@ describe "StopAreas" do    describe "new" do            it "creates stop_area and return to show" do -      pending        visit referential_stop_areas_path(referential)        click_link "Ajouter un arrêt"        fill_in "Nom", :with => "StopArea 1"        fill_in "Numéro d'enregistrement", :with => "test-1" -      #fill_in "Identifiant Neptune", :with => "test:StopArea:1"         +      fill_in "Identifiant Neptune", :with => "test:StopArea:1"                click_button("Créer arrêt")        page.should have_content("StopArea 1")      end @@ -50,7 +44,6 @@ describe "StopAreas" do    describe "edit and return to show" do            it "edit stop_area" do -      pending        visit referential_stop_area_path(referential, subject)        click_link "Modifier cet arrêt"        fill_in "Nom", :with => "StopArea Modified" diff --git a/spec/requests/time_tables_spec.rb b/spec/requests/time_tables_spec.rb index c935587b3..412dcece6 100644 --- a/spec/requests/time_tables_spec.rb +++ b/spec/requests/time_tables_spec.rb @@ -4,12 +4,11 @@ require 'spec_helper'  describe "TimeTables" do    login_user -  let(:time_tables) { Array.new(2) { create(:time_table) } } +  let!(:time_tables) { Array.new(2) { create(:time_table) } }    subject { time_tables.first }    describe "list" do      it "display time_tables" do -      pending        visit referential_time_tables_path(referential)        page.should have_content(time_tables.first.comment)        page.should have_content(time_tables.last.comment) @@ -19,7 +18,6 @@ describe "TimeTables" do    describe "show" do            it "display time_table" do -      pending        visit referential_time_tables_path(referential)        click_link "#{time_tables.first.comment}"        page.should have_content(time_tables.first.comment) @@ -29,7 +27,6 @@ describe "TimeTables" do    describe "new" do            it "creates time_table and return to show" do -      pending        visit referential_time_tables_path(referential)        click_link "Ajouter un calendrier"        fill_in "Description", :with => "TimeTable 1" @@ -41,7 +38,6 @@ describe "TimeTables" do    describe "edit and return to show" do            it "edit time_table" do -      pending        visit referential_time_table_path(referential, subject)        click_link "Modifier ce calendrier"        fill_in "Description", :with => "TimeTable Modified" diff --git a/spec/support/devise.rb b/spec/support/devise.rb index b50f3a71a..8713e96fa 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -3,7 +3,7 @@ module DeviseRequestHelper    def login_user      organisation = Organisation.find_by_name("first") || create(:organisation, :name => "first") -    @user ||= create(:user, :organisation => organisation)  +    @user ||= create(:user, :organisation => organisation)      @user.confirm!      login_as @user, :scope => :user      # post_via_redirect user_session_path, 'user[email]' => @user.email, 'user[password]' => @user.password @@ -22,7 +22,7 @@ module DeviseRequestHelper          login_user        end        after(:each) do -        Warden.test_reset!             +        Warden.test_reset!        end      end diff --git a/spec/support/type_ids_modelable_spec.rb b/spec/support/type_ids_modelable_spec.rb new file mode 100644 index 000000000..d5a3f7042 --- /dev/null +++ b/spec/support/type_ids_modelable_spec.rb @@ -0,0 +1,100 @@ +require 'spec_helper' + +shared_examples_for TypeIdsModelable do +  context 'class methods' do +    it 'should be a TypeIdsModelable class' do +      described_class.type_ids_modelable_class?.should be_true +    end +    describe ".references_relation" do +      it "shoud demodulize, underscore and puralize" do +        described_class.references_relation( Chouette::StopArea).should == "stop_areas" +      end +    end +  end + +  context 'with an instance' do +    describe "#references" do +      it "should be empty if references_type is nil" do +        type_ids_model.references_type = nil +        type_ids_model.references.should be_empty +      end +      it "should be empty if reference_ids is blank" do +        type_ids_model.reference_ids = "" +        type_ids_model.references.should be_empty +      end +    end +    describe "#references=" do +      let(:lines) { create_list :line, 3 } + +      context "when references defined" do +        before(:each) do +          type_ids_model.references = lines +        end +        it "should set reference_ids to [data_a.id]" do +          type_ids_model.reference_ids.should == lines.map(&:id) +        end +        it "should set references_type to EffectiveDataTypeA" do +          type_ids_model.references_type.should == 'Chouette::Line' +        end +      end +      context "when references blank" do +        before(:each) do +          type_ids_model.references = "" +        end +        it "should set reference_ids to []" do +          type_ids_model.reference_ids.should == [] +        end +        it "should set references_type to nil" do +          type_ids_model.references_type.should be_nil +        end +      end +    end + +    describe "#references_relation" do +      it "should be 'lines' when relation_type is 'Chouette::Line'" do +        type_ids_model.references_type = "Chouette::Line" +        type_ids_model.references_relation.should == "lines" +      end + +      it "should be 'networks' when relation_type is 'Chouette::Network'" do +        type_ids_model.references_type = "Chouette::Network" +        type_ids_model.references_relation.should == "networks" +      end + +      it "should be nil when relation_type is blank" do +        type_ids_model.references_type = "" +        type_ids_model.references_relation.should be_nil +      end + +      it "should be nil when relation_type is 'dummy'" do +        type_ids_model.references_type = "dummy" +        type_ids_model.references_relation.should be_nil +      end +    end + +    describe "#reference_ids" do +      it "should parse raw_reference_ids and returns ids" do +        type_ids_model.stub :raw_reference_ids => "1,2,3" +        type_ids_model.reference_ids.should == [1,2,3] +      end + +      it "should be empty if raw_reference_ids is blank" do +        type_ids_model.stub :raw_reference_ids => "" +        type_ids_model.reference_ids.should be_empty +      end +    end + +    describe "#reference_ids=" do +      it "should join ids with comma" do +        type_ids_model.reference_ids = [1,2,3] +        type_ids_model.raw_reference_ids.should == "1,2,3" +      end +      it "should be nil if records is blank" do +        type_ids_model.reference_ids = [] +        type_ids_model.raw_reference_ids.should be_nil +      end +    end +  end + + +end diff --git a/spec/views/imports/index.html.erb_spec.rb b/spec/views/import_tasks/index.html.erb_spec.rb index c0f2d3462..c0f2d3462 100644 --- a/spec/views/imports/index.html.erb_spec.rb +++ b/spec/views/import_tasks/index.html.erb_spec.rb diff --git a/spec/views/import_tasks/new.html.erb_spec.rb b/spec/views/import_tasks/new.html.erb_spec.rb new file mode 100644 index 000000000..002832dc9 --- /dev/null +++ b/spec/views/import_tasks/new.html.erb_spec.rb @@ -0,0 +1,15 @@ +require 'spec_helper' + +describe "import_tasks/new.html.erb" do + +  assign_referential +  let!(:import_task) { assign(:import_task, ImportTask.new) } + +  let!(:available_imports) { assign(:available_imports, []) } + +  it "should display a radio button to choose import type" do +    render +    rendered.should have_selector("input", :type => "select", :name => "import_task[format]") +  end + +end diff --git a/spec/views/imports/new.html.erb_spec.rb b/spec/views/imports/new.html.erb_spec.rb deleted file mode 100644 index 081999c60..000000000 --- a/spec/views/imports/new.html.erb_spec.rb +++ /dev/null @@ -1,15 +0,0 @@ -require 'spec_helper' - -describe "imports/new.html.erb" do - -  assign_referential -  let!(:import) { assign(:import, NeptuneImport.new) } - -  let!(:available_imports) { assign(:available_imports, []) } - -  it "should display a radio button to choose import type" do -    render -    rendered.should have_selector("input", :type => "radio", :name => "import[type]") -  end - -end diff --git a/spec/views/rule_parameter_sets/index.html.erb_spec.rb b/spec/views/rule_parameter_sets/index.html.erb_spec.rb new file mode 100644 index 000000000..0f50ea387 --- /dev/null +++ b/spec/views/rule_parameter_sets/index.html.erb_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe "/rule_parameter_sets/index" do + +  assign_referential +  let!(:rule_parameter_sets) { assign :rule_parameter_sets, [ Factory(:rule_parameter_set), +                                                              Factory(:rule_parameter_set)] } + +  it "should render a show link for each rule_parameter_set" do +    render +    rule_parameter_sets.each do |rule_parameter_set| +      rendered.should have_selector(".rule_parameter_set a[href='#{view.referential_rule_parameter_set_path(referential, rule_parameter_set)}']", :text => rule_parameter_set.name) +    end +  end + +  it "should render a link to create a new rule_parameter_set" do +    render +    view.content_for(:sidebar).should have_selector(".actions a[href='#{new_referential_rule_parameter_set_path(referential)}']") +  end + +end + diff --git a/spec/views/rule_parameter_sets/new.html.erb_spec.rb b/spec/views/rule_parameter_sets/new.html.erb_spec.rb new file mode 100644 index 000000000..4670ecceb --- /dev/null +++ b/spec/views/rule_parameter_sets/new.html.erb_spec.rb @@ -0,0 +1,26 @@ +require 'spec_helper' + +describe "/rule_parameter_sets/new" do + +  assign_referential +  let!(:rule_parameter_set) { assign :rule_parameter_set, build( :rule_parameter_set, :referential => referential) } + +  describe "form" do + +    it "should render input for name" do +      render +      rendered.should have_selector("form") do +        with_selector "input[type=text][name=?]", rule_parameter_set.name +      end +    end +    it "should render input div for added_mode_parameter_set" do +      render +      rendered.should have_selector("form") do +        with_selector "#added_mode_parameter_set" +      end +    end + +  end + +end + | 
