aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--INSTALL.md146
-rw-r--r--app/assets/javascripts/main_menu.coffee5
-rw-r--r--app/assets/stylesheets/OpenLayers/custom.sass57
-rw-r--r--app/assets/stylesheets/components/_modals.sass6
-rw-r--r--app/assets/stylesheets/components/_referential_overview.sass15
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/calendars_controller.rb11
-rw-r--r--app/controllers/compliance_check_sets_controller.rb2
-rw-r--r--app/controllers/referentials_controller.rb8
-rw-r--r--app/controllers/workbenches_controller.rb11
-rw-r--r--app/helpers/compliance_control_sets_helper.rb2
-rw-r--r--app/helpers/table_builder_helper.rb2
-rw-r--r--app/helpers/table_builder_helper/column.rb16
-rw-r--r--app/javascript/helpers/routes_map.coffee130
-rw-r--r--app/javascript/packs/referential_lines/show.js2
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js3
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourney.js10
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CreateModal.js8
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js5
-rw-r--r--app/models/chouette/access_link.rb2
-rw-r--r--app/models/chouette/access_point.rb2
-rw-r--r--app/models/chouette/connection_link.rb2
-rw-r--r--app/models/chouette/group_of_line.rb2
-rw-r--r--app/models/chouette/journey_pattern.rb2
-rw-r--r--app/models/chouette/line.rb2
-rw-r--r--app/models/chouette/network.rb2
-rw-r--r--app/models/chouette/pt_link.rb2
-rw-r--r--app/models/chouette/route.rb2
-rw-r--r--app/models/chouette/stop_point.rb2
-rw-r--r--app/models/chouette/time_table.rb2
-rw-r--r--app/models/chouette/time_table_date.rb1
-rw-r--r--app/models/chouette/time_table_period.rb1
-rw-r--r--app/models/chouette/timeband.rb1
-rw-r--r--app/models/chouette/vehicle_journey.rb18
-rw-r--r--app/models/chouette/vehicle_journey_at_stop.rb2
-rw-r--r--app/models/compliance_check_message_export.rb4
-rw-r--r--app/models/concerns/custom_fields_support.rb24
-rw-r--r--app/models/custom_field.rb76
-rw-r--r--app/models/dashboard.rb1
-rw-r--r--app/models/import_message_export.rb4
-rw-r--r--app/models/organisation.rb2
-rw-r--r--app/models/workbench.rb4
-rw-r--r--app/policies/workbench_policy.rb11
-rw-r--r--app/services/referential_overview.rb6
-rw-r--r--app/views/calendars/_form_advanced.html.slim2
-rw-r--r--app/views/compliance_check_sets/index.html.slim7
-rw-r--r--app/views/dashboards/_dashboard.html.slim6
-rw-r--r--app/views/lines/show.html.slim10
-rw-r--r--app/views/referential_lines/show.html.slim2
-rw-r--r--app/views/referentials/_form.html.slim14
-rw-r--r--app/views/referentials/_overview.html.slim9
-rw-r--r--app/views/stif/dashboards/_dashboard.html.slim2
-rw-r--r--app/views/stop_areas/show.html.slim2
-rw-r--r--app/views/workbenches/_form.html.slim9
-rw-r--r--app/views/workbenches/edit.html.slim8
-rw-r--r--app/views/workbenches/show.html.slim2
-rw-r--r--config/locales/stop_areas.en.yml4
-rw-r--r--config/locales/stop_areas.fr.yml4
-rw-r--r--config/locales/workbenches.en.yml15
-rw-r--r--config/locales/workbenches.fr.yml15
-rw-r--r--config/routes.rb4
-rw-r--r--db/migrate/20180208174834_add_attributes_to_workbench.rb9
-rw-r--r--db/schema.rb16
-rw-r--r--lib/stif/dashboard.rb4
-rw-r--r--spec/controllers/line_referentials_controller_spec.rb4
-rw-r--r--spec/controllers/lines_controller_spec.rb8
-rw-r--r--spec/controllers/referentials_controller_spec.rb36
-rw-r--r--spec/controllers/stop_area_referentials_controller_spec.rb4
-rw-r--r--spec/controllers/stop_areas_controller_spec.rb8
-rw-r--r--spec/factories/custom_fields.rb2
-rw-r--r--spec/features/compliance_control_sets_spec.rb15
-rw-r--r--spec/helpers/table_builder_helper_spec.rb47
-rw-r--r--spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js2
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb5
-rw-r--r--spec/models/custom_field_spec.rb42
-rw-r--r--spec/models/referential_spec.rb25
-rw-r--r--spec/support/pundit/pundit_view_policy.rb6
-rw-r--r--spec/views/referentials/show.html.erb_spec.rb1
78 files changed, 651 insertions, 316 deletions
diff --git a/INSTALL.md b/INSTALL.md
index e44b072f4..392ef5d9f 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -8,6 +8,17 @@ Example with [rvm](https://rvm.io/) (other solutions : rbenv, packages..):
rvm install 2.3.1
```
+Nokogiri on macOS
+
+http://www.nokogiri.org/tutorials/installing_nokogiri.html tells us that `xz` can cause troubles, here is what to do
+
+```
+brew unlink xz
+gem install nokogiri # or bundle install
+brew link xz
+```
+
+
## Node and Yarn
Yarn needs node. If you use Node Version Manager [NVM](https://github.com/creationix/nvm) you can rely on the content of `.nvmrc`. Otherwise please make sure to use a compatible version, still best to use the same as indicated by `.nvrmc`.
@@ -15,7 +26,7 @@ Yarn needs node. If you use Node Version Manager [NVM](https://github.com/creati
* Install node
```sh
-nvm install 6.12.0
+nvm install 6.13.0
```
* Install [yarn](https://yarnpkg.com/lang/en/docs/install/)
@@ -36,41 +47,6 @@ sudo apt-get update && sudo apt-get install yarn
yarn install
```
-### Installation Caveats
-
-#### Node Related Issue, libv8
-
-`libv8` might cause you troubles, depending on your local configuration. If you have `libv8` installed (probably because of `node.js`) you might need to tell bundler/Rubygems to use the system version.
-
-```sh
-bundle config build.libv8 --with-system-v8
-bundle
-```
-
-or
-
-```sh
-gem install libv8 -v '<version>' -- --with-system-v8
-bundle
-```
-
-You will get the correct value of `<version>` from bundler's error message.
-
-#### Node Related Issue, therubyracer
-
-Even after `libv8` installation working, the gem `therubyracer` might not like the `libv8` version chosen.
-
-In that case however we can let the gem make its own choice:
-
-```sh
-gem uninstall libv8
-gem install therubyracer -v '<version>'
-```
-
-The version to be installed is indicated in the error message bundler gave us in the first place.
-
-This will install an appropriate `libv8` version and we can continue with `bundle`.
-
## Postgres
### Create user
@@ -89,53 +65,12 @@ When promted for the password enter the highly secure string `chouette`.
As documented [here](https://github.com/dryade/georuby-ext/issues/2) we need some more libs before we can start the `rake` setup tasks.
-
On mac/OS :
```sh
brew install postgis
```
-<<<<<<< HEAD
-### Authentication
-
-See `config.chouette_authentication_settings`.
-
-Use the database authentication or get an invitation to [STIF Portail](http://stif-portail-dev.af83.priv/).
-
-### Run seed
-
-Run :
-
- bundle exec rake db:seed
-
-Two users are created : stif-boiv@af83.com/secret and stif-boiv+transporteur@af83.com/secret
-
-If you have access to STIF CodifLigne and Reflex :
-
- bundle exec rake codifligne:sync
- bundle exec rake reflex:sync
-
-To create Referential with some data (Route, JourneyPattern, VehicleJourney, etc) :
-
- bundle exec rake referential:create
-
-# Troubleshooting
-
-If PG complains about illegal type `hstore` in your tests that is probably because the shared extension is not installed, here is what to do:
-
-#### Check installation
-
-* Run tests
-
- bundle exec rake spec
- bundle exec rake teaspoon
-
-* Start local server
-
- bundle exec rails server
-
-=======
On debian/ubuntu system :
```sh
@@ -156,50 +91,34 @@ Go into your local repository and install the gems
bundle install
```
-#### Nokogiri on macOS
-
-http://www.nokogiri.org/tutorials/installing_nokogiri.html tells us that `xz` can cause troubles, here is what to do
-
-```
-brew unlink xz
-gem install nokogiri # or bundle install
-brew link xz
-```
-
### Database
#### Create database
```sh
bundle exec rake db:create db:migrate
-RAILS_ENV=test bundle exec rake db:create db:migrate
```
-#### Load seed datas
->>>>>>> master
+#### Use seed
+
+Run :
```sh
bundle exec rake db:seed:stif
```
-#### Synchronise datas with lines and stop areas referentials
-
-* Launch Sidekiq
-
-```sh
-bundle exec sidekiq
-```
+Two users are created : stif-boiv@af83.com/secret and stif-boiv+transporteur@af83.com/secret
-* Execute the Synchronization Tasks
+#### Synchronize with STIF CODIFLIGNE (Line) and REFLEX (StopArea)
```sh
bundle exec rake codifligne:sync
bundle exec rake reflex:sync
```
-**N.B.** These are asynchronious tasks, you can observe the launched jobs in your [Sidekiq Console](http://localhost:3000/sidekiq)
+**N.B.** These are asynchronous tasks, you can observe the launched jobs in your [Sidekiq Console](http://localhost:3000/sidekiq)
-#### Data in various Apartments (Referentials)
+#### Create Referential
To create `Referential` objects with some data (`Route`, `JourneyPattern`, `VehicleJourney`, etc), you need to wait codifligne and reflex jobs finished. And then you can launch :
@@ -207,33 +126,32 @@ To create `Referential` objects with some data (`Route`, `JourneyPattern`, `Vehi
bundle exec rake referential:create
```
-### Check installation
+### Run tests
-#### Run tests
-
-#### Rspec
+* Rspec (Rails test)
```sh
bundle exec rake spec
-bundle exec rake teaspoon
```
-If Postgres complains about illegal type `hstore` or `unaccent` in your tests that is probably because the shared extension is not installed, here is what to do:
-
- bundle exec rake db:test:purge
-
-Thanks to `lib/tasks/extensions.rake`.
+* Jest (JavaScript tests)
-#### Jest (React integration specs)
+```sh
+grunt jest #to run the whole specs.
+grunt #to watch for changes and automatically run corresponding tests.
+```
-`grunt jest` to run the whole specs.
+### Run
-`grunt` to watch for changes and automatically run corresponding tests.
+Launch Sidekiq
-#### Start local server
+```sh
+bundle exec sidekiq
+```
```sh
bin/webpack-dev-server // Launch webpack server to compile assets on the fly
bundle exec rails server // Launch rails server
```
+
You need to have an account on [STIF Portail](http://stif-portail-dev.af83.priv/) to connect to the Rails application.
diff --git a/app/assets/javascripts/main_menu.coffee b/app/assets/javascripts/main_menu.coffee
index e943f448a..22ecebd25 100644
--- a/app/assets/javascripts/main_menu.coffee
+++ b/app/assets/javascripts/main_menu.coffee
@@ -21,8 +21,9 @@ $ ->
sticker = () ->
limit = 51
+ offset = 30
- if $(window).scrollTop() >= limit
+ if $(window).scrollTop() >= limit + offset
if stickyActions.length == 0
if ($('.page-action .small').length > 0)
stickyActions.push
@@ -53,7 +54,7 @@ $ ->
for child in item.content
child.appendTo $('.sticky-paction')
- else
+ else if $(window).scrollTop() <= limit - offset
$('#main_nav').removeClass 'sticky'
if $('#menu_top').find('.sticky-content').length > 0
diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass
index fa874d924..013c056d6 100644
--- a/app/assets/stylesheets/OpenLayers/custom.sass
+++ b/app/assets/stylesheets/OpenLayers/custom.sass
@@ -2,15 +2,20 @@
.list-group-item &
margin-top: 15px
- .routes-labels
+ .ol-routes-layers
+ position: absolute
+ right: 42px
+ top: .5em
padding: 0
- display: flex
- justify-content: space-between
- flex-wrap: wrap
margin: 5px -5px
- li
- list-style-type: none
- flex: 1 0 25%
+ width: 30%
+ background-color: transparentize(white, 0.2)
+ border-radius: 3px
+ max-height: 90%
+ overflow-y: scroll
+ a
+ display: block
+ width: calc(100% - 10px)
border: 1px solid $lightgrey
padding: 5px
margin: 5px
@@ -18,11 +23,21 @@
cursor: pointer
color: $blue
white-space: nowrap
-
+ text-overflow: ellipsis
+ overflow: hidden
+ font-size: 0.6em
&:hover
- background: $orange
+ text-decoration: none
+
+ &.active
+ background: $blue
color: white
+ .ol-routes-layers-button-wrapper
+ position: absolute
+ right: .5em
+ top: .5em
+
.ol-scale-line
background-color: transparent
bottom: 5px
@@ -55,20 +70,20 @@
.ol-zoom
background-color: transparent
- .ol-zoom-in, .ol-zoom-out
- background-color: $darkblue
- color: #fff
- border-radius: 3px
- margin: 0
+ .ol-zoom-in, .ol-zoom-out, .ol-routes-layers-button
+ background-color: $darkblue
+ color: #fff
+ border-radius: 3px
+ margin: 0
- .ol-zoom-in
- border-bottom-left-radius: 0
- border-bottom-right-radius: 0
+ .ol-zoom-in
+ border-bottom-left-radius: 0
+ border-bottom-right-radius: 0
- .ol-zoom-out
- margin-top: 1px
- border-top-left-radius: 0
- border-top-right-radius: 0
+ .ol-zoom-out
+ margin-top: 1px
+ border-top-left-radius: 0
+ border-top-right-radius: 0
.ol-zoomslider
margin: 2px
diff --git a/app/assets/stylesheets/components/_modals.sass b/app/assets/stylesheets/components/_modals.sass
index e52a2e125..14b783c51 100644
--- a/app/assets/stylesheets/components/_modals.sass
+++ b/app/assets/stylesheets/components/_modals.sass
@@ -50,3 +50,9 @@ $modalW: 600px
.modal-footer
border-color: rgba($blue, 0.25)
padding: 15px 30px
+
+ .has-error .form-group
+ margin-bottom: -10px
+
+ .form-group
+ margin-bottom: 25px
diff --git a/app/assets/stylesheets/components/_referential_overview.sass b/app/assets/stylesheets/components/_referential_overview.sass
index fc48411a3..7a0cc98c5 100644
--- a/app/assets/stylesheets/components/_referential_overview.sass
+++ b/app/assets/stylesheets/components/_referential_overview.sass
@@ -117,6 +117,7 @@
padding: 7px 10px
border-bottom: 1px solid $grey
font-size: 0.8em
+ display: block
&:last-child
border-bottom: none
.number
@@ -135,10 +136,9 @@
overflow: hidden
.name
display: inline-block
- width: $left-size - 50px()
+ width: $left-size - 10px
white-space: nowrap
line-height: 20px
- margin-left: 5px
text-overflow: ellipsis
overflow: hidden
vertical-align: bottom
@@ -182,8 +182,8 @@
height: 100%
transition: margin 0.5s
background: white
- &:last-child
- box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
+ // &:last-child
+ // box-shadow: 0 -10px 10px rgba(0,0,0,0.5)
.week-span
left: 15px
top: 15px
@@ -246,18 +246,17 @@
&.selected, &:hover
color: $blue
background-color: transparentize($blue, 0.7)
+
+ &:hover
+ background-color: transparentize(white, 0.7)
&:after
content: ""
left: -1px
right: -1px
top: 100%
height: 10000px
- background-color: transparentize($blue, 0.7)
position: absolute
z-index: 4
- &:hover
- background-color: transparentize(white, 0.7)
- &:after
background-color: transparentize(white, 0.7)
.line
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 45b7f55f6..c4961123d 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -28,7 +28,7 @@ class ApplicationController < ActionController::Base
protected
def user_not_authorized
- redirect_to forbidden_path
+ render 'errors/forbidden', status: 403
end
def current_organisation
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 75d4cbd09..cc7570d65 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -31,10 +31,11 @@ class CalendarsController < ChouetteController
end
def create
- create! do
- if @calendar.valid? && has_feature?('application_days_on_calendars')
- redirect_to([:edit, @calendar])
- return
+ create! do |success, failure|
+ if has_feature?('application_days_on_calendars')
+ success.html do
+ redirect_to([:edit, @workgroup, @calendar])
+ end
end
end
end
@@ -125,4 +126,4 @@ class CalendarsController < ChouetteController
scope
end
-end \ No newline at end of file
+end
diff --git a/app/controllers/compliance_check_sets_controller.rb b/app/controllers/compliance_check_sets_controller.rb
index 271598428..62b0e6ba3 100644
--- a/app/controllers/compliance_check_sets_controller.rb
+++ b/app/controllers/compliance_check_sets_controller.rb
@@ -12,7 +12,7 @@ class ComplianceCheckSetsController < ChouetteController
@q_for_form = scope.ransack(params[:q])
format.html {
@compliance_check_sets = ComplianceCheckSetDecorator.decorate(
- @q_for_form.result.order(created_at: :desc)
+ @q_for_form.result.order(created_at: :desc).paginate(page: params[:page], per_page: 30)
)
}
end
diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb
index 5267c15d8..6e3694547 100644
--- a/app/controllers/referentials_controller.rb
+++ b/app/controllers/referentials_controller.rb
@@ -7,6 +7,8 @@ class ReferentialsController < ChouetteController
respond_to :json, :only => :show
respond_to :js, :only => :show
+ before_action :check_cloning_source_is_accessible, only: %i(new create)
+
def new
new! do
build_referential
@@ -175,6 +177,12 @@ class ReferentialsController < ChouetteController
)
end
+ def check_cloning_source_is_accessible
+ return unless params[:from]
+ source = Referential.find params[:from]
+ return user_not_authorized unless current_user.organisation.workgroups.include?(source.workbench.workgroup)
+ end
+
def load_workbench
@workbench ||= Workbench.find(params[:workbench_id]) if params[:workbench_id]
@workbench ||= resource&.workbench if params[:id]
diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb
index 2a71fe811..35438eaaf 100644
--- a/app/controllers/workbenches_controller.rb
+++ b/app/controllers/workbenches_controller.rb
@@ -3,7 +3,10 @@ class WorkbenchesController < ChouetteController
include RansackDateFilter
before_action only: [:show] { set_date_time_params("validity_period", Date) }
defaults resource_class: Workbench
- respond_to :html, only: [:show, :index]
+
+ include PolicyChecker
+
+ respond_to :html, except: :destroy
def index
redirect_to dashboard_path
@@ -24,7 +27,6 @@ class WorkbenchesController < ChouetteController
current_workbench_id: params[:id]
}
)
- show!
end
def delete_referentials
@@ -38,6 +40,11 @@ class WorkbenchesController < ChouetteController
end
private
+
+ def workbench_params
+ params.require(:workbench).permit(:import_compliance_control_set_id, :merge_compliance_control_set_id)
+ end
+
def resource
@workbench = current_organisation.workbenches.find params[:id]
end
diff --git a/app/helpers/compliance_control_sets_helper.rb b/app/helpers/compliance_control_sets_helper.rb
index 448d5c008..0c63cb139 100644
--- a/app/helpers/compliance_control_sets_helper.rb
+++ b/app/helpers/compliance_control_sets_helper.rb
@@ -1,7 +1,7 @@
module ComplianceControlSetsHelper
def organisations_filters_values
- [current_organisation, Organisation.find_by_name("STIF")].uniq
+ [current_organisation, *Organisation.find_by_name("STIF")].uniq
end
def floating_links ccs_id
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 2068dd23c..d16858678 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -224,7 +224,7 @@ module TableBuilderHelper
if column.linkable?
path = column.link_to(item)
- link = link_to(value, path)
+ link = value.present? && path.present? ? link_to(value, path) : ""
if overhead.empty?
bcont << content_tag(:td, link, title: 'Voir')
diff --git a/app/helpers/table_builder_helper/column.rb b/app/helpers/table_builder_helper/column.rb
index 05aa9f563..ff6f2f36f 100644
--- a/app/helpers/table_builder_helper/column.rb
+++ b/app/helpers/table_builder_helper/column.rb
@@ -2,19 +2,21 @@ module TableBuilderHelper
class Column
attr_reader :key, :name, :attribute, :sortable
- def initialize(key: nil, name: '', attribute:, sortable: true, link_to: nil)
+ def initialize(key: nil, name: '', attribute:, sortable: true, link_to: nil, **opts)
if key.nil? && name.empty?
raise ColumnMustHaveKeyOrNameError
end
-
+ opts ||= {}
@key = key
@name = name
@attribute = attribute
@sortable = sortable
@link_to = link_to
+ @condition = opts[:if]
end
def value(obj)
+ return unless check_condition(obj)
if @attribute.is_a?(Proc)
@attribute.call(obj)
else
@@ -36,8 +38,18 @@ module TableBuilderHelper
end
def link_to(obj)
+ return unless check_condition(obj)
@link_to.call(obj)
end
+
+ def check_condition(obj)
+ condition_val = true
+ if @condition.present?
+ condition_val = @condition
+ condition_val = condition_val.call(obj) if condition_val.is_a?(Proc)
+ end
+ !!condition_val
+ end
end
diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee
index 6834406fc..42377cd6e 100644
--- a/app/javascript/helpers/routes_map.coffee
+++ b/app/javascript/helpers/routes_map.coffee
@@ -1,3 +1,65 @@
+RoutesLayersButton = (options) ->
+ menu = options.menu
+
+ toggleMenu = (e)=>
+ $(menu.element).toggleClass 'hidden'
+ button.innerHTML = if button.innerHTML == "+" then "-" else "+"
+
+ button = document.createElement("button")
+ button.innerHTML = "+"
+ button.addEventListener('click', toggleMenu, false)
+ button.addEventListener('touchstart', toggleMenu, false)
+ button.className = "ol-routes-layers-button"
+
+ element = document.createElement('div');
+ element.className = 'ol-control ol-routes-layers-button-wrapper';
+
+ element.appendChild(button)
+
+ ol.control.Control.call(this, {
+ element
+ target: options.target
+ })
+
+ol.inherits RoutesLayersButton, ol.control.Control
+
+RoutesLayersControl = (routes, routes_map) ->
+
+ element = document.createElement('div')
+ element.className = 'ol-unselectable ol-routes-layers hidden'
+ Object.keys(routes).forEach (id)=>
+ route = routes[id]
+ route.active = true
+ label = document.createElement('a')
+ label.title = route.name
+ label.className = 'active'
+ label.innerHTML = route.name
+ element.appendChild label
+ label.addEventListener "click", =>
+ route.active = !route.active
+ $(label).toggleClass "active"
+ route.active
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active)
+ routes_map.fitZoom()
+ label.addEventListener "mouseenter", =>
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(true)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(true)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(true)
+
+ label.addEventListener "mouseleave", =>
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active)
+
+
+ ol.control.Control.call(this, {
+ element
+ })
+
+ol.inherits RoutesLayersControl, ol.control.Control
+
class RoutesMap
constructor: (@target)->
@initMap()
@@ -20,6 +82,7 @@ class RoutesMap
addRoute: (route)->
geoColPts = []
geoColLns = []
+ route.active = true
@routes[route.id] = route if route.id
stops = route.stops || route
geoColEdges = [
@@ -77,68 +140,49 @@ class RoutesMap
@map.addLayer vectorEdgesLayer
@map.addLayer vectorLnsLayer
- lineStyle: (highlighted=false)->
+ lineStyle: (active=true)->
new ol.style.Style
stroke: new ol.style.Stroke
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 3
+ color: '#007fbb'
+ width: if active then 3 else 0
- edgeStyles: (highlighted=false)->
+ edgeStyles: (active=true)->
new ol.style.Style
image: new ol.style.Circle
radius: 5
stroke: new ol.style.Stroke
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 2
+ color: '#007fbb'
+ width: if active then 3 else 0
fill: new ol.style.Fill
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 2
+ color: '#007fbb'
+ width: if active then 3 else 0
- defaultStyles: (highlighted=false)->
+ defaultStyles: (active=true)->
new ol.style.Style
image: new ol.style.Circle
radius: 4
stroke: new ol.style.Stroke
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 2
+ color: '#007fbb'
+ width: if active then 3 else 0
fill: new ol.style.Fill
color: '#ffffff'
- width: 2
+ width: if active then 3 else 0
addRoutesLabels: ->
- labelsContainer = $("<ul class='routes-labels'></ul>")
- labelsContainer.appendTo $("##{@target}")
- @vectorPtsLayer = null
- @vectorEdgesLayer = null
- @vectorLnsLayer = null
+ menu = new RoutesLayersControl(@routes, this)
+ @map.addControl menu
+ @map.addControl new RoutesLayersButton(menu: menu)
+
+ fitZoom: ()->
+ area = []
+ found = false
Object.keys(@routes).forEach (id)=>
route = @routes[id]
- label = $("<li>#{route.name}</ul>")
- label.appendTo labelsContainer
- label.mouseleave =>
- route.vectorPtsLayer.setStyle @defaultStyles(false)
- route.vectorEdgesLayer.setStyle @edgeStyles(false)
- route.vectorLnsLayer.setStyle @lineStyle(false)
- route.vectorPtsLayer.setZIndex 2
- route.vectorEdgesLayer.setZIndex 3
- route.vectorLnsLayer.setZIndex 1
- @fitZoom()
- label.mouseenter =>
- route.vectorPtsLayer.setStyle @defaultStyles(true)
- route.vectorEdgesLayer.setStyle @edgeStyles(true)
- route.vectorLnsLayer.setStyle @lineStyle(true)
- route.vectorPtsLayer.setZIndex 11
- route.vectorEdgesLayer.setZIndex 12
- route.vectorLnsLayer.setZIndex 10
- @fitZoom(route)
-
- fitZoom: (route)->
- if route
- area = []
- route.stops.forEach (stop, i) =>
- area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
- else
- area = @area
+ if route.active
+ found = true
+ route.stops.forEach (stop, i) =>
+ area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ area = @area unless found
boundaries = ol.extent.applyTransform(
ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
)
diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js
index 542188018..99c5072ef 100644
--- a/app/javascript/packs/referential_lines/show.js
+++ b/app/javascript/packs/referential_lines/show.js
@@ -6,5 +6,5 @@ routes = JSON.parse(decodeURIComponent(routes))
var map = new RoutesMap('routes_map')
map.addRoutes(routes)
-// map.addRoutesLabels()
+map.addRoutesLabels()
map.fitZoom()
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index e67753e4b..5fb88f024 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -203,11 +203,10 @@ const actions = {
let field = fields[key]
if(field.validity && !field.validity.valid){
valid = false
- $(field).parent().addClass('has-error').children('.help-block').remove()
+ $(field).parent().parent().addClass('has-error').children('.help-block').remove()
$(field).parent().append("<span class='small help-block'>" + field.validationMessage + "</span>")
}
})
-
return valid
},
toggleArrivals : () => ({
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index 7db0cee1c..d605614c7 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -48,6 +48,14 @@ export default class VehicleJourney extends Component {
}
}
+ displayDelta(delta) {
+ if(delta > 99){
+ return "+"
+ }
+ return delta
+ }
+
+
hasTimeTable(time_tables, tt) {
let found = false
time_tables.map((t, index) => {
@@ -150,7 +158,7 @@ export default class VehicleJourney extends Component {
}
<div className={(this.columnHasDelta() ? '' : 'hidden')}>
{(vj.delta != 0) &&
- <span className='sb sb-chrono sb-lg text-warning' data-textinside={vj.delta}></span>
+ <span className='sb sb-chrono sb-lg text-warning' data-textinside={this.displayDelta(vj.delta)}></span>
}
</div>
<div data-headline={I18n.t("vehicle_journeys.form.departure_at")}>
diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
index 24d9a23c2..a60429765 100644
--- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js
+++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
@@ -12,7 +12,13 @@ export default class CreateModal extends Component {
}
handleSubmit() {
- if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0]) && this.props.modal.modalProps.selectedJPModal) {
+ if(!this.props.modal.modalProps.selectedJPModal){
+ let field = $('#NewVehicleJourneyModal').find(".vjCreateSelectJP")
+ field.parent().parent().addClass('has-error').children('.help-block').remove()
+ field.parent().append("<span class='small help-block'>" + I18n.t("simple_form.required.text") + "</span>")
+ return
+ }
+ if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0])) {
this.props.onAddVehicleJourney(_.assign({}, this.refs, {custom_fields: this.custom_fields}), this.props.modal.modalProps.selectedJPModal, this.props.stopPointsList, this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company)
this.props.onModalClose()
$('#NewVehicleJourneyModal').modal('hide')
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index 8705b3cf2..e7f68761e 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -90,6 +90,11 @@ const vehicleJourney= (state = {}, action, keep) => {
}
})
+ let lastStop = action.selectedJourneyPattern.stop_areas && action.selectedJourneyPattern.stop_areas[action.selectedJourneyPattern.stop_areas.length - 1]
+ if(lastStop && lastStop.stop_area_short_description.id == sp.id){
+ newVjas.departure_time = newVjas.arrival_time
+ }
+
if(newVjas.dummy){
newVjas.departure_time = {hour: "00", minute: "00"}
newVjas.arrival_time = {hour: "00", minute: "00"}
diff --git a/app/models/chouette/access_link.rb b/app/models/chouette/access_link.rb
index 4b99ab5ba..6b08443be 100644
--- a/app/models/chouette/access_link.rb
+++ b/app/models/chouette/access_link.rb
@@ -2,8 +2,6 @@ module Chouette
class AccessLink < Chouette::TridentActiveRecord
has_paper_trail
include ObjectidSupport
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
attr_accessor :access_link_type, :link_orientation_type, :link_key
diff --git a/app/models/chouette/access_point.rb b/app/models/chouette/access_point.rb
index b6f78f239..ac6580015 100644
--- a/app/models/chouette/access_point.rb
+++ b/app/models/chouette/access_point.rb
@@ -5,8 +5,6 @@ require 'geo_ruby'
module Chouette
class AccessPoint < Chouette::ActiveRecord
has_paper_trail
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
include Geokit::Mappable
include ProjectionFields
diff --git a/app/models/chouette/connection_link.rb b/app/models/chouette/connection_link.rb
index d5ddc606a..c53d6f5f1 100644
--- a/app/models/chouette/connection_link.rb
+++ b/app/models/chouette/connection_link.rb
@@ -3,8 +3,6 @@ module Chouette
has_paper_trail
include ObjectidSupport
include ConnectionLinkRestrictions
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
attr_accessor :connection_link_type
diff --git a/app/models/chouette/group_of_line.rb b/app/models/chouette/group_of_line.rb
index 75ee1ce73..3b6a7cea7 100644
--- a/app/models/chouette/group_of_line.rb
+++ b/app/models/chouette/group_of_line.rb
@@ -5,8 +5,6 @@ module Chouette
include GroupOfLineRestrictions
include LineReferentialSupport
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
has_and_belongs_to_many :lines, :class_name => 'Chouette::Line', :order => 'lines.name'
diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb
index 10c8b5439..ff85f376a 100644
--- a/app/models/chouette/journey_pattern.rb
+++ b/app/models/chouette/journey_pattern.rb
@@ -4,8 +4,6 @@ module Chouette
include ChecksumSupport
include JourneyPatternRestrictions
include ObjectidSupport
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
belongs_to :route
has_many :vehicle_journeys, :dependent => :destroy
diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb
index d077d5c9d..b3c4f2463 100644
--- a/app/models/chouette/line.rb
+++ b/app/models/chouette/line.rb
@@ -8,8 +8,6 @@ module Chouette
include StifTransportSubmodeEnumerations
extend ActiveModel::Naming
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
belongs_to :company
belongs_to :network
diff --git a/app/models/chouette/network.rb b/app/models/chouette/network.rb
index 6843c69ad..942fc5d67 100644
--- a/app/models/chouette/network.rb
+++ b/app/models/chouette/network.rb
@@ -5,8 +5,6 @@ module Chouette
include LineReferentialSupport
include ObjectidSupport
extend Enumerize
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
has_many :lines
attr_accessor :source_type_name
diff --git a/app/models/chouette/pt_link.rb b/app/models/chouette/pt_link.rb
index d14d5f29c..399539d44 100644
--- a/app/models/chouette/pt_link.rb
+++ b/app/models/chouette/pt_link.rb
@@ -3,8 +3,6 @@ require 'geokit'
module Chouette
class PtLink < Chouette::ActiveRecord
has_paper_trail
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
include Geokit::Mappable
def geometry
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 3729deb7d..26b80733d 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -12,8 +12,6 @@ module Chouette
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
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
def self.nullable_attributes
[:published_name, :comment, :number, :name, :direction, :wayback]
diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb
index 3b9eaa2f6..6b363cd93 100644
--- a/app/models/chouette/stop_point.rb
+++ b/app/models/chouette/stop_point.rb
@@ -9,8 +9,6 @@ module Chouette
include ForAlightingEnumerations
include ObjectidSupport
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
belongs_to :stop_area
belongs_to :route, inverse_of: :stop_points
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 20d6e69ac..506e498b8 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -7,8 +7,6 @@ module Chouette
include ApplicationDaysSupport
include TimetableSupport
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
acts_as_taggable
attr_accessor :tag_search
diff --git a/app/models/chouette/time_table_date.rb b/app/models/chouette/time_table_date.rb
index 98d8fa765..6a68d7fe1 100644
--- a/app/models/chouette/time_table_date.rb
+++ b/app/models/chouette/time_table_date.rb
@@ -2,7 +2,6 @@ module Chouette
class TimeTableDate < Chouette::ActiveRecord
include ChecksumSupport
- self.primary_key = "id"
belongs_to :time_table, inverse_of: :dates
acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0
diff --git a/app/models/chouette/time_table_period.rb b/app/models/chouette/time_table_period.rb
index d9b707675..6965d828a 100644
--- a/app/models/chouette/time_table_period.rb
+++ b/app/models/chouette/time_table_period.rb
@@ -2,7 +2,6 @@ module Chouette
class TimeTablePeriod < Chouette::ActiveRecord
include ChecksumSupport
- self.primary_key = "id"
belongs_to :time_table, inverse_of: :periods
acts_as_list :scope => 'time_table_id = #{time_table_id}',:top_of_list => 0
diff --git a/app/models/chouette/timeband.rb b/app/models/chouette/timeband.rb
index 6155ffc77..5a4e17b98 100644
--- a/app/models/chouette/timeband.rb
+++ b/app/models/chouette/timeband.rb
@@ -10,7 +10,6 @@ module Chouette
class Timeband < Chouette::TridentActiveRecord
include ObjectidSupport
has_paper_trail
- self.primary_key = "id"
validates :start_time, :end_time, presence: true
validates_with Chouette::TimebandValidator
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 194dc85ff..60279422c 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -3,11 +3,10 @@ module Chouette
class VehicleJourney < Chouette::TridentActiveRecord
has_paper_trail
include ChecksumSupport
+ include CustomFieldsSupport
include VehicleJourneyRestrictions
include ObjectidSupport
include StifTransportModeEnumerations
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
enum journey_category: { timed: 0, frequency: 1 }
@@ -347,21 +346,6 @@ module Chouette
end
end
- def self.custom_fields
- CustomField.where(resource_type: self.name.split("::").last)
- end
-
-
- def custom_fields
- Hash[*self.class.custom_fields.map do |v|
- [v.code, v.slice(:code, :name, :field_type, :options).update(value: custom_field_value(v.code))]
- end.flatten]
- end
-
- def custom_field_value key
- (custom_field_values || {})[key.to_s]
- end
-
def self.matrix(vehicle_journeys)
Hash[*VehicleJourneyAtStop.where(vehicle_journey_id: vehicle_journeys.pluck(:id)).map do |vjas|
[ "#{vjas.vehicle_journey_id}-#{vjas.stop_point_id}", vjas]
diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb
index 3b4f35f13..d875442ee 100644
--- a/app/models/chouette/vehicle_journey_at_stop.rb
+++ b/app/models/chouette/vehicle_journey_at_stop.rb
@@ -6,8 +6,6 @@ module Chouette
DAY_OFFSET_MAX = 1
- # FIXME http://jira.codehaus.org/browse/JRUBY-6358
- self.primary_key = "id"
belongs_to :stop_point
belongs_to :vehicle_journey
diff --git a/app/models/compliance_check_message_export.rb b/app/models/compliance_check_message_export.rb
index 04e1a9caa..bbaaa8e3f 100644
--- a/app/models/compliance_check_message_export.rb
+++ b/app/models/compliance_check_message_export.rb
@@ -26,12 +26,14 @@ class ComplianceCheckMessageExport
end
def to_csv(options = {})
- CSV.generate(options.slice(:col_sep, :quote_char, :force_quotes)) do |csv|
+ csv_string = CSV.generate(options.slice(:col_sep, :quote_char, :force_quotes)) do |csv|
csv << column_names
compliance_check_messages.each do |compliance_check_message|
csv << [compliance_check_message.compliance_check.criticity, *compliance_check_message.message_attributes.values_at('test_id', 'source_objectid'), options[:server_url] + compliance_check_message.message_attributes['source_object_path'], I18n.t("compliance_check_messages.#{compliance_check_message.message_key}", compliance_check_message.message_attributes.deep_symbolize_keys)]
end
end
+ # We add a BOM to indicate we use UTF-8
+ "\uFEFF" + csv_string
end
def to_zip(temp_file,options = {})
diff --git a/app/models/concerns/custom_fields_support.rb b/app/models/concerns/custom_fields_support.rb
new file mode 100644
index 000000000..6c76bd653
--- /dev/null
+++ b/app/models/concerns/custom_fields_support.rb
@@ -0,0 +1,24 @@
+module CustomFieldsSupport
+ extend ActiveSupport::Concern
+
+ included do
+ validate :custom_fields_values_are_valid
+
+ def self.custom_fields
+ CustomField.where(resource_type: self.name.split("::").last)
+ end
+
+ def custom_fields
+ CustomField::Collection.new self
+ end
+
+ def custom_field_value key
+ (custom_field_values || {})[key.to_s]
+ end
+
+ private
+ def custom_fields_values_are_valid
+ custom_fields.values.all?{|cf| cf.valid?}
+ end
+ end
+end
diff --git a/app/models/custom_field.rb b/app/models/custom_field.rb
index 774c8b0f6..4a840744e 100644
--- a/app/models/custom_field.rb
+++ b/app/models/custom_field.rb
@@ -6,4 +6,80 @@ class CustomField < ActiveRecord::Base
validates :name, uniqueness: {scope: [:resource_type, :workgroup_id]}
validates :code, uniqueness: {scope: [:resource_type, :workgroup_id], case_sensitive: false}
+
+ class Collection < HashWithIndifferentAccess
+ def initialize object
+ vals = object.class.custom_fields.map do |v|
+ [v.code, CustomField::Value.new(object, v, object.custom_field_value(v.code))]
+ end
+ super Hash[*vals.flatten]
+ end
+
+ def to_hash
+ HashWithIndifferentAccess[*self.map{|k, v| [k, v.to_hash]}.flatten(1)]
+ end
+ end
+
+ class Value
+ def self.new owner, custom_field, value
+ field_type = custom_field.options["field_type"]
+ klass_name = field_type && "CustomField::Value::#{field_type.classify}"
+ klass = klass_name && const_defined?(klass_name) ? klass_name.constantize : CustomField::Value::Base
+ klass.new owner, custom_field, value
+ end
+
+ class Base
+ def initialize owner, custom_field, value
+ @custom_field = custom_field
+ @raw_value = value
+ @owner = owner
+ @errors = []
+ @validated = false
+ @valid = false
+ end
+
+ delegate :code, :name, :field_type, :options, to: :@custom_field
+
+ def validate
+ @valid = true
+ end
+
+ def valid?
+ validate unless @validated
+ @valid
+ end
+
+ def value
+ @raw_value
+ end
+
+ def errors_key
+ "custom_fields.#{code}"
+ end
+
+ def to_hash
+ HashWithIndifferentAccess[*%w(code name field_type options value).map{|k| [k, send(k)]}.flatten(1)]
+ end
+ end
+
+ class Integer < Base
+ def value
+ @raw_value.to_i
+ end
+
+ def validate
+ @valid = true
+ unless @raw_value =~ /\A\d*\Z/
+ @owner.errors.add errors_key, "'#{@raw_value}' is not a valid integer"
+ @valid = false
+ end
+ end
+ end
+
+ class String < Base
+ def value
+ "#{@raw_value}"
+ end
+ end
+ end
end
diff --git a/app/models/dashboard.rb b/app/models/dashboard.rb
index 46c621266..e0857dca3 100644
--- a/app/models/dashboard.rb
+++ b/app/models/dashboard.rb
@@ -27,4 +27,5 @@ class Dashboard
def current_organisation
context.send(:current_organisation)
end
+
end
diff --git a/app/models/import_message_export.rb b/app/models/import_message_export.rb
index 05f8a2cc7..991eb0f61 100644
--- a/app/models/import_message_export.rb
+++ b/app/models/import_message_export.rb
@@ -26,12 +26,14 @@ class ImportMessageExport
end
def to_csv(options = {})
- CSV.generate(options) do |csv|
+ csv_string = CSV.generate(options) do |csv|
csv << column_names
import_messages.each do |import_message|
csv << [import_message.criticity, import_message.message_key, I18n.t("import_messages.#{import_message.message_key}", import_message.message_attributes.deep_symbolize_keys), *import_message.resource_attributes.values_at("filename", "line_number", "column_number") ]
end
end
+ # We add a BOM to indicate we use UTF-8
+ "\uFEFF" + csv_string
end
def to_zip(temp_file,options = {})
diff --git a/app/models/organisation.rb b/app/models/organisation.rb
index e8fb4e060..745bc0d22 100644
--- a/app/models/organisation.rb
+++ b/app/models/organisation.rb
@@ -13,6 +13,8 @@ class Organisation < ActiveRecord::Base
has_many :line_referentials, through: :line_referential_memberships
has_many :workbenches
+ has_many :workgroups, through: :workbenches
+
has_many :calendars
has_many :api_keys, class_name: 'Api::V1::ApiKey'
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index eb53af7aa..b6f90c7dc 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -42,6 +42,10 @@ class Workbench < ActiveRecord::Base
end
end
+ def calendars
+ workgroup.calendars.where('(organisation_id = ? OR shared = ?)', organisation.id, true)
+ end
+
def self.default
self.last if self.count == 1
where(name: DEFAULT_WORKBENCH_NAME).last
diff --git a/app/policies/workbench_policy.rb b/app/policies/workbench_policy.rb
new file mode 100644
index 000000000..7b925e91a
--- /dev/null
+++ b/app/policies/workbench_policy.rb
@@ -0,0 +1,11 @@
+class WorkbenchPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ scope
+ end
+ end
+
+ def update?
+ true
+ end
+end
diff --git a/app/services/referential_overview.rb b/app/services/referential_overview.rb
index ccfe0617a..7ef2909ad 100644
--- a/app/services/referential_overview.rb
+++ b/app/services/referential_overview.rb
@@ -208,7 +208,11 @@ class ReferentialOverview
end
def span
- h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b")
+ if @start_date.month == @end_date.month
+ h.l(@start_date, format: "#{@start_date.day}-#{@end_date.day} %b %Y")
+ else
+ "#{h.l(@start_date, format: "%d %b")} - #{h.l(@end_date, format: "%d %b %Y")}"
+ end
end
def number
diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim
index e796e2e36..aa4fd4e40 100644
--- a/app/views/calendars/_form_advanced.html.slim
+++ b/app/views/calendars/_form_advanced.html.slim
@@ -3,6 +3,6 @@
= javascript_tag do
| window.actionType = "#{raw params[:action]}";
// | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};
- | window.timetablesUrl = "#{calendar_url(@calendar).html_safe}";
+ | window.timetablesUrl = "#{workgroup_calendar_url(@workgroup, @calendar).html_safe}";
= javascript_pack_tag 'calendars/edit.js'
diff --git a/app/views/compliance_check_sets/index.html.slim b/app/views/compliance_check_sets/index.html.slim
index 31ad31e5b..9abd95dd1 100644
--- a/app/views/compliance_check_sets/index.html.slim
+++ b/app/views/compliance_check_sets/index.html.slim
@@ -23,9 +23,10 @@
), \
TableBuilderHelper::Column.new( \
key: :associated_object, \
- attribute: Proc.new{|n| n.referential.present? ? n.referential.name : ''}, \
+ if: ->(compliance_check_set){ compliance_check_set.referential.present? }, \
+ attribute: Proc.new{|n| n.referential.name}, \
link_to: lambda do |compliance_check_set| \
- compliance_check_set.referential.present? ? referential_path(compliance_check_set.referential_id) : '#' \
+ referential_path(compliance_check_set.referential_id) \
end \
), \
TableBuilderHelper::Column.new( \
@@ -42,6 +43,8 @@
],
sortable: true,
cls: 'table has-filter has-search'
+
+ = new_pagination @compliance_check_sets, 'pull-right'
- unless @compliance_check_sets.any?
.row.mt-xs
.col-lg-12
diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim
index 7f78934a6..f93b85cad 100644
--- a/app/views/dashboards/_dashboard.html.slim
+++ b/app/views/dashboards/_dashboard.html.slim
@@ -22,12 +22,12 @@
.panel.panel-default
.panel-heading
h3.panel-title.with_actions
- = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(workbench.workgroup)
+ = link_to I18n.t("activerecord.models.calendar", count: workbench.calendars.size), workgroup_calendars_path(workbench.workgroup)
div
= link_to '', workgroup_calendars_path(workbench.workgroup), class: ' fa fa-chevron-right pull-right'
- - if @dashboard.current_organisation.calendars.present?
+ - if workbench.calendars.present?
.list-group
- - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar|
+ - workbench.calendars.order("updated_at desc").limit(5).each do |calendar|
= link_to calendar.name, workgroup_calendars_path(workbench.workgroup, calendar), class: 'list-group-item'
- else
.panel-body
diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim
index 34b907bdd..96bb5bb0d 100644
--- a/app/views/lines/show.html.slim
+++ b/app/views/lines/show.html.slim
@@ -6,13 +6,13 @@
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
= definition_list t('metadatas'),
- { 'ID Codif' => @line.get_objectid.short_id,
- 'Activé' => (@line.deactivated? ? t('false') : t('true')),
+ { t('id_codif') => @line.get_objectid.short_id,
+ @line.human_attribute_name(:deactivated) => (@line.deactivated? ? t('false') : t('true')),
@line.human_attribute_name(:network_id) => (@line.network.nil? ? t('lines.index.unset') : @line.network.name),
@line.human_attribute_name(:company_id) => (@line.company.nil? ? t('lines.index.unset') : @line.company.name),
- 'Transporteur(s) secondaire(s)' => (@line.secondary_companies.nil? ? t('lines.index.unset') : array_to_html_list(@line.secondary_companies.collect(&:name))),
- 'Nom court' => @line.number,
- 'Code public' => (@line.registration_number ? @line.registration_number : '-'),
+ @line.human_attribute_name(:secondary_companies) => (@line.secondary_companies.nil? ? t('lines.index.unset') : array_to_html_list(@line.secondary_companies.collect(&:name))),
+ @line.human_attribute_name(:number) => @line.number,
+ @line.human_attribute_name(:registration_number) => (@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 : '-'),
diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim
index 5ea0e31bb..ef32ef6b0 100644
--- a/app/views/referential_lines/show.html.slim
+++ b/app/views/referential_lines/show.html.slim
@@ -82,6 +82,6 @@
= replacement_msg t('routes.search_no_results')
= javascript_tag do
- | window.routes = "#{URI.escape(@routes.map{|r| {name: r.name, id: r.id, stops: route_json_for_edit(r, serialize: false)}}.to_json)}"
+ | 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)}"
= javascript_pack_tag 'referential_lines/show.js'
diff --git a/app/views/referentials/_form.html.slim b/app/views/referentials/_form.html.slim
index 1e59ab566..96d847ec1 100644
--- a/app/views/referentials/_form.html.slim
+++ b/app/views/referentials/_form.html.slim
@@ -47,8 +47,13 @@
= link_to_add_association t('simple_form.labels.referential.actions.add_period'), subform, :periods, class: 'btn btn-outline-primary'
.separator
+ .row
+ .col-lg-11
+ = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' }
+ .col-lg-1
+ a.clear-lines.btn.btn-default href='#'
+ .fa.fa-trash
- = subform.input :lines, as: :select, collection: Chouette::Line.includes(:company).order(:name).where(objectid: current_functional_scope), selected: subform.object.line_ids, label_method: :display_name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': t('simple_form.labels.referential.placeholders.select_lines'), 'multiple': 'multiple', style: 'width: 100%' }
.hidden = form.input :workbench_id, as: :hidden
@@ -58,3 +63,10 @@
class: 'btn btn-default formSubmitr',
data: { disable_with: t('actions.processing') },
form: 'referential_form'
+
+ - content_for :javascript do
+ coffee:
+ $(".clear-lines").click (e)->
+ e.preventDefault()
+ $(e.currentTarget).parents('.row').first().find('[name*=line]').val('').trigger('change')
+ false
diff --git a/app/views/referentials/_overview.html.slim b/app/views/referentials/_overview.html.slim
index 870f642d4..6bed5f282 100644
--- a/app/views/referentials/_overview.html.slim
+++ b/app/views/referentials/_overview.html.slim
@@ -35,9 +35,12 @@
.lines= I18n.t("referentials.overview.head.lines")
.lines
- overview.lines.each do |line|
- .line
- a.number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}" title=line.name
- = line.number
+ a.line title=line.name
+ - if line.number.present?
+ .number style="background-color: #{line.color.present? ? "##{line.color}" : 'whitesmoke'}"
+ = line.number
+ - else
+ .name= line.name
.company= line.company&.name
.mode= line.transport_mode.present? ? t("enumerize.transport_mode.#{line.transport_mode}") : ""
.right
diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim
index 83a2106bb..e0f754fd4 100644
--- a/app/views/stif/dashboards/_dashboard.html.slim
+++ b/app/views/stif/dashboards/_dashboard.html.slim
@@ -57,7 +57,7 @@
.panel-heading
h3.panel-title.with_actions
= I18n.t("calendars.index.title")
- span.badge.ml-xs = @dashboard.calendars.count if @dashboard.calendars.present?
+ span.badge.ml-xs = @dashboard.workbench.calendars.count if @dashboard.calendars.present?
div
= link_to '', workgroup_calendars_path(@dashboard.workbench.workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see')
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index a4e14a272..34b872e91 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -20,7 +20,7 @@
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
@stop_area.human_attribute_name(:city_name) => @stop_area.city_name,
@stop_area.human_attribute_name(:country_code) => @stop_area.country_code.presence || '-',
- 'Etat' => (@stop_area.deleted_at ? 'Supprimé' : 'Actif'),
+ t('activerecord.attributes.stop_area.state') => (@stop_area.deleted_at ? t('stop_areas.show.state.deactivated') : t('stop_areas.show.state.active')),
@stop_area.human_attribute_name(:comment) => @stop_area.try(:comment),
})
= definition_list t('metadatas'), attributes
diff --git a/app/views/workbenches/_form.html.slim b/app/views/workbenches/_form.html.slim
new file mode 100644
index 000000000..534a5f378
--- /dev/null
+++ b/app/views/workbenches/_form.html.slim
@@ -0,0 +1,9 @@
+= simple_form_for @workbench, html: { class: 'form-horizontal', id: 'workbench_form' }, wrapper: :horizontal_form do |f|
+ .row
+ .col-lg-12
+ = f.input :import_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
+ = f.input :merge_compliance_control_set_id, as: :select, collection: current_organisation.compliance_control_sets, value_method: :id
+
+ .separator
+
+ = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'workbench_form'
diff --git a/app/views/workbenches/edit.html.slim b/app/views/workbenches/edit.html.slim
new file mode 100644
index 000000000..893024490
--- /dev/null
+++ b/app/views/workbenches/edit.html.slim
@@ -0,0 +1,8 @@
+- breadcrumb @workbench
+- page_header_content_for @workbench
+
+.page_content
+ .container-fluid
+ .row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1
+ == render 'form'
diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim
index 159aa8ea2..5c2468296 100644
--- a/app/views/workbenches/show.html.slim
+++ b/app/views/workbenches/show.html.slim
@@ -3,6 +3,8 @@
- content_for :page_header_content do
.row.mb-sm
.col-lg-12.text-right
+ - if policy(Workbench).update?
+ = 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.add'), new_workbench_referential_path(@workbench), class: 'btn btn-primary'
diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml
index c1ced1094..ac3dce280 100644
--- a/config/locales/stop_areas.en.yml
+++ b/config/locales/stop_areas.en.yml
@@ -66,6 +66,9 @@ en:
access_managment: "Access Points and Links managment"
access_points: "Access Points"
not_editable: "Le type d'arrêt est non modifiable"
+ state:
+ active: Active
+ deactivated: Deactivated
genealogical:
genealogical: "Links between stop area"
genealogical_routing: "Routing constraint's links"
@@ -139,6 +142,7 @@ en:
created_at: Created at
updated_at: Updated at
waiting_time: Waiting time (minutes)
+ state: State
formtastic:
titles:
stop_area:
diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml
index ede1aada6..f75c4ebe7 100644
--- a/config/locales/stop_areas.fr.yml
+++ b/config/locales/stop_areas.fr.yml
@@ -67,6 +67,9 @@ fr:
access_managment: "Gestion des accès et liens associés"
access_points: "Points d'accès"
not_editable: "Le type d'arrêt est non modifiable"
+ state:
+ active: Actif
+ deactivated: Désactivé
genealogical:
genealogical: "Lien entre arrêts"
genealogical_routing: "Liens de l'ITL"
@@ -141,6 +144,7 @@ fr:
created_at: "Créé le"
updated_at: "Edité le"
waiting_time: Temps de desserte (minutes)
+ state: État
formtastic:
titles:
stop_area:
diff --git a/config/locales/workbenches.en.yml b/config/locales/workbenches.en.yml
index 7f21f47a0..2d9b27045 100644
--- a/config/locales/workbenches.en.yml
+++ b/config/locales/workbenches.en.yml
@@ -2,6 +2,14 @@ en:
workbenches:
show:
title: "%{name}"
+ edit:
+ title: "Configure the workbench"
+ update:
+ title: "Configure the workbench"
+ referential_count:
+ zero: "There are no referentials in your workbench"
+ one: "There is one referential in your workbench"
+ other: "There are #{count} referentials in your workbench"
index:
title: "%{organisation} dashboard"
offers:
@@ -12,10 +20,9 @@ en:
calendars: "Calendars"
see: "See the list"
no_content: "No content yet."
- referential_count:
- zero: "There is no referential in your workbench"
- one: "There is one referential in your workbench"
- other: "There are #{count} referentials in your workbench"
+ actions:
+ show_output: "Merge offer"
+ affect_ccset: "Configure"
activerecord:
models:
workbench:
diff --git a/config/locales/workbenches.fr.yml b/config/locales/workbenches.fr.yml
index e7a392e66..8eee1a516 100644
--- a/config/locales/workbenches.fr.yml
+++ b/config/locales/workbenches.fr.yml
@@ -2,12 +2,27 @@ fr:
workbenches:
show:
title: "%{name}"
+ edit:
+ title: "Configurer l'espace de travail"
+ update:
+ title: "Configurer l'espace de travail"
referential_count:
zero: "Aucun jeu de données dans cet espace de travail"
one: "1 jeu de données dans cet espace de travail"
other: "#{count} jeux de données dans cet espace de travail"
+ index:
+ title: "%{organisation} dashboard"
+ offers:
+ title: "Offre de transport"
+ organisation: "Offres de mon Organisation"
+ idf: "Offres IDF"
+ referentials: "Jeux de données"
+ calendars: "Calendriers"
+ see: "Voir la liste"
+ no_content: "Aucun contenu"
actions:
show_output: "Finaliser l'Offre"
+ configure: "Configurer"
activerecord:
models:
workbench:
diff --git a/config/routes.rb b/config/routes.rb
index 456cb66f5..a3a21511c 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,7 +3,7 @@ require 'sidekiq/web'
ChouetteIhm::Application.routes.draw do
resource :dashboard
- resources :workbenches, only: [:show, :index] do
+ resources :workbenches, except: [:destroy] do
delete :referentials, on: :member, action: :delete_referentials
resources :imports do
get :download, on: :member
@@ -174,7 +174,7 @@ ChouetteIhm::Application.routes.draw do
namespace :api do
namespace :v1 do
- resources :workbenches, only: [:index, :show] do
+ resources :workbenches, except: [:destroy] do
resources :imports, only: [:index, :show, :create]
end
resources :access_links, only: [:index, :show]
diff --git a/db/migrate/20180208174834_add_attributes_to_workbench.rb b/db/migrate/20180208174834_add_attributes_to_workbench.rb
new file mode 100644
index 000000000..02002a772
--- /dev/null
+++ b/db/migrate/20180208174834_add_attributes_to_workbench.rb
@@ -0,0 +1,9 @@
+class AddAttributesToWorkbench < ActiveRecord::Migration
+ def change
+ add_column :workbenches, :import_compliance_control_set_id, :integer, limit: 8
+ add_column :workbenches, :merge_compliance_control_set_id, :integer, limit: 8
+
+ add_index :workbenches, :import_compliance_control_set_id
+ add_index :workbenches, :merge_compliance_control_set_id
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d6f3cdbe0..27e38e1b7 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -421,9 +421,9 @@ ActiveRecord::Schema.define(version: 20180301142531) do
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.datetime "notified_parent_at"
t.string "creator"
end
@@ -1008,17 +1008,21 @@ ActiveRecord::Schema.define(version: 20180301142531) do
create_table "workbenches", id: :bigserial, force: :cascade do |t|
t.string "name"
- t.integer "organisation_id", limit: 8
+ t.integer "organisation_id", limit: 8
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "line_referential_id", limit: 8
- t.integer "stop_area_referential_id", limit: 8
- t.integer "output_id", limit: 8
+ t.integer "line_referential_id", limit: 8
+ t.integer "stop_area_referential_id", limit: 8
+ t.integer "output_id", limit: 8
t.string "objectid_format"
- t.integer "workgroup_id", limit: 8
+ t.integer "workgroup_id", limit: 8
+ t.integer "import_compliance_control_set_id", limit: 8
+ t.integer "merge_compliance_control_set_id", limit: 8
end
+ add_index "workbenches", ["import_compliance_control_set_id"], name: "index_workbenches_on_import_compliance_control_set_id", using: :btree
add_index "workbenches", ["line_referential_id"], name: "index_workbenches_on_line_referential_id", using: :btree
+ add_index "workbenches", ["merge_compliance_control_set_id"], name: "index_workbenches_on_merge_compliance_control_set_id", using: :btree
add_index "workbenches", ["organisation_id"], name: "index_workbenches_on_organisation_id", using: :btree
add_index "workbenches", ["stop_area_referential_id"], name: "index_workbenches_on_stop_area_referential_id", using: :btree
add_index "workbenches", ["workgroup_id"], name: "index_workbenches_on_workgroup_id", using: :btree
diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb
index 46c635091..f558b79fb 100644
--- a/lib/stif/dashboard.rb
+++ b/lib/stif/dashboard.rb
@@ -1,7 +1,7 @@
module Stif
class Dashboard < ::Dashboard
def workbench
- @workbench ||= current_organisation.workbenches.find_by(name: "Gestion de l'offre")
+ @workbench ||= current_organisation.workbenches.default
end
def workgroup
@@ -13,7 +13,7 @@ module Stif
end
def calendars
- @calendars ||= Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, workgroup.id)
+ workbench.calendars
end
end
end
diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb
index 17ffb670d..8e8d48fda 100644
--- a/spec/controllers/line_referentials_controller_spec.rb
+++ b/spec/controllers/line_referentials_controller_spec.rb
@@ -6,8 +6,8 @@ RSpec.describe LineReferentialsController, :type => :controller do
describe 'PUT sync' do
let(:request){ put :sync, id: line_referential.id }
- it 'should redirect to 403' do
- expect(request).to redirect_to "/403"
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
end
with_permission "line_referentials.synchronize" do
diff --git a/spec/controllers/lines_controller_spec.rb b/spec/controllers/lines_controller_spec.rb
index 65fe88b96..96f49bb36 100644
--- a/spec/controllers/lines_controller_spec.rb
+++ b/spec/controllers/lines_controller_spec.rb
@@ -7,8 +7,8 @@ RSpec.describe LinesController, :type => :controller do
describe 'PUT deactivate' do
let(:request){ put :deactivate, id: line.id, line_referential_id: line_referential.id }
- it 'should redirect to 403' do
- expect(request).to redirect_to "/403"
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
end
with_permission "lines.change_status" do
@@ -24,8 +24,8 @@ RSpec.describe LinesController, :type => :controller do
before(:each){
line.deactivate!
}
- it 'should redirect to 403' do
- expect(request).to redirect_to "/403"
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
end
with_permission "lines.change_status" do
diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb
index 5e0b1e505..ff450c905 100644
--- a/spec/controllers/referentials_controller_spec.rb
+++ b/spec/controllers/referentials_controller_spec.rb
@@ -6,6 +6,42 @@ describe ReferentialsController, :type => :controller do
let(:organisation) { create :organisation }
let(:other_referential) { create :referential, organisation: organisation }
+ describe "GET new" do
+ let(:request){ get :new, workbench_id: referential.workbench_id }
+ before{ request }
+
+ it 'returns http success' do
+ expect(response).to have_http_status(200)
+ end
+
+ context "when cloning another referential" do
+ let(:source){ referential }
+ let(:request){ get :new, workbench_id: referential.workbench_id, from: source.id }
+
+ it 'returns http success' do
+ expect(response).to have_http_status(200)
+ end
+
+ context "when the referential is in another organisation but accessible by the user" do
+ let(:source){ create(:workbench_referential) }
+ before do
+ source.workbench.update_attribute :workgroup_id, referential.workbench.workgroup_id
+ end
+
+ it 'returns http forbidden' do
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ context "when the referential is not accessible by the user" do
+ let(:source){ create(:workbench_referential) }
+ it 'returns http forbidden' do
+ expect(response).to have_http_status(403)
+ end
+ end
+ end
+ end
+
describe 'PUT archive' do
context "user's organisation matches referential's organisation" do
it 'returns http success' do
diff --git a/spec/controllers/stop_area_referentials_controller_spec.rb b/spec/controllers/stop_area_referentials_controller_spec.rb
index 384323334..737ef631f 100644
--- a/spec/controllers/stop_area_referentials_controller_spec.rb
+++ b/spec/controllers/stop_area_referentials_controller_spec.rb
@@ -6,7 +6,9 @@ RSpec.describe StopAreaReferentialsController, :type => :controller do
describe 'PUT sync' do
let(:request){ put :sync, id: stop_area_referential.id }
- it { expect(request).to redirect_to "/403" }
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
+ end
with_permission "stop_area_referentials.synchronize" do
it 'returns HTTP success' do
diff --git a/spec/controllers/stop_areas_controller_spec.rb b/spec/controllers/stop_areas_controller_spec.rb
index 23bca3c36..f39ac5776 100644
--- a/spec/controllers/stop_areas_controller_spec.rb
+++ b/spec/controllers/stop_areas_controller_spec.rb
@@ -7,8 +7,8 @@ RSpec.describe StopAreasController, :type => :controller do
describe 'PUT deactivate' do
let(:request){ put :deactivate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id }
- it 'should redirect to 403' do
- expect(request).to redirect_to "/403"
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
end
with_permission "stop_areas.change_status" do
@@ -24,8 +24,8 @@ RSpec.describe StopAreasController, :type => :controller do
before(:each){
stop_area.deactivate!
}
- it 'should redirect to 403' do
- expect(request).to redirect_to "/403"
+ it 'should respond with 403' do
+ expect(request).to have_http_status 403
end
with_permission "stop_areas.change_status" do
diff --git a/spec/factories/custom_fields.rb b/spec/factories/custom_fields.rb
index 2f5fae555..7c43a6147 100644
--- a/spec/factories/custom_fields.rb
+++ b/spec/factories/custom_fields.rb
@@ -4,6 +4,6 @@ FactoryGirl.define do
resource_type "VehicleJourney"
sequence(:name){|n| "custom field ##{n}"}
field_type "list"
- options( { "capacity" => "0" } )
+ options( { capacity: "0" } )
end
end
diff --git a/spec/features/compliance_control_sets_spec.rb b/spec/features/compliance_control_sets_spec.rb
index 36dc5c2a9..0f4597db3 100644
--- a/spec/features/compliance_control_sets_spec.rb
+++ b/spec/features/compliance_control_sets_spec.rb
@@ -8,6 +8,9 @@ RSpec.describe "ComplianceControlSets", type: :feature do
let( :control_set ){ create :compliance_control_set, organisation: organisation }
let( :controls ){ control_set.compliance_controls }
+ let(:other_orga) { create :organisation }
+ let(:other_control_cset) { create :compliance_control_set, organisation: other_orga }
+
let(:blox){
2.times.map{ | _ | create :compliance_control_block, compliance_control_set: control_set }
}
@@ -95,6 +98,18 @@ RSpec.describe "ComplianceControlSets", type: :feature do
end
+ describe 'index' do
+
+ before do
+ visit compliance_control_sets_path
+ end
+
+ it "only showw compliance control sets from user organisation" do
+ expect(page).not_to have_content (other_orga.name)
+ expect(page).to have_content (organisation.name)
+ end
+ end
+
def make_control ccblock=nil, times: 1, severity: :warning
times.times do
make_one_control ccblock, severity
diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb
index 478875118..b0c17859f 100644
--- a/spec/helpers/table_builder_helper_spec.rb
+++ b/spec/helpers/table_builder_helper_spec.rb
@@ -441,6 +441,53 @@ describe TableBuilderHelper, type: :helper do
allow(helper).to receive(:mutual_workbench).and_return(referential.workbench)
}
+ context "with a condition" do
+ let(:columns){
+ [
+ TableBuilderHelper::Column.new(
+ key: :name,
+ attribute: 'name',
+ if: condition
+ ),
+ ]
+ }
+
+ context "when the condition is true" do
+ let(:condition){ ->(obj){true} }
+ it "should show the value" do
+ items.each do |i|
+ tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}"
+ expect(tr).to include(i.name)
+ end
+ end
+ end
+
+ context "when the condition depends on the object" do
+ let(:condition){ ->(obj){ obj == referential } }
+ it "should show the value accordingly" do
+ tr = helper.send(:tr, item, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{referential.id}"
+ expect(tr).to include(referential.name)
+ tr = helper.send(:tr, other_item, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{other_referential.id}"
+ expect(tr).to_not include(other_referential.name)
+ end
+ end
+
+ context "when the condition is false" do
+ let(:condition){ ->(obj){false} }
+ it "should not show the value" do
+ items.each do |i|
+ tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name, :index)
+ klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}"
+ expect(tr).to_not include(i.name)
+ end
+ end
+ end
+
+ end
+
context "with all rows non-selectable" do
let(:selectable){ false }
it "sets all rows as non selectable" do
diff --git a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
index 608115727..bfa0942c6 100644
--- a/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
+++ b/spec/javascript/vehicle_journeys/reducers/vehicleJourneys_spec.js
@@ -219,7 +219,7 @@ describe('vehicleJourneys reducer', () => {
type: 'ADD_VEHICLEJOURNEY',
data: fakeData,
selectedJourneyPattern: fakeSelectedJourneyPattern,
- stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0, waiting_time: null}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600, waiting_time: 10}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3, id: 3, time_zone_offset: 0, waiting_time: 20}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4, id: 4, time_zone_offset: 0}],
+ stopPointsList: [{object_id: 'test-1', city_name: 'city', stop_area_id: 1, id: 1, time_zone_offset: 0, waiting_time: 10}, {object_id: 'test-2', city_name: 'city', stop_area_id: 2, id: 2, time_zone_offset: -3600, waiting_time: 10}, {object_id: 'test-3', city_name: 'city', stop_area_id: 3, id: 3, time_zone_offset: 0, waiting_time: 20}, {object_id: 'test-4', city_name: 'city', stop_area_id: 4, id: 4, time_zone_offset: 0, waiting_time: 100}],
selectedCompany: fakeSelectedCompany
})
).toEqual([{
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 76e73d9cf..c69655bd4 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -260,7 +260,7 @@ describe Chouette::VehicleJourney, :type => :model do
item['purchase_windows'] = []
item['footnotes'] = []
item['purchase_windows'] = []
- item['custom_fields'] = vj.custom_fields
+ item['custom_fields'] = vj.custom_fields.to_hash
vj.vehicle_journey_at_stops.each do |vjas|
item['vehicle_journey_at_stops'] << vehicle_journey_at_stop_to_state(vjas)
@@ -282,7 +282,6 @@ describe Chouette::VehicleJourney, :type => :model do
Chouette::VehicleJourney.state_update(route, collection)
}.to change {Chouette::VehicleJourney.count}.by(1)
-
obj = Chouette::VehicleJourney.last
expect(obj).to receive(:after_commit_objectid).and_call_original
@@ -292,7 +291,7 @@ describe Chouette::VehicleJourney, :type => :model do
expect(collection.last['objectid']).to eq obj.objectid
expect(obj.published_journey_name).to eq 'dummy'
- expect(obj.custom_fields["energy"]["value"]).to eq 99
+ expect(obj.custom_fields["energy"].value).to eq 99
end
it 'should expect local times' do
diff --git a/spec/models/custom_field_spec.rb b/spec/models/custom_field_spec.rb
index 51128b0a2..b92bcfbdb 100644
--- a/spec/models/custom_field_spec.rb
+++ b/spec/models/custom_field_spec.rb
@@ -16,7 +16,6 @@ RSpec.describe CustomField, type: :model do
end
end
-
context "custom fields for a resource" do
let!( :fields ){ [create(:custom_field), create(:custom_field, code: :energy)] }
let!( :instance_fields ){
@@ -26,10 +25,49 @@ RSpec.describe CustomField, type: :model do
}
}
it { expect(Chouette::VehicleJourney.custom_fields).to eq(fields) }
- it { expect(vj.custom_fields).to eq(instance_fields) }
+ it {
+ instance_fields.each do |code, cf|
+ cf.each do |k, v|
+ expect(vj.custom_fields[code].send(k)).to eq(v)
+ end
+ end
+ }
end
context "custom field_values for a resource" do
it { expect(vj.custom_field_value("energy")).to eq(99) }
end
+
+ context "with an 'integer' field_type" do
+ let!(:field){ [create(:custom_field, code: :energy, options: {field_type: 'integer'})] }
+ let!( :vj ){ create :vehicle_journey, custom_field_values: {energy: "99"} }
+ it "should cast the value" do
+ expect(vj.custom_fields[:energy].value).to eq 99
+ end
+
+ it "should validate the value" do
+ {
+ "99" => true,
+ "azerty" => false,
+ "91a" => false,
+ "a91" => false
+ }.each do |val, valid|
+ vj = build :vehicle_journey, custom_field_values: {energy: val}
+ if valid
+ expect(vj.validate).to be_truthy
+ else
+ expect(vj.validate).to be_falsy
+ expect(vj.errors.messages[:"custom_fields.energy"]).to be_present
+ end
+ end
+ end
+ end
+
+ context "with a 'string' field_type" do
+ let!(:field){ [create(:custom_field, code: :energy, options: {field_type: 'string'})] }
+ let!( :vj ){ create :vehicle_journey, custom_field_values: {energy: 99} }
+ it "should cast the value" do
+ expect(vj.custom_fields[:energy].value).to eq '99'
+ end
+ end
end
diff --git a/spec/models/referential_spec.rb b/spec/models/referential_spec.rb
index 025ad80f9..1d9b3d78a 100644
--- a/spec/models/referential_spec.rb
+++ b/spec/models/referential_spec.rb
@@ -58,16 +58,21 @@ describe Referential, :type => :model do
Referential.new_from(ref, [])
end
- # let(:saved_clone) do
- # clone.tap do |clone|
- # clone.organisation = ref.organisation
- # clone.metadatas.each do |metadata|
- # metadata.line_ids = ref.lines.where(id: clone.line_ids, objectid: JSON.parse(ref.organisation.sso_attributes["functional_scope"]).collect(&:id)
- # metadata.periodes = metadata.periodes.map { |period| Range.new(period.end+1, period.end+10) }
- # end
- # clone.save!
- # end
- # end
+ let!(:workbench){ create :workbench }
+
+ let(:saved_clone) do
+ clone.tap do |clone|
+ clone.organisation = workbench.organisation
+ clone.workbench = workbench
+ clone.metadatas = [create(:referential_metadata, referential: clone)]
+ clone.save!
+ end
+ end
+
+ it 'should create a Referential' do
+ ref
+ expect { saved_clone }.to change{Referential.count}.by(1)
+ end
xit 'should create a ReferentialCloning' do
expect { saved_clone }.to change{ReferentialCloning.count}.by(1)
diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb
index 316ff6718..efe7f0f76 100644
--- a/spec/support/pundit/pundit_view_policy.rb
+++ b/spec/support/pundit/pundit_view_policy.rb
@@ -5,13 +5,13 @@ module Pundit
into.let(:current_referential){ referential || build_stubbed(:referential, organisation: organisation) }
into.let(:current_user){ create :user, permissions: permissions, organisation: organisation }
into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) }
- into.let(:current_offer_workbench) { create :workbench, organisation: organisation}
+ into.let(:current_workbench) { create :workbench, organisation: organisation}
into.before do
allow(view).to receive(:pundit_user) { pundit_user }
allow(view).to receive(:current_user) { current_user }
allow(view).to receive(:current_organisation).and_return(organisation)
- allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench)
- allow(view).to receive(:current_workgroup).and_return(current_offer_workbench.workgroup)
+ allow(view).to receive(:current_workbench).and_return(current_workbench)
+ allow(view).to receive(:current_workgroup).and_return(current_workbench.workgroup)
allow(view).to receive(:has_feature?){ |f| respond_to?(:features) && features.include?(f)}
allow(view).to receive(:user_signed_in?).and_return true
allow(view).to receive(:policy) do |instance|
diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb
index a7f37d180..82328cb8e 100644
--- a/spec/views/referentials/show.html.erb_spec.rb
+++ b/spec/views/referentials/show.html.erb_spec.rb
@@ -11,6 +11,7 @@ describe "referentials/show", type: :view do
let(:organisation){ referential.try(:organisation) }
let(:permissions){ [] }
let(:current_organisation) { organisation }
+ let(:organisation) { referential.organisation }
let(:readonly){ false }
before :each do