diff options
200 files changed, 983 insertions, 1498 deletions
| @@ -3,7 +3,7 @@ source 'https://rubygems.org'  # Use https for github  git_source(:github) { |name| "https://github.com/#{name}.git" } -git_source(:af83) { |name| "git@github.com:af83/#{name}.git" } +git_source(:af83) { |name| "https://github.com/af83/#{name}.git" }  # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'  gem 'rails', '~> 4.2.8' @@ -90,7 +90,7 @@ gem 'georuby', '2.3.0' # Fix version for georuby-ext because api has changed  gem 'mimemagic'  # User interface -gem 'language_engine', github: 'af83/language_engine' +gem 'language_engine', af83: 'language_engine'  gem 'calendar_helper', '0.2.5'  gem 'cocoon'  gem 'slim-rails', '~> 3.1' @@ -134,7 +134,7 @@ gem 'acts_as_tree', '~> 2.1.0', require: 'acts_as_tree'  gem 'rabl'  gem 'carrierwave', '~> 1.0' -gem 'sidekiq' +gem 'sidekiq', require: ['sidekiq', 'sidekiq/web']  gem 'whenever', github: 'af83/whenever', require: false # '~> 0.9'  gem 'rake'  gem 'devise-async' diff --git a/Gemfile.lock b/Gemfile.lock index 251de0e1a..4e3c76690 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,5 +1,5 @@  GIT -  remote: git@github.com:af83/has_array_of.git +  remote: https://github.com/af83/has_array_of.git    revision: a6439d93291c7a1ca224ea95a8d39ed101e2f05f    specs:      has_array_of (0.0.1) @@ -8,28 +8,28 @@ GIT        railties (>= 4.0)  GIT -  remote: git@github.com:af83/stif-codifline-api.git -  revision: c0efb26bf202e0770348bdac060b14c28e575ac2 +  remote: https://github.com/af83/language_engine.git +  revision: c4d7d5af781b55c1df4806c3960caf3c22f1ee96 +  specs: +    language_engine (0.0.7) +      rails (~> 4.2) + +GIT +  remote: https://github.com/af83/stif-codifline-api.git +  revision: a02384e2e50e7530b31ff28ad6c6cc925edf11e1    specs:      codifligne (0.0.2) -      nokogiri (>= 1.7.2) +      nokogiri (>= 1.8.2)  GIT -  remote: git@github.com:af83/stif-reflex-api.git -  revision: 7edaeddd971a1ed366bf6def1513bf8808ab2d1d +  remote: https://github.com/af83/stif-reflex-api.git +  revision: 102a1d9e04dc65cbd3e61d9d485032a7529b4cd2    specs:      reflex (0.0.2)        nokogiri (>= 1.7.2)        ruby-filemagic  GIT -  remote: https://github.com/af83/language_engine.git -  revision: c4d7d5af781b55c1df4806c3960caf3c22f1ee96 -  specs: -    language_engine (0.0.7) -      rails (~> 4.2) - -GIT    remote: https://github.com/af83/whenever.git    revision: b7963381a11243affe4f35881c85be0710f434e3    specs: @@ -306,7 +306,7 @@ GEM        thor        with_env (> 1.0)        xml-simple -    loofah (2.1.1) +    loofah (2.2.2)        crass (~> 1.0.2)        nokogiri (>= 1.5.9)      mail (2.6.4) @@ -410,8 +410,8 @@ GEM        activesupport (>= 3.2)        choice (~> 0.2.0)        ruby-graphviz (~> 1.2) -    rails-html-sanitizer (1.0.3) -      loofah (~> 2.0) +    rails-html-sanitizer (1.0.4) +      loofah (~> 2.2, >= 2.2.2)      rails-i18n (4.0.9)        i18n (~> 0.7)        railties (~> 4.0) diff --git a/app/assets/stylesheets/components/_pagination.sass b/app/assets/stylesheets/components/_pagination.sass index 88ba61c3c..b811a559c 100644 --- a/app/assets/stylesheets/components/_pagination.sass +++ b/app/assets/stylesheets/components/_pagination.sass @@ -7,6 +7,9 @@    border-radius: 0    line-height: 34px +  &:first-letter +    text-transform: capitalize +    .page_links      display: inline-block      vertical-align: top diff --git a/app/controllers/access_links_controller.rb b/app/controllers/access_links_controller.rb index 19b3eb742..4321ab37a 100644 --- a/app/controllers/access_links_controller.rb +++ b/app/controllers/access_links_controller.rb @@ -18,7 +18,6 @@ class AccessLinksController < ChouetteController    end    def show -    @map = AccessLinkMap.new(resource).with_helpers(self)      @access_point = Chouette::AccessPoint.find(params[:access_point_id])      #@access_link = Chouette::AccessLink.find(params[:id])      @stop_area = @access_link.stop_area diff --git a/app/controllers/access_points_controller.rb b/app/controllers/access_points_controller.rb index 112a13a86..5d9ee8de8 100644 --- a/app/controllers/access_points_controller.rb +++ b/app/controllers/access_points_controller.rb @@ -22,7 +22,6 @@ class AccessPointsController < ChouetteController    end    def show -    map.editable = false      @generic_access_links = @access_point.generic_access_link_matrix      @detail_access_links = @access_point.detail_access_link_matrix      show! do |format| @@ -38,7 +37,6 @@ class AccessPointsController < ChouetteController    def edit      access_point.position ||= access_point.default_position -    map.editable = true      edit!    end @@ -47,10 +45,6 @@ class AccessPointsController < ChouetteController    alias_method :access_point, :resource -  def map -    @map = AccessPointMap.new(access_point).with_helpers(self) -  end -    def collection      @q = parent.access_points.search(params[:q])      @access_points ||= diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index a6f31eead..adb3b4764 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -64,13 +64,13 @@ class CalendarsController < ChouetteController    end    def calendar_params -    permitted_params = [:id, :name, :short_name, :shared, periods_attributes: [:id, :begin, :end, :_destroy], date_values_attributes: [:id, :value, :_destroy]] +    permitted_params = [:id, :name, :shared, periods_attributes: [:id, :begin, :end, :_destroy], date_values_attributes: [:id, :value, :_destroy]]      permitted_params << :shared if policy(Calendar).share?      params.require(:calendar).permit(*permitted_params)    end    def sort_column -    Calendar.column_names.include?(params[:sort]) ? params[:sort] : 'short_name' +    Calendar.column_names.include?(params[:sort]) ? params[:sort] : 'name'    end    def sort_direction diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb index 73dc18f59..7df922d01 100644 --- a/app/controllers/compliance_controls_controller.rb +++ b/app/controllers/compliance_controls_controller.rb @@ -5,7 +5,7 @@ class ComplianceControlsController < ChouetteController    actions :all, :except => [:index]    def select_type -    @sti_subclasses = ComplianceControl.subclasses +    @sti_subclasses = ComplianceControl.subclasses.sort_by {|compliance_control| compliance_control.default_code}    end    def show diff --git a/app/controllers/connection_links_controller.rb b/app/controllers/connection_links_controller.rb index f14868776..a7f9758e8 100644 --- a/app/controllers/connection_links_controller.rb +++ b/app/controllers/connection_links_controller.rb @@ -24,7 +24,6 @@ class ConnectionLinksController < ChouetteController    end    def show -    @map = ConnectionLinkMap.new(resource).with_helpers(self)      show!    end diff --git a/app/controllers/development_toolbar_controller.rb b/app/controllers/development_toolbar_controller.rb index 20349f7b8..be9a37eba 100644 --- a/app/controllers/development_toolbar_controller.rb +++ b/app/controllers/development_toolbar_controller.rb @@ -6,6 +6,13 @@ class DevelopmentToolbarController < ApplicationController      organisation.save      current_user.permissions = params[:permissions].keys.select{|k| params[:permissions][k] == "true"}      current_user.save +    if params[:export_types].present? +      params[:export_types].each do |workgroup_id, export_types| +        workgroup = Workgroup.find workgroup_id +        workgroup.export_types = export_types.keys.select{|k| export_types[k] == "true"} +        workgroup.save! +      end +    end      redirect_to request.referrer || "/"    end  end diff --git a/app/controllers/group_of_lines_controller.rb b/app/controllers/group_of_lines_controller.rb index 46d9d077f..353cff2dc 100644 --- a/app/controllers/group_of_lines_controller.rb +++ b/app/controllers/group_of_lines_controller.rb @@ -11,7 +11,6 @@ class GroupOfLinesController < ChouetteController    belongs_to :line_referential    def show -    @map = GroupOfLineMap.new(resource).with_helpers(self)      @lines = resource.lines.order(:name)      show!    end diff --git a/app/controllers/journey_patterns_controller.rb b/app/controllers/journey_patterns_controller.rb index 881ab6630..85b6a85ce 100644 --- a/app/controllers/journey_patterns_controller.rb +++ b/app/controllers/journey_patterns_controller.rb @@ -29,7 +29,6 @@ class JourneyPatternsController < ChouetteController    end    def show -    @map = JourneyPatternMap.new(journey_pattern).with_helpers(self)      @stop_points = journey_pattern.stop_points.paginate(:page => params[:page])      show!    end diff --git a/app/controllers/networks_controller.rb b/app/controllers/networks_controller.rb index 1c69b1240..bb2ca9f7f 100644 --- a/app/controllers/networks_controller.rb +++ b/app/controllers/networks_controller.rb @@ -11,8 +11,6 @@ class NetworksController < ChouetteController    belongs_to :line_referential    def show -    @map = NetworkMap.new(resource).with_helpers(self) -      show! do        @network = @network.decorate(context: {          line_referential: line_referential diff --git a/app/controllers/referential_group_of_lines_controller.rb b/app/controllers/referential_group_of_lines_controller.rb index 1294fc5d5..66bb71b36 100644 --- a/app/controllers/referential_group_of_lines_controller.rb +++ b/app/controllers/referential_group_of_lines_controller.rb @@ -11,7 +11,6 @@ class ReferentialGroupOfLinesController < ChouetteController    belongs_to :referential    def show -    @map = GroupOfLineMap.new(resource).with_helpers(self)      @lines = resource.lines.order(:name)      show!    end diff --git a/app/controllers/referential_networks_controller.rb b/app/controllers/referential_networks_controller.rb index fe00a99df..3b76deba1 100644 --- a/app/controllers/referential_networks_controller.rb +++ b/app/controllers/referential_networks_controller.rb @@ -10,8 +10,6 @@ class ReferentialNetworksController < ChouetteController    belongs_to :referential, :parent_class => Referential    def show -    @map = NetworkMap.new(resource).with_helpers(self) -      show! do        @network = ReferentialNetworkDecorator.decorate(          @network, diff --git a/app/controllers/referential_stop_areas_controller.rb b/app/controllers/referential_stop_areas_controller.rb index 0ed330180..fa09bb773 100644 --- a/app/controllers/referential_stop_areas_controller.rb +++ b/app/controllers/referential_stop_areas_controller.rb @@ -50,22 +50,14 @@ class ReferentialStopAreasController  < ChouetteController    end    def new -    @map = StopAreaMap.new( Chouette::StopArea.new).with_helpers(self) -    @map.editable = true      new!    end    def create -    @map = StopAreaMap.new(Chouette::StopArea.new).with_helpers(self) -    @map.editable = true -      create!    end    def show -    map.editable = false -    @access_points = @stop_area.access_points -      show! do |format|        unless stop_area.position or params[:default] or params[:routing]          format.kml { @@ -80,13 +72,11 @@ class ReferentialStopAreasController  < ChouetteController    def edit      edit! do        stop_area.position ||= stop_area.default_position -      map.editable = true     end    end    def update      stop_area.position ||= stop_area.default_position -    map.editable = true      update!    end @@ -107,10 +97,6 @@ class ReferentialStopAreasController  < ChouetteController    alias_method :stop_area, :resource -  def map -    @map = StopAreaMap.new(stop_area).with_helpers(self) -  end -    def collection      @q = parent.present? ? parent.stop_areas.search(params[:q]) : referential.stop_areas.search(params[:q]) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 418ba3751..96a23c938 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -32,8 +32,6 @@ class RoutesController < ChouetteController    end    def show -    @map = RouteMap.new(route).with_helpers(self) -      @route_sp = route.stop_points      if sort_sp_column && sort_sp_direction        @route_sp = @route_sp.order(sort_sp_column + ' ' + sort_sp_direction) diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index a71392344..d0d9f652d 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -65,22 +65,15 @@ class StopAreasController < ChouetteController    def new      authorize resource_class -    # @map = StopAreaMap.new( Chouette::StopArea.new).with_helpers(self) -    # @map.editable = true      new!    end    def create      authorize resource_class -    # @map = StopAreaMap.new( Chouette::StopArea.new).with_helpers(self) -    # @map.editable = true -      create!    end    def show -    # map.editable = false -    # @access_points = @stop_area.access_points      show! do |format|        unless stop_area.position or params[:default] or params[:routing]          format.kml { @@ -95,9 +88,7 @@ class StopAreasController < ChouetteController    def edit      authorize stop_area -    edit! do -      map.editable = true -    end +    super    end    def destroy @@ -107,8 +98,6 @@ class StopAreasController < ChouetteController    def update      authorize stop_area -    map.editable = true -      update!    end @@ -129,10 +118,6 @@ class StopAreasController < ChouetteController    alias_method :stop_area, :resource    alias_method :stop_area_referential, :parent -  def map -    @map = StopAreaMap.new(stop_area).with_helpers(self) -  end -    def collection      scope = parent.present? ? parent.stop_areas : referential.stop_areas      scope = ransack_status(scope) diff --git a/app/decorators/referential_decorator.rb b/app/decorators/referential_decorator.rb index 41cad237d..cce14d160 100644 --- a/app/decorators/referential_decorator.rb +++ b/app/decorators/referential_decorator.rb @@ -43,7 +43,7 @@ class ReferentialDecorator < AF83::Decorator      end      instance_decorator.action_link policy: :edit, secondary: :show, on: :show do |l| -      l.content 'Purger' +      l.content t('actions.clean_up')        l.href '#'        l.type 'button'        l.data {{ diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 356c7e69e..479b661c8 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -14,14 +14,17 @@ module ApplicationHelper    def page_header_title(object)      # Unwrap from decorator, we want to know the object model name      object = object.object if object.try(:object) - +          if Referential === object        return object.full_name      end      local = "#{object.model_name.name.underscore.pluralize}.#{params[:action]}.title" + +    arg = object.organisation.name if Workbench === object +      if object.try(:name) -      t(local, name: object.name || object.id) +      t(local, name: arg || object.name || object.id)      else        t(local)      end diff --git a/app/helpers/compliance_controls_helper.rb b/app/helpers/compliance_controls_helper.rb index ba0c538c9..297ae3afa 100644 --- a/app/helpers/compliance_controls_helper.rb +++ b/app/helpers/compliance_controls_helper.rb @@ -8,4 +8,15 @@ module ComplianceControlsHelper      key, pattern = key_pattern      [t("compliance_controls.filters.subclasses.#{key}"), "-#{pattern}-"]    end + +  def compliance_control_metadatas(compliance_control) +    attributes = resource.class.dynamic_attributes +    attributes.push(*resource.control_attributes.keys) if resource.respond_to? :control_attributes + +    {}.tap do |hash| +      attributes.each do |attribute| +        hash[ComplianceControl.human_attribute_name(attribute)] = resource.send(attribute) +      end +    end +  end  end  diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb index 4e92c7e38..2e784ad35 100644 --- a/app/helpers/exports_helper.rb +++ b/app/helpers/exports_helper.rb @@ -16,7 +16,7 @@ module ExportsHelper      if message.message_key == "full_text"        message.message_attributes["text"]      else -      t([message.class.name.underscore.gsub('/', '_').pluralize, message.message_key].join('.'), message.message_attributes.symbolize_keys) +      t([message.class.name.underscore.gsub('/', '_').pluralize, message.message_key].join('.'), message.message_attributes&.symbolize_keys || {})      end    end @@ -53,4 +53,7 @@ module ExportsHelper      end    end +  def workgroup_exports workgroup +    Export::Base.user_visible_descendants.select{|e| workgroup.has_export? e.name} +  end  end diff --git a/app/helpers/multiple_selection_toolbox_helper.rb b/app/helpers/multiple_selection_toolbox_helper.rb index e0a1d2dd4..7e02c6d73 100644 --- a/app/helpers/multiple_selection_toolbox_helper.rb +++ b/app/helpers/multiple_selection_toolbox_helper.rb @@ -20,7 +20,7 @@ module MultipleSelectionToolboxHelper              data: {                path: delete_path,                # #5206 Missing Translations -              confirm: 'Etes-vous sûr(e) de vouloir effectuer cette action ?' +              confirm: t('actions.are_you_sure')              },              title: t("actions.#{action}")            ) do @@ -34,7 +34,7 @@ module MultipleSelectionToolboxHelper      label = content_tag(        :span, -      ("<span>0</span> élément(s) sélectionné(s)").html_safe, +      ("<span>0</span> #{t('table_builders.selected_elements')}").html_safe,        class: 'info-msg'      ) diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb index 61714a066..84b4015a2 100644 --- a/app/helpers/routes_helper.rb +++ b/app/helpers/routes_helper.rb @@ -24,7 +24,7 @@ module RoutesHelper        stop_area_attributes = stop_point.stop_area.attributes.slice("name","city_name", "zip_code", "registration_number", "longitude", "latitude", "area_type", "comment")        stop_area_attributes["short_name"] = truncate(stop_area_attributes["name"], :length => 30) || ""        stop_point_attributes = stop_point.attributes.slice("for_boarding","for_alighting") -      stop_area_attributes.merge(stop_point_attributes).merge(stoppoint_id: stop_point.id, stoparea_id: stop_point.stop_area.id).merge(user_objectid: stop_point.stop_area.user_objectid) +      stop_area_attributes.merge(stop_point_attributes).merge(stoppoint_id: stop_point.id, stoparea_id: stop_point.stop_area.id, stoparea_kind: stop_point.stop_area.kind).merge(user_objectid: stop_point.stop_area.user_objectid)      end      data = data.to_json if serialize      data diff --git a/app/javascript/helpers/save_button.js b/app/javascript/helpers/save_button.js index 7e0bd5bbe..af5ee54a8 100644 --- a/app/javascript/helpers/save_button.js +++ b/app/javascript/helpers/save_button.js @@ -35,7 +35,7 @@ export default class SaveButton extends Component{                      this.props.editMode ? this.submitForm() : this.props.onEnterEditMode()                    }}                  > -                  {this.props.editMode ? "Valider" : "Editer"} +                  {this.props.editMode ? I18n.t('actions.submit') : I18n.t('actions.edit')}                  </button>                </div>              </form> diff --git a/app/javascript/journey_patterns/actions/index.js b/app/javascript/journey_patterns/actions/index.js index b90908264..666157ea4 100644 --- a/app/javascript/journey_patterns/actions/index.js +++ b/app/javascript/journey_patterns/actions/index.js @@ -220,7 +220,16 @@ const actions = {        })    },    fetchRouteCosts: (dispatch, key, index) => { -    if (actions.routeCostsCache) { +    if(actions.fetchingRouteCosts){ +        // A request is already sent, wait for it +        if(!actions.waitingForRouteCosts){ +          actions.waitingForRouteCosts = [] +        } +        actions.waitingForRouteCosts.push([key, index]) +        return +    } + +    if(actions.routeCostsCache) {        // Dispatch asynchronously to prevent warning when        // this executes during `render()`        requestAnimationFrame(() => { @@ -231,6 +240,7 @@ const actions = {          ))        })      } else { +      actions.fetchingRouteCosts = true        fetch(window.routeCostsUrl, {          credentials: 'same-origin',        }).then(response => { @@ -240,6 +250,12 @@ const actions = {          actions.routeCostsCache = costs          dispatch(actions.receiveRouteCosts(costs, key, index)) +        if(actions.waitingForRouteCosts){ +          actions.waitingForRouteCosts.map(function(item, i) { +            dispatch(actions.receiveRouteCosts(costs, item[0], item[1])) +          }) +        } +        actions.fetchingRouteCosts = false        })      }    }, diff --git a/app/javascript/journey_patterns/components/ConfirmModal.js b/app/javascript/journey_patterns/components/ConfirmModal.js index ccd0a9384..fdf32649f 100644 --- a/app/javascript/journey_patterns/components/ConfirmModal.js +++ b/app/javascript/journey_patterns/components/ConfirmModal.js @@ -9,11 +9,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan          <div className='modal-dialog'>            <div className='modal-content'>              <div className='modal-header'> -              <h4 className='modal-title'>Confirmation</h4> +              <h4 className='modal-title'>{I18n.t('journey_patterns.show.confirmation')}</h4>              </div>              <div className='modal-body'>                <div className='mt-md mb-md'> -                <p>Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?</p> +                <p>{I18n.t('journey_patterns.show.confirm_page_change')}</p>                </div>              </div>              <div className='modal-footer'> @@ -23,7 +23,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                  type='button'                  onClick={() => { onModalCancel(modal.confirmModal.callback) }}                > -                Ne pas valider +                {I18n.t('cancel')}              </button>                <button                  className='btn btn-primary' @@ -31,7 +31,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                  type='button'                  onClick={() => { onModalAccept(modal.confirmModal.callback, journeyPatterns) }}                > -                Valider +                {I18n.t('actions.submit')}              </button>              </div>            </div> diff --git a/app/javascript/journey_patterns/components/CreateModal.js b/app/javascript/journey_patterns/components/CreateModal.js index a6c1b608a..36b5740dc 100644 --- a/app/javascript/journey_patterns/components/CreateModal.js +++ b/app/javascript/journey_patterns/components/CreateModal.js @@ -38,14 +38,14 @@ export default class CreateModal extends Component {                    <div className='modal-dialog'>                      <div className='modal-content'>                        <div className='modal-header'> -                        <h4 className='modal-title'>Ajouter une mission</h4> +                        <h4 className='modal-title'>{I18n.t('journey_patterns.actions.new')}</h4>                        </div>                        {(this.props.modal.type == 'create') && (                          <form>                            <div className='modal-body'>                              <div className='form-group'> -                              <label className='control-label is-required'>Nom</label> +                              <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>                                <input                                  type='text'                                  ref='name' @@ -57,7 +57,7 @@ export default class CreateModal extends Component {                              <div className='row'>                                <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                                  <div className='form-group'> -                                  <label className='control-label is-required'>Nom public</label> +                                  <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}c</label>                                    <input                                      type='text'                                      ref='published_name' @@ -69,7 +69,7 @@ export default class CreateModal extends Component {                                </div>                                <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                                  <div className='form-group'> -                                  <label className='control-label'>Code mission</label> +                                  <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>                                    <input                                      type='text'                                      ref='registration_number' @@ -87,14 +87,14 @@ export default class CreateModal extends Component {                                type='button'                                onClick={this.props.onModalClose}                                > -                              Annuler +                              {I18n.t('cancel')}                              </button>                              <button                                className='btn btn-primary'                                type='button'                                onClick={this.handleSubmit.bind(this)}                                > -                              Valider +                              {I18n.t('actions.submit')}                              </button>                            </div>                          </form> diff --git a/app/javascript/journey_patterns/components/EditModal.js b/app/javascript/journey_patterns/components/EditModal.js index c960cb41c..1960849fb 100644 --- a/app/javascript/journey_patterns/components/EditModal.js +++ b/app/javascript/journey_patterns/components/EditModal.js @@ -18,12 +18,12 @@ export default class EditModal extends Component {      if (this.props.editMode) {        return (          <h4 className='modal-title'> -          Editer la mission +          {I18n.t('journey_patterns.actions.edit')}            {this.props.modal.type == 'edit' && <em> "{this.props.modal.modalProps.journeyPattern.name}"</em>}          </h4>        )      } else { -      return <h4 className='modal-title'> Informations </h4> +      return <h4 className='modal-title'> {I18n.t('journey_patterns.show.informations')} </h4>      }    } @@ -41,7 +41,7 @@ export default class EditModal extends Component {                  <form>                    <div className='modal-body'>                      <div className='form-group'> -                      <label className='control-label is-required'>Nom</label> +                      <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>                        <input                          type='text'                          ref='name' @@ -57,7 +57,7 @@ export default class EditModal extends Component {                      <div className='row'>                        <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                          <div className='form-group'> -                          <label className='control-label is-required'>Nom public</label> +                          <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}</label>                            <input                              type='text'                              ref='published_name' @@ -72,7 +72,7 @@ export default class EditModal extends Component {                        </div>                        <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>                          <div className='form-group'> -                          <label className='control-label'>Code mission</label> +                          <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>                            <input                              type='text'                              ref='registration_number' @@ -86,7 +86,7 @@ export default class EditModal extends Component {                        </div>                      </div>                      <div> -                      <label className='control-label'>Signature métier</label> +                      <label className='control-label'>{I18n.attribute_name('journey_pattern', 'checksum')}</label>                          <input                          type='text'                          ref='checksum' @@ -105,14 +105,14 @@ export default class EditModal extends Component {                          type='button'                          onClick={this.props.onModalClose}                        > -                        Annuler +                        {I18n.t('cancel')}                        </button>                        <button                          className='btn btn-primary'                          type='button'                          onClick={this.handleSubmit.bind(this)}                        > -                        Valider +                        {I18n.t('actions.submit')}                        </button>                      </div>                    } diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js index 15d8b6db4..d381b0d50 100644 --- a/app/javascript/journey_patterns/components/JourneyPattern.js +++ b/app/javascript/journey_patterns/components/JourneyPattern.js @@ -23,7 +23,7 @@ export default class JourneyPattern extends Component{      let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid      return ( -      <a href={vjURL}>Horaires des courses</a> +      <a href={vjURL}>{I18n.t('journey_patterns.journey_pattern.vehicle_journey_at_stops')}</a>      )    } @@ -80,7 +80,6 @@ export default class JourneyPattern extends Component{      let from = null      this.props.value.stop_points.map((stopPoint, i) =>{        let usePoint = stopPoint.checked -      console.log(stopPoint)        if(onlyCommercial && (i == 0 || i == this.props.value.stop_points.length - 1) && stopPoint.kind == "non_commercial"){          usePoint = false        } @@ -131,23 +130,20 @@ export default class JourneyPattern extends Component{      }    } -  componentWillUpdate() { -    [this.totalTime, this.totalDistance] = this.totals(false) -  } -    render() {      this.previousSpId = undefined +    let [totalTime, totalDistance] = this.totals(false)      let [commercialTotalTime, commercialTotalDistance] = this.totals(true)      return (        <div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.object_id ? '' : ' to_record') + (this.props.value.errors ? ' has-error': '') + (this.hasFeature('costs_in_journey_patterns') ? ' with-costs' : '')}>          <div className='th'>            <div className='strong mb-xs'>{this.props.value.object_id ? this.props.value.short_id : '-'}</div>            <div>{this.props.value.registration_number}</div> -          <div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div> +          <div>{I18n.t('journey_patterns.show.stop_points_count', {count: actions.getChecked(this.props.value.stop_points).length})}</div>            {this.hasFeature('costs_in_journey_patterns') &&              <div className="small row totals"> -              <span className="col-md-6"><i className="fa fa-arrows-h"></i>{this.totalDistance}</span> -              <span className="col-md-6"><i className="fa fa-clock-o"></i>{this.totalTime}</span> +              <span className="col-md-6"><i className="fa fa-arrows-h"></i>{totalDistance}</span> +              <span className="col-md-6"><i className="fa fa-clock-o"></i>{totalTime}</span>              </div>            }            {this.hasFeature('costs_in_journey_patterns') && @@ -171,7 +167,7 @@ export default class JourneyPattern extends Component{                    data-toggle='modal'                    data-target='#JourneyPatternModal'                    > -                  {this.props.editMode ? 'Editer' : 'Consulter'} +                  {this.props.editMode ? I18n.t('actions.edit') : I18n.t('actions.show')}                  </button>                </li>                <li className={this.props.value.object_id ? '' : 'disabled'}> @@ -187,7 +183,7 @@ export default class JourneyPattern extends Component{                      this.props.onDeleteJourneyPattern(this.props.index)}                    }                    > -                    <span className='fa fa-trash'></span>Supprimer +                    <span className='fa fa-trash'></span>{I18n.t('actions.destroy')}                    </button>                  </li>                </ul> diff --git a/app/javascript/journey_patterns/components/JourneyPatterns.js b/app/javascript/journey_patterns/components/JourneyPatterns.js index 930acb390..91c783189 100644 --- a/app/javascript/journey_patterns/components/JourneyPatterns.js +++ b/app/javascript/journey_patterns/components/JourneyPatterns.js @@ -84,14 +84,14 @@ export default class JourneyPatterns extends Component {            <div className='col-lg-12'>              {(this.props.status.fetchSuccess == false) && (                <div className="alert alert-danger mt-sm"> -                <strong>Erreur : </strong> -                la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème +                <strong>{I18n.t('error')} : </strong> +                {I18n.t('journeys_patterns.journey_pattern.fetching_error')}                </div>              )}              { _.some(this.props.journeyPatterns, 'errors') && (                <div className="alert alert-danger mt-sm"> -                <strong>Erreur : </strong> +                <strong> {I18n.t('error')} : </strong>                  {this.props.journeyPatterns.map((jp, index) =>                    jp.errors && jp.errors.map((err, i) => {                      return ( @@ -107,9 +107,9 @@ export default class JourneyPatterns extends Component {              <div className={'table table-2entries mt-sm mb-sm' + ((this.props.journeyPatterns.length > 0) ? '' : ' no_result')}>                <div className='t2e-head w20'>                  <div className='th'> -                  <div className='strong mb-xs'>ID Mission</div> -                  <div>Code mission</div> -                  <div>Nb arrêts</div> +                  <div className='strong mb-xs'>{I18n.t('objectid')}</div> +                  <div>{I18n.attribute_name('journey_pattern', 'registration_number')}</div> +                  <div>{I18n.attribute_name('journey_pattern', 'stop_points')}</div>                    { this.hasFeature('costs_in_journey_patterns') &&                       <div>                         <div>{I18n.attribute_name('journey_pattern', 'full_journey_time')}</div> diff --git a/app/javascript/journey_patterns/components/Navigate.js b/app/javascript/journey_patterns/components/Navigate.js index 78f324a7d..9e454da5e 100644 --- a/app/javascript/journey_patterns/components/Navigate.js +++ b/app/javascript/journey_patterns/components/Navigate.js @@ -1,5 +1,6 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types' +import capitalize from 'lodash/capitalize'  import actions from '../actions'  export default function Navigate({ dispatch, journeyPatterns, pagination, status }) { @@ -17,7 +18,7 @@ export default function Navigate({ dispatch, journeyPatterns, pagination, status        <div className='row'>          <div className='col-lg-12 text-right'>            <div className='pagination'> -            Liste des missions {firstItemOnPage} à {(lastItemOnPage < pagination.totalCount) ? lastItemOnPage : pagination.totalCount} sur {pagination.totalCount} +            {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('journey_pattern', { plural: true })), from: firstItemOnPage, to: lastItemOnPage, count: pagination.totalCount})}              <form className='page_links' onSubmit={e => {                  e.preventDefault()                }}> diff --git a/app/javascript/packs/routes/edit.js b/app/javascript/packs/routes/edit.js index b787bec97..fc7aa203d 100644 --- a/app/javascript/packs/routes/edit.js +++ b/app/javascript/packs/routes/edit.js @@ -29,6 +29,7 @@ const getInitialState = () => {      state.push({        stoppoint_id: v.stoppoint_id,        stoparea_id: v.stoparea_id, +      stoparea_kind: v.stoparea_kind,        user_objectid: v.user_objectid,        short_name: v.short_name ? v.short_name.replace("'", "\'") : '',        area_type: v.area_type, @@ -39,8 +40,8 @@ const getInitialState = () => {        name: v.name ? v.name.replace("'", "\'") : '',        registration_number: v.registration_number,        text: fancyText, -      for_boarding: v.for_boarding || "normal", -      for_alighting: v.for_alighting || "normal", +      for_boarding: v.for_boarding, +      for_alighting: v.for_alighting,        longitude: v.longitude || 0,        latitude: v.latitude || 0,        comment: v.comment ? v.comment.replace("'", "\'") : '', diff --git a/app/javascript/packs/vehicle_journeys/index.js b/app/javascript/packs/vehicle_journeys/index.js index e6867cb17..9cad3870e 100644 --- a/app/javascript/packs/vehicle_journeys/index.js +++ b/app/javascript/packs/vehicle_journeys/index.js @@ -9,7 +9,7 @@ import { enableBatching } from '../../vehicle_journeys/batch'  // logger, DO NOT REMOVE  // var applyMiddleware = require('redux').applyMiddleware -// var createLogger = require('redux-logger') +// import { createLogger } from 'redux-logger';  // var thunkMiddleware = require('redux-thunk').default  // var promise = require('redux-promise') diff --git a/app/javascript/routes/actions/index.js b/app/javascript/routes/actions/index.js index 13b2d60b2..5fbf5bce9 100644 --- a/app/javascript/routes/actions/index.js +++ b/app/javascript/routes/actions/index.js @@ -56,7 +56,12 @@ const actions = {    unselectMarker: (index) => ({      type: 'UNSELECT_MARKER',      index -  }) +  }), +  defaultAttribute: (attribute, stopAreaKind) => { +    if (attribute !== '') return attribute +    if (stopAreaKind === undefined) return '' +    return stopAreaKind === "commercial" ? "normal" : "forbidden"  +  }   }  module.exports = actions diff --git a/app/javascript/routes/components/BSelect2.js b/app/javascript/routes/components/BSelect2.js index 035bce155..89e1b6cfa 100644 --- a/app/javascript/routes/components/BSelect2.js +++ b/app/javascript/routes/components/BSelect2.js @@ -17,6 +17,7 @@ export default class BSelect3 extends Component {      this.props.onChange(this.props.index, {        text: e.currentTarget.textContent,        stoparea_id: e.currentTarget.value, +      stoparea_kind: e.params.data.kind,        user_objectid: e.params.data.user_objectid,        longitude: e.params.data.longitude,        latitude: e.params.data.latitude, diff --git a/app/javascript/routes/components/StopPoint.js b/app/javascript/routes/components/StopPoint.js index af51a6bb4..368ec8261 100644 --- a/app/javascript/routes/components/StopPoint.js +++ b/app/javascript/routes/components/StopPoint.js @@ -4,6 +4,8 @@ import PropTypes from 'prop-types'  import BSelect2 from './BSelect2'  import OlMap from './OlMap' +import { defaultAttribute } from '../actions'  +  export default function StopPoint(props, {I18n}) {    return (      <div className='nested-fields'> @@ -17,14 +19,14 @@ export default function StopPoint(props, {I18n}) {          </div>          <div> -          <select className='form-control' value={props.value.for_boarding} id="for_boarding" onChange={props.onSelectChange}> +          <select className='form-control' value={defaultAttribute(props.value.for_boarding, props.value.stoparea_kind)} id="for_boarding" onChange={props.onSelectChange}>              <option value="normal">{I18n.t('routes.edit.stop_point.boarding.normal')}</option>              <option value="forbidden">{I18n.t('routes.edit.stop_point.boarding.forbidden')}</option>            </select>          </div>          <div> -          <select className='form-control' value={props.value.for_alighting} id="for_alighting" onChange={props.onSelectChange}> +          <select className='form-control' value={defaultAttribute(props.value.for_alighting, props.value.stoparea_kind)} id="for_alighting" onChange={props.onSelectChange}>              <option value="normal">{I18n.t('routes.edit.stop_point.alighting.normal')}</option>              <option value="forbidden">{I18n.t('routes.edit.stop_point.alighting.forbidden')}</option>            </select> diff --git a/app/javascript/routes/index.js b/app/javascript/routes/index.js index febae7d54..3c7322953 100644 --- a/app/javascript/routes/index.js +++ b/app/javascript/routes/index.js @@ -26,6 +26,7 @@ const getInitialState = () => {      state.push({        stoppoint_id: v.stoppoint_id,        stoparea_id: v.stoparea_id, +      stoparea_kind: v.stoparea_kind,        user_objectid: v.user_objectid,        short_name: v.short_name ? v.short_name.replace("'", "\'") : '',        area_type: v.area_type, @@ -36,8 +37,8 @@ const getInitialState = () => {        name: v.name ? v.name.replace("'", "\'") : '',        registration_number: v.registration_number,        text: fancyText, -      for_boarding: v.for_boarding || "normal", -      for_alighting: v.for_alighting || "normal", +      for_boarding: v.for_boarding || '', +      for_alighting: v.for_alighting || '',        longitude: v.longitude || 0,        latitude: v.latitude || 0,        comment: v.comment ? v.comment.replace("'", "\'") : '', diff --git a/app/javascript/routes/reducers/stopPoints.js b/app/javascript/routes/reducers/stopPoints.js index 0b42b504f..ba183d002 100644 --- a/app/javascript/routes/reducers/stopPoints.js +++ b/app/javascript/routes/reducers/stopPoints.js @@ -8,8 +8,8 @@ const stopPoint = (state = {}, action, length) => {          text: '',          index: length,          edit: true, -        for_boarding: 'normal', -        for_alighting: 'normal', +        for_boarding: '', +        for_alighting: '',          olMap: {            isOpened: false,            json: {} @@ -68,6 +68,7 @@ const stopPoints = (state = [], action) => {                stoppoint_id: t.stoppoint_id,                text: action.text.text,                stoparea_id: action.text.stoparea_id, +              stoparea_kind: action.text.stoparea_kind,                user_objectid: action.text.user_objectid,                latitude: action.text.latitude,                longitude: action.text.longitude, diff --git a/app/javascript/time_tables/components/SaveTimetable.js b/app/javascript/time_tables/components/SaveTimetable.js index 704590abd..468f1773b 100644 --- a/app/javascript/time_tables/components/SaveTimetable.js +++ b/app/javascript/time_tables/components/SaveTimetable.js @@ -26,7 +26,7 @@ export default class SaveTimetable extends Component{                  }                }}              > -              Valider +              {I18n.t('actions.submit')}              </button>            </form>          </div> diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js index 75e8a3932..330b4e02f 100644 --- a/app/javascript/vehicle_journeys/components/ConfirmModal.js +++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js @@ -16,7 +16,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                type='button'                onClick={() => { onModalCancel(modal.confirmModal.callback) }}              > -              Ne pas valider +              {I18n.t('cancel')}            </button>              <button                className='btn btn-danger' @@ -24,7 +24,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan                type='button'                onClick={() => { onModalAccept(modal.confirmModal.callback, vehicleJourneys) }}              > -              Valider +              {I18n.t('actions.submit')}            </button>            </div>          </div> diff --git a/app/javascript/vehicle_journeys/components/Navigate.js b/app/javascript/vehicle_journeys/components/Navigate.js index 24843babc..e79823e49 100644 --- a/app/javascript/vehicle_journeys/components/Navigate.js +++ b/app/javascript/vehicle_journeys/components/Navigate.js @@ -1,5 +1,6 @@  import React, { Component } from 'react'  import PropTypes from 'prop-types' +import capitalize from 'lodash/capitalize'  import actions from'../actions'  export default function Navigate({ dispatch, vehicleJourneys, pagination, status, filters}) { @@ -17,7 +18,7 @@ export default function Navigate({ dispatch, vehicleJourneys, pagination, status    if(status.fetchSuccess == true) {      return (        <div className="pagination"> -        {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})} +        {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('vehicle_journey', { plural: true })), from: minVJ, to: maxVJ, count: pagination.totalCount })}          <form className='page_links' onSubmit={e => {e.preventDefault()}}>            <button              onClick={e => { diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js index ca08ba3b1..c6f59ce9d 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js @@ -195,7 +195,7 @@ export default class VehicleJourneys extends Component {                </div>              )} -            { this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && ( +            { _.some(this.vehicleJourneysList(), 'errors') && (                <div className="alert alert-danger mt-sm">                  <strong>{I18n.tc("error")}</strong>                  {this.vehicleJourneysList().map((vj, index) => diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js index a60429765..f49b51f08 100644 --- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js +++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js @@ -47,7 +47,7 @@ export default class CreateModal extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Ajouter une course</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.actions.new')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -57,7 +57,7 @@ export default class CreateModal extends Component {                          <div className='row'>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Nom de la course</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'journey_name')}</label>                                <input                                  type='text'                                  ref='published_journey_name' @@ -68,7 +68,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Nom du transporteur</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company_name')}</label>                                <CompanySelect2                                  company = {this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company || undefined}                                  onSelect2Company = {(e) => this.props.onSelect2Company(e)} @@ -78,7 +78,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label is-required'>Nom public de la mission</label> +                              <label className='control-label is-required'>{I18n.attribute_name('vehicle_journey', 'journey_pattern_published_name')}</label>                                <MissionSelect2                                  selection={this.props.modal.modalProps}                                  onSelect2JourneyPattern={this.props.onSelect2JourneyPattern} @@ -89,7 +89,7 @@ export default class CreateModal extends Component {                            </div>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>Numéro de train</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'published_journey_identifier')}</label>                                <input                                  type='text'                                  ref='published_journey_identifier' @@ -105,7 +105,7 @@ export default class CreateModal extends Component {                            />                            { this.props.modal.modalProps.selectedJPModal && this.props.modal.modalProps.selectedJPModal.full_schedule && <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                                <div className='form-group'> -                                <label className='control-label'>Heure de départ</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'start_time')}</label>                                  <div className='input-group time'>                                    <input                                      type='number' @@ -142,14 +142,14 @@ export default class CreateModal extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className='btn btn-primary'                            type='button'                            onClick={this.handleSubmit.bind(this)}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js index 4815003d3..b1ce3786b 100644 --- a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js +++ b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js @@ -13,7 +13,7 @@ export default function DeleteVehicleJourneys({onDeleteVehicleJourneys, vehicleJ            e.preventDefault()            onDeleteVehicleJourneys()          }} -        title='Supprimer' +        title={ I18n.t('actions.delete') }        >          <span className='fa fa-trash'></span>        </button> diff --git a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js index 102a87d85..d7e48bf08 100644 --- a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js @@ -93,7 +93,7 @@ export default class DuplicateVehicleJourney extends Component {                  <div className='modal-content'>                    <div className='modal-header'>                      <h4 className='modal-title'> -                      Dupliquer { actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'plusieurs courses' : 'une course' } +                      {I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate', { count: actions.getSelected(this.props.vehicleJourneys).length })}                      </h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -102,7 +102,7 @@ export default class DuplicateVehicleJourney extends Component {                      <form className='form-horizontal'>                        <div className='modal-body'>                          <div className={'form-group ' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'hidden' : '' )}> -                          <label className='control-label is-required col-sm-8'>Horaire de départ indicatif</label> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.start_time')}</label>                            <span className="col-sm-4">                              <span className={'input-group time' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? ' disabled' : '')}>                                <input @@ -133,7 +133,7 @@ export default class DuplicateVehicleJourney extends Component {                          </div>                          <div className='form-group'> -                          <label className='control-label is-required col-sm-8'>Nombre de courses à créer et dupliquer</label> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.number')}</label>                            <div className="col-sm-4">                              <input                                type='number' @@ -152,7 +152,7 @@ export default class DuplicateVehicleJourney extends Component {                          </div>                          <div className='form-group'> -                          <label className='control-label is-required col-sm-8'>Décalage à partir duquel on créé les courses</label> +                          <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.delta')}</label>                            <span className="col-sm-4">                              <input                                type='number' @@ -178,7 +178,7 @@ export default class DuplicateVehicleJourney extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className={'btn btn-primary ' + (this.state.additional_time == 0 && this.state.originalDT.hour == this.state.duplicate_time_hh && this.state.originalDT.minute == this.state.duplicate_time_mm ? 'disabled' : '')} @@ -186,7 +186,7 @@ export default class DuplicateVehicleJourney extends Component {                            onClick={this.handleSubmit}                            disabled={this.disableValidateButton()}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js index d3c01f154..e4e266c79 100644 --- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js @@ -96,7 +96,7 @@ export default class EditVehicleJourney extends Component {                          <div className='row'>                            <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company')}</label> +                              <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'published_journey_identifier')}</label>                                <input                                  type='text'                                  ref='published_journey_identifier' @@ -173,14 +173,14 @@ export default class EditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                          </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit.bind(this)}                            > -                            Valider +                            {I18n.t('actions.submit')}                          </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js index 880542216..5d300f70c 100644 --- a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js @@ -43,11 +43,11 @@ export default class NotesEditVehicleJourney extends Component {    renderAssociatedFN() {      if (this.footnotes().associated.length == 0) { -      return <h3>Aucune note associée</h3> +      return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_footnotes')}</h3>      } else {        return (          <div> -          <h3>Notes associées :</h3> +          <h3>{I18n.t('vehicle_journeys.form.purchase_windows')} :</h3>            {this.footnotes().associated.map((lf, i) =>              <div                key={i} @@ -68,13 +68,13 @@ export default class NotesEditVehicleJourney extends Component {    }    renderToAssociateFN() { -    if (window.line_footnotes.length == 0) return <h3>La ligne ne possède pas de notes</h3> +    if (window.line_footnotes.length == 0) return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_line_footnotes')}</h3>      if (this.footnotes().to_associate.length == 0) return false      return (        <div> -        <h3 className='mt-lg'>Sélectionnez les notes à associer à cette course :</h3> +        <h3 className='mt-lg'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.select_footnotes')} :</h3>          {this.footnotes().to_associate.map((lf, i) =>            <div key={i} className='panel panel-default'>              <div className='panel-heading'> @@ -111,7 +111,7 @@ export default class NotesEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Notes</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.footnotes')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -130,14 +130,14 @@ export default class NotesEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                          </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit.bind(this)}                            > -                            Valider +                            {I18n.t('actions.submit')}                          </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js index ce9a4cde9..30c511302 100644 --- a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js @@ -44,7 +44,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Calendriers commerciaux associés</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.purchase_windows')}s</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -58,7 +58,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                                  <div className='wrapper'>                                    <div>                                      <div className='form-group'> -                                      <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? "Aucun calendrier commercial associé" : "Calendriers commerciaux associés"}</label> +                                      <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_purchase_windows') : I18n.t('vehicle_journeys.form.purchase_windows')}</label>                                      </div>                                    </div>                                    <div></div> @@ -117,14 +117,14 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                            </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit}                            > -                            Valider +                            {I18n.t('actions.submit')}                            </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js index 6574bfa2d..bc3d8db34 100644 --- a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js @@ -27,6 +27,7 @@ export default class ShiftVehicleJourney extends Component {    }    render() { +    let id = this.props.modal.type == 'shift' && actions.getSelected(this.props.vehicleJourneys)[0].short_id      if(this.props.status.isFetching == true) {        return false      } @@ -48,10 +49,7 @@ export default class ShiftVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Mettre à jour une course</h4> -                    {(this.props.modal.type == 'shift') && ( -                      <em>Mettre à jour les horaires de la course {actions.getSelected(this.props.vehicleJourneys)[0].short_id}</em> -                    )} +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.slide_title', {id: id})}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -61,7 +59,7 @@ export default class ShiftVehicleJourney extends Component {                          <div className='row'>                            <div className='col-lg-4 col-lg-offset-4 col-md-4 col-md-offset-4 col-sm-4 col-sm-offset-4 col-xs-12'>                              <div className='form-group'> -                              <label className='control-label is-required'>Avec un décalage de</label> +                              <label className='control-label is-required'>{I18n.t('vehicle_journeys.form.slide_delta')}</label>                                <input                                  type='number'                                  style={{'width': 104}} @@ -85,14 +83,14 @@ export default class ShiftVehicleJourney extends Component {                            type='button'                            onClick={this.props.onModalClose}                            > -                          Annuler +                          {I18n.t('cancel')}                          </button>                          <button                            className={'btn btn-primary ' + (this.state.additional_time == 0 ? 'disabled' : '')}                            type='button'                            onClick={this.handleSubmit.bind(this)}                            > -                          Valider +                          {I18n.t('actions.submit')}                          </button>                        </div>                      </form> diff --git a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js index f21480563..7a2686c13 100644 --- a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js @@ -44,7 +44,7 @@ export default class TimetablesEditVehicleJourney extends Component {                <div className='modal-dialog'>                  <div className='modal-content'>                    <div className='modal-header'> -                    <h4 className='modal-title'>Calendriers associés</h4> +                    <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.time_tables')}</h4>                      <span type="button" className="close modal-close" data-dismiss="modal">×</span>                    </div> @@ -58,7 +58,7 @@ export default class TimetablesEditVehicleJourney extends Component {                                  <div className='wrapper'>                                    <div>                                      <div className='form-group'> -                                      <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? "Aucun calendrier associé" : "Calendriers associés"}</label> +                                      <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_timetables'): I18n.t('vehicle_journeys.form.timetables')}</label>                                      </div>                                    </div>                                    <div></div> @@ -119,14 +119,14 @@ export default class TimetablesEditVehicleJourney extends Component {                              type='button'                              onClick={this.props.onModalClose}                            > -                            Annuler +                            {I18n.t('cancel')}                            </button>                            <button                              className='btn btn-primary'                              type='button'                              onClick={this.handleSubmit}                            > -                            Valider +                            {I18n.t('actions.submit')}                            </button>                          </div>                        } diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js index 5c7f75d99..b7e9691c1 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js @@ -16,6 +16,7 @@ export default class BSelect4 extends Component {    }    render() { +    let placeHolder = I18n.t('')      return (        <Select2          data={(this.props.company) ? [this.props.company.name] : undefined} @@ -29,7 +30,7 @@ export default class BSelect4 extends Component {            allowClear: true,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Filtrer par transporteur...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.affect_company'),            language: require('./fr'),            ajax: {              url: origin + path + '/companies.json' + '?line_id=' + line, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js index 72dbd0152..96b34125d 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js @@ -74,7 +74,7 @@ export default class BSelect4 extends Component {        width: '100%',        escapeMarkup: function (markup) { return markup; },        templateResult: formatRepo, -      placeholder: 'Filtrer par code, nom ou OID de mission...', +      placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.journey_pattern'),        language: require('./fr'),        allowClear: false,        escapeMarkup: function (markup) { return markup; }, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js index 0339455ca..9a345b464 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js @@ -26,7 +26,7 @@ export default class BSelect4 extends Component {            allowClear: false,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Filtrer par calendrier...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.timetable'),            language: require('./fr'),            ajax: {              url: origin + path + this.props.chunkURL, diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js index ccb4c9595..f5881cef7 100644 --- a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js +++ b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js @@ -25,7 +25,7 @@ export default class BSelect4b extends Component {          options={{            allowClear: false,            theme: 'bootstrap', -          placeholder: 'Filtrer par ID course...', +          placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.id'),            width: '100%',            language: require('./fr'),            ajax: { diff --git a/app/maps/access_link_map.rb b/app/maps/access_link_map.rb deleted file mode 100644 index 544a1e792..000000000 --- a/app/maps/access_link_map.rb +++ /dev/null @@ -1,29 +0,0 @@ - -class AccessLinkMap < ApplicationMap - -  attr_reader :access_link, :access_link_style - -  def initialize(access_link, access_link_style = nil) -    @access_link = access_link -    @access_link_style = access_link_style -  end - -  def customize_map(map, page) -    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 => 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 => 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 - -  def ready? -    Chouette::StopArea.bounds.present? -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds([access_link.stop_area.geometry,access_link.access_point.geometry].compact) -  end - -end diff --git a/app/maps/access_point_map.rb b/app/maps/access_point_map.rb deleted file mode 100644 index 3f0013738..000000000 --- a/app/maps/access_point_map.rb +++ /dev/null @@ -1,56 +0,0 @@ -class AccessPointMap < ApplicationMap - -  attr_reader :access_point - -  attr_accessor :editable -  alias_method :editable?, :editable - -  def initialize(access_point) -    @access_point = access_point -  end - -  def customize_map(map, page) -    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) -    page.assign "parent_layer", kml_layer(access_point.stop_area,  :style_map => Design::StopAreasStyleMap.new(helpers).style_map) -    page << map.add_layer(:parent_layer) -     -     -    if editable? -     page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined")   -      # TODO virer ce code inline        -      page << <<EOF -      edit_access_point_layer.events.on({  -                        'featuremodified': function(event) { -                          geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), new OpenLayers.Projection("EPSG:4326")); -                          $('#access_point_coordinates').val(geometry.y.toString()+ ","+ geometry.x.toString()); - -                          if(referential_projection != undefined) -                          { -                            projection_geometry = event.feature.geometry.clone().transform(new OpenLayers.Projection("EPSG:900913"), referential_projection ); -                            $('#access_point_projection_xy').val(projection_geometry.x.toString()+ ","+ projection_geometry.y.toString());                                                   } -                         } -                      }); -EOF -      page << map.add_control(OpenLayers::Control::ModifyFeature.new(:edit_access_point_layer, :mode => 8, :autoActivate => true)) - -    else -      page << map.add_control( hover_control_display_name(:parent_layer) ) -    end - -    page << map.set_center(center.to_google.to_openlayers, 16, false, true) -  end -   -  def projection_type -    access_point.referential.projection_type -  end - -  def ready? -    center.present? -  end - -  def center -    access_point.geometry or access_point.default_position -  end - -end diff --git a/app/maps/application_map.rb b/app/maps/application_map.rb deleted file mode 100644 index 19b9038ec..000000000 --- a/app/maps/application_map.rb +++ /dev/null @@ -1,188 +0,0 @@ -class ApplicationMap - -  include MapLayers -  include MapLayers::ViewHelpers - -  attr_accessor :helpers -  cattr_accessor :ign_api_key - -  def helpers -    @helpers ||= Helpers.new -  end - -  # For example, in a controller : -  # -  #   @map = MyMap.new(...).with_helpers(self) -  # -  def with_helpers(helpers) -    self.helpers = helpers -    self -  end - -  def geoportail_key -    if ( Rails.application.secrets.respond_to? :geoportail_api_key) -      return Rails.application.secrets.geoportail_api_key -    end -    return nil -  end - -  class Helpers -    include ActionDispatch::Routing::UrlFor -    include Rails.application.routes.url_helpers -  end - -  def projection(name) -    OpenLayers::Projection.new(name) -  end - -  def controls -    [ OpenLayers::Control::LayerSwitcher.new(:ascending => true), -      OpenLayers::Control::ScaleLine.new, -      OpenLayers::Control::Navigation.new, -      OpenLayers::Control::PanZoomBar.new, -      OpenLayers::Control::Attribution.new] -  end - -  def id -    "map" -  end - -  def map -    @map ||= MapLayers::Map.new(id, :projection => projection("EPSG:900913"), :controls => controls) do |map, page| -      if self.geoportail_key -        page << map.add_layer(geoportail_ortho_wmts) -        page << map.add_layer(geoportail_scans_wmts) -        page << map.add_layer(geoportail_cadastre_wmts) -      end - -      page << map.add_layer(MapLayers::OSM_MAPNIK) -      #page << map.add_layers([geoportail_scans, geoportail_ortho]) -      page << map.add_layer(google_physical) -      page << map.add_layer(google_streets) -      page << map.add_layer(google_hybrid) -      page << map.add_layer(google_satellite) - -      customize_map(map,page) if respond_to?( :customize_map) -    end -  end - -  def name -    self.class.name.underscore.gsub(/_map$/, '') -  end -  alias_method :default_class, :name - -  def to_html(options = {}) -    if not respond_to?(:ready?) or ready? -      expand = options[:no_fullscreen] ? '' : "<button type=\"button\" data-ce-id=\"#{id}\" data-ce-action=\"map-fullscreen\" class=\"ce-MapExpandBlock\"><i class=\"fa fa-expand\"></i></button>" -      "<div id=\"#{id}\" class=\"#{default_class}\">#{expand}</div>#{map.to_html(options)}".html_safe -    end -  end - -  def kml -    OpenLayers::Format::KML.new :extractStyles => true, :extractAttributes => true, :maxDepth => 2 -  end -  def geoportail_cadastre_wmts -    OpenLayers::Layer::WMTS.new( geoportail_options.update(:name => I18n.t("maps.ign_cadastre"), -        :format => "image/png", -        :layer => "CADASTRALPARCELS.PARCELS")) -  end - -  def geoportail_ortho_wmts -    OpenLayers::Layer::WMTS.new( geoportail_options.update(:name => I18n.t("maps.ign_ortho"), -        :layer => "ORTHOIMAGERY.ORTHOPHOTOS")) -  end - -  def geoportail_scans_wmts -    OpenLayers::Layer::WMTS.new( geoportail_options.update(:name => I18n.t("maps.ign_map"), -        :layer => "GEOGRAPHICALGRIDSYSTEMS.MAPS")) -  end - -  def geoportail_options -    { :url => "http://gpp3-wxs.ign.fr/#{self.geoportail_key}/wmts", -        :matrixSet => "PM", -        :style => "normal", -        :numZoomLevels => 19, -        :group => "IGN", -	:attribution => 'Map base: ©IGN <a href="http://www.geoportail.fr/" target="_blank"><img src="http://api.ign.fr/geoportail/api/js/2.0.0beta/theme/geoportal/img/logo_gp.gif"></a> <a href="http://www.geoportail.gouv.fr/depot/api/cgu/licAPI_CGUF.pdf" alt="TOS" title="TOS" target="_blank">Terms of Service</a>'} -  end - -  def strategy_fixed -    OpenLayers::Strategy::Fixed.new :preload => true -  end - -  def google_physical -    OpenLayers::Layer::Google.new(I18n.t("maps.google_physical"), -                      :type => :"google.maps.MapTypeId.TERRAIN") -  end - -  def google_streets -    OpenLayers::Layer::Google.new I18n.t("maps.google_streets"), :numZoomLevels => 20 -  end - -  def google_hybrid -    OpenLayers::Layer::Google.new I18n.t("maps.google_hybrid"), :type => :"google.maps.MapTypeId.HYBRID", :numZoomLevels => 20 -  end - -  def google_satellite -    OpenLayers::Layer::Google.new I18n.t("maps.google_satellite"), :type => :"google.maps.MapTypeId.SATELLITE", :numZoomLevels => 22 -  end - -  def hover_control_display_name(layer) -    OpenLayers::Control::SelectFeature.new( layer, { -                                              :autoActivate => true, -                                              :hover => true, -                                              :renderIntent => "temporary", -                                              :eventListeners => { -                                                :featurehighlighted => JsExpr.new("function(e) { -          var feature = e.feature ; -          if (feature.attributes.inactive != undefined) -            return; -          var stop_area_type_label = ''; -          if (feature.attributes.stop_area_type_label != undefined) -            stop_area_type_label = feature.attributes.stop_area_type_label; -          var popup = new OpenLayers.Popup.Anchored('chicken', -                                                 new OpenLayers.LonLat(feature.geometry.x, feature.geometry.y), -                                                 null, -                                                 \"<div class='popup_hover'><p><b>\" + feature.attributes.name +\"</b></p>\" + stop_area_type_label + \"</div> \", null, false, null); -          popup.autoSize = true; -          popup.displayClass = 'popup_hover'; - -          feature.popup = popup; -          map.addPopup(popup); -        }"), -                                                :featureunhighlighted => JsExpr.new("function(e) { -          var feature = e.feature; -          if (feature.attributes.inactive != undefined) -            return; -          map.removePopup(feature.popup); -          feature.popup.destroy(); -          feature.popup = null; -        }") -                                              } } ) -  end - -  def kml_layer(url_or_object, options_or_url_options = {}, options = nil) -    unless options -      url_options = {} -      options = options_or_url_options -    else -      url_options = options_or_url_options -    end - -    url_options = url_options.merge(:format => :kml) - -    url = -      case url_or_object -      when String -        url_or_object -      when Array -        helpers.polymorphic_path_patch( helpers.polymorphic_path(url_or_object, url_options)) -      else -        helpers.polymorphic_path_patch( helpers.polymorphic_path([url_or_object.referential, url_or_object], url_options)) -      end - -    protocol = OpenLayers::Protocol::HTTP.new :url => url, :format => kml -    OpenLayers::Layer::Vector.new name, {:projection => projection("EPSG:4326"), :strategies => [strategy_fixed], :protocol => protocol, :displayInLayerSwitcher => false}.merge(options) -  end - -end diff --git a/app/maps/connection_link_map.rb b/app/maps/connection_link_map.rb deleted file mode 100644 index 82050c4da..000000000 --- a/app/maps/connection_link_map.rb +++ /dev/null @@ -1,27 +0,0 @@ - -class ConnectionLinkMap < ApplicationMap - -  attr_reader :connection_link, :connection_link_style - -  def initialize(connection_link, connection_link_style = nil) -    @connection_link = connection_link -    @connection_link_style = connection_link_style -  end - -  def customize_map(map, page) -    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 => 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 - -  def ready? -    Chouette::StopArea.bounds.present? -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(connection_link.stop_areas.collect(&:geometry).compact) -  end - -end diff --git a/app/maps/design/access_link_style_map.rb b/app/maps/design/access_link_style_map.rb deleted file mode 100644 index 742f7ed0e..000000000 --- a/app/maps/design/access_link_style_map.rb +++ /dev/null @@ -1,43 +0,0 @@ -class Design::AccessLinkStyleMap < Design::GenericStyleMap -  attr_accessor :style - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def default_style -    { -      :fontColor => "black",  -      :fontSize => "11px", -      :fontWeight => "bold", -      :labelAlign => "ct", -      :labelXOffset => 0, -      :labelYOffset => -10, -      :strokeColor => "#000000", -      :strokeOpacity => 1, -      :strokeWidth => 3, -      :strokeLineCap => "round", -      :strokeDashstyle => "solid", -      :externalGraphic => @helpers.assets_path_patch( "map/${positionType}.png"), -      :graphicWidth => 36, -      :graphicHeight => 36,  -      :graphicOpacity => 1,	 -      :graphicXOffset => -18, -      :graphicYOffset => -18, -      :display => true -    } -  end - -  def context -    context = {  -      :positionType => :" function(feature) { if (feature.attributes.departure != undefined) { return 'departure'; } else { return 'arrival'; }} "  -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context})) -  end - -end - diff --git a/app/maps/design/access_points_style_map.rb b/app/maps/design/access_points_style_map.rb deleted file mode 100644 index f7740006d..000000000 --- a/app/maps/design/access_points_style_map.rb +++ /dev/null @@ -1,58 +0,0 @@ -class Design::AccessPointsStyleMap < Design::GenericStyleMap -  attr_accessor :style, :context, :temporary -   -  def default_style -    raise "Helpers nil" if @helpers.nil? -    {:label => "${label}", -     :fontColor => "black", -     :fontSize => "11px", -     :fontWeight => "bold", -     :labelAlign => "ct", -     :labelXOffset => 0, -     :labelYOffset => -20, -     :pointRadius => 1,  -     :externalGraphic => @helpers.assets_path_patch( "map/access_${accessType}.png"),       -     :graphicWidth => 25, -     :graphicHeight => 25,  -     :graphicOpacity => 1,     -     :graphicXOffset => -12.5, -     :graphicYOffset => -12.5 } -  end -  def temporary_style -    raise "Helpers nil" if @helpers.nil? -    {:label => "${label}", -     :fontColor => "darkblue", -     :fontSize => "12px", -     :fontWeight => "bold", -     :labelAlign => "ct", -     :labelXOffset => 0, -     :labelYOffset => -20, -     :pointRadius => 1,  -     :externalGraphic => @helpers.assets_path_patch( "map/access_${accessType}.png"),       -     :graphicWidth => 25, -     :graphicHeight => 25,  -     :graphicOpacity => 1,     -     :graphicXOffset => -12.5, -     :graphicYOffset => -12.5 } -  end - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -    @temporary = options[:style].present? ? temporary_style.merge(options[:style]) : temporary_style -  end - -   -  def context -    { -      :label => :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} ",  -      :accessType => :" function(feature) { return feature.attributes.access_point_type.toLowerCase();} "  -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context}), -                             :temporary => OpenLayers::Style.new(temporary, { :context => context}) ) -  end - -end diff --git a/app/maps/design/connection_link_style_map.rb b/app/maps/design/connection_link_style_map.rb deleted file mode 100644 index 88eeb9457..000000000 --- a/app/maps/design/connection_link_style_map.rb +++ /dev/null @@ -1,43 +0,0 @@ -class Design::ConnectionLinkStyleMap < Design::GenericStyleMap -  attr_accessor :style - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def default_style -    { -      :fontColor => "black",  -      :fontSize => "11px", -      :fontWeight => "bold", -      :labelAlign => "ct", -      :labelXOffset => 0, -      :labelYOffset => -15, -      :strokeColor => "#000000", -      :strokeOpacity => 1, -      :strokeWidth => 3, -      :strokeLineCap => "round", -      :strokeDashstyle => "solid", -      :externalGraphic => @helpers.assets_path_patch( "map/${positionType}.png"), -      :graphicWidth => 36, -      :graphicHeight => 36,  -      :graphicOpacity => 1,	 -      :graphicXOffset => -18, -      :graphicYOffset => -18, -      :display => true -    } -  end - -  def context -    context = {  -      :positionType => :" function(feature) { if (feature.attributes.departure != undefined) { return 'departure'; } else { return 'arrival'; }} "  -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context})) -  end - -end - diff --git a/app/maps/design/edit_access_point_style_map.rb b/app/maps/design/edit_access_point_style_map.rb deleted file mode 100644 index 48c293470..000000000 --- a/app/maps/design/edit_access_point_style_map.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Design::EditAccessPointStyleMap < Design::GenericStyleMap -  attr_accessor :style -   -  def default_style -    { :fontColor => "black", -      :fontSize => "11px", -      :fontWeight => "bold", -      :labelAlign => "ct", -      :labelXOffset => 0, -      :labelYOffset => -15, -      :pointRadius => 4, -      :fillColor => "white", -      :fillOpacity => 1, -      :strokeColor => "black", -      :strokeOpacity => 1, -      :strokeWidth => 2 }  -  end - -  def select_style -   { :fontColor => "black",  -     :fontSize => "11px", -     :fontWeight => "bold", -     :pointRadius => 4, -     :fillColor => "#86b41d", -     :fillOpacity => 1, -     :strokeColor => "black", -     :strokeOpacity => 1, -     :strokeWidth => 2 } -  end - -  def initialize(helpers, options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def context -    {  -      :label => :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} " -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context}), :select =>  OpenLayers::Style.new(style.merge( select_style), { :context => context})) -  end - -end diff --git a/app/maps/design/edit_stop_area_style_map.rb b/app/maps/design/edit_stop_area_style_map.rb deleted file mode 100644 index 2431f8a0f..000000000 --- a/app/maps/design/edit_stop_area_style_map.rb +++ /dev/null @@ -1,46 +0,0 @@ -class Design::EditStopAreaStyleMap < Design::GenericStyleMap -  attr_accessor :style -   -  def default_style -    { :fontColor => "black", -      :fontSize => "11px", -      :fontWeight => "bold", -      :labelAlign => "ct", -      :labelXOffset => 0, -      :labelYOffset => -15, -      :pointRadius => 4, -      :fillColor => "white", -      :fillOpacity => 1, -      :strokeColor => "black", -      :strokeOpacity => 1, -      :strokeWidth => 2 }  -  end - -  def select_style -   { :fontColor => "black",  -     :fontSize => "11px", -     :fontWeight => "bold", -     :pointRadius => 4, -     :fillColor => "#86b41d", -     :fillOpacity => 1, -     :strokeColor => "black", -     :strokeOpacity => 1, -     :strokeWidth => 2 } -  end - -  def initialize(helpers, options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def context -    {  -      :label => :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} " -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context}), :select =>  OpenLayers::Style.new(style.merge( select_style), { :context => context})) -  end - -end diff --git a/app/maps/design/generic_style_map.rb b/app/maps/design/generic_style_map.rb deleted file mode 100644 index 0056cc964..000000000 --- a/app/maps/design/generic_style_map.rb +++ /dev/null @@ -1,5 +0,0 @@ -class Design::GenericStyleMap -  include MapLayers -  include MapLayers::ViewHelpers - -end diff --git a/app/maps/design/journey_pattern_style_map.rb b/app/maps/design/journey_pattern_style_map.rb deleted file mode 100644 index b5323d6ae..000000000 --- a/app/maps/design/journey_pattern_style_map.rb +++ /dev/null @@ -1,50 +0,0 @@ -class Design::JourneyPatternStyleMap < Design::GenericStyleMap -  attr_accessor :style - -  def initialize(helpers, options = {}) -    @helpers = helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def select_style -    default_style.merge externalGraphic: @helpers.assets_path_patch( "map/stop_area_hover.png") -  end - -  def default_style -    { -      label: "${label}", -      fontColor: "black", -      fontSize: "14px", -      fontWeight: "bold", -      labelAlign: "ct", -      labelXOffset: 0, -      labelYOffset: -15, -      strokeColor: "#000000", -      strokeOpacity: 1, -      strokeWidth: 3, -      strokeLineCap: "round", -      strokeDashstyle: "solid", -      externalGraphic: @helpers.assets_path_patch( "map/${positionType}.png"), -      graphicWidth: 12, -      graphicHeight: 12, -      graphicOpacity: 1, -      graphicXOffset: -6, -      graphicYOffset: -6, -      display: true -    } -  end - -  def context -    { -      label: :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} ", -      positionType: :" function(feature) { if (feature.attributes.iconCode != undefined) {return feature.attributes.iconCode;} else { return '';} } " -    } -  end - -  def style_map -    OpenLayers::StyleMap.new( -        default: OpenLayers::Style.new(style, { context: context}), -        select:  OpenLayers::Style.new(style.merge( select_style), { context: context})) -  end - -end diff --git a/app/maps/design/line_style_map.rb b/app/maps/design/line_style_map.rb deleted file mode 100644 index e1d76078c..000000000 --- a/app/maps/design/line_style_map.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Design::LineStyleMap < Design::GenericStyleMap -  attr_accessor :style, :line_priority, :line_color - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @line_color = options[:line_color] -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def stroke_width -    stroke_width = 3 -  end - -  def default_style -    style = { -      :strokeColor => line_color || "#000000", -      :strokeOpacity => 1, -      :strokeWidth => stroke_width, -      :strokeLineCap => "round", -      :strokeDashstyle => "solid", -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style)) -  end - -end diff --git a/app/maps/design/route_style_map.rb b/app/maps/design/route_style_map.rb deleted file mode 100644 index 35585e81e..000000000 --- a/app/maps/design/route_style_map.rb +++ /dev/null @@ -1,47 +0,0 @@ -class Design::RouteStyleMap < Design::GenericStyleMap -  attr_accessor :style - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -  end - -  def select_style -    default_style.merge :externalGraphic => @helpers.assets_path_patch( "map/stop_area_hover.png") -  end -  def default_style -    { -      :label => "${label}", -      :fontColor => "black", -      :fontSize => "11px", -      :fontWeight => "bold", -      :labelAlign => "ct", -      :labelXOffset => 0, -      :labelYOffset => -15, -      :strokeColor => "#000000", -      :strokeOpacity => 1, -      :strokeWidth => 3, -      :strokeLineCap => "round", -      :strokeDashstyle => "solid", -      :externalGraphic => @helpers.assets_path_patch( "map/${positionType}.png"), -      :graphicWidth => 12, -      :graphicHeight => 12, -      :graphicOpacity => 1, -      :graphicXOffset => -6, -      :graphicYOffset => -6, -      :display => true -    } -  end - -  def context -    context = { -      :label => :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} ", -      :positionType => :" function(feature) { if (feature.attributes.departure != undefined) { return 'stop_area_green'; } else if (feature.attributes.arrival != undefined) { return 'stop_area_red'; } else { return 'stop_area_black'; }} " -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context}), :select =>  OpenLayers::Style.new(style.merge( select_style), { :context => context})) -  end - -end diff --git a/app/maps/design/stop_areas_style_map.rb b/app/maps/design/stop_areas_style_map.rb deleted file mode 100644 index f45c423e2..000000000 --- a/app/maps/design/stop_areas_style_map.rb +++ /dev/null @@ -1,59 +0,0 @@ -class Design::StopAreasStyleMap < Design::GenericStyleMap -  attr_accessor :style, :context, :temporary -   -  def default_style -    raise "Helpers nil" if @helpers.nil? -    {:label => "${label}", -     :fontColor => "black", -     :fontSize => "11px", -     :fontWeight => "bold", -     :labelAlign => "ct", -     :labelXOffset => 0, -     :labelYOffset => -20, -     :pointRadius => 1,  -     :externalGraphic => @helpers.assets_path_patch( "map/${areaType}.png"),       -     :graphicWidth => 25, -     :graphicHeight => 25,  -     :graphicOpacity => 1,     -     :graphicXOffset => -12.5, -     :graphicYOffset => -12.5 } -  end -  def temporary_style -    raise "Helpers nil" if @helpers.nil? -    {:label => "${label}", -     :fontColor => "darkblue", -     :fontSize => "12px", -     :fontWeight => "bold", -     :labelAlign => "ct", -     :labelXOffset => 0, -     :labelYOffset => -20, -     :pointRadius => 1,  -     :externalGraphic => @helpers.assets_path_patch( "map/${areaType}.png"),       -     :graphicWidth => 25, -     :graphicHeight => 25,  -     :graphicOpacity => 1,     -     :graphicXOffset => -12.5, -     :graphicYOffset => -12.5 } -  end - - -  def initialize(helpers,options = {}) -    @helpers= helpers -    @style = options[:style].present? ? default_style.merge(options[:style]) : default_style -    @temporary = options[:style].present? ? temporary_style.merge(options[:style]) : temporary_style -  end - -   -  def context -    { -      :label => :" function(feature) {if(feature.layer.map.getZoom() > 13) { return feature.attributes.name;} else {return '';}} ",  -      :areaType => :" function(feature) { return feature.attributes.stop_area_type.toLowerCase();} "  -    } -  end - -  def style_map -    OpenLayers::StyleMap.new(:default => OpenLayers::Style.new(style, { :context => context}), -                             :temporary => OpenLayers::Style.new(temporary, { :context => context}) ) -  end - -end diff --git a/app/maps/group_of_line_map.rb b/app/maps/group_of_line_map.rb deleted file mode 100644 index b9c174cb9..000000000 --- a/app/maps/group_of_line_map.rb +++ /dev/null @@ -1,26 +0,0 @@ -class GroupOfLineMap < ApplicationMap - -  attr_reader :group_of_line, :group_of_line_style - -  def initialize(group_of_line, group_of_line_style = nil) -    @group_of_line = group_of_line -    @group_of_line_style = group_of_line_style -  end - -  def customize_map(map, page) -    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) ) -    page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(group_of_line.stop_areas.collect(&:geometry).compact) -  end - -  def ready? -    Chouette::StopArea.bounds.present? -  end - -end diff --git a/app/maps/journey_pattern_map.rb b/app/maps/journey_pattern_map.rb deleted file mode 100644 index 9a0da5743..000000000 --- a/app/maps/journey_pattern_map.rb +++ /dev/null @@ -1,29 +0,0 @@ -class JourneyPatternMap < ApplicationMap - -  attr_reader :journey_pattern, :style - -  def initialize(journey_pattern, style = nil) -    @journey_pattern = journey_pattern -    @style = style -  end - -  def customize_map(map, page) -    layer = kml_layer([journey_pattern.referential, journey_pattern.route.line, journey_pattern.route, journey_pattern], { setLayerIndex: 999, styleMap: Design::JourneyPatternStyleMap.new(helpers).style_map, rendererOptions: { zIndexing: true } }) -    page.assign 'journeyPatternLayer', layer -    page.assign 'selectFeature', OpenLayers::Control::SelectFeature.new(:journeyPatternLayer) - -    page << map.add_layer(:journeyPatternLayer) -    page << map.add_control(hover_control_display_name(:journeyPatternLayer)) -    page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds -  end - -  def ready? -    bounds.present? -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(journey_pattern.route.stop_areas.collect(&:geometry).compact) -  end - -end - diff --git a/app/maps/line_map.rb b/app/maps/line_map.rb deleted file mode 100644 index 1acde11ff..000000000 --- a/app/maps/line_map.rb +++ /dev/null @@ -1,29 +0,0 @@ - -class LineMap < ApplicationMap - -  attr_reader :line, :line_style - -  def initialize(line, line_style = nil) -    @line = line -    @line_style = line_style -  end - -  def customize_map(map, page) -    page << map.add_layer(kml_layer(line, :styleMap => Design::LineStyleMap.new( :style => line_style).style_map)) -    page.assign "stop_areas_layer", kml_layer([line.line_referential, 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) ) -    page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(line.stop_areas.collect(&:geometry).compact) -  end - -  def ready? -    bounds.present? -  end - -end diff --git a/app/maps/network_map.rb b/app/maps/network_map.rb deleted file mode 100644 index 109e390d0..000000000 --- a/app/maps/network_map.rb +++ /dev/null @@ -1,26 +0,0 @@ -class NetworkMap < ApplicationMap - -  attr_reader :network, :network_style - -  def initialize(network, network_style = nil) -    @network = network -    @network_style = network_style -  end - -  def customize_map(map, page) -    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) ) -    page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(network.stop_areas.collect(&:geometry).compact) -  end - -  def ready? -    Chouette::StopArea.bounds.present? -  end - -end diff --git a/app/maps/route_map.rb b/app/maps/route_map.rb deleted file mode 100644 index bdd6c4a56..000000000 --- a/app/maps/route_map.rb +++ /dev/null @@ -1,31 +0,0 @@ -class RouteMap < ApplicationMap - -  attr_reader :route, :style - -  def initialize(route, style = nil) -    @route = route -    @style = style -  end - -  def customize_map(map, page) -    layer = kml_layer([route.referential, route.line, route], :styleMap => Design::RouteStyleMap.new(helpers, {context: context = {label: ""}}).style_map) -    page.assign "routeLayer", layer -    selectFeature = OpenLayers::Control::SelectFeature.new( :routeLayer) - -    page << map.add_layer( :routeLayer) -    page << map.add_control( hover_control_display_name(:routeLayer) ) - -    page.assign "selectFeature", selectFeature -    page << map.zoom_to_extent(bounds.to_google.to_openlayers) if bounds -  end - -  def ready? -    bounds.present? -  end - -  def bounds -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(route.stop_areas.collect(&:geometry).compact) -  end - -end - diff --git a/app/maps/stop_area_map.rb b/app/maps/stop_area_map.rb deleted file mode 100644 index 07321834b..000000000 --- a/app/maps/stop_area_map.rb +++ /dev/null @@ -1,145 +0,0 @@ -class StopAreaMap < ApplicationMap - -  attr_reader :stop_area - -  attr_accessor :editable -  alias_method :editable?, :editable - -  def initialize(stop_area) -    @stop_area = stop_area -  end - -  def customize_map(map, page) -      if stop_area.children.present? -        page.assign "children_layer", kml_layer(stop_area, { :children => true }, :style_map => Design::StopAreasStyleMap.new(helpers).style_map) -        page << map.add_layer(:children_layer) -        page << map.add_control( hover_control_display_name(:children_layer) ) -      end -      if stop_area.routing_stops.present? -        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 - - -        if stop_area.new_record? -          page << <<EOF -          var createStyleMap = function() { -            var defProp = {strokeColor: "black", strokeOpacity: 1, strokeWidth: 2, fillColor: "white", fillOpacity: 1}; -            var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); -            return new OpenLayers.StyleMap({'default': defStyle}); -          }; -          var edit_stop_area_layer = new OpenLayers.Layer.Vector( "edit_stop_area_layer", {styleMap: createStyleMap()}); - -EOF -        else -          page.assign "edit_stop_area_layer", kml_layer(stop_area, { :default => editable? }, :style_map => Design::EditStopAreaStyleMap.new(helpers).style_map) -        end - -        page << <<EOF -        var createAddressStyleMap = function() { -          var defProp = {fill: false, stroke: false, label: "\uf041", labelAlign: "cb", labelXOffset: 0, labelYOffset: 0, fontSize:"20px", fontOpacity: 1, fontFamily: "FontAwesome", labelOutlineWidth: 2}; -          var defStyle = OpenLayers.Util.applyDefaults(defProp, OpenLayers.Feature.Vector.style["default"]); -          return new OpenLayers.StyleMap({'default': defStyle, }); -        }; -        var address_layer = new OpenLayers.Layer.Vector( "address_layer", {styleMap: createAddressStyleMap()}); - -        var removeAddress = function() { -          address_layer.destroyFeatures(); -        }; - -        var addAddress = function( lat, lng, name ) { -          var wgs84point = new OpenLayers.Geometry.Point( lat, lng); -          var point = transformedGeometry( wgs84point, "EPSG:4326", "EPSG:900913" ) -          var feature = new OpenLayers.Feature.Vector( point, { name: name}); -          address_layer.addFeatures( [feature]); - -          var bounds = new OpenLayers.Bounds(); -          bounds.extend( feature.geometry.getBounds()); -          for (var x in edit_stop_area_layer.features) { -              bounds.extend( edit_stop_area_layer.features[x].geometry.getBounds()); -          } -          map.zoomToExtent(bounds.scale(2), true); -        }; -        var transformedGeometry = function( geometry, origin, target ) { -          return geometry.clone().transform( new OpenLayers.Projection( origin ), new OpenLayers.Projection( target )); -        } -EOF -        page << map.add_layer(:address_layer) -        page << map.add_layer(:edit_stop_area_layer) - -        if editable? -          page.assign "referential_projection", projection_type.present? ? projection("EPSG:" + projection_type) : JsVar.new("undefined") - -          # TODO virer ce code inline -          page << <<EOF - -          var getEventWGS84 = function( event) { -            return transformedGeometry( event.geometry, "EPSG:900913", "EPSG:4326"); -          } -          var getEventProjection = function( event, projCode) { -            return transformedGeometry( event.geometry, "EPSG:900913", projCode); -          } -          var updateStopAreaCoordinates = function( event ) { -            var geometry = getEventWGS84( event ); -            $('#stop_area_coordinates').val( geometry.y.toString()+ ","+ geometry.x.toString()); -          } -          var updateStopAreaProjectionXY = function( event, projCode ) { -            var geometry = getEventProjection( event, projCode); -            $('#stop_area_projection_xy').val( geometry.x.toString()+ ","+ geometry.y.toString()); -          } - -          var drawControl = new OpenLayers.Control.DrawFeature( edit_stop_area_layer, OpenLayers.Handler.Point, -              { featureAdded: function(event) { -              console.log( "featureAdded" ); -                  updateStopAreaCoordinates( event); -                  if( typeof referential_projection !== 'undefined') { -                    updateStopAreaProjectionXY( event, referential_projection.projCode); -                  } -                  this.deactivate(); -                } -              }); - -          var dragControl = new OpenLayers.Control.DragFeature( edit_stop_area_layer, -              { autoActivate: true, -                onComplete: function(event) { -                  updateStopAreaCoordinates( event); -                  if( typeof referential_projection !== 'undefined') { -                    updateStopAreaProjectionXY( event, referential_projection.projCode); -                  } -                }, -              }); -            map.addControl( dragControl); -            map.addControl( drawControl); -EOF - -          if stop_area.new_record? -          page << <<EOF -            drawControl.activate(); -EOF -          end -        end - -      page << map.set_center(center.to_google.to_openlayers, 16, false, true) -      end -  end - -  def projection_type -    stop_area.projection -  end - -  def ready? -    center.present? -  end - -  def center -    stop_area.geometry or stop_area.default_position -  end - -  def bounds -    # for ITL only -    @bounds ||= GeoRuby::SimpleFeatures::Point.bounds(stop_area.routing_stops.collect(&:geometry).compact) -  end - -end diff --git a/app/models/calendar.rb b/app/models/calendar.rb index 84b569ab4..32eedf9ea 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -12,8 +12,7 @@ class Calendar < ActiveRecord::Base    belongs_to :organisation    belongs_to :workgroup -  validates_presence_of :name, :short_name, :organisation, :workgroup -  validates_uniqueness_of :short_name +  validates_presence_of :name, :organisation, :workgroup    has_many :time_tables diff --git a/app/models/calendar_observer.rb b/app/models/calendar_observer.rb index c81addff4..0414d01d2 100644 --- a/app/models/calendar_observer.rb +++ b/app/models/calendar_observer.rb @@ -3,7 +3,7 @@ class CalendarObserver < ActiveRecord::Observer    def after_update calendar      return unless calendar.shared -    User.with_organisation.each do |user| +    User.from_workgroup(calendar.workgroup_id).each do |user|        MailerJob.perform_later('CalendarMailer', 'updated', [calendar.id, user.id])      end    end @@ -11,7 +11,7 @@ class CalendarObserver < ActiveRecord::Observer    def after_create calendar      return unless calendar.shared -    User.with_organisation.each do |user| +    User.from_workgroup(calendar.workgroup_id).each do |user|        MailerJob.perform_later('CalendarMailer', 'created', [calendar.id, user.id])      end    end diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb index 3a3d5d56a..5a5132200 100644 --- a/app/models/chouette/journey_pattern.rb +++ b/app/models/chouette/journey_pattern.rb @@ -176,7 +176,7 @@ module Chouette          i += 1          _start = _end          _end = stop_points[i] -        val += costs_between(_start, _end)[:distance] +        val += costs_between(_start, _end)[:distance] || 0        end        val      end diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index 2f83fc5bf..ae7c25377 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -6,8 +6,6 @@ module Chouette      include ObjectidSupport      include StifTransportModeEnumerations      include StifTransportSubmodeEnumerations -    extend ActiveModel::Naming -      belongs_to :company      belongs_to :network diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index f814d5160..13288bc6b 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -4,9 +4,7 @@ module Chouette      include RouteRestrictions      include ChecksumSupport      include ObjectidSupport -      extend Enumerize -    extend ActiveModel::Naming      enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)      enumerize :wayback, in: %i(outbound inbound), default: :outbound @@ -69,10 +67,6 @@ module Chouette      validates_presence_of :name      validates_presence_of :published_name      validates_presence_of :line - -    # validates_presence_of :direction -    # validates_presence_of :wayback -      validates :wayback, inclusion: { in: self.wayback.values }      after_save :calculate_costs!, if: ->() { TomTom.enabled? } diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb index 8c9f26d6d..ccdff609f 100644 --- a/app/models/chouette/stop_area.rb +++ b/app/models/chouette/stop_area.rb @@ -383,11 +383,11 @@ module Chouette      end      def activated? -      deleted_at.nil? && confirmed_at +      !!(deleted_at.nil? && confirmed_at)      end      def deactivated? -      deleted_at +      deleted_at.present?      end      def activate diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index 537343005..1cc06f927 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -76,6 +76,7 @@ require_dependency 'generic_attribute_control/uniqueness'  require_dependency 'journey_pattern_control/duplicates'  require_dependency 'journey_pattern_control/vehicle_journey'  require_dependency 'line_control/route' +require_dependency 'line_control/lines_scope'  require_dependency 'route_control/duplicates'  require_dependency 'route_control/journey_pattern'  require_dependency 'route_control/minimum_length' diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb index fdd976f39..bc78ff28c 100644 --- a/app/models/concerns/iev_interfaces/task.rb +++ b/app/models/concerns/iev_interfaces/task.rb @@ -52,12 +52,13 @@ module IevInterfaces::Task    end    def notify_parent +    return unless self.class.finished_statuses.include?(status) +      return unless parent.present? -    return unless status_changed? +    return if notified_parent_at      parent.child_change -    t = Time.now -    self.notified_parent_at = t -    self.class.where(id: self.id).update_all notified_parent_at: t + +    update_column :notified_parent_at, Time.now    end    def children_succeedeed @@ -65,6 +66,7 @@ module IevInterfaces::Task    end    def update_status +    Rails.logger.info "update_status for #{inspect}"      status =        if children.where(status: self.class.failed_statuses).count > 0          'failed' diff --git a/app/models/concerns/min_max_values_validation.rb b/app/models/concerns/min_max_values_validation.rb index eff779d81..a79f5ec85 100644 --- a/app/models/concerns/min_max_values_validation.rb +++ b/app/models/concerns/min_max_values_validation.rb @@ -3,11 +3,13 @@ module MinMaxValuesValidation    included do      validates_presence_of :minimum, :maximum +    validates_numericality_of :minimum, :maximum, allow_nil: true, greater_than_or_equal_to: 0 +    validates_format_of :minimum, :maximum, with: %r{\A\d+(\.\d+)?\Z}      validate :min_max_values_validation    end    def min_max_values_validation -    return true if (minimum && maximum) && (minimum.to_i < maximum.to_i) +    return true if (minimum && maximum) && (minimum.to_f < maximum.to_f)      errors.add(:minimum, I18n.t('compliance_controls.min_max_values', min: minimum, max: maximum))    end  end diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb index 4a840744e..402df7fa9 100644 --- a/app/models/custom_field.rb +++ b/app/models/custom_field.rb @@ -38,7 +38,11 @@ class CustomField < ActiveRecord::Base          @valid = false        end -      delegate :code, :name, :field_type, :options, to: :@custom_field +      delegate :code, :name, :field_type, to: :@custom_field + +      def options +        @custom_field.options || {} +      end        def validate          @valid = true diff --git a/app/models/export/base.rb b/app/models/export/base.rb index 6085e0ffb..6cf4c6b02 100644 --- a/app/models/export/base.rb +++ b/app/models/export/base.rb @@ -1,7 +1,9 @@  class Export::Base < ActiveRecord::Base    self.table_name = "exports" -  validates :type, presence: true +  belongs_to :referential + +  validates :type, :referential_id, presence: true    def self.messages_class_name      "Export::Message" @@ -38,8 +40,28 @@ class Export::Base < ActiveRecord::Base      end    end +  def self.user_visible? +    false +  end + +  def self.inherited child +    super child +    child.instance_eval do +      def self.user_visible? +        true +      end +    end +  end +    def self.option name, opts={}      store_accessor :options, name + +    if opts[:serialize] +      define_method name do +        JSON.parse(options[name.to_s]) rescue opts[:serialize].new +      end +    end +      if !!opts[:required]        validates name, presence: true      end @@ -51,6 +73,10 @@ class Export::Base < ActiveRecord::Base      @options ||= {}    end +  def self.options= options +    @options = options +  end +    include IevInterfaces::Task    def self.model_name diff --git a/app/models/export/referential_companies.rb b/app/models/export/simple_exporter/base.rb index 0b6187060..4e6e8eba4 100644 --- a/app/models/export/referential_companies.rb +++ b/app/models/export/simple_exporter/base.rb @@ -1,44 +1,48 @@ -class Export::ReferentialCompanies < Export::Base -  option :referential_id, -    type: :select, -    collection: ->(){workbench.referentials.all}, -    required: true, -    display: ->(val){r = Referential.find(val); link_to(r.name, [r])} +class Export::SimpleExporter::Base < Export::Base +  after_commit :call_exporter_async, on: :create -  after_create :call_exporter_async +  def self.user_visible? +    false +  end -  def referential -    Referential.find referential_id +  def self.inherited child +    super child +    child.options = @options +    child.instance_eval do +      def self.user_visible? +        true +      end +    end    end    def call_exporter_async      SimpleExportWorker.perform_async(id)    end -  def exporter -    SimpleExporter.define :referential_companies do |config| -      config.separator = ";" -      config.encoding = 'ISO-8859-1' -      config.add_column :name -      config.add_column :registration_number -    end +  def simple_exporter_configuration_name + +  end +  def exporter      @exporter ||= begin        if options[:_exporter_id] -        exporter = SimpleExporter.find options[:exporter_id] +        exporter = SimpleJsonExporter.find options[:_exporter_id]        else -        exporter = SimpleExporter.create configuration_name: :referential_companies +        exporter = SimpleJsonExporter.create configuration_name: simple_exporter_configuration_name          options[:_exporter_id] = exporter.id        end        exporter      end    end +  def configure_exporter config +  end +    def call_exporter -    tmp = Tempfile.new ["referential_companies", ".csv"] +    tmp = Tempfile.new [simple_exporter_configuration_name.to_s, ".json"]      referential.switch      exporter.configure do |config| -      config.collection = referential.companies.order(:name) +      configure_exporter config      end      exporter.filepath = tmp.path      exporter.export @@ -49,14 +53,12 @@ class Export::ReferentialCompanies < Export::Base    end    def set_status_from_exporter -    if exporter.status == :error +    if exporter.status.to_s == "error"        self.status = :failed -    else -      if exporter.status == :success +    elsif exporter.status.to_s == "success"          self.status = :successful -      else -        self.status = :warning -      end +    else +      self.status = :warning      end    end diff --git a/app/models/generic_attribute_control/min_max.rb b/app/models/generic_attribute_control/min_max.rb index 18873b683..bab900f0e 100644 --- a/app/models/generic_attribute_control/min_max.rb +++ b/app/models/generic_attribute_control/min_max.rb @@ -1,9 +1,7 @@  module GenericAttributeControl    class MinMax < ComplianceControl      store_accessor :control_attributes, :minimum, :maximum, :target - -    validates_numericality_of :minimum, allow_nil: true, greater_than_or_equal_to: 0 -    validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0 +          validates :target, presence: true      include MinMaxValuesValidation diff --git a/app/models/import/base.rb b/app/models/import/base.rb index 1dd9c4195..62494c92e 100644 --- a/app/models/import/base.rb +++ b/app/models/import/base.rb @@ -21,6 +21,7 @@ class Import::Base < ActiveRecord::Base    end    def child_change +    Rails.logger.info "child_change for #{inspect}"      return if self.class.finished_statuses.include?(status)      super @@ -28,6 +29,7 @@ class Import::Base < ActiveRecord::Base    end    def update_referentials +    Rails.logger.info "update_referentials for #{inspect}"      return unless self.class.finished_statuses.include?(status)      children.each do |import| diff --git a/app/models/line_control/lines_scope.rb b/app/models/line_control/lines_scope.rb new file mode 100644 index 000000000..4210a10dd --- /dev/null +++ b/app/models/line_control/lines_scope.rb @@ -0,0 +1,8 @@ +module LineControl +  class LinesScope < ComplianceControl + +    def self.default_code; "3-Line-2" end + +    def prerequisite; I18n.t("compliance_controls.#{self.class.name.underscore}.prerequisite") end +  end +end diff --git a/app/models/user.rb b/app/models/user.rb index 31e634415..eca7ede0c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -30,6 +30,8 @@ class User < ActiveRecord::Base    scope :with_organisation, -> { where.not(organisation_id: nil) } +  scope :from_workgroup, ->(workgroup_id) { joins(:workbenches).where(workbenches: {workgroup_id: workgroup_id}) } +    # Callback invoked by DeviseCasAuthenticable::Model#authernticate_with_cas_ticket    def cas_extra_attributes=(extra_attributes) @@ -67,6 +69,10 @@ class User < ActiveRecord::Base      permissions && permissions.include?(permission)    end +  def can_monitor_sidekiq? +    has_permission?("sidekiq.monitor") +  end +    private    # remove organisation and referentials if last user of it diff --git a/app/models/vehicle_journey_control/speed.rb b/app/models/vehicle_journey_control/speed.rb index e5e331b50..c9775e7a3 100644 --- a/app/models/vehicle_journey_control/speed.rb +++ b/app/models/vehicle_journey_control/speed.rb @@ -2,8 +2,6 @@ module VehicleJourneyControl    class Speed < ComplianceControl      store_accessor :control_attributes, :minimum, :maximum -    validates_numericality_of :minimum, allow_nil: true, greater_than_or_equal_to: 0 -    validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0      include MinMaxValuesValidation      def self.default_code; "3-VehicleJourney-2" end diff --git a/app/models/vehicle_journey_import.rb b/app/models/vehicle_journey_import.rb index 250f3a9e9..2eb723c29 100644 --- a/app/models/vehicle_journey_import.rb +++ b/app/models/vehicle_journey_import.rb @@ -1,7 +1,7 @@  class VehicleJourneyImport -  include ActiveModel::Validations -  include ActiveModel::Conversion -  extend  ActiveModel::Naming +  include ActiveModel::Model + +  extend EnhancedModelI18n    attr_accessor :file, :route    attr_accessor :created_vehicle_journey_count,:updated_vehicle_journey_count,:deleted_vehicle_journey_count diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb index 708225a2a..7e3e857ec 100644 --- a/app/models/workgroup.rb +++ b/app/models/workgroup.rb @@ -19,4 +19,8 @@ class Workgroup < ActiveRecord::Base    def custom_fields_definitions      Hash[*custom_fields.map{|cf| [cf.code, cf]}.flatten]    end + +  def has_export? export_name +    export_types.include? export_name +  end  end diff --git a/app/views/access_links/show.html.slim b/app/views/access_links/show.html.slim index 59f72a55f..ebc801313 100644 --- a/app/views/access_links/show.html.slim +++ b/app/views/access_links/show.html.slim @@ -1,8 +1,6 @@  = title_tag t('access_links.show.title', access_link: @access_link.name )  .access_link_show -  = @map.to_html -    .summary      p        label = "#{@access_link.human_attribute_name('access_link_type')} : " diff --git a/app/views/access_points/_form.html.slim b/app/views/access_points/_form.html.slim index 5ba7a6863..5c0c59174 100644 --- a/app/views/access_points/_form.html.slim +++ b/app/views/access_points/_form.html.slim @@ -1,6 +1,4 @@  .container-fluid -  = @map.to_html if @map -    = semantic_form_for [@referential, @stop_area, @access_point] do |form|      = form.inputs do        = form.input :id, as: :hidden diff --git a/app/views/access_points/show.html.slim b/app/views/access_points/show.html.slim index 7c87fa16e..1c46e2b5c 100644 --- a/app/views/access_points/show.html.slim +++ b/app/views/access_points/show.html.slim @@ -1,8 +1,6 @@  = title_tag t('access_points.show.title', access_point: @access_point.name)  .access_point_show -  = @map.to_html if @access_point.long_lat_type != nil -    .summary      p        label = "#{@access_point.human_attribute_name('comment')} : " @@ -92,7 +90,7 @@ div  	div.access_link_pairs      table  	    = render partial: 'access_link_pairs/access_link_pair', collection: access_links_pairs(@detail_access_links) -                          +  - content_for :sidebar do    ul.actions      li diff --git a/app/views/autocomplete_calendars/autocomplete.rabl b/app/views/autocomplete_calendars/autocomplete.rabl index 3a7703c53..9a91e1d69 100644 --- a/app/views/autocomplete_calendars/autocomplete.rabl +++ b/app/views/autocomplete_calendars/autocomplete.rabl @@ -1,5 +1,5 @@  collection @calendars, :object_root => false -attribute :id, :name, :short_name, :shared +attribute :id, :name, :shared  node :text do |cal|    "<strong>" + cal.name + " - " + cal.id.to_s + "</strong>" diff --git a/app/views/autocomplete_stop_areas/around.rabl b/app/views/autocomplete_stop_areas/around.rabl index d067dc4d0..116038639 100644 --- a/app/views/autocomplete_stop_areas/around.rabl +++ b/app/views/autocomplete_stop_areas/around.rabl @@ -15,6 +15,7 @@ child @stop_areas, root: :features, object_root: false do        area_type: Chouette::AreaType.find(s.area_type).label,        registration_number: s.registration_number,        stoparea_id: s.id, +      stoparea_kind: s.kind,        text: "#{s.name}, #{s.zip_code} #{s.city_name}",        user_objectid: s.user_objectid,        zip_code: s.zip_code, diff --git a/app/views/autocomplete_stop_areas/index.rabl b/app/views/autocomplete_stop_areas/index.rabl index c92b708f4..786f942d6 100644 --- a/app/views/autocomplete_stop_areas/index.rabl +++ b/app/views/autocomplete_stop_areas/index.rabl @@ -15,7 +15,8 @@ node do |stop_area|    :latitude => stop_area.latitude,    :area_type => Chouette::AreaType.find(stop_area.area_type).label,    :comment => stop_area.comment, -  :text => stop_area.full_name +  :text => stop_area.full_name, +  :kind => stop_area.kind    }  end diff --git a/app/views/autocomplete_stop_areas/show.rabl b/app/views/autocomplete_stop_areas/show.rabl index 73ce277cf..6ebf38900 100644 --- a/app/views/autocomplete_stop_areas/show.rabl +++ b/app/views/autocomplete_stop_areas/show.rabl @@ -9,7 +9,8 @@ node do |stop_area|    :short_name => truncate(stop_area.name, :length => 30) || "",    :zip_code => stop_area.zip_code || "",    :city_name => stop_area.city_name || "", -  :short_city_name => truncate(stop_area.city_name, :length => 15) || "" +  :short_city_name => truncate(stop_area.city_name, :length => 15) || "", +  :kind => stop_area.kind    }  end diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim index 8bfe1974e..d7e2a927e 100644 --- a/app/views/calendars/_filters.html.slim +++ b/app/views/calendars/_filters.html.slim @@ -1,7 +1,7 @@  = search_form_for @q, url: workgroup_calendars_path(@workgroup), builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f|    .ffg-row      .input-group.search_bar class=filter_item_class(params[:q], :name_or_short_name_cont) -      = f.search_field :name_or_short_name_cont, class: 'form-control', placeholder: 'Indiquez un nom/nom court de calendrier...' +      = f.search_field :name_cont, class: 'form-control', placeholder: I18n.t('calendars.filters.name_cont')        span.input-group-btn          button.btn.btn-default#search_btn type='submit'            span.fa.fa-search @@ -10,13 +10,13 @@      .form-group.togglable class=filter_item_class(params[:q], :shared_true)        = f.label Calendar.human_attribute_name(:shared), required: false, class: 'control-label'        .form-group.checkbox_list -        = f.input :shared_true, as: :boolean, label: ("<span>Oui</span>").html_safe, wrapper_html: { class: 'checkbox-wrapper' } -        = f.input :shared_false, as: :boolean, label: ("<span>Non</span>").html_safe, wrapper_html: { class: 'checkbox-wrapper' } +        = f.input :shared_true, as: :boolean, label: ("<span>#{I18n.t('yes')}</span>").html_safe, wrapper_html: { class: 'checkbox-wrapper' } +        = f.input :shared_false, as: :boolean, label: ("<span>#{I18n.t('no')}</span>").html_safe, wrapper_html: { class: 'checkbox-wrapper' }      .form-group class=filter_item_class(params[:q], :contains_date)        = f.label Calendar.human_attribute_name(:date), class: 'control-label'        = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', include_blank: true    .actions -    = link_to 'Effacer', workgroup_calendars_path(@workgroup), class: 'btn btn-link' -    = f.submit 'Filtrer', id: 'calendar_filter_btn', class: 'btn btn-default' +    = link_to I18n.t('actions.erase'), workgroup_calendars_path(@workgroup), class: 'btn btn-link' +    = f.submit I18n.t('actions.filter'), id: 'calendar_filter_btn', class: 'btn btn-default' diff --git a/app/views/calendars/_form_simple.html.slim b/app/views/calendars/_form_simple.html.slim index ba18c765b..a87a3dab5 100644 --- a/app/views/calendars/_form_simple.html.slim +++ b/app/views/calendars/_form_simple.html.slim @@ -4,8 +4,7 @@        .row          .col-lg-12            = f.input :name -          = f.input :short_name - +                      - if policy(@calendar).share?              .form-group.has_switch                = f.label :shared, class: 'col-sm-4 col-xs-5 control-label' @@ -33,24 +32,24 @@          .separator -      .row -        .col-lg-12 -          .subform -            .nested-head -              .wrapper -                div -                  .form-group -                    label.control-label -                      = t('simple_form.labels.calendar.ranges.begin') -                div -                  .form-group -                    label.control-label -                      = t('simple_form.labels.calendar.ranges.end') -                div - -            = f.simple_fields_for :periods do |period| -              = render 'period_fields', f: period -            .links.nested-linker -              = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary' +        .row +          .col-lg-12 +            .subform +              .nested-head +                .wrapper +                  div +                    .form-group +                      label.control-label +                        = t('simple_form.labels.calendar.ranges.begin') +                  div +                    .form-group +                      label.control-label +                        = t('simple_form.labels.calendar.ranges.end') +                  div + +              = f.simple_fields_for :periods do |period| +                = render 'period_fields', f: period +              .links.nested-linker +                = link_to_add_association t('simple_form.labels.calendar.add_a_date_range'), f, :periods, class: 'btn btn-outline-primary'        = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'calendar_form' diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index 0b58c0c72..2c87a6f7a 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -20,10 +20,6 @@                  end \                ), \                TableBuilderHelper::Column.new( \ -                key: :short_name, \ -                attribute: 'short_name' \ -              ), \ -              TableBuilderHelper::Column.new( \                  key: :organisation, \                  attribute: Proc.new { |c| c.organisation.name } \                ), \ @@ -39,6 +35,6 @@      - unless @calendars.any?        .row.mt-xs          .col-lg-12 -          = replacement_msg t('calendars.search_no_results') +          = replacement_msg t('.search_no_results')  = javascript_pack_tag 'date_filters' diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim index cec4f66a5..648c98928 100644 --- a/app/views/calendars/show.html.slim +++ b/app/views/calendars/show.html.slim @@ -6,11 +6,11 @@      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12          = definition_list t('metadatas'), -          { 'Nom court' => resource.try(:short_name), -            Calendar.human_attribute_name(:shared) => t("#{resource.shared}"), -            'Organisation' => resource.organisation.name, -            Calendar.human_attribute_name(:dates) =>  resource.dates.collect{|d| l(d, format: :short)}.join(', ').html_safe, -            Calendar.human_attribute_name(:date_ranges) => resource.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe } +          { Calendar.tmf('short_name') => resource.try(:short_name), +            Calendar.tmf('shared') => t("#{resource.shared}"), +            Calendar.tmf('organisation') => resource.organisation.name, +            Calendar.tmf('dates') =>  resource.dates.collect{|d| l(d, format: :short)}.join(', ').html_safe, +            Calendar.tmf('date_ranges') => resource.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe }      - if has_feature?('application_days_on_calendars')        .row diff --git a/app/views/companies/new.html.slim b/app/views/companies/new.html.slim index cc085ffe2..1747b8e10 100644 --- a/app/views/companies/new.html.slim +++ b/app/views/companies/new.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :lines, @line_referential +- breadcrumb :companies, @line_referential  .page_content    .container-fluid      .row diff --git a/app/views/compliance_check_sets/show.html.slim b/app/views/compliance_check_sets/show.html.slim index 4df14ab06..4e1a8e2f9 100644 --- a/app/views/compliance_check_sets/show.html.slim +++ b/app/views/compliance_check_sets/show.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :compliance_check_sets, @workbench, @compliance_check_set +- breadcrumb :compliance_check_set, @workbench, @compliance_check_set  - page_header_content_for @compliance_check_set  / PageContent @@ -39,7 +39,7 @@                attribute: Proc.new { |n| I18n.t('compliance_check_sets.show.metrics', n.metrics.deep_symbolize_keys) } \              ), \              TableBuilderHelper::Column.new( \ -              name: 'Téléchargement' , \ +              key: :download , \                attribute: Proc.new { |n| '<i class="fa fa-download" aria-hidden="true"></i>'.html_safe }, \                sortable: false, \                link_to: lambda do |compliance_check_resource| \ diff --git a/app/views/compliance_checks/show.html.slim b/app/views/compliance_checks/show.html.slim index 3b3861e0c..535fce67d 100644 --- a/app/views/compliance_checks/show.html.slim +++ b/app/views/compliance_checks/show.html.slim @@ -9,5 +9,5 @@          = render partial: "shared/controls/metadatas"          - if resource.compliance_check_block            = definition_list t('compliance_controls.show.metadatas.compliance_check_block'), -            I18n.t('activerecord.attributes.compliance_control_blocks.transport_mode') => I18n.t("enumerize.transport_mode.#{resource.compliance_check_block.transport_mode}"), -            I18n.t('activerecord.attributes.compliance_control_blocks.transport_submode') => resource.compliance_check_block.transport_submode.empty? ? I18n.t("enumerize.transport_submode.undefined") : I18n.t("enumerize.transport_submode.#{resource.compliance_check_block.transport_submode}") +            ComplianceCheckBlock.tmf('transport_mode') => I18n.t("enumerize.transport_mode.#{resource.compliance_check_block.transport_mode}"), +            ComplianceCheckBlock.tmf('transport_submode') => resource.compliance_check_block.transport_submode.empty? ? I18n.t("enumerize.transport_submode.undefined") : I18n.t("enumerize.transport_submode.#{resource.compliance_check_block.transport_submode}") diff --git a/app/views/compliance_control_sets/_filters.html.slim b/app/views/compliance_control_sets/_filters.html.slim index 5cf282559..5f6d9e27b 100644 --- a/app/views/compliance_control_sets/_filters.html.slim +++ b/app/views/compliance_control_sets/_filters.html.slim @@ -8,7 +8,7 @@    .ffg-row      .form-group.togglable class=filter_item_class(params[:q], :organisation_name_eq_any)        = f.label t('activerecord.models.organisation.one'), required: false, class: 'control-label' -      = f.input :organisation_name_eq_any, collection: organisations_filters_values, as: :check_boxes, label: false, label_method: lambda {|w| ("<span>#{w.name}</span>").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'} +      = f.input :organisation_name_eq_any, collection: organisations_filters_values, as: :check_boxes, value_method: :name, label: false, label_method: lambda {|w| ("<span>#{w.name}</span>").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'}      .form-group.togglable class=filter_item_class(params[:q], :updated_at)        = f.label Import::Base.human_attribute_name(:updated_at), required: false, class: 'control-label' diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim index 59100681d..729c1ce43 100644 --- a/app/views/compliance_control_sets/show.html.slim +++ b/app/views/compliance_control_sets/show.html.slim @@ -6,8 +6,8 @@      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12          = definition_list t('metadatas'), -            ComplianceControlSet.human_attribute_name(:name) => @compliance_control_set.name, -            I18n.t('activerecord.attributes.compliance_control_set.owner_jdc') => @compliance_control_set.organisation.name +            ComplianceControlSet.tmf('name') => @compliance_control_set.name, +            ComplianceControlSet.tmf('owner_jdc') => @compliance_control_set.organisation.name    - if params[:q].present? || @blocks_to_compliance_controls_map.any? || @direct_compliance_controls      .row diff --git a/app/views/connection_links/show.html.slim b/app/views/connection_links/show.html.slim index 5d8864bb5..ca6593131 100644 --- a/app/views/connection_links/show.html.slim +++ b/app/views/connection_links/show.html.slim @@ -1,8 +1,6 @@  = title_tag t('connection_links.show.title', :connection_link => @connection_link.name)  .connection_link_show -  = @map.to_html -    .summary      p        label = "#{@connection_link.human_attribute_name(:departure)} : " diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 2f0791f50..e1be3df4a 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -5,7 +5,7 @@          .panel-heading            h3.panel-title.with_actions              div -              = link_to workbench.name, workbench_path(workbench) +              = link_to t('dashboards.workbench.title', organisation: workbench.organisation.name), workbench_path(workbench)                span.badge.ml-xs = workbench.referentials.count if workbench.referentials.present?              div @@ -23,6 +23,7 @@          .panel-heading            h3.panel-title.with_actions              = link_to I18n.t("activerecord.models.calendar", count: workbench.calendars.size), workgroup_calendars_path(workbench.workgroup) +            span.badge.ml-xs = workbench.calendars.count if workbench.calendars.present?              div                = link_to '', workgroup_calendars_path(workbench.workgroup), class: ' fa fa-chevron-right pull-right'          - if workbench.calendars.present? @@ -39,7 +40,7 @@        - @dashboard.current_organisation.stop_area_referentials.each do |referential|          .panel-heading            h3.panel-title -            = referential.name +            = t('dashboards.stop_area_referentials.title')          .list-group            = link_to Chouette::StopArea.model_name.human.pluralize.capitalize, stop_area_referential_stop_areas_path(referential), class: 'list-group-item' @@ -47,7 +48,7 @@        - @dashboard.current_organisation.line_referentials.all.each do |referential|          .panel-heading            h3.panel-title -            = referential.name +            = t('dashboards.line_referentials.title')          .list-group              = link_to Chouette::Line.model_name.human.pluralize.capitalize, line_referential_lines_path(referential), class: 'list-group-item'              = link_to Chouette::Company.model_name.human.pluralize.capitalize, line_referential_companies_path(referential), class: 'list-group-item' diff --git a/app/views/exports/_form.html.slim b/app/views/exports/_form.html.slim index 7817fdf1a..999e33e34 100644 --- a/app/views/exports/_form.html.slim +++ b/app/views/exports/_form.html.slim @@ -4,7 +4,8 @@      .col-lg-12        = form.input :name      .col-lg-12 -      = form.input :type, as: :select, collection: Export::Base.user_visible_descendants, label_method: :human_name +      = form.input :type, as: :select, collection: workgroup_exports(workbench.workgroup), label_method: :human_name +      = form.input :referential_id, as: :select, collection: workbench.referentials, label_method: :name        - Export::Base.user_visible_descendants.each do |child|          .slave data-master="[name='export[type]']" data-value=child.name diff --git a/app/views/exports/show.html.slim b/app/views/exports/show.html.slim index 2a7d7583c..3a4047ae9 100644 --- a/app/views/exports/show.html.slim +++ b/app/views/exports/show.html.slim @@ -10,7 +10,16 @@          - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.status") => export_status(@export.status)})          - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.parent") => link_to(@export.parent.name, [@export.parent.workbench, @export.parent])}) if @export.parent.present?          - metadatas = metadatas.update Hash[*@export.visible_options.map{|k, v| [t("activerecord.attributes.export.#{@export.object.class.name.demodulize.underscore}.#{k}"), @export.display_option_value(k, self)]}.flatten] -        - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.file") => (@export.file.present? ? link_to(t("actions.download"), @export.file.url) : "-")}) +        - if @export.children.any? +          - files = @export.children.map(&:file).select(&:present?) +          - if files.any? +            - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.files") => ""}) +            - @export.children.each do |e| +              - metadatas = metadatas.update({"- #{e.class.human_name}" => e.file.present? ? link_to(e.file.file.filename, e.file.url) : "-"}) +          - else +            - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.files") => "-"}) +        - else +          - metadatas = metadatas.update({I18n.t("activerecord.attributes.export.file") => (@export.file.present? ? link_to(t("actions.download"), @export.file.url) : "-")})          = definition_list t('metadatas'), metadatas      .row diff --git a/app/views/group_of_lines/show.html.slim b/app/views/group_of_lines/show.html.slim index de215bfa0..a447a345d 100644 --- a/app/views/group_of_lines/show.html.slim +++ b/app/views/group_of_lines/show.html.slim @@ -3,8 +3,6 @@  = title_tag t('group_of_lines.show.title', :group_of_line => @group_of_line.name )  .group_of_line_show -  = @map.to_html -    .summary      p        label = "#{@group_of_line.human_attribute_name('registration_number')} : " diff --git a/app/views/imports/show.html.slim b/app/views/imports/show.html.slim index 48a4f334c..9d0a6423d 100644 --- a/app/views/imports/show.html.slim +++ b/app/views/imports/show.html.slim @@ -6,7 +6,7 @@    .container-fluid      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12 -        = definition_list t('metadatas'), { 'Récupération des données' => '-', "Nom de l'archive" => @import.try(:file_identifier)} +        = definition_list t('metadatas'), { t('.data_recovery') => '-', t('.filename') => @import.try(:file_identifier)}      .row        .col-lg-12 @@ -19,7 +19,7 @@            = table_builder_2 @import.children,              [ \                TableBuilderHelper::Column.new( \ -                name: 'Nom du jeu de données', \ +                name: t('.referential_name'), \                  attribute: 'name', \                  sortable: false, \                  link_to: lambda do |import| \ @@ -35,12 +35,12 @@                  end \                ), \                TableBuilderHelper::Column.new( \ -                name: 'Contrôle STIF', \ +                name: t('.stif_control'), \                  attribute: '', \                  sortable: false, \                ), \                TableBuilderHelper::Column.new( \ -                name: 'Contrôle organisation', \ +                name: t('.organisation_control'), \                  attribute: '', \                  sortable: false, \                ) \ @@ -49,11 +49,11 @@              overhead: [ \                {}, \                { \ -                title: "#{@import.children_succeedeed} jeu de données validé sur #{@import.children.count} présent(s) dans l'archive", \ +                title: I18n.t('imports.show.results', count: @import.children_succeedeed, total: @import.children.count), \                  width: 1, \                  cls: "#{@import.import_status_css_class} full-border" \                }, { \ -                title: 'Bilan des jeux de contrôles d\'import <span title="Lorem ipsum..." class="fa fa-lg fa-info-circle text-info"></span>', \ +                title: I18n.t('imports.show.summary').html_safe, \                  width: 2, \                  cls: 'overheaded-default colspan="2"' \                } \ diff --git a/app/views/journey_patterns/show.html.slim b/app/views/journey_patterns/show.html.slim index a77536130..cff0321ec 100644 --- a/app/views/journey_patterns/show.html.slim +++ b/app/views/journey_patterns/show.html.slim @@ -1,8 +1,6 @@  = title_tag t('journey_patterns.show.title', journey_pattern: journey_name( @journey_pattern), route: @route.name )  .journey_pattern_show -  = @map.to_html -    .summary      p        label = "#{@journey_pattern.human_attribute_name(:name)} : " diff --git a/app/views/layouts/navigation/_nav_panel_operations.html.slim b/app/views/layouts/navigation/_nav_panel_operations.html.slim index 8dce829cd..1c5a1f14b 100644 --- a/app/views/layouts/navigation/_nav_panel_operations.html.slim +++ b/app/views/layouts/navigation/_nav_panel_operations.html.slim @@ -1,5 +1,5 @@  #operations_panel.nav_panel    .panel-title -    h2 Opérations +    h2 = t('layouts.operations')    .panel-body      p = "Lorem ipsum dolor sit amet..." diff --git a/app/views/layouts/navigation/_nav_panel_profile.html.slim b/app/views/layouts/navigation/_nav_panel_profile.html.slim index bcbf89e67..b0dee5d53 100644 --- a/app/views/layouts/navigation/_nav_panel_profile.html.slim +++ b/app/views/layouts/navigation/_nav_panel_profile.html.slim @@ -1,6 +1,6 @@  #profile_panel.nav_panel    .panel-title -    h2 Mon Profil +    h2 = t('layouts.user.profile')    .panel-body      p = current_user.name      p = current_organisation.name diff --git a/app/views/layouts/navigation/_page_header.html.slim b/app/views/layouts/navigation/_page_header.html.slim index 49f56544b..bdc4bdfed 100644 --- a/app/views/layouts/navigation/_page_header.html.slim +++ b/app/views/layouts/navigation/_page_header.html.slim @@ -12,7 +12,7 @@              h1 = yield :page_header_title            - else              - if defined?(resource_class) -              h1 = t("#{resource_class.model_name.name.underscore.gsub('/', '.').pluralize}.#{params[:action]}.title") +              h1 = resource_class.t_action(params[:action])        .col-lg-3.col-md-4.col-sm-5.col-xs-5.text-right          .page-action diff --git a/app/views/referential_group_of_lines/show.html.slim b/app/views/referential_group_of_lines/show.html.slim index 504af0187..61a762350 100644 --- a/app/views/referential_group_of_lines/show.html.slim +++ b/app/views/referential_group_of_lines/show.html.slim @@ -2,8 +2,6 @@  = title_tag t('group_of_lines.show.title', :group_of_line => @group_of_line.name )  .group_of_line_show -  = @map.to_html -    .summary      p        label = "#{@group_of_line.human_attribute_name('registration_number')} : " diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index ef32ef6b0..91868a002 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -7,16 +7,16 @@        .col-lg-6.col-md-6.col-sm-12.col-xs-12          = definition_list t('metadatas'),            {  t('id_codif') => @line.get_objectid.short_id, -             'Activé' => (@line.deactivated? ? t('false') : t('true')), -             @line.human_attribute_name(:network) => (@line.network.nil? ? t('lines.index.unset') : link_to(@line.network.name, [@referential, @line.network]) ), -             @line.human_attribute_name(:company) => (@line.company.nil? ? t('lines.index.unset') : link_to(@line.company.name, [@referential, @line.company]) ), -             'Transporteur(s) secondaire(s)' => (@line.secondary_companies.nil? ? t('lines.index.unset') : @line.secondary_companies.collect(&:name).join(', ')), -             'Nom court' => @line.number, -             'Code public' => (@line.registration_number ? @line.registration_number : '-'), -             @line.human_attribute_name(:transport_mode) => (@line.transport_mode.present? ? t("enumerize.transport_mode.#{@line.transport_mode}") : '-'), -             @line.human_attribute_name(:transport_submode) => (@line.transport_submode.present? ? t("enumerize.transport_submode.#{@line.transport_submode}") : '-'), -             @line.human_attribute_name(:url) => (@line.url ? @line.url : '-'), -             @line.human_attribute_name(:seasonal) => (@line.seasonal? ? t('true') : t('false')),} +             Chouette::Line.tmf('activated') => (@line.deactivated? ? t('false') : t('true')), +             Chouette::Line.tmf('network_id') => (@line.network.nil? ? t('lines.index.unset') : link_to(@line.network.name, [@referential, @line.network]) ), +             Chouette::Line.tmf('company') => (@line.company.nil? ? t('lines.index.unset') : link_to(@line.company.name, [@referential, @line.company]) ), +             Chouette::Line.tmf('secondary_company') => (@line.secondary_companies.nil? ? t('lines.index.unset') : @line.secondary_companies.collect(&:name).join(', ')), +             Chouette::Line.tmf('registration_number') => @line.number, +             Chouette::Line.tmf('published_name') => (@line.registration_number ? @line.registration_number : '-'), +             Chouette::Line.tmf('transport_mode') => (@line.transport_mode.present? ? t("enumerize.transport_mode.#{@line.transport_mode}") : '-'), +             Chouette::Line.tmf('transport_submode') => (@line.transport_submode.present? ? t("enumerize.transport_submode.#{@line.transport_submode}") : '-'), +             Chouette::Line.tmf('url') => (@line.url ? @line.url : '-'), +             Chouette::Line.tmf('seasonal') => (@line.seasonal? ? t('true') : t('false')),}        .col-lg-6.col-md-6.col-sm-12.col-xs-12          #routes_map.map.mb-lg      .row @@ -53,12 +53,12 @@                      attribute: 'wayback_text' \                    ), \                    TableBuilderHelper::Column.new( \ -                    name: 'Arrêt de départ', \ +                    name: Chouette::Route.tmf('stop_area_departure'), \                      attribute: Proc.new { |r| r.try(:stop_points).first.try(:stop_area).try(:name) }, \                      sortable: false \                    ), \                    TableBuilderHelper::Column.new( \ -                    name: "Arrêt d'arrivée", \ +                    name: Chouette::Route.tmf('stop_area_arrival'), \                      attribute: Proc.new{ |r| r.try(:stop_points).last.try(:stop_area).try(:name) }, \                      sortable: false \                    ), \ @@ -79,7 +79,7 @@          - unless @routes.any?            .row.mt-xs              .col-lg-12 -              = replacement_msg t('routes.search_no_results') +              = replacement_msg t('routes.filters.no_results')  = javascript_tag do    | window.routes = "#{URI.escape(@routes.select{|r| r.wayback == :outbound}.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}" diff --git a/app/views/referential_stop_areas/_form.html.slim b/app/views/referential_stop_areas/_form.html.slim index 8181ec3f3..3921c8bf1 100644 --- a/app/views/referential_stop_areas/_form.html.slim +++ b/app/views/referential_stop_areas/_form.html.slim @@ -1,9 +1,6 @@  = semantic_form_for [@referential, @stop_area] do |form|    .row      .container-fluid -      - if !manage_itl && @map -        = @map.to_html -        = form.inputs do          = form.input :id, as: :hidden          = form.input :name, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")} diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim index 6bed5f282..b3258ffd1 100644 --- a/app/views/referentials/_overview.html.slim +++ b/app/views/referentials/_overview.html.slim @@ -16,8 +16,8 @@            = f.input :transport_mode_eq_any, collection: overview.referential_lines.map(&:transport_mode).compact.uniq.sort, as: :check_boxes, label: false, label_method: lambda{|l| ("<span>" + t("enumerize.transport_mode.#{l}") + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list'}        .actions -        = link_to 'Effacer', url_for() + "##{overview.pagination_param_name}", class: 'btn btn-link' -        = f.submit 'Filtrer', class: 'btn btn-default' +        = link_to t('actions.erase'), url_for() + "##{overview.pagination_param_name}", class: 'btn btn-link' +        = f.submit t('actions.filter'), class: 'btn btn-default'    .time-travel      .btn-group diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index 375d7c57b..d2e750fb0 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -59,7 +59,7 @@              action: :index          - else -          = replacement_msg t('stop_areas.search_no_results') +          = replacement_msg t('stop_areas.filters.search_no_results')  = javascript_tag do    | window.route = "#{URI.escape(route_json_for_edit(@route))}" diff --git a/app/views/routing_constraint_zones/_filters.html.slim b/app/views/routing_constraint_zones/_filters.html.slim index 74e299a8b..561359943 100644 --- a/app/views/routing_constraint_zones/_filters.html.slim +++ b/app/views/routing_constraint_zones/_filters.html.slim @@ -1,16 +1,16 @@  = search_form_for @q, url: referential_line_routing_constraint_zones_path(@referential, @line), class: 'form form-filter' do |f|    .ffg-row      .input-group.search_bar class=filter_item_class(params[:q], :name_or_objectid_cont) -      = f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: "Indiquez un nom d'ITL ou un ID..." +      = f.search_field :name_or_objectid_cont, class: 'form-control', placeholder: t('.name_or_objectid_cont')        span.input-group-btn          button.btn.btn-default#search-btn type='submit'            span.fa.fa-search    .ffg-row      .form-group class=filter_item_class(params[:q], :route_id_eq) -      = f.label 'Itinéraire associé', required: false, class: 'control-label' -      = f.input :route_id_eq, as: :select, collection: @line.routing_constraint_zones.pluck(:route_id).uniq, label: false, label_method: lambda { |r| @line.routing_constraint_zones.find_by(route_id: r).route_name }, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez un itinéraire...' }, wrapper_html: { class: 'select2ed'} +      = f.label t('.associated_route.title'), required: false, class: 'control-label' +      = f.input :route_id_eq, as: :select, collection: @line.routing_constraint_zones.pluck(:route_id).uniq, label: false, label_method: lambda { |r| @line.routing_constraint_zones.find_by(route_id: r).route_name }, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('.associated_route.placeholder') }, wrapper_html: { class: 'select2ed'}    .actions -    = link_to 'Effacer', referential_line_routing_constraint_zones_path(@referential, @line), class: 'btn btn-link' -    = f.submit 'Filtrer', class: 'btn btn-default' +    = link_to t('actions.erase'), referential_line_routing_constraint_zones_path(@referential, @line), class: 'btn btn-link' +    = f.submit t('actions.filter'), class: 'btn btn-default' diff --git a/app/views/routing_constraint_zones/index.html.slim b/app/views/routing_constraint_zones/index.html.slim index 2f67b467e..7e9fb12a3 100644 --- a/app/views/routing_constraint_zones/index.html.slim +++ b/app/views/routing_constraint_zones/index.html.slim @@ -13,7 +13,7 @@            = table_builder_2 @routing_constraint_zones,              [ \                TableBuilderHelper::Column.new( \ -                name: 'ID', \ +                name: t('objectid'), \                  attribute: Proc.new { |n| n.get_objectid.local_id }, \                  sortable: false \                ), \ @@ -43,4 +43,4 @@      - unless @routing_constraint_zones.any?        .row.mt-xs          .col-lg-12 -          = replacement_msg t('routing_constraint_zones.search_no_results') +          = replacement_msg t('.search_no_results') diff --git a/app/views/shared/_development_toolbar.html.slim b/app/views/shared/_development_toolbar.html.slim index aafd37885..836066b3d 100644 --- a/app/views/shared/_development_toolbar.html.slim +++ b/app/views/shared/_development_toolbar.html.slim @@ -20,6 +20,20 @@                    - if Rails.application.config.development_toolbar.features_doc_url                      = link_to "#{Rails.application.config.development_toolbar.features_doc_url}##{feature}", target: :blank do                        .fa.fa-question-circle + +            - if @workbench +              h4 +                = "Exports" +                .toggles +                  = link_to 'all', '#', data: {mask: 'export_types', val: true} +                  = link_to 'none', '#', data: {mask: 'export_types', val: false} +              ul +                - Export::Base.user_visible_descendants.each do |export| +                  li +                    = hidden_field_tag "export_types[#{@workbench.workgroup_id}][#{export.name}]", false, id: "" +                    = check_box_tag "export_types[#{@workbench.workgroup_id}][#{export.name}]", true, @workbench.workgroup.has_export?(export.name) +                    = label :export_types, export.human_name +            .col.permissions              h4                = "Permissions" diff --git a/app/views/shared/controls/_metadatas.html.slim b/app/views/shared/controls/_metadatas.html.slim index 49df06166..80f3936e6 100644 --- a/app/views/shared/controls/_metadatas.html.slim +++ b/app/views/shared/controls/_metadatas.html.slim @@ -7,9 +7,5 @@      I18n.t('activerecord.attributes.compliance_control.predicate') => resource.predicate,      I18n.t('activerecord.attributes.compliance_control.prerequisite') => resource.prerequisite,    }.merge( \ -    {}.tap do |hash| \ -      resource.class.dynamic_attributes.each do |attribute| \ -        hash[ComplianceControl.human_attribute_name(attribute)] = resource.send(attribute) \ -      end \ -    end \ -  ) +    compliance_control_metadatas(resource) \ +  )
\ No newline at end of file diff --git a/app/views/shared/iev_interfaces/_filters.html.slim b/app/views/shared/iev_interfaces/_filters.html.slim index 9b114c38d..6414af7a2 100644 --- a/app/views/shared/iev_interfaces/_filters.html.slim +++ b/app/views/shared/iev_interfaces/_filters.html.slim @@ -1,4 +1,4 @@ -= search_form_for @q, url: workbench_imports_path(@workbench), html: { method: :get, class: 'form form-filter' } do |f| += search_form_for @q, url: request.path, html: { method: :get, class: 'form form-filter' } do |f|    .ffg-row      .input-group.search_bar class=filter_item_class(params[:q], :name_or_creator_cont)        = f.search_field :name_or_creator_cont, class: 'form-control', placeholder: t('imports.filters.name_or_creator_cont') diff --git a/app/views/shared/iev_interfaces/_messages.html.slim b/app/views/shared/iev_interfaces/_messages.html.slim index 82f1add57..022f4ee01 100644 --- a/app/views/shared/iev_interfaces/_messages.html.slim +++ b/app/views/shared/iev_interfaces/_messages.html.slim @@ -3,7 +3,7 @@      - messages.order(:created_at).each do | message |        li          .row class=bootstrap_class_for_message_criticity(message.criticity) -          - if message.message_attributes["line"] +          - if message.message_attributes && message.message_attributes["line"]              .col-md-1= "L. #{message.message_attributes["line"]}"              .col-md-5= export_message_content message            - else diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index e0f754fd4..7538c7fc7 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -1,8 +1,4 @@  .row -  .col-lg-12 -    h2.content_header = t('.subtitle') - -.row    .col-lg-6.col-md-6.col-sm-6.col-xs-12      .panel.panel-default        .panel-heading diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim index d6682ef70..1cba88f94 100644 --- a/app/views/stop_areas/_form.html.slim +++ b/app/views/stop_areas/_form.html.slim @@ -1,9 +1,7 @@  = simple_form_for [@stop_area_referential, @stop_area], html: {class: 'form-horizontal', id: 'stop_area_form'}, wrapper: :horizontal_form do |f|    .row      .col-lg-12 -      /- if !manage_itl && @map        - if !manage_itl -        /= @map.to_html          = f.input :id, as: :hidden          = f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}          - if has_feature?(:stop_area_localized_names) diff --git a/app/views/stop_areas/autocomplete.rabl b/app/views/stop_areas/autocomplete.rabl index a5f0bd5ec..26fca36b2 100644 --- a/app/views/stop_areas/autocomplete.rabl +++ b/app/views/stop_areas/autocomplete.rabl @@ -15,7 +15,8 @@ node do |stop_area|      :latitude                  => stop_area.latitude,      :area_type                 => stop_area.area_type,      :comment                   => stop_area.comment, -    :text                      => "<span class='small label label-info'>#{I18n.t("area_types.label.#{stop_area.area_type}")}</span>#{stop_area.full_name}" +    :text                      => "<span class='small label label-info'>#{I18n.t("area_types.label.#{stop_area.area_type}")}</span>#{stop_area.full_name}", +    :kind                      => stop_area.kind    }  end diff --git a/app/views/vehicle_journey_imports/new.html.slim b/app/views/vehicle_journey_imports/new.html.slim index 6220de273..923fd8b7f 100644 --- a/app/views/vehicle_journey_imports/new.html.slim +++ b/app/views/vehicle_journey_imports/new.html.slim @@ -1,11 +1,9 @@ -= title_tag t('vehicle_journey_imports.new.title') -  .main_actions  = semantic_form_for [@referential, @line, @route, @vehicle_journey_import] do |form|    = form.inputs do      = form.input :file, as: :file, input_html: { title: "#{t('.tooltip.file')}", 'data-placement': "right", 'data-toggle': "tooltip", 'data-trigger': "hover" } -   +    = form.actions do      = form.action :submit, as: :button , label: t('formtastic.import') -    = form.action :cancel, as: :link
\ No newline at end of file +    = form.action :cancel, as: :link diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim index d23c61394..cd55d3ce6 100644 --- a/app/views/vehicle_journeys/index.html.slim +++ b/app/views/vehicle_journeys/index.html.slim @@ -1,10 +1,13 @@  - breadcrumb :vehicle_journeys, @referential, @route  - content_for :page_header_title, t('vehicle_journeys.index.title', route: @route.name) -- if @route.opposite_route.present? -  - content_for :page_header_content do -    .row.mb-sm -     .col-lg-12.text-right -       = link_to(t('routes.actions.opposite_route_timetable'), [@referential, @route.line, @route.opposite_route, :vehicle_journeys], class: 'btn btn-primary sticky-action') +- content_for :page_header_content do +  .row.mb-sm +    .col-lg-12.text-right +      = link_to I18n.t("time_tables.index.title"), [@referential, :time_tables], class: 'btn btn-primary sticky-action', target: :blank +      - if has_feature? :purchase_windows +        = link_to I18n.t("purchase_windows.index.title"), [@referential, :purchase_windows], class: 'btn btn-primary sticky-action', target: :blank +      - if @route.opposite_route.present? +        = link_to(t('routes.actions.opposite_route_timetable'), [@referential, @route.line, @route.opposite_route, :vehicle_journeys], class: 'btn btn-primary sticky-action')  .page_content diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index 5c2468296..8312338d0 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -7,6 +7,7 @@          = link_to t('workbenches.actions.configure'), edit_workbench_path(@workbench), class: 'btn btn-primary'        - if policy(Referential).create?          = link_to t('actions.import'), workbench_imports_path(@workbench), class: 'btn btn-primary' +        = link_to t('actions.export'), workbench_exports_path(@workbench), class: 'btn btn-primary'          = link_to t('actions.add'), new_workbench_referential_path(@workbench), class: 'btn btn-primary'        = link_to t('workbenches.actions.show_output'), workbench_output_path(@workbench), class: 'btn btn-primary' diff --git a/app/workers/workgroup_export_worker.rb b/app/workers/workgroup_export_worker.rb index 29493cea6..a354573e8 100644 --- a/app/workers/workgroup_export_worker.rb +++ b/app/workers/workgroup_export_worker.rb @@ -27,6 +27,7 @@ class WorkgroupExportWorker          netex_export.workbench = workbench_export.workbench          netex_export.creator = workbench_export.creator          netex_export.export_type = :line +        netex_export.referential = workbench_export.referential          netex_export.duration = workbench_export.duration          netex_export.line_code = line.objectid          netex_export.parent = workbench_export diff --git a/config/initializers/i18n.rb b/config/initializers/i18n.rb new file mode 100644 index 000000000..fdf5d6c04 --- /dev/null +++ b/config/initializers/i18n.rb @@ -0,0 +1,164 @@ +module I18n +  class << self +    def translate_with_fallback key, options={}, original=nil +      options[:locale] ||= I18n.locale +      begin +        self.translate_without_fallback(key, {raise: true}.update(options)) +      rescue => e +        split = key.to_s.split('.') +        if split.size <= 2 +          translate_without_fallback original || key, options +        else +          v = split.pop +          v2 = split.pop +          split.pop if v2 == "default" +          split << "default" << v +          new_key = split.join('.') +          translate_with_fallback new_key, options, original || key +        end +      end +    end +    alias_method_chain :translate, :fallback +    alias_method :t, :translate +  end + +  def self.tc(key, params={}) +    self.t('label_with_colon', label: key.t(params)).html_safe +  end + +  def self.tmf(key, params={}) +    model, col = key.split "." +    begin +      self.t "activerecord.attributes.#{key}", {raise: true}.update(params) +    rescue +      begin +        self.t "activerecord.attributes.common.#{col}", {raise: true}.update(params) +      rescue +        begin +          self.t "simple_form.labels.#{key}", {raise: true}.update(params) +        rescue +          "activerecord.attributes.#{key}".t params +        end +      end +    end +  end + +  def self.tmfc(key, params={}) +    self.t('label_with_colon', label: self.tmf(key, params)).html_safe +  end + +  def self.missing_keys_logger +    @@my_logger ||= Logger.new("#{Rails.root}/log/missing_keys.log") +  end + +  def self.log_missing_key key, params={} +    missing_keys_logger.info "key: '#{key}', locale: '#{I18n.locale}', params: #{params}" +  end + +  def self.t_with_default(key, params={}) +    begin +      self.t(key, {raise: true}.update(params)) +    rescue +      if Rails.env.development? +        log_missing_key key, params +        "<span class='label label-danger' title='#{self.t(key, params)}'>!</span>#{key.split('.').last}".html_safe +      else +        key.split('.').last +      end +    end +  end +end + +module EnhancedI18n +  def t(params={}) +    I18n.t_with_default(self, params) +  end + +  def tc(params={}) +    I18n.tc(self, params) +  end + +  def tmf(params={}) +    I18n.tmf(self, params) +  end + +  def tmfc(params={}) +    I18n.tmfc(self, params) +  end +end + +module EnhancedTimeI18n +  def l(params={}) +    I18n.l(self, params) +  end +end + +class Symbol +  include EnhancedI18n +end + +class String +  include EnhancedI18n +end + +class Time +  include EnhancedTimeI18n +end + +class DateTime +  include EnhancedTimeI18n +end + +class Date +  include EnhancedTimeI18n +end + +module EnhancedModelI18n +  # Human name of the class (plural) +  def t opts={} +    "activerecord.models.#{i18n_key}".t({count: 2}.update(opts)) +  end + +  # Human name of the class (singular) +  def ts opts={} +    self.t({count: 1}.update(opts)) +  end + +  # Human name of the class (with comma) +  def tc(params={}) +    I18n.tc(i18n_key, params) +  end + +  # Human name of the attribute +  def tmf(attribute, params={}) +    I18n.tmf "#{i18n_key}.#{attribute}", params +  end + +  # Translate the given action on the model, with default +  def t_action(action, params={}) +    key = case action.to_sym +    when :create +      :new +    when :update +      :edit +    else +      action +    end + +    begin +      I18n.translate_without_fallback "#{i18n_key.pluralize}.#{key}.title", ({raise: true}.update(params)) +    rescue +      I18n.translate_without_fallback "#{key}.title", params +    end +  end + +  private +  def i18n_key +    model_name.to_s.underscore.gsub('/', '_') +  end + +end + +class ActiveRecord::Base +  extend EnhancedModelI18n +end diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml index 278915526..c349b709f 100644 --- a/config/locales/actions.en.yml +++ b/config/locales/actions.en.yml @@ -5,6 +5,7 @@ en:      deactivate: 'Deactivate'      destroy: "Destroy"      delete: "Delete" +    download: 'Download'      search: "Search"      submit: "Submit"      processing: "Processing…" @@ -15,7 +16,7 @@ en:      unarchive: "Unarchive"      clone: 'Clone'      duplicate: 'Clone' -    clean_up: 'Clean up' +    clean_up: 'Purge'      sync: 'Synchronize'      combine: 'Combine'      actualize: 'Actualize' diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml index 92e16f21e..88e08aaef 100644 --- a/config/locales/actions.fr.yml +++ b/config/locales/actions.fr.yml @@ -5,6 +5,7 @@ fr:      deactivate: 'Désactiver'      destroy: 'Supprimer'      delete: 'Supprimer' +    download: 'Télécharger'      search: "Chercher"      submit: "Valider"      processing: "En cours…" diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml index c3df413af..3d16e7c05 100644 --- a/config/locales/calendars.en.yml +++ b/config/locales/calendars.en.yml @@ -1,6 +1,8 @@  en:    calendars: -    search_no_results: 'No calendar matching your query' +    filters: +      name_cont: Search by name +    search_no_results: 'No calendar template matching your query'      days:        monday: M        tuesday: Tu @@ -37,7 +39,7 @@ en:        all: All        shared: Shared        not_shared: Not shared -      search_no_results: No calendar matching your query +      search_no_results: No calendar templates matching your query        date: Date      new:        title: Add a new calendar @@ -59,12 +61,11 @@ en:    activerecord:      models:        calendar: -        one: calendar -        other: calendars +        one: calendar template +        other: calendar templates      attributes:        calendar:          name: Name -        short_name: Short name          date_ranges: Date ranges          dates: Dates          shared: Shared diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml index 6fd265925..8c933f168 100644 --- a/config/locales/calendars.fr.yml +++ b/config/locales/calendars.fr.yml @@ -1,6 +1,8 @@  fr:    calendars: -    search_no_results: 'Aucun calendrier ne correspond à votre recherche' +    filters: +      name_cont: 'Indiquez un nom de calendrier...' +      no_results: 'Aucun calendrier ne correspond à votre recherche'      days:        monday: L        tuesday: Ma @@ -64,7 +66,6 @@ fr:      attributes:        calendar:          name: Nom -        short_name: Nom court          date_ranges: Intervalles de dates          dates: Dates          shared: Partagé diff --git a/config/locales/clean_ups.en.yml b/config/locales/clean_ups.en.yml index 876694592..6cbb2c453 100644 --- a/config/locales/clean_ups.en.yml +++ b/config/locales/clean_ups.en.yml @@ -5,7 +5,7 @@ en:      success_jp: "%{count} journey patterns deleted"      failure: "Fail when clean_up : %{error_message}"      actions: -      clean_up: "clean up" +      clean_up: "Clean up"        confirm: "Clean up will destroy time tables which ended on requested date\nand next recursively all object without any time table\nPlease confirm this action"    activemodel:      attributes: diff --git a/config/locales/compliance_check_messages.en.yml b/config/locales/compliance_check_messages.en.yml index 216a363a3..88841f308 100644 --- a/config/locales/compliance_check_messages.en.yml +++ b/config/locales/compliance_check_messages.en.yml @@ -22,10 +22,11 @@ en:      3_routingconstraint_2: "The Routing Constraint Zone %{source_objectid} covers all the stop points of its related route : %{target_0_objectid}."      3_routingconstraint_3: "The Routing Constraint Zone %{source_objectid} has less than 2 stop points"      3_line_1: "On line :%{source_label} (%{source_objectid}), no route has an opposite route" +    3_line_2: "The line %{source_label} (%{source_objectid}) is not in the lines scope of the organization %{reference_value}"      3_generic_1: "%{source_objectid} : the %{source_attribute} attribute value (%{error_value}) does not respect the following pattern : %{reference_value}"      3_generic_2_1: "%{source_objectid}  : the %{source_attribute} attributes's value (%{error_value}) is greater than the authorized maximum value : %{reference_value}"      3_generic_2_2: "%{source_objectid}  : the %{source_attribute} attributes's value (%{error_value}) is smaller than the authorized minimum value %{reference_value}"      3_generic_3: "%{source_objectid}  : the %{source_attribute} attribute (%{error_value}) has a value shared with : %{target_0_objectid}"      3_shape_1: "Tracé %{source_objectid} : le tracé passe trop loin de l'arrêt %{target_0_label} (%{target_0_objectid}) : %{error_value} > %{reference_value}"      3_shape_2: "Tracé %{source_objectid} : le tracé n'est pas défini entre les arrêts %{target_0_label} (%{target_0_objectid}) et %{target_1_label} (%{target_1_objectid})" -    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections"
\ No newline at end of file +    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections" diff --git a/config/locales/compliance_check_messages.fr.yml b/config/locales/compliance_check_messages.fr.yml index db127d236..167ef411a 100644 --- a/config/locales/compliance_check_messages.fr.yml +++ b/config/locales/compliance_check_messages.fr.yml @@ -22,10 +22,11 @@ fr:      3_routingconstraint_2: "L'ITL %{source_objectid} couvre tous les arrêts de l'itinéraire %{target_0_objectid}."      3_routingconstraint_3: "L'ITL %{source_objectid} n'a pas suffisament d'arrêts (minimum 2 arrêts requis)"      3_line_1: "Sur la ligne %{source_label} (%{source_objectid}), aucun itinéraire n'a d'itinéraire inverse" +    3_line_2: "La ligne %{source_label} (%{source_objectid}) ne fait pas partie du périmètre de lignes de l'organisation %{reference_value}"      3_generic_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} qui ne respecte pas le motif %{reference_value}"      3_generic_2_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} supérieure à la valeur maximale autorisée %{reference_value}"      3_generic_2_2: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} inférieure à la valeur minimale autorisée %{reference_value}"      3_generic_3: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} partagée avec %{target_0_objectid}"      3_shape_1: "Tracé %{source_objectid} : le tracé passe trop loin de l'arrêt %{target_0_label} (%{target_0_objectid}) : %{error_value} > %{reference_value}"      3_shape_2: "Tracé %{source_objectid} : le tracé n'est pas défini entre les arrêts %{target_0_label} (%{target_0_objectid}) et %{target_1_label} (%{target_1_objectid})" -    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections"
\ No newline at end of file +    3_shape_3: "Le tracé de l'itinéraire %{source_objectid} est en écart avec la voirie sur %{error_value} sections" diff --git a/config/locales/compliance_check_resource.en.yml b/config/locales/compliance_check_resource.en.yml new file mode 100644 index 000000000..f8a31b81a --- /dev/null +++ b/config/locales/compliance_check_resource.en.yml @@ -0,0 +1,8 @@ +en: +  activerecord: +    attributes: +      compliance_check_resource: +        name: Name +        status: Status +        metrics: Metrics +        download: Download
\ No newline at end of file diff --git a/config/locales/compliance_check_resources.fr.yml b/config/locales/compliance_check_resources.fr.yml new file mode 100644 index 000000000..0fe4b83ed --- /dev/null +++ b/config/locales/compliance_check_resources.fr.yml @@ -0,0 +1,8 @@ +fr: +  activerecord: +    attributes: +      compliance_check_resource: +        name: Nom +        status: Statut +        metrics: Métriques +        download: Téléchargement
\ No newline at end of file diff --git a/config/locales/compliance_check_sets.en.yml b/config/locales/compliance_check_sets.en.yml index 5e8c3b24f..63708328b 100644 --- a/config/locales/compliance_check_sets.en.yml +++ b/config/locales/compliance_check_sets.en.yml @@ -20,7 +20,7 @@ en:        title: Executed control report %{name}      show:        title: Compliance check set report -      table_state: "%{lines_status} lines imported on %{lines_in_compliance_check_set} in the archive" +      table_state: "%{lines_status} lines imported out of %{lines_in_compliance_check_set} in the archive"        table_explanation: "These controls apply to all imported data and condition the construction of your organization's offer."        table_title: Analysed lines state        metrics: "%{ok_count} ok, %{error_count} errors, %{warning_count} warnings, %{uncheck_count} n/a" diff --git a/config/locales/compliance_control_blocks.en.yml b/config/locales/compliance_control_blocks.en.yml index b9c01278c..275f05106 100644 --- a/config/locales/compliance_control_blocks.en.yml +++ b/config/locales/compliance_control_blocks.en.yml @@ -1,4 +1,4 @@ -fr: +en:    activerecord:      models:        compliance_control_block:  diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index 10c4f5e9a..c69689390 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -10,6 +10,12 @@ en:        new_control: Creating a Control        select_types: Control Type Selection        edit: Edit compliance control set +    new: +      title: New compliance control set %{name} +    show: +      title: Consult compliance control set %{name} +    edit: +      title: Edit compliance control set %{name}      actions:        new: Add        edit: Edit @@ -18,6 +24,7 @@ en:        add_compliance_control: Compliance Control        add_compliance_control_block: Compliance Control Block        destroy_confirm: Are you sure ? +      loaded: Load the control      filters:        name: 'Enter name ...'      search_no_results: 'No compliance control set found' diff --git a/config/locales/compliance_controls.en.yml b/config/locales/compliance_controls.en.yml index f7d461fdb..18069f2f7 100644 --- a/config/locales/compliance_controls.en.yml +++ b/config/locales/compliance_controls.en.yml @@ -29,6 +29,8 @@ en:        title: "Add a new compliance control"      edit:        title: "Update compliance control" +    select_type: +      title: "Select a control type"      actions:        new: Add        edit: Edit @@ -140,6 +142,11 @@ en:          3_line_1: "On line :%{source_label} (%{source_objectid}), no route has an opposite route"        description: "The routes of a line must have an opposite route"        prerequisite: Line has multiple routes +    line_control/lines_scope: +      messages: +        3_line_2: "The line %{source_label} (%{source_objectid}) is not in the lines scope of the organization %{reference_value}" +      description: "The line must be included in the lines scope of the organization" +      prerequisite: "None"      generic_attribute_control/pattern:        messages:          3_generic_1: "%{source_objectid} : the %{source_attribute} attribute value (%{error_value}) does not respect the following pattern : %{reference_value}" @@ -207,6 +214,8 @@ en:          one: "Unactivated stop points"        line_control/route:          one: "The routes of a line must have an opposite route" +      line_control/lines_scope: +        one: "Lines must be included in the lines scope of the organization"        generic_attribute_control/pattern:          one: "Attribute pattern of an object in a line"        generic_attribute_control/min_max: diff --git a/config/locales/compliance_controls.fr.yml b/config/locales/compliance_controls.fr.yml index 78b92451f..7dc6eeeb3 100644 --- a/config/locales/compliance_controls.fr.yml +++ b/config/locales/compliance_controls.fr.yml @@ -139,6 +139,11 @@ fr:          3_line_1: "Sur la ligne %{source_label} (%{source_objectid}), aucun itinéraire n'a d'itinéraire inverse"        description: "Les itinéraires d'une ligne doivent être associés en aller/retour"        prerequisite: Ligne disposant de plusieurs itinéraires +    line_control/lines_scope: +      messages: +        3_line_2: "La ligne %{source_label} (%{source_objectid}) ne fait pas partie du périmètre de lignes de l'organisation %{reference_value}" +      description: "Les lignes doivent appartenir au périmètre de lignes de l'organisation" +      prerequisite: "Aucun"      generic_attribute_control/pattern:        messages:          3_generic_1: "%{source_objectid} : l'attribut %{source_attribute} a une valeur %{error_value} qui ne respecte pas le motif %{reference_value}" @@ -206,6 +211,8 @@ fr:          one: "ITL & arret désactivé"        line_control/route:          one: "Appariement des itinéraires" +      line_control/lines_scope: +        one: "Les lignes doivent appartenir au périmètre de lignes de l'organisation"        generic_attribute_control/pattern:          one: "Contrôle du contenu selon un pattern"        generic_attribute_control/min_max: diff --git a/config/locales/dashboard.en.yml b/config/locales/dashboard.en.yml index 8d46ff7aa..361a3cf2b 100644 --- a/config/locales/dashboard.en.yml +++ b/config/locales/dashboard.en.yml @@ -2,6 +2,8 @@ en:    dashboards:      show:        title: "Dashboard %{organisation}" +    workbench: +      title: Transport offer %{organisation}      calendars:        title: Calendars        none: No calendar created diff --git a/config/locales/dashboard.fr.yml b/config/locales/dashboard.fr.yml index d0aa36d61..1e1c095b1 100644 --- a/config/locales/dashboard.fr.yml +++ b/config/locales/dashboard.fr.yml @@ -2,6 +2,8 @@ fr:    dashboards:      show:        title: "Tableau de bord %{organisation}" +    workbench: +      title: Offre de transport %{organisation}      calendars:        title: Modèles de calendrier        none: Aucun calendrier défini diff --git a/config/locales/en.yml b/config/locales/en.yml index 8af8067db..05d21a1f2 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2,6 +2,7 @@ en:    "true": "Yes"    "false": "No"    "unknown": "Unknown" +  label_with_colon: "%{label}: "    time: diff --git a/config/locales/export_messages.en.yml b/config/locales/export_messages.en.yml index f7951a103..9823d7f78 100644 --- a/config/locales/export_messages.en.yml +++ b/config/locales/export_messages.en.yml @@ -1,3 +1,4 @@  en:    export_messages:      success: Success +    no_matching_journey: No matching journey found diff --git a/config/locales/export_messages.fr.yml b/config/locales/export_messages.fr.yml index 5c2191f35..4f45fd8e1 100644 --- a/config/locales/export_messages.fr.yml +++ b/config/locales/export_messages.fr.yml @@ -1,3 +1,4 @@  fr:    export_messages:      success: Succès +    no_matching_journey: Aucun trajet correspondant diff --git a/config/locales/exports.en.yml b/config/locales/exports.en.yml index 88c1b99f8..de34e797c 100644 --- a/config/locales/exports.en.yml +++ b/config/locales/exports.en.yml @@ -84,7 +84,11 @@ en:          max_distance_for_connection_link: "Max distance for connection link"          ignore_last_word: "ignore last word"          ignore_end_chars: "ignore last chars" +        type: "Export type" +        file: "Output" +        files: "Outputs"          parent: Parent +        referential_id: Referential        export:          <<: *attrs          base: diff --git a/config/locales/exports.fr.yml b/config/locales/exports.fr.yml index fa3ac8fc7..62aae70cd 100644 --- a/config/locales/exports.fr.yml +++ b/config/locales/exports.fr.yml @@ -86,7 +86,9 @@ fr:          ignore_end_chars: "ignorer les n derniers caractères"          type: "Type d'export"          file: "Résultat" +        files: "Résultats"          parent: Parent +        referential_id: Jeu de données        export:          <<: *attrs          base: diff --git a/config/locales/fr.yml b/config/locales/fr.yml index e1f52ff55..733ba05b9 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -2,6 +2,7 @@ fr:    "true": "Oui"    "false": "Non"    "unknown": "Non précisé" +  label_with_colon: "%{label} : "    time:      formats: diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index d0db87fb1..c8683a2a7 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -26,6 +26,13 @@ en:        compliance_check: "Validation report"        compliance_check_of: "Validation of import: "        import_of_validation: "Import of the validation" +      data_recovery: Data recovery +      filename: Filename +      referential_name: Referential name +      stif_control: STIF Control +      organisation_control: Organization control +      results: "%{count} validated referential(s) out of %{total} in the file" +      summary: Summay of import compliance check sets <span title="Lorem ipsum..." class="fa fa-lg fa-info-circle text-info"></span>      compliance_check_task: "Validate Report"      severities:        info: "Information" diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index 40272889a..733254fa4 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -26,6 +26,13 @@ fr:        compliance_check: "Test de conformité"        compliance_check_of: "Validation de l'import : "        import_of_validation: "L'import de la validation" +      data_recorvery: Récupération des données +      filename: Nom de l'archive +      referential_name: Nom du référentiel +      stif_control: Contrôle STIF +      organisation_control: Contrôle organisation +      results: "%{count} jeu(x) de données validé(s) sur %{total}" +      summary: Bilan des jeux de contrôles d'import <span title="Lorem ipsum..." class="fa fa-lg fa-info-circle text-info"></span>      compliance_check_task: "Validation"      severities:        info: "Information" diff --git a/config/locales/journey_patterns.en.yml b/config/locales/journey_patterns.en.yml index d480e144d..70ae94dd9 100644 --- a/config/locales/journey_patterns.en.yml +++ b/config/locales/journey_patterns.en.yml @@ -1,6 +1,7 @@  en:    journey_patterns:      journey_pattern: +      fetching_error: "There has been a problem fetching the data. Please reload the page to try again."        from_to: "From '%{departure}' to '%{arrival}'"        stop_count: "%{count}/%{route_count} stops"        vehicle_journeys_count: "Vehicle journeys: %{count}" @@ -19,6 +20,13 @@ en:      show:        title: "Journey Pattern %{journey_pattern}"        stop_points: "Stop point on journey pattern list" +      stop_points_count:  +        none: '%{count} stop areas' +        one: '%{count} stop area' +        other: '%{count} stop areas' +      informations: Informations +      confirmation: Confimation +      confirm_page_change: You are about to change page. Would you like to save your work before that ?      index:        title: "Journey Patterns of %{route}"      form: @@ -50,7 +58,8 @@ en:          creator_id: "Created by"          full_journey_time: Full journey          commercial_journey_time: Commercial journey - +        stop_points: Nb stop areas +        checksum: Checksum    formtastic:      titles:        journey_pattern: diff --git a/config/locales/journey_patterns.fr.yml b/config/locales/journey_patterns.fr.yml index 32c1f3f97..10653a02d 100644 --- a/config/locales/journey_patterns.fr.yml +++ b/config/locales/journey_patterns.fr.yml @@ -1,6 +1,7 @@  fr:    journey_patterns:      journey_pattern: +      fetching_error: "La récupération des courses a rencontré un problème. Rechargez la page pour tenter de corriger le problème."        from_to: "De '%{departure}' à '%{arrival}'"        stop_count: "%{count}/%{route_count} arrêts"        vehicle_journeys_count: "Courses: %{count}" @@ -19,6 +20,13 @@ fr:      show:        title: "Mission %{journey_pattern}"        stop_points: "Liste des arrêts de la mission" +      stop_points_count:  +        none: '%{count} arrêt' +        one: '%{count} arrêt' +        other: '%{count} arrêts' +      informations: Informations +      confirmation: Confimation +      confirm_page_change: Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?      index:        title: "Missions de %{route}"      form: @@ -50,6 +58,8 @@ fr:          creator_id: "Créé par"          full_journey_time: Parcours complet          commercial_journey_time: Parcours commercial +        stop_points: Nb arrêts +        checksum: Signature métier    formtastic:      titles:        journey_pattern: diff --git a/config/locales/layouts.en.yml b/config/locales/layouts.en.yml index debff05e5..d5717b400 100644 --- a/config/locales/layouts.en.yml +++ b/config/locales/layouts.en.yml @@ -3,6 +3,7 @@ en:      back_to_dashboard: "Back to Dashboard"      help: "Help"      home: "Home" +    operations: Operations      user:        profile: "My Profile"        sign_out: "Sign out" diff --git a/config/locales/layouts.fr.yml b/config/locales/layouts.fr.yml index 5e835bcf7..17d23c756 100644 --- a/config/locales/layouts.fr.yml +++ b/config/locales/layouts.fr.yml @@ -3,6 +3,7 @@ fr:      back_to_dashboard: "Retour au Tableau de Bord"      help: "Aide"      home: "Accueil" +    operations: Opérations      user:        profile: "Mon Profil"        sign_out: "Déconnexion" diff --git a/config/locales/purchase_windows.en.yml b/config/locales/purchase_windows.en.yml index 9ce05a1b9..9ff1576cd 100644 --- a/config/locales/purchase_windows.en.yml +++ b/config/locales/purchase_windows.en.yml @@ -63,7 +63,7 @@ en:          one: purchase window          other: purchase windows      attributes: -      purchase_windows: +      purchase_window:          name: Name          date_ranges: Date ranges          referential: Referential @@ -71,7 +71,7 @@ en:          bounding_dates: Bounding Dates      errors:        models: -        purchase_windows: +        purchase_window:            attributes:              dates:                date_in_date_ranges: A date can not be in Dates and in Date ranges. diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml index b7483c0aa..1381d5ddd 100644 --- a/config/locales/referentials.en.yml +++ b/config/locales/referentials.en.yml @@ -3,7 +3,7 @@ en:      filters:        name_or_number_or_objectid: 'Search by name, number or objectid'        name: 'Search by name' -      line: 'Seach by associated lines' +      line: 'Search by associated lines'      search_no_results: 'No data space matching your query'      error_period_filter: "The period filter must have valid bounding dates"      index: @@ -51,7 +51,7 @@ en:      overview:        head:          dates: Dates -        lines: Lignes +        lines: Lines          today: Today          prev_page: Prev. page          next_page: Next page @@ -64,7 +64,7 @@ en:          other: "data spaces"      attributes:        referential: -        name: "Data space name" +        name: "Name"          status: "Status"          slug: "Code"          prefix: "Neptune Object Id prefix" @@ -105,7 +105,7 @@ en:          created_from: 'Created from'          updated_at: "Updated"          created_at: "Created" -        organisation: 'Organisation' +        organisation: 'Organization'          number_of_lines: 'No. of lines'    formtastic:      titles: diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml index 53183a4c2..ec6c7c643 100644 --- a/config/locales/referentials.fr.yml +++ b/config/locales/referentials.fr.yml @@ -32,7 +32,7 @@ fr:          title: 'Dupliquer un jeu de données'        submit: "Valider"      select_compliance_control_set: -      title: "Sélection du jeu de contôle" +      title: "Sélection du jeu de contôles"      actions:        new: "Créer un jeu de données"        destroy_confirm: "Etes vous sûr de vouloir supprimer ce jeu de données ?" diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index bd8358bdd..58869b895 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -1,6 +1,8 @@  en:    routes: -    search_no_results: "No route matching your query" +    filters: +      placeholder: Search by name or ID +      no_results: "No route matching your query"      actions:        new: "Add a new route"        edit: "Edit this route" @@ -55,7 +57,7 @@ en:        for_boarding: "Boarding"        for_alighting: "Alighting"      duplicate: -      title: "Duplicate route" +      title: "Clone route"        success: "Route cloned with success"      route:        no_journey_pattern: "No Journey pattern" @@ -82,7 +84,7 @@ en:          number: "Number"          direction: "Direction"          wayback: "Direction" -        stop_points: "Nb Stop points" +        stop_points: "Nb Stop areas"          opposite_route: "Reversed route"          opposite_route_id: "Reversed route"          objectid: "Neptune identifier" @@ -91,6 +93,8 @@ en:          updated_at: Updated at          creator_id: "Created by"          no_journey_pattern: "No journey pattern" +        stop_area_departure: Stop area departure  +        stop_area_arrival: Stop area arrival     formtastic:      titles:        route: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index c08e64cfd..ddf706794 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -1,6 +1,8 @@  fr:    routes: -    search_no_results: "Aucun itinéraire ne correspond à votre recherche" +    filters: +      placeholder: Indiquez un nom d'itinéraire ou un ID... +      no_results: "Aucun itinéraire ne correspond à votre recherche"      actions:        new: "Ajouter un itinéraire"        edit: "Editer cet itinéraire" @@ -95,6 +97,8 @@ fr:          updated_at: "Edité le"          creator_id: "Créé par"          no_journey_pattern: "Pas de mission" +        stop_area_departure: Arrêt de départ +        stop_area_arrival: Arrêt d'arrivée    formtastic:      titles:        route: diff --git a/config/locales/routing_constraint_zones.en.yml b/config/locales/routing_constraint_zones.en.yml index 5675fd5db..2143ce1e1 100644 --- a/config/locales/routing_constraint_zones.en.yml +++ b/config/locales/routing_constraint_zones.en.yml @@ -26,7 +26,11 @@ en:                stop_points_not_from_route: 'Stop point does not belong to the Route of this Routing constraint zone.'                all_stop_points_selected: 'All stop points from route cannot be selected.'    routing_constraint_zones: -    search_no_results: "No ITL matches your query" +    filters: +      associated_route:  +        title: Associated route +        placeholder: Put the name of a route... +      name_or_objectid_cont:  Search by name or ID...      actions:        destroy_confirm: Are you sure you want to delete this routing constraint zone?      new: @@ -36,4 +40,5 @@ en:      show:        title: "Routing constraint zone %{name}"      index: -      title: "Interdictions of local trafficous" +      title: "Routing constraint zones" +      search_no_results: "No ITL matches your query" diff --git a/config/locales/routing_constraint_zones.fr.yml b/config/locales/routing_constraint_zones.fr.yml index d4b97fff2..b5e0fa7fb 100644 --- a/config/locales/routing_constraint_zones.fr.yml +++ b/config/locales/routing_constraint_zones.fr.yml @@ -26,7 +26,11 @@ fr:                stop_points_not_from_route: "Arrêt sur séquence d'arrêts n'appartient pas à la Route de cette Zone de contrainte."                all_stop_points_selected: "Une ITL ne peut pas couvrir tous les arrêts d'un itinéraire."    routing_constraint_zones: -    search_no_results: "Aucune ITL ne correspond à votre recherche" +    filters: +      associated_route:  +        title: Itinéraire associé +        placeholder: Indiquez un itinéraire... +      name_or_objectid_cont:  Indiquez un nom d'ITL ou un ID...      actions:        destroy_confirm: Etes vous sûr de supprimer cette ITL ?      new: @@ -37,3 +41,4 @@ fr:        title: "Zone de contrainte %{name}"      index:        title: "Interdictions de trafic local" +      search_no_results: "Aucune ITL ne correspond à votre recherche" diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml index 9e70993aa..37d39b76c 100644 --- a/config/locales/stop_areas.en.yml +++ b/config/locales/stop_areas.en.yml @@ -19,11 +19,11 @@ en:        localisation: "Localisation"        accessibility: "Accessibility"      actions: -      new: "Add a new stop" -      create: "Add a new stop" -      edit: "Edit this stop" -      update: "Edit this stop" -      destroy: "Remove" +      new: "Add a new stop area" +      create: "Add a new stop area" +      edit: "Edit stop area" +      update: "Edit stop area" +      destroy: "Delete stop area"        activate: "Activate this stop"        deactivate: "Deactivate this stop"        activate_confirm: "Are you sure you want to activate this stop ?" diff --git a/config/locales/table_builders.en.yml b/config/locales/table_builders.en.yml new file mode 100644 index 000000000..9ee59a1e1 --- /dev/null +++ b/config/locales/table_builders.en.yml @@ -0,0 +1,3 @@ +en: +  table_builders: +    selected_elements: "selected element(s)"
\ No newline at end of file diff --git a/config/locales/table_builders.fr.yml b/config/locales/table_builders.fr.yml new file mode 100644 index 000000000..3c92640fc --- /dev/null +++ b/config/locales/table_builders.fr.yml @@ -0,0 +1,3 @@ +fr: +  table_builders: +    selected_elements: "élement(s) sélectionné(s)"
\ No newline at end of file diff --git a/config/locales/vehicle_journey_exports.en.yml b/config/locales/vehicle_journey_exports.en.yml index 93a782026..4e658353e 100644 --- a/config/locales/vehicle_journey_exports.en.yml +++ b/config/locales/vehicle_journey_exports.en.yml @@ -1,7 +1,7 @@  en:    vehicle_journey_exports:      new: -      title: "Export existing vehicle journey at stops" +      title: Vehicle journeys export        basename: "vehicle_journeys"      label:        vehicle_journey_id: "vj id (empty for new vj)" diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml index f1ba96dc5..79e805ee8 100644 --- a/config/locales/vehicle_journeys.en.yml +++ b/config/locales/vehicle_journeys.en.yml @@ -1,14 +1,29 @@  en:    vehicle_journeys:      vehicle_journeys_matrix: +      filters: +        id: Filter by ID... +        timetable: Filter by journey pattern... +        timetable: Filter by timetable...        cancel_selection: "Cancel Selection"        fetching_error: "There has been a problem fetching the data. Please reload the page to try again."        line_routes: "Line's routes"        modal_confirm: 'Do you want to save mofications before moving on to the next page ?' -      pagination: "Schedules %{minVJ} to %{maxVJ} over %{total}"        selected_journeys: "%{count} selected journeys"        show_purchase_window: 'Show the purchase window'        show_timetable: 'Show calendar' +      no_associated_timetables: No associated timetables +      no_associated_purchase_windows: No associated purchase windows +      no_associated_footnotes: No associated footnotes +      duplicate: +        one: Clone %{count} vehicle journey +        other: Clone %{count} vehicle journeys +        start_time: Indicative start time +        number: Number of vehicle journeys to create and clone +        delta: Delta from which vehicle journeys are created +      affect_company: Affect company +      no_line_footnotes: The line doesn't have any footnotes +      select_footnotes: Select footnotes to associate with the vehicle journey      vehicle_journey:        title_stopless: "Vehicle journey %{name}"        title: "Vehicle journey leaving from %{stop} at %{time}" @@ -17,10 +32,10 @@ en:        title: "Vehicle journey frequency leaving from %{stop} at %{time}"        title_frequency: "Vehicle journey frequency with %{interval}min leaving from %{stop} at %{time_first} to %{time_last}"      actions: -      index: "Vehicle time's board" -      new: "Add a new timed vehicle journey" +      index: "Vehicle journeys" +      new: "Add a new vehicle journey"        new_frequency: "Add a new frequency vehicle journey" -      edit: "Edit this timed vehicle journey" +      edit: "Edit this vehicle journey"        edit_frequency: "Edit this frequency vehicle journey"        destroy: "Remove this vehicle journey"        destroy_confirm: "Are you sure you want destroy this vehicle journey?" @@ -48,15 +63,18 @@ en:        show_journeys_without_schedule: "Show journeys without schedule"        slide_arrival: "arrival time at first stop"        slide_departure: "departure time at first stop" -      slide_title: "Shift all vehicle passing times" +      slide_title: "Shift all the vehicle journey passing times : %{id}"        slide: "Shift" +      slide_delta: "Shift of"        starting_stop: "Departure"        stop_title: "Stop"        submit_frequency_edit: "Edit frequency vehicle journey"        submit_frequency: "Create frequency vehicle journey"        submit_timed_edit: "Edit vehicle journey"        submit_timed: "Create vehicle journey" -      time_tables: "Associated calendars to vehicle journey" +      time_tables: "Associated timetables" +      purchase_windows: Associated purchase windows +      footnotes: Associated footnotes        to_arrivals: "Copy departures to arrivals"        to_departures: "Copy arrivals to departures"        to: "at" @@ -102,6 +120,7 @@ en:          checksum: "Checksum"          comment: "Comments"          company: "Company" +        company_name: "Company name"          created_at: Created at          creator_id: "Created by"          departure_time: "Departure" @@ -110,9 +129,10 @@ en:          footnote_ids: "Footnotes"          id: "Journey ID"          journey_frequency_ids: "Timeband" -        journey_name: "Name of the journey" +        journey_name: "Name of the vehicle journey"          journey_pattern_id: "Pattern ID"          journey_pattern: "Journey Pattern" +        journey_pattern_published_name: "Journey Pattern published name"          line: "Line"          mobility_restricted_suitability: "PRM accessibility"          name: "Journey Name" @@ -137,6 +157,7 @@ en:          updated_at: Updated at          vehicle_journey_at_stop_ids: "Time list"          vehicle_type_identifier: "Vehicle Type Identifier" +        start_time: Start time      errors:        models:          vehicle_journey: diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml index d144e580f..4336bc6dc 100644 --- a/config/locales/vehicle_journeys.fr.yml +++ b/config/locales/vehicle_journeys.fr.yml @@ -1,14 +1,29 @@  fr:    vehicle_journeys:      vehicle_journeys_matrix: +      filters: +        id: Filtrer par ID course... +        journey_pattern: 'Filtrer par code, nom ou OID de mission...' +        timetable: Filter by timetable...        cancel_selection: "Annuler la sélection"        fetching_error: "La récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème."        line_routes: "Séquences d'arrêts de la ligne"        modal_confirm: 'Voulez-vous valider vos modifications avant de changer de page?' -      pagination: "Liste des horaires %{minVJ} à %{maxVJ} sur %{total}"        selected_journeys: "%{count} course(s) sélectionnée(s)"        show_purchase_window: 'Voir le calendrier commercial'        show_timetable: 'Voir le calendrier' +      no_associated_timetables: Aucun calendrier associé +      no_associated_purchase_windows: Aucun calendrier commercial associé +      no_associated_footnotes: Aucune note associée +      duplicate: +        one: Dupliquer %{count} course +        other: Dupliquer %{count} courses +        start_time: Horaire de départ indicatif +        number: Nombre de courses à créer et dupliquer +        delta: Décalage à partir duquel on créé les courses +      affect_company: Indiquez un nom de transporteur... +      no_line_footnotes: La ligne ne possède pas de notes +      select_footnotes: Sélectionnez les notes à associer à cette course      vehicle_journey:        title_stopless: "Course %{name}"        title: "Course partant de %{stop} à %{time}" @@ -48,8 +63,9 @@ fr:        show_journeys_without_schedule: "Afficher les courses sans horaires"        slide_arrival: "horaire d'arrivée au 1° arrêt à"        slide_departure: "horaire de départ au 1° arrêt à" -      slide_title: "Décaler l'ensemble des horaires de course" +      slide_title: "Décaler l'ensemble des horaires de la course : %{id}"        slide: "Décaler" +      slide_delta: "Avec un décalage de"        starting_stop: "Origine"        stop_title: "Arrêt"        submit_frequency_edit: "Editer course en fréquence" @@ -57,6 +73,8 @@ fr:        submit_timed_edit: "Editer course"        submit_timed: "Créer course"        time_tables: "Calendriers associés à la course" +      purchase_windows: "Calendriers commerciaux associés à la course" +      footnotes: "Notes associés à la course"        to_arrivals: "Copie départs vers arrivées"        to_arrivals: "Copie départs vers arrivées"        to_departures: "Copie arrivées vers départs" @@ -103,6 +121,7 @@ fr:          checksum: "Signature métier"          comment: "Commentaires"          company: "Transporteur" +        company|_name: "Nom du transporteur"          created_at: "Créé le"          creator_id: "Créé par"          departure_time: "Départ" @@ -114,6 +133,7 @@ fr:          journey_name: "Nom de la course"          journey_pattern_id: "ID Mission"          journey_pattern: "Mission" +        journey_pattern_published_name: "Nom public de la mission"          line: "Ligne"          mobility_restricted_suitability: "Accessibilité PMR"          name: "Nom Course" @@ -129,7 +149,7 @@ fr:          route: "Itinéraire"          time_slot: "Fréquence"          time_table_ids: "Liste des calendriers" -        time_tables: "Calendriers" +        time_tables: "Calendriers associés"          train_number: "Numéro de train"          transport_mode: "Mode de transport"          transport_submode: "Sous-mode de transport" @@ -138,6 +158,7 @@ fr:          updated_at: "Edité le"          vehicle_journey_at_stop_ids: "Liste des horaires"          vehicle_type_identifier: "Type d'identifiant du véhicule" +        start_time: Heure de départ      errors:        models:          vehicle_journey: diff --git a/config/locales/will_paginate.en.yml b/config/locales/will_paginate.en.yml index 29b8fe2bf..8f3189675 100644 --- a/config/locales/will_paginate.en.yml +++ b/config/locales/will_paginate.en.yml @@ -32,11 +32,11 @@ en:        single_page:          zero:  "No item found"          one:   "1 %{model} shown" -        other: "%{model} 1 to %{count} of %{count}" +        other: "%{model} 1 to %{count} out of %{count}"        single_page_html:          zero:  "No item found"          one:   "1 %{model} shown" -        other: "%{model} 1 to %{count} of %{count}" +        other: "%{model} 1 to %{count} out of %{count}" -      multi_page: "%{model} %{from} to %{to} of %{count}" -      multi_page_html: "%{model} %{from} to %{to} of %{count}" +      multi_page: "%{model} list %{from} to %{to} out of %{count}" +      multi_page_html: "%{model} list %{from} to %{to} out of %{count}" diff --git a/config/locales/workbenches.en.yml b/config/locales/workbenches.en.yml index 2d9b27045..876f18766 100644 --- a/config/locales/workbenches.en.yml +++ b/config/locales/workbenches.en.yml @@ -1,7 +1,7 @@  en:    workbenches:      show: -      title: "%{name}" +      title: "Transport offer %{name}"      edit:        title: "Configure the workbench"      update: @@ -21,7 +21,7 @@ en:          see: "See the list"          no_content: "No content yet."      actions: -      show_output: "Merge offer" +      show_output: "Merge Transport Offer"        affect_ccset: "Configure"    activerecord:      models: @@ -29,3 +29,8 @@ en:          zero: "workbench"          one: "workbench"          other: "workbenches" +    attributes: +      workbench: +        import_compliance_control_set_id: Space data before import +        merge_compliance_control_set_id: Space data before merge + diff --git a/config/locales/workbenches.fr.yml b/config/locales/workbenches.fr.yml index 8eee1a516..f857bfcd1 100644 --- a/config/locales/workbenches.fr.yml +++ b/config/locales/workbenches.fr.yml @@ -1,7 +1,7 @@  fr:    workbenches:      show: -      title: "%{name}" +      title: "Offre de transport %{name}"      edit:        title: "Configurer l'espace de travail"      update: @@ -29,3 +29,7 @@ fr:          zero: "espace de travail"          one: "espace de travail"          other: "espaces de travail" +    attributes: +      workbench: +        import_compliance_control_set_id: Jeu de données après import +        merge_compliance_control_set_id: Jeu de Données avant intégration diff --git a/config/routes.rb b/config/routes.rb index 25105241a..41b345aa5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,3 @@ -require 'sidekiq/web' -  ChouetteIhm::Application.routes.draw do    resource :dashboard @@ -179,7 +177,9 @@ ChouetteIhm::Application.routes.draw do      end    end -  mount Sidekiq::Web => '/sidekiq' +  authenticate :user, lambda { |u| u.can_monitor_sidekiq? } do +    mount Sidekiq::Web => '/sidekiq' +  end    namespace :api do      namespace :v1 do diff --git a/db/migrate/20180315152714_remove_short_name_from_calendars.rb b/db/migrate/20180315152714_remove_short_name_from_calendars.rb new file mode 100644 index 000000000..3b6759f7b --- /dev/null +++ b/db/migrate/20180315152714_remove_short_name_from_calendars.rb @@ -0,0 +1,5 @@ +class RemoveShortNameFromCalendars < ActiveRecord::Migration +  def change +    remove_column :calendars, :short_name, :string +  end +end diff --git a/db/migrate/20180326085804_bind_exports_and_imports_types_to_workgroups.rb b/db/migrate/20180326085804_bind_exports_and_imports_types_to_workgroups.rb new file mode 100644 index 000000000..d75336673 --- /dev/null +++ b/db/migrate/20180326085804_bind_exports_and_imports_types_to_workgroups.rb @@ -0,0 +1,6 @@ +class BindExportsAndImportsTypesToWorkgroups < ActiveRecord::Migration +  def change +    add_column :workgroups, "import_types", :string, default: [], array: true +    add_column :workgroups, "export_types", :string, default: [], array: true +  end +end diff --git a/db/schema.rb b/db/schema.rb index 58c8b0779..d90bf7b6c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -15,9 +15,10 @@ ActiveRecord::Schema.define(version: 20180319043333) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" -  enable_extension "postgis"    enable_extension "hstore" +  enable_extension "postgis"    enable_extension "unaccent" +  enable_extension "objectid"    create_table "access_links", id: :bigserial, force: :cascade do |t|      t.integer  "access_point_id",                        limit: 8 @@ -83,20 +84,18 @@ ActiveRecord::Schema.define(version: 20180319043333) do    create_table "calendars", id: :bigserial, force: :cascade do |t|      t.string    "name" -    t.string    "short_name"      t.daterange "date_ranges",                               array: true      t.date      "dates",                                     array: true      t.boolean   "shared",                    default: false      t.integer   "organisation_id", limit: 8      t.datetime  "created_at"      t.datetime  "updated_at" -    t.integer   "workgroup_id",    limit: 8      t.integer   "int_day_types"      t.date      "excluded_dates",                            array: true +    t.integer   "workgroup_id",    limit: 8    end    add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree -  add_index "calendars", ["short_name"], name: "index_calendars_on_short_name", unique: true, using: :btree    add_index "calendars", ["workgroup_id"], name: "index_calendars_on_workgroup_id", using: :btree    create_table "clean_up_results", id: :bigserial, force: :cascade do |t| @@ -119,6 +118,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.datetime "updated_at"      t.date     "end_date"      t.string   "date_type" +    t.string   "mode"    end    add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree @@ -299,18 +299,58 @@ ActiveRecord::Schema.define(version: 20180319043333) do    add_index "custom_fields", ["resource_type"], name: "index_custom_fields_on_resource_type", using: :btree +  create_table "export_messages", id: :bigserial, force: :cascade do |t| +    t.string   "criticity" +    t.string   "message_key" +    t.hstore   "message_attributes" +    t.integer  "export_id",           limit: 8 +    t.integer  "resource_id",         limit: 8 +    t.datetime "created_at" +    t.datetime "updated_at" +    t.hstore   "resource_attributes" +  end + +  add_index "export_messages", ["export_id"], name: "index_export_messages_on_export_id", using: :btree +  add_index "export_messages", ["resource_id"], name: "index_export_messages_on_resource_id", using: :btree + +  create_table "export_resources", id: :bigserial, force: :cascade do |t| +    t.integer  "export_id",     limit: 8 +    t.string   "status" +    t.datetime "created_at" +    t.datetime "updated_at" +    t.string   "resource_type" +    t.string   "reference" +    t.string   "name" +    t.hstore   "metrics" +  end + +  add_index "export_resources", ["export_id"], name: "index_export_resources_on_export_id", using: :btree +    create_table "exports", id: :bigserial, force: :cascade do |t| -    t.integer  "referential_id",  limit: 8      t.string   "status" -    t.string   "type" -    t.string   "options" +    t.string   "current_step_id" +    t.float    "current_step_progress" +    t.integer  "workbench_id",          limit: 8 +    t.integer  "referential_id",        limit: 8 +    t.string   "name"      t.datetime "created_at"      t.datetime "updated_at" -    t.string   "references_type" -    t.string   "reference_ids" +    t.string   "file" +    t.datetime "started_at" +    t.datetime "ended_at" +    t.string   "token_upload" +    t.string   "type" +    t.integer  "parent_id",             limit: 8 +    t.string   "parent_type" +    t.datetime "notified_parent_at" +    t.integer  "current_step",                    default: 0 +    t.integer  "total_steps",                     default: 0 +    t.string   "creator" +    t.hstore   "options"    end    add_index "exports", ["referential_id"], name: "index_exports_on_referential_id", using: :btree +  add_index "exports", ["workbench_id"], name: "index_exports_on_workbench_id", using: :btree    create_table "facilities", id: :bigserial, force: :cascade do |t|      t.integer  "stop_area_id",       limit: 8 @@ -766,6 +806,7 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.datetime "created_at"      t.datetime "updated_at"      t.string   "objectid_format" +    t.string   "registration_number_format"    end    create_table "stop_areas", id: :bigserial, force: :cascade do |t| @@ -801,7 +842,10 @@ ActiveRecord::Schema.define(version: 20180319043333) do      t.integer  "waiting_time"      t.string   "kind"      t.jsonb    "localized_names" +      t.datetime "confirmed_at" +    t.json     "custom_field_values" +    end    add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree diff --git a/db/seeds/stif.seeds.rb b/db/seeds/stif.seeds.rb index f898021ce..aa87b6f6c 100644 --- a/db/seeds/stif.seeds.rb +++ b/db/seeds/stif.seeds.rb @@ -8,6 +8,7 @@ line_referential = LineReferential.find_or_create_by!(name: "CodifLigne", object  workgroup = Workgroup.find_or_create_by!(name: "Gestion de l'offre théorique IDFm") do |w|    w.line_referential      = line_referential    w.stop_area_referential = stop_area_referential +  w.export_types = ["Export::Netex"]  end  Workbench.update_all workgroup_id: workgroup diff --git a/lib/tasks/erd.rake b/lib/tasks/erd.rake index 96bb7fe37..b5790a9ab 100644 --- a/lib/tasks/erd.rake +++ b/lib/tasks/erd.rake @@ -5,11 +5,11 @@ namespace :generate do      sh "bundle exec rake erd only='Organisation,Referential,User,Workbench,Workgroup' filename='organisation' title='Organisation'"      sh "bundle exec rake erd only='Calendar,Referential,ReferentialMetadata,Chouette::Line,Chouette::Route,Chouette::JourneyPattern,Chouette::VehicleJourney,Chouette::VehicleJourneyAtStop,Chouette::TimeTable,Chouette::TimeTableDate,Chouette::TimeTablePeriod,Chouette::Footnote,Chouette::Network,Chouette::Company,Chouette::StopPoint,Chouette::StopArea' filename='offer_datas' title='Offer Datas'"      sh "bundle exec rake erd only='Organisation,StopAreaReferential,StopAreaReferentialSync,StopAreaReferentialSyncMessage,StopAreaReferentialMembership,LineReferential,LineReferentialSync,LineReferentialSyncMessage,LineReferentialMembership' filename='referentiels_externes' title='Référentiels externes'" -    sh "bundle exec rake erd only='NetexImport,Import,WorkbenchImport,ImportResource,ImportMessage' filename='import' title='Import'" +    sh "bundle exec rake erd only='Import::Netex,Import::Base,Import::Workbench,Import::Resource,Import::Message' filename='import' title='Import'"      sh "bundle exec rake erd only='ComplianceControlSet,ComplianceControlBlock,ComplianceControl,ComplianceCheckSet,ComplianceCheckBlock,ComplianceCheck,ComplianceCheckResource,ComplianceCheckMessage' filename='validation' title='Validation'"      sh "bundle exec rake erd only='Organisation,Workgroup,Workbench,ReferentialSuite,Referential' filename='merge' title='Merge'" -    #sh "bundle exec rake erd only='VehicleJourney,VehicleJourneyExport' filename='export' title='Export'" -    #sh "bundle exec rake erd only='' filename='integration' title='Integration'" +    sh "bundle exec rake erd only='Export::Base,Export::Message,Export::Resource,Export::Workgroup' filename='export' title='Export'" +    sh "bundle exec rake erd only='Workbench,Referential,ReferentialSuite,Merge' filename='merge' title='Merge'"      #sh "bundle exec rake erd only='' filename='publication' title='Publication'"    end diff --git a/spec/controllers/api/v1/internals/netex_imports_controller_spec.rb b/spec/controllers/api/v1/internals/netex_imports_controller_spec.rb index ccdc258f4..b53ee3f05 100644 --- a/spec/controllers/api/v1/internals/netex_imports_controller_spec.rb +++ b/spec/controllers/api/v1/internals/netex_imports_controller_spec.rb @@ -1,6 +1,6 @@  RSpec.describe Api::V1::Internals::NetexImportsController, type: :controller do    let(:import_1) { create :netex_import } -  let(:import_2) { create :netex_import } +  let(:import_2) { create :netex_import, status: "successful" }    describe "GET #notify_parent" do      context 'unauthenticated' do @@ -17,14 +17,14 @@ RSpec.describe Api::V1::Internals::NetexImportsController, type: :controller do        describe "with existing record" do -        before(:each) do  +        before(:each) do            get :notify_parent, id: import_2.id, format: :json          end          it 'should be successful' do            expect(response).to have_http_status 200          end -         +          it "calls #notify_parent on the import" do            expect(import_2.reload.notified_parent_at).not_to be_nil          end @@ -39,4 +39,3 @@ RSpec.describe Api::V1::Internals::NetexImportsController, type: :controller do      end    end  end - diff --git a/spec/controllers/exports_controller_spec.rb b/spec/controllers/exports_controller_spec.rb index 3a67497ec..9d8dde4ff 100644 --- a/spec/controllers/exports_controller_spec.rb +++ b/spec/controllers/exports_controller_spec.rb @@ -2,7 +2,7 @@ RSpec.describe ExportsController, :type => :controller do    login_user    let(:workbench) { create :workbench } -  let(:export)    { create(:netex_export, workbench: workbench) } +  let(:export)    { create(:netex_export, workbench: workbench, referential: first_referential) }    describe 'GET #new' do      it 'should be successful if authorized' do @@ -21,7 +21,7 @@ RSpec.describe ExportsController, :type => :controller do      let(:params){ {name: "foo"} }      let(:request){ post :create, workbench_id: workbench.id, export: params  }      it 'should create no objects' do -      expect{request}.to_not change{Export::Base.count} +      expect{request}.to_not change{Export::Netex.count}      end      context "with full params" do @@ -29,11 +29,12 @@ RSpec.describe ExportsController, :type => :controller do          name: "foo",          type: "Export::Netex",          duration: 12, -        export_type: :line +        export_type: :line, +        referential_id: first_referential.id        }}        it 'should be successful' do -        expect{request}.to change{Export::Base.count}.by(1) +        expect{request}.to change{Export::Netex.count}.by(1)        end        it "displays a flash message" do @@ -51,7 +52,7 @@ RSpec.describe ExportsController, :type => :controller do        }}        it 'should be unsuccessful' do -        expect{request}.to change{Export::Base.count}.by(0) +        expect{request}.to change{Export::Netex.count}.by(0)        end      end @@ -59,11 +60,12 @@ RSpec.describe ExportsController, :type => :controller do        let(:params){{          name: "foo",          type: "Export::Workgroup", -        duration: 90 +        duration: 90, +        referential_id: first_referential.id        }}        it 'should be successful' do -        expect{request}.to change{Export::Base.count}.by(1) +        expect{request}.to change{Export::Workgroup.count}.by(1)        end      end diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index f8e8697ec..e4dc6bc23 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -68,14 +68,8 @@ RSpec.describe RoutesController, type: :controller do      end      it_behaves_like "route, line and referential linked" - -    it "assigns RouteMap.new(route) as @map" do -      expect(assigns[:map]).to be_an_instance_of(RouteMap) -      expect(assigns[:map].route).to eq(route) -    end    end -    describe "POST /duplicate" do      let!( :route_prime ){ route } diff --git a/spec/factories/calendars.rb b/spec/factories/calendars.rb index d9fd242d1..d78f230c6 100644 --- a/spec/factories/calendars.rb +++ b/spec/factories/calendars.rb @@ -1,7 +1,6 @@  FactoryGirl.define do    factory :calendar do      sequence(:name) { |n| "Calendar #{n}" } -    sequence(:short_name) { |n| "Cal #{n}" }      date_ranges { [generate(:date_range)] }      sequence(:dates) { |n| [ Date.yesterday - n, Date.yesterday - 2*n ] }      shared false @@ -14,4 +13,3 @@ FactoryGirl.define do      date..(date+1)    end  end - diff --git a/spec/features/connection_links_spec.rb b/spec/features/connection_links_spec.rb index 2f6283dcd..7e95aeb13 100644 --- a/spec/features/connection_links_spec.rb +++ b/spec/features/connection_links_spec.rb @@ -1,3 +1,4 @@ +# coding: utf-8  RSpec.describe "ConnectionLinks", type: :feature do    login_user @@ -19,14 +20,6 @@ RSpec.describe "ConnectionLinks", type: :feature do        click_link "#{connection_links.first.name}"        expect(page).to have_content(connection_links.first.name)      end - -    it "display map" do -      allow(subject).to receive(:stop_areas).and_return(Array.new(2) { create(:stop_area) }) -      visit referential_connection_links_path(referential) -      click_link "#{connection_links.first.name}" -      expect(page).to have_selector("#map.connection_link") -    end -    end    describe "new" do diff --git a/spec/features/group_of_lines_spec.rb b/spec/features/group_of_lines_spec.rb index 8b88e6e9e..6b2f1968a 100644 --- a/spec/features/group_of_lines_spec.rb +++ b/spec/features/group_of_lines_spec.rb @@ -40,12 +40,6 @@ describe "Group of lines", :type => :feature do        click_link subject.name        expect(page).to have_content(subject.name)      end - -    it "display map" do -      visit line_referential_group_of_lines_path(line_referential) -      click_link "#{subject.name}" -      expect(page).to have_selector("#map.group_of_line") -    end    end    # Fixme #1780 diff --git a/spec/models/calendar_observer_spec.rb b/spec/models/calendar_observer_spec.rb index 4fba02bef..dd7034af4 100644 --- a/spec/models/calendar_observer_spec.rb +++ b/spec/models/calendar_observer_spec.rb @@ -1,8 +1,13 @@  require 'rails_helper'  RSpec.describe CalendarObserver, type: :observer do -  let(:calendar) { create(:calendar, shared: true) } -  let(:user)     { create(:user, organisation: create(:organisation)) } +  let(:workgroup_1) { create :workgroup } +  let(:workgroup_2) { create :workgroup } + +  let(:calendar) { create(:calendar, shared: true, workgroup_id: workgroup_1.id) } +   +  let(:user_1)     { create(:user, organisation: create(:organisation, workbenches: [create(:workbench, workgroup_id: workgroup_1.id)] )) } +  let(:user_2)     { create(:user, organisation: create(:organisation, workbenches: [create(:workbench, workgroup_id: workgroup_2.id)] )) }    context 'after_update' do      it 'should observe calendar updates' do @@ -12,14 +17,21 @@ RSpec.describe CalendarObserver, type: :observer do      it 'should schedule mailer on calendar update' do        calendar.name = 'edited_name' -      expect(MailerJob).to receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user.id] +      expect(MailerJob).to receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user_1.id]        calendar.save      end      it 'should not schedule mailer for none shared calendar on update' do        calendar = create(:calendar, shared: false)        calendar.name = 'edited_name' -      expect(MailerJob).to_not receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user.id] +      expect(MailerJob).to_not receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user_1.id] +      calendar.save +    end + +    it "should only send mail to user from the same workgroup" do +      calendar.name = 'edited_name' +      expect(MailerJob).to receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user_1.id] +      expect(MailerJob).to_not receive(:perform_later).with 'CalendarMailer', 'updated', [calendar.id, user_2.id]        calendar.save      end    end @@ -31,13 +43,13 @@ RSpec.describe CalendarObserver, type: :observer do      end      it 'should schedule mailer on calendar create' do -      expect(MailerJob).to receive(:perform_later).with 'CalendarMailer', 'created', [anything, user.id] -      build(:calendar, shared: true).save +      expect(MailerJob).to receive(:perform_later).with 'CalendarMailer', 'created', [anything, user_1.id] +      build(:calendar, shared: true, workgroup_id: workgroup_1.id).save      end      it 'should not schedule mailer for none shared calendar on create' do -      expect(MailerJob).to_not receive(:perform_later).with 'CalendarMailer', 'created', [anything, user.id] -      build(:calendar, shared: false).save +      expect(MailerJob).to_not receive(:perform_later).with 'CalendarMailer', 'created', [anything, user_1.id] +      build(:calendar, shared: false, workgroup_id: workgroup_1.id).save      end    end  end diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb index a5c0a7471..09ac0e416 100644 --- a/spec/models/calendar_spec.rb +++ b/spec/models/calendar_spec.rb @@ -4,8 +4,6 @@ RSpec.describe Calendar, :type => :model do    it { is_expected.to validate_presence_of(:organisation) }    it { is_expected.to validate_presence_of(:name) } -  it { is_expected.to validate_presence_of(:short_name) } -  it { is_expected.to validate_uniqueness_of(:short_name) }    it { is_expected.to be_versioned }    describe '#to_time_table' do diff --git a/spec/models/chouette/route/route_stop_points_spec.rb b/spec/models/chouette/route/route_stop_points_spec.rb index 03c53b4cf..af26f017a 100644 --- a/spec/models/chouette/route/route_stop_points_spec.rb +++ b/spec/models/chouette/route/route_stop_points_spec.rb @@ -78,15 +78,16 @@ RSpec.describe Chouette::Route, :type => :model do    end    describe "#stop_points" do +    let(:first_stop_point) { subject.stop_points.first}      context "#find_by_stop_area" do        context "when arg is first quay id" do -        let(:first_stop_point) { subject.stop_points.first}          it "should return first quay" do            expect(subject.stop_points.find_by_stop_area( first_stop_point.stop_area_id)).to eq( first_stop_point)          end        end      end    end +    describe "#stop_areas" do      let(:line){ create(:line)}      let(:route_1){ create(:route, :line => line)} diff --git a/spec/models/export/base_spec.rb b/spec/models/export/base_spec.rb index edc0788f2..3d10ecead 100644 --- a/spec/models/export/base_spec.rb +++ b/spec/models/export/base_spec.rb @@ -110,24 +110,49 @@ RSpec.describe Export::Base, type: :model do    end    describe "#notify_parent" do -    it "must call #child_change on its parent" do -      allow(netex_export).to receive(:update) +    context "when export is finished" do +      before do +        netex_export.status = "successful" +        netex_export.notified_parent_at = nil +      end + +      it "must call #child_change on its parent" do +        allow(netex_export).to receive(:update) -      expect(workgroup_export).to receive(:child_change) -      netex_export.status = :foo -      netex_export.notify_parent +        expect(workgroup_export).to receive(:child_change) +        netex_export.notified_parent_at = nil +        netex_export.notify_parent +      end + +      it "must update the :notified_parent_at field of the child export" do +        allow(workgroup_export).to receive(:child_change) + +        Timecop.freeze(Time.now) do +          netex_export.notify_parent +          expect(netex_export.notified_parent_at.utc.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%3N') +          expect(netex_export.reload.notified_parent_at.utc.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%3N') +        end +      end      end -    it "must update the :notified_parent_at field of the child export" do -      allow(workgroup_export).to receive(:child_change) +    context "when export is not finished" do +      before do +        netex_export.status = "running" +        netex_export.notified_parent_at = nil +      end -      Timecop.freeze(Time.now) do -        netex_export.status = :bar +      it "must not call #child_change on its parent" do +        allow(netex_export).to receive(:update) + +        expect(workgroup_export).to_not receive(:child_change) +        netex_export.notify_parent +      end +      it "must keep nil the :notified_parent_at field of the child export" do          netex_export.notify_parent -        expect(netex_export.notified_parent_at.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N') -        expect(netex_export.reload.notified_parent_at.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N') +        expect(netex_export.notified_parent_at).to be_nil        end +      end    end diff --git a/spec/models/import/import_spec.rb b/spec/models/import/import_spec.rb index 102c0e1d6..b11c4922c 100644 --- a/spec/models/import/import_spec.rb +++ b/spec/models/import/import_spec.rb @@ -111,23 +111,47 @@ RSpec.describe Import::Base, type: :model do    end    describe "#notify_parent" do -    it "must call #child_change on its parent" do -      allow(netex_import).to receive(:update) +    context "when import is finished" do +      before do +        netex_import.status = "successful" +        netex_import.notified_parent_at = nil +      end + +      it "must call #child_change on its parent" do +        allow(netex_import).to receive(:update) -      expect(workbench_import).to receive(:child_change) -      netex_import.status = :foo -      netex_import.notify_parent +        expect(workbench_import).to receive(:child_change) +        netex_import.notify_parent +      end + +      it "must update the :notified_parent_at field of the child import" do +        allow(workbench_import).to receive(:child_change) +        Timecop.freeze(Time.now) do +          netex_import.notify_parent +          expect(netex_import.notified_parent_at.utc.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%3N') +          expect(netex_import.reload.notified_parent_at.utc.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.utc.strftime('%Y-%m-%d %H:%M:%S.%3N') +        end +      end      end -    it "must update the :notified_parent_at field of the child import" do -      allow(workbench_import).to receive(:child_change) -      Timecop.freeze(Time.now) do -        netex_import.status = :bar +    context "when import is not finished" do +      before do +        netex_import.status = "running" +        netex_import.notified_parent_at = nil +      end + +      it "must not call #child_change on its parent" do +        allow(netex_import).to receive(:update) + +        expect(workbench_import).to_not receive(:child_change) +        netex_import.notify_parent +      end +      it "must keep nil the :notified_parent_at field of the child import" do          netex_import.notify_parent -        expect(netex_import.notified_parent_at.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N') -        expect(netex_import.reload.notified_parent_at.strftime('%Y-%m-%d %H:%M:%S.%3N')).to eq Time.now.strftime('%Y-%m-%d %H:%M:%S.%3N') +        expect(netex_import.notified_parent_at).to be_nil        end +      end    end diff --git a/spec/support/shared_examples/compliance_control_validation.rb b/spec/support/shared_examples/compliance_control_validation.rb index b23c2984f..3a8232193 100644 --- a/spec/support/shared_examples/compliance_control_validation.rb +++ b/spec/support/shared_examples/compliance_control_validation.rb @@ -12,7 +12,25 @@ RSpec.shared_examples_for 'has min_max_values' do      end    end +  context "is valid" do +    it 'if minimum is well formatted' do +      subject.minimum = "12" +      expect_it.to be_valid +      subject.minimum = "12.0" +      expect_it.to be_valid +      subject.minimum = "12.01" +      expect_it.to be_valid +    end +  end +    context "is invalid" do +    it 'if minimum is not well formatted' do +      subject.minimum = "AA" +      expect_it.not_to be_valid +      subject.minimum = "12." +      expect_it.not_to be_valid +    end +      it 'if no value is provided' do        subject.minimum = nil        subject.maximum = nil | 
