aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Donnet2018-01-31 12:20:25 +0100
committerGitHub2018-01-31 12:20:25 +0100
commit4fa30ef61bd334de0627267b7b2eda4e09c8b728 (patch)
treefa73d3d20cfa67a818b6f1d5f3a0a03898659cad
parente54ee3a4379afb763906ab2ba2fd980349c48334 (diff)
parentc463c3a950246c4c2660ce7df1c1ea8f2acbe578 (diff)
downloadchouette-core-4fa30ef61bd334de0627267b7b2eda4e09c8b728.tar.bz2
Merge pull request #263 from af83/5750-non-commercial-stop-areas
5750 non commercial stop areas
-rw-r--r--Gemfile.lock22
-rw-r--r--app/assets/stylesheets/OpenLayers/custom.sass21
-rw-r--r--app/assets/stylesheets/components/_forms.sass8
-rw-r--r--app/assets/stylesheets/modules/_vj_collection.sass6
-rw-r--r--app/controllers/stop_areas_controller.rb3
-rw-r--r--app/controllers/vehicle_journeys_controller.rb2
-rw-r--r--app/helpers/routes_helper.rb8
-rw-r--r--app/javascript/helpers/master_slave.coffee18
-rw-r--r--app/javascript/helpers/routes_map.coffee157
-rw-r--r--app/javascript/helpers/stop_area_header_manager.js4
-rw-r--r--app/javascript/packs/referential_lines/show.js10
-rw-r--r--app/javascript/packs/routes/show.js123
-rw-r--r--app/javascript/packs/stop_areas/new.js3
-rw-r--r--app/javascript/routes/components/StopPointList.js4
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js11
-rw-r--r--app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js2
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourney.js3
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourneys.js2
-rw-r--r--app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js3
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js2
-rw-r--r--app/models/chouette/area_type.rb25
-rw-r--r--app/models/chouette/stop_area.rb18
-rw-r--r--app/policies/stop_area_policy.rb2
-rw-r--r--app/views/referential_lines/show.html.slim8
-rw-r--r--app/views/stop_areas/_form.html.slim11
-rw-r--r--app/views/stop_areas/show.html.slim8
-rw-r--r--app/views/vehicle_journeys/show.rabl1
-rw-r--r--config/locales/area_types.en.yml6
-rw-r--r--config/locales/area_types.fr.yml6
-rw-r--r--config/locales/stop_areas.fr.yml2
-rw-r--r--config/webpack/environment.js2
-rw-r--r--config/webpack/loaders/coffee.js6
-rw-r--r--db/migrate/20180126134944_add_kind_to_stop_areas.rb6
-rw-r--r--db/schema.rb9
-rw-r--r--package.json3
-rw-r--r--spec/javascript/vehicle_journeys/actions_spec.js41
-rw-r--r--spec/models/chouette/area_type_spec.rb4
-rw-r--r--spec/models/chouette/stop_area_spec.rb10
-rw-r--r--yarn.lock12
39 files changed, 431 insertions, 161 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index ba1a90a5a..ba86a911f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -156,6 +156,7 @@ GEM
sort_alphabetical (~> 1.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
+ crass (1.0.3)
cucumber (2.4.0)
builder (>= 2.1.2)
cucumber-core (~> 1.5.0)
@@ -265,7 +266,7 @@ GEM
htmlbeautifier (1.3.1)
httparty (0.14.0)
multi_xml (>= 0.5.2)
- i18n (0.9.0)
+ i18n (0.9.3)
concurrent-ruby (~> 1.0)
i18n-tasks (0.9.15)
activesupport (>= 4.0.2)
@@ -302,7 +303,8 @@ GEM
thor
with_env (> 1.0)
xml-simple
- loofah (2.0.3)
+ loofah (2.1.1)
+ crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.6.4)
mime-types (>= 1.16, < 4)
@@ -313,7 +315,7 @@ GEM
mime-types-data (3.2016.0521)
mimemagic (0.3.2)
mini_portile2 (2.3.0)
- minitest (5.10.3)
+ minitest (5.11.2)
money (6.10.1)
i18n (>= 0.6.4, < 1.0)
multi_json (1.12.1)
@@ -368,7 +370,7 @@ GEM
rack
rack-protection (1.5.3)
rack
- rack-proxy (0.6.2)
+ rack-proxy (0.6.3)
rack
rack-test (0.6.3)
rack (>= 1.0)
@@ -396,8 +398,8 @@ GEM
rails-assets-jquery (>= 1.0.0)
rails-deprecated_sanitizer (1.0.3)
activesupport (>= 4.2.0.alpha)
- rails-dom-testing (1.0.8)
- activesupport (>= 4.2.0.beta, < 5.0)
+ rails-dom-testing (1.0.9)
+ activesupport (>= 4.2.0, < 5.0)
nokogiri (~> 1.6)
rails-deprecated_sanitizer (>= 1.0.1)
rails-erd (1.5.2)
@@ -419,7 +421,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (2.2.2)
rake
- rake (12.0.0)
+ rake (12.3.0)
ransack (1.8.3)
actionpack (>= 3.0)
activerecord (>= 3.0)
@@ -535,7 +537,7 @@ GEM
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
- thor (0.19.4)
+ thor (0.20.0)
thread (0.2.2)
thread_safe (0.3.6)
tilt (1.4.1)
@@ -547,7 +549,7 @@ GEM
json (>= 1.8, < 3.0)
parser (>= 2.3.0.7)
rainbow (>= 1.99.1, < 3.0)
- tzinfo (1.2.3)
+ tzinfo (1.2.4)
thread_safe (~> 0.1)
uglifier (2.7.2)
execjs (>= 0.3.0)
@@ -560,7 +562,7 @@ GEM
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
- webpacker (3.0.2)
+ webpacker (3.2.1)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
diff --git a/app/assets/stylesheets/OpenLayers/custom.sass b/app/assets/stylesheets/OpenLayers/custom.sass
index 7a5b4baf1..5a3612f99 100644
--- a/app/assets/stylesheets/OpenLayers/custom.sass
+++ b/app/assets/stylesheets/OpenLayers/custom.sass
@@ -2,6 +2,27 @@
.list-group-item &
margin-top: 15px
+ .routes-labels
+ padding: 0
+ display: flex
+ justify-content: space-between
+ flex-wrap: wrap
+ margin: 5px -5px
+ li
+ list-style-type: none
+ flex: 1 0 25%
+ border: 1px solid $lightgrey
+ padding: 5px
+ margin: 5px
+ border-radius: 5px
+ cursor: pointer
+ color: $blue
+ white-space: nowrap
+ max-width: 33%
+
+ &:hover
+ background: $orange
+ color: white
.ol-scale-line
background-color: transparent
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index b7f720963..214795b8b 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -85,9 +85,15 @@ input
// BS horizontal form label positionning fix
.form-horizontal
+ input[type="radio"].form-control
+ height: auto
+ width: auto
.form-group
position: relative
-
+ .radio-inline
+ padding-top: 4px
+ &:first-child
+ padding-left: 0
> .control-label
&[class*='col-sm-']
float: none
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 56769e52b..d99c67bd7 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -9,6 +9,9 @@
position: relative
padding-left: 25px
+ .fa
+ margin-left: 5px
+
> .headlined
&:before
margin-left: -25px
@@ -113,6 +116,9 @@
margin-left: 5px
&.has-error
+ .errors
+ color: $red
+ font-size: 0.8em
&:before
content: ''
position: absolute
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 79ffea72e..8d424b8d1 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -97,7 +97,7 @@ class StopAreasController < ChouetteController
edit! do
stop_area.position ||= stop_area.default_position
map.editable = true
- end
+ end
end
def destroy
@@ -203,6 +203,7 @@ class StopAreasController < ChouetteController
:url,
:waiting_time,
:zip_code,
+ :kind,
)
end
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index c1762c13e..ed6ba6ed1 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -66,6 +66,8 @@ class VehicleJourneysController < ChouetteController
:city_name => sp.stop_area.try(:city_name),
:comment => sp.stop_area.try(:comment),
:area_type => sp.stop_area.try(:area_type),
+ :area_type_i18n => I18n.t(sp.stop_area.try(:area_type), scope: 'area_types.label'),
+ :area_kind => sp.stop_area.try(:kind),
:stop_area_id => sp.stop_area_id,
:registration_number => sp.stop_area.try(:registration_number),
:nearest_topic_name => sp.stop_area.try(:nearest_topic_name),
diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb
index 4bffa99d4..61714a066 100644
--- a/app/helpers/routes_helper.rb
+++ b/app/helpers/routes_helper.rb
@@ -19,13 +19,15 @@ module RoutesHelper
css
end
- def route_json_for_edit(route)
- route.stop_points.includes(:stop_area).order(:position).map do |stop_point|
+ def route_json_for_edit(route, serialize: true)
+ data = route.stop_points.includes(:stop_area).order(:position).map do |stop_point|
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)
- end.to_json
+ end
+ data = data.to_json if serialize
+ data
end
end
diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee
new file mode 100644
index 000000000..4866a55e3
--- /dev/null
+++ b/app/javascript/helpers/master_slave.coffee
@@ -0,0 +1,18 @@
+class MasterSlave
+ constructor: (selector)->
+ $(selector).find('[data-master]').each (i, slave)->
+ $slave = $(slave)
+ master = $($slave.data().master)
+ console.log $slave
+ console.log $slave.find("input:disabled, select:disabled")
+ $slave.find("input:disabled, select:disabled").attr "data-slave-force-disabled", "true"
+ toggle = ->
+ val = master.filter(":checked").val() if master.filter("[type=radio]").length > 0
+ val ||= master.val()
+ selected = val == $slave.data().value
+ $slave.toggle selected
+ $slave.find("input, select").filter(":not([data-slave-force-disabled])").attr "disabled", !selected
+ master.change toggle
+ toggle()
+
+export default MasterSlave
diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee
new file mode 100644
index 000000000..85def1390
--- /dev/null
+++ b/app/javascript/helpers/routes_map.coffee
@@ -0,0 +1,157 @@
+class RoutesMap
+ constructor: (@target)->
+ @initMap()
+ @area = []
+ @seenStopIds = []
+ @routes = {}
+
+ initMap: ->
+ @map = new ol.Map
+ target: @target,
+ layers: [ new ol.layer.Tile(source: new ol.source.OSM()) ]
+ controls: [ new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider() ],
+ interactions: ol.interaction.defaults(zoom: true)
+ view: new ol.View()
+
+ addRoutes: (routes)->
+ for route in routes
+ @addRoute route
+
+ addRoute: (route)->
+ geoColPts = []
+ geoColLns = []
+ @routes[route.id] = route if route.id
+ stops = route.stops || route
+ geoColEdges = [
+ new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[0].longitude), parseFloat(stops[0].latitude)]))
+ }),
+ new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stops[stops.length - 1].longitude), parseFloat(stops[stops.length - 1].latitude)]))
+ })
+ ]
+ stops.forEach (stop, i) =>
+ if i < stops.length - 1
+ geoColLns.push new ol.Feature
+ geometry: new ol.geom.LineString([
+ ol.proj.fromLonLat([parseFloat(stops[i].longitude), parseFloat(stops[i].latitude)]),
+ ol.proj.fromLonLat([parseFloat(stops[i + 1].longitude), parseFloat(stops[i + 1].latitude)])
+ ])
+
+ geoColPts.push(new ol.Feature({
+ geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
+ }))
+ unless @seenStopIds.indexOf(stop.stoparea_id) > 0
+ @area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ @seenStopIds.push stop.stoparea_id
+
+ vectorPtsLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColPts
+ }),
+ style: @defaultStyles(),
+ zIndex: 2
+ })
+ route.vectorPtsLayer = vectorPtsLayer if route.id
+ vectorEdgesLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColEdges
+ }),
+ style: @edgeStyles(),
+ zIndex: 3
+ })
+ route.vectorEdgesLayer = vectorEdgesLayer if route.id
+ vectorLnsLayer = new ol.layer.Vector({
+ source: new ol.source.Vector({
+ features: geoColLns
+ }),
+ style: [@lineStyle()],
+ zIndex: 1
+ })
+ route.vectorLnsLayer = vectorLnsLayer if route.id
+ @map.addLayer vectorPtsLayer
+ @map.addLayer vectorEdgesLayer
+ @map.addLayer vectorLnsLayer
+
+ lineStyle: (highlighted=false)->
+ new ol.style.Style
+ stroke: new ol.style.Stroke
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 3
+
+ edgeStyles: (highlighted=false)->
+ 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
+ fill: new ol.style.Fill
+ color: if highlighted then "#ed7f00" else '#007fbb'
+ width: 2
+
+ defaultStyles: (highlighted=false)->
+ 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
+ fill: new ol.style.Fill
+ color: '#ffffff'
+ width: 2
+
+ addRoutesLabels: ->
+ labelsContainer = $("<ul class='routes-labels'></ul>")
+ labelsContainer.appendTo $("##{@target}")
+ @vectorPtsLayer = null
+ @vectorEdgesLayer = null
+ @vectorLnsLayer = null
+ 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
+ boundaries = ol.extent.applyTransform(
+ ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
+ )
+ @map.getView().fit boundaries, @map.getSize()
+ tooCloseToBounds = false
+ mapBoundaries = @map.getView().calculateExtent @map.getSize()
+ mapWidth = mapBoundaries[2] - mapBoundaries[0]
+ mapHeight = mapBoundaries[3] - mapBoundaries[1]
+ marginSize = 0.1
+ heightMargin = marginSize * mapHeight
+ widthMargin = marginSize * mapWidth
+ tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin
+ tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin
+ tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin
+ tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin
+ if tooCloseToBounds
+ @map.getView().setZoom(@map.getView().getZoom() - 1)
+
+
+export default RoutesMap
diff --git a/app/javascript/helpers/stop_area_header_manager.js b/app/javascript/helpers/stop_area_header_manager.js
index c9f397dee..2c820caf9 100644
--- a/app/javascript/helpers/stop_area_header_manager.js
+++ b/app/javascript/helpers/stop_area_header_manager.js
@@ -19,7 +19,7 @@ export default class StopAreaHeaderManager {
<div
className={(showHeadline) ? 'headlined' : ''}
data-headline={showHeadline}
- title={sp.city_name + ' (' + sp.zip_code +')'}
+ title={sp.city_name ? sp.city_name + ' (' + sp.zip_code +')' : ""}
>
<span>
<span>
@@ -27,6 +27,8 @@ export default class StopAreaHeaderManager {
{sp.time_zone_formatted_offset && <span className="small">
&nbsp;({sp.time_zone_formatted_offset})
</span>}
+ {sp.area_kind == 'non_commercial' && <span className="fa fa-question-circle" title={sp.area_type_i18n}>
+ </span>}
</span>
</span>
</div>
diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js
new file mode 100644
index 000000000..542188018
--- /dev/null
+++ b/app/javascript/packs/referential_lines/show.js
@@ -0,0 +1,10 @@
+import clone from '../../helpers/clone'
+import RoutesMap from '../../helpers/routes_map'
+
+let routes = clone(window, "routes", true)
+routes = JSON.parse(decodeURIComponent(routes))
+
+var map = new RoutesMap('routes_map')
+map.addRoutes(routes)
+// map.addRoutesLabels()
+map.fitZoom()
diff --git a/app/javascript/packs/routes/show.js b/app/javascript/packs/routes/show.js
index 71777c379..c20de0800 100644
--- a/app/javascript/packs/routes/show.js
+++ b/app/javascript/packs/routes/show.js
@@ -1,121 +1,8 @@
import clone from '../../helpers/clone'
+import RoutesMap from '../../helpers/routes_map'
+
let route = clone(window, "route", true)
route = JSON.parse(decodeURIComponent(route))
-
-const geoColPts = []
-const geoColLns = []
-const area = []
-const geoColEdges = [
- new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)]))
- }),
- new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(route[route.length - 1].longitude), parseFloat(route[route.length - 1].latitude)]))
- })
-]
-route.forEach(function (stop, i) {
- if (i < route.length - 1) {
- geoColLns.push(new ol.Feature({
- geometry: new ol.geom.LineString([
- ol.proj.fromLonLat([parseFloat(route[i].longitude), parseFloat(route[i].latitude)]),
- ol.proj.fromLonLat([parseFloat(route[i + 1].longitude), parseFloat(route[i + 1].latitude)])
- ])
- }))
- }
- geoColPts.push(new ol.Feature({
- geometry: new ol.geom.Point(ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]))
- }))
- area.push([parseFloat(stop.longitude), parseFloat(stop.latitude)])
-})
-var edgeStyles = new ol.style.Style({
- image: new ol.style.Circle(({
- radius: 5,
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 2
- }),
- fill: new ol.style.Fill({
- color: '#007fbb',
- width: 2
- })
- }))
-})
-var defaultStyles = new ol.style.Style({
- image: new ol.style.Circle(({
- radius: 4,
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 2
- }),
- fill: new ol.style.Fill({
- color: '#ffffff',
- width: 2
- })
- }))
-})
-var lineStyle = new ol.style.Style({
- stroke: new ol.style.Stroke({
- color: '#007fbb',
- width: 3
- })
-})
-
-var vectorPtsLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColPts
- }),
- style: defaultStyles,
- zIndex: 2
-})
-var vectorEdgesLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColEdges
- }),
- style: edgeStyles,
- zIndex: 3
-})
-var vectorLnsLayer = new ol.layer.Vector({
- source: new ol.source.Vector({
- features: geoColLns
- }),
- style: [lineStyle],
- zIndex: 1
-})
-
-var map = new ol.Map({
- target: 'route_map',
- layers: [
- new ol.layer.Tile({
- source: new ol.source.OSM()
- }),
- vectorPtsLayer,
- vectorEdgesLayer,
- vectorLnsLayer
- ],
- controls: [new ol.control.ScaleLine(), new ol.control.Zoom(), new ol.control.ZoomSlider()],
- interactions: ol.interaction.defaults({
- zoom: true
- }),
- view: new ol.View({
- center: ol.proj.fromLonLat([parseFloat(route[0].longitude), parseFloat(route[0].latitude)]),
- zoom: 13
- })
-});
-const boundaries = ol.extent.applyTransform(
- ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
-)
-map.getView().fit(boundaries, map.getSize());
-let tooCloseToBounds = false
-const mapBoundaries = map.getView().calculateExtent(map.getSize())
-const mapWidth = mapBoundaries[2] - mapBoundaries[0]
-const mapHeight = mapBoundaries[3] - mapBoundaries[1]
-const marginSize = 0.1
-const heightMargin = marginSize * mapHeight
-const widthMargin = marginSize * mapWidth
-tooCloseToBounds = tooCloseToBounds || (boundaries[0] - mapBoundaries[0]) < widthMargin
-tooCloseToBounds = tooCloseToBounds || (mapBoundaries[2] - boundaries[2]) < widthMargin
-tooCloseToBounds = tooCloseToBounds || (boundaries[1] - mapBoundaries[1]) < heightMargin
-tooCloseToBounds = tooCloseToBounds || (mapBoundaries[3] - boundaries[3]) < heightMargin
-if(tooCloseToBounds){
- map.getView().setZoom(map.getView().getZoom() - 1)
-}
+var map = new RoutesMap('route_map')
+map.addRoute(route)
+map.fitZoom()
diff --git a/app/javascript/packs/stop_areas/new.js b/app/javascript/packs/stop_areas/new.js
new file mode 100644
index 000000000..ffe702cdb
--- /dev/null
+++ b/app/javascript/packs/stop_areas/new.js
@@ -0,0 +1,3 @@
+import MasterSlave from "../../helpers/master_slave"
+
+new MasterSlave("form")
diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js
index 43a027084..b39fa0c9c 100644
--- a/app/javascript/routes/components/StopPointList.js
+++ b/app/javascript/routes/components/StopPointList.js
@@ -56,7 +56,7 @@ export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick
)
}
-StopPointList.PropTypes = {
+StopPointList.propTypes = {
stopPoints: PropTypes.array.isRequired,
onDeleteClick: PropTypes.func.isRequired,
onMoveUpClick: PropTypes.func.isRequired,
@@ -68,4 +68,4 @@ StopPointList.PropTypes = {
StopPointList.contextTypes = {
I18n: PropTypes.object
-} \ No newline at end of file
+}
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 2675328e3..4a4ec371d 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -380,6 +380,17 @@ const actions = {
}
})
},
+
+ validate : (dispatch, vehicleJourneys, next) => {
+ dispatch(actions.didValidateVehicleJourneys(vehicleJourneys))
+ actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
+ },
+
+ didValidateVehicleJourneys : (vehicleJourneys) => ({
+ type: 'DID_VALIDATE_VEHICLE_JOURNEYS',
+ vehicleJourneys
+ }),
+
submitVehicleJourneys : (dispatch, state, next) => {
dispatch(actions.fetchingApi())
let urlJSON = window.location.pathname + "_collection.json"
diff --git a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
index 6e94b04a3..fb921df9c 100644
--- a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
@@ -13,7 +13,7 @@ export default class SaveVehicleJourneys extends SaveButton{
}
submitForm(){
- this.props.onSubmitVehicleJourneys(this.props.dispatch, this.props.vehicleJourneys)
+ this.props.validate(this.props.vehicleJourneys, this.props.dispatch)
}
}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index d240757a3..2b5783dda 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -153,6 +153,9 @@ export default class VehicleJourney extends Component {
/>
</span>
</div>
+ {vj.errors && <div className="errors">
+ {vj.errors}
+ </div>}
</div>
</div>
)}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
index b188962c2..256ca81f9 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
@@ -89,7 +89,7 @@ export default class VehicleJourneys extends Component {
</div>
)}
- { _.some(this.props.vehicleJourneys, 'errors') && (
+ { this.props.vehicleJourneys.errors && this.props.vehicleJourneys.errors.length && _.some(this.props.vehicleJourneys, 'errors') && (
<div className="alert alert-danger mt-sm">
<strong>Erreur : </strong>
{this.props.vehicleJourneys.map((vj, index) =>
diff --git a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
index f5f879ed8..3daf831f8 100644
--- a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
@@ -23,6 +23,9 @@ const mapDispatchToProps = (dispatch) => {
},
onSubmitVehicleJourneys: (next, state) => {
actions.submitVehicleJourneys(dispatch, state, next)
+ },
+ validate: (state) =>{
+ actions.validate(dispatch, state)
}
}
}
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index ae45993a8..1a15ec46d 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -273,6 +273,8 @@ export default function vehicleJourneys(state = [], action) {
return vj
}
})
+ case 'DID_VALIDATE_VEHICLE_JOURNEYS':
+ return [...action.vehicleJourneys]
default:
return state
}
diff --git a/app/models/chouette/area_type.rb b/app/models/chouette/area_type.rb
index 4703ea646..e17d2ee8d 100644
--- a/app/models/chouette/area_type.rb
+++ b/app/models/chouette/area_type.rb
@@ -1,13 +1,22 @@
class Chouette::AreaType
include Comparable
- ALL = %i(zdep zder zdlp zdlr lda gdl).freeze
+ COMMERCIAL = %i(zdep zder zdlp zdlr lda gdl).freeze
+ NON_COMMERCIAL = %i(deposit border service_area relief other).freeze
+ ALL = COMMERCIAL + NON_COMMERCIAL
+ @@commercial = COMMERCIAL
+ @@non_commercial = NON_COMMERCIAL
@@all = ALL
- mattr_accessor :all
+ mattr_accessor :all, :commercial, :non_commercial
- def self.all=(values)
- @@all = ALL & values
+ def self.commercial=(values)
+ @@commercial = COMMERCIAL & values
+ reset_caches!
+ end
+
+ def self.non_commercial=(values)
+ @@non_commercial = NON_COMMERCIAL & values
reset_caches!
end
@@ -20,12 +29,14 @@ class Chouette::AreaType
end
def self.reset_caches!
+ @@all = @@commercial + @@non_commercial
@@instances = {}
- @@options = nil
+ @@options = {}
end
- def self.options
- @@options ||= all.map { |c| find(c) }.map { |t| [ t.label, t.code ] }
+ def self.options(kind=:all)
+ @@options ||= {}
+ @@options[kind] ||= self.send(kind).map { |c| find(c) }.map { |t| [ t.label, t.code ] }
end
attr_reader :code
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index ea1855ea8..ad42d54ae 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -10,6 +10,7 @@ module Chouette
extend Enumerize
enumerize :area_type, in: Chouette::AreaType::ALL
+ enumerize :kind, in: %i(commercial non_commercial)
with_options dependent: :destroy do |assoc|
assoc.has_many :stop_points
@@ -31,6 +32,7 @@ module Chouette
validates_format_of :registration_number, :with => %r{\A[\d\w_\-]+\Z}, :allow_blank => true
validates_presence_of :name
+ validates_presence_of :kind
validates_presence_of :latitude, :if => :longitude
validates_presence_of :longitude, :if => :latitude
validates_numericality_of :latitude, :less_than_or_equal_to => 90, :greater_than_or_equal_to => -90, :allow_nil => true
@@ -41,6 +43,7 @@ module Chouette
validates_numericality_of :waiting_time, greater_than_or_equal_to: 0, only_integer: true, if: :waiting_time
validate :parent_area_type_must_be_greater
+ validate :area_type_of_right_kind
def self.nullable_attributes
[:registration_number, :street_name, :country_code, :fare_code,
@@ -56,6 +59,13 @@ module Chouette
end
end
+ def area_type_of_right_kind
+
+ unless Chouette::AreaType.send(self.kind).map(&:to_s).include?(self.area_type)
+ errors.add(:area_type, I18n.t('stop_areas.errors.incorrect_kind_area_type'))
+ end
+ end
+
after_update :clean_invalid_access_links
before_save :coordinates_to_lat_lng
@@ -96,6 +106,10 @@ module Chouette
end
end
+ def local_id
+ id.to_s
+ end
+
def children_in_depth
return [] if self.children.empty?
@@ -374,5 +388,9 @@ module Chouette
return nil unless time_zone.present?
ActiveSupport::TimeZone[time_zone]&.formatted_offset
end
+
+ def commercial?
+ kind == "commercial"
+ end
end
end
diff --git a/app/policies/stop_area_policy.rb b/app/policies/stop_area_policy.rb
index 6db48b702..fd73b7092 100644
--- a/app/policies/stop_area_policy.rb
+++ b/app/policies/stop_area_policy.rb
@@ -3,7 +3,7 @@ class StopAreaPolicy < ApplicationPolicy
def search_scope scope_name
scope = resolve
if scope_name&.to_s == "route_editor"
- scope = scope.where(area_type: 'zdep') unless user.organisation.has_feature?("route_stop_areas_all_types")
+ scope = scope.where("kind = ? OR area_type = ?", :non_commercial, 'zdep') unless user.organisation.has_feature?("route_stop_areas_all_types")
end
scope
end
diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim
index 02d605d8c..5ea0e31bb 100644
--- a/app/views/referential_lines/show.html.slim
+++ b/app/views/referential_lines/show.html.slim
@@ -17,7 +17,8 @@
@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')),}
-
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ #routes_map.map.mb-lg
.row
.col-lg-12
.h3 = t('lines.show.routes.title')
@@ -79,3 +80,8 @@
.row.mt-xs
.col-lg-12
= 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)}"
+
+= javascript_pack_tag 'referential_lines/show.js'
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index b2322f73a..aa156f7bd 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -6,10 +6,13 @@
/= @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")}
+ = f.input :kind, as: :radio_buttons, checked: @stop_area.kind, :input_html => {:disabled => !@stop_area.new_record?}, :include_blank => false, item_wrapper_class: 'radio-inline', wrapper: :horizontal_form, disabled: !@stop_area.new_record?
- = f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
-
- = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options, :include_blank => false
+ .slave data-master="[name='stop_area[kind]']" data-value="commercial"
+ = f.input :parent_id, as: :select, :collection => [f.object.parent_id], input_html: { data: { select2_ajax: 'true', url: autocomplete_stop_area_referential_stop_areas_path(@stop_area_referential), initvalue: {id: f.object.parent_id, text: f.object.parent.try(:full_name)}}}
+ - %i(non_commercial commercial).each do |kind|
+ .slave data-master="[name='stop_area[kind]']" data-value=kind
+ = f.input :area_type, as: :select, :input_html => {id: kind, :disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options(kind), :include_blank => false, disabled: !@stop_area.new_record?
.location_info
h3 = t("stop_areas.stop_area.localisation")
@@ -49,3 +52,5 @@
.separator
= f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'stop_area_form'
+
+= javascript_pack_tag "stop_areas/new"
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index b5ec8ac00..b0896c1e0 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -6,11 +6,11 @@
.container-fluid
.row
.col-lg-6.col-md-6.col-sm-12.col-xs-12
- - attributes = { t('id_reflex') => @stop_area.get_objectid.short_id,
- @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-",
- @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
+ - attributes = { t('id_reflex') => @stop_area.get_objectid.short_id }
+ - attributes.merge!({ @stop_area.human_attribute_name(:parent) => @stop_area.parent ? link_to(@stop_area.parent.name, stop_area_referential_stop_area_path(@stop_area_referential, @stop_area.parent)) : "-" }) if @stop_area.commercial?
+ - attributes.merge!({ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
@stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number,
- }
+ })
- attributes.merge!(@stop_area.human_attribute_name(:waiting_time) => @stop_area.waiting_time_text) if has_feature?(:stop_area_waiting_time)
- attributes.merge!({ "Coordonnées" => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl
index fc65e6cb6..dca0866b3 100644
--- a/app/views/vehicle_journeys/show.rabl
+++ b/app/views/vehicle_journeys/show.rabl
@@ -45,6 +45,7 @@ child(:vehicle_journey_at_stops_matrix, :object_root => false) do |vehicle_stops
end
node(:dummy) { vehicle_stop.dummy }
+ node(:area_kind) { vehicle_stop.stop_point.stop_area.kind }
node(:stop_area_object_id) do
vehicle_stop.stop_point.stop_area.objectid
diff --git a/config/locales/area_types.en.yml b/config/locales/area_types.en.yml
index 34ec3243d..5d23a6665 100644
--- a/config/locales/area_types.en.yml
+++ b/config/locales/area_types.en.yml
@@ -6,3 +6,9 @@ en:
zdlp: ZDLp
zdlr: ZDLr
lda: LDA
+ gdl: GDL
+ deposit: Deposit
+ border: Border
+ service_area: Service Area
+ relief: Relief point
+ other: Other
diff --git a/config/locales/area_types.fr.yml b/config/locales/area_types.fr.yml
index fd4e1e741..bb249c235 100644
--- a/config/locales/area_types.fr.yml
+++ b/config/locales/area_types.fr.yml
@@ -6,3 +6,9 @@ fr:
zdlp: ZDLp
zdlr: ZDLr
lda: LDA
+ gdl: GDL
+ deposit: Dépôt
+ border: Frontière
+ service_area: Aire de service / Pause
+ relief: Point de releve
+ other: Autre
diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml
index 0095bbe6d..283000960 100644
--- a/config/locales/stop_areas.fr.yml
+++ b/config/locales/stop_areas.fr.yml
@@ -5,6 +5,7 @@ fr:
errors:
empty: Aucun stop_area_id
parent_area_type: ne peut être de type %{area_type}
+ incorrect_kind_area_type: Ce type d'arrêt est invalide pour cette catégorie
default_geometry_success: "%{count} arrêts édités"
stop_area:
no_position: "Pas de position"
@@ -97,6 +98,7 @@ fr:
attributes:
stop_area:
name: "Nom"
+ kind: "Catégorie"
registration_number: "Numéro d'enregistrement"
published_name: "Nom public"
deleted: "Supprimé"
diff --git a/config/webpack/environment.js b/config/webpack/environment.js
index e7c879fb9..688bcbe8e 100644
--- a/config/webpack/environment.js
+++ b/config/webpack/environment.js
@@ -1,4 +1,5 @@
const { environment } = require('@rails/webpacker')
+const coffee = require('./loaders/coffee')
const CleanWebpackPlugin = require('clean-webpack-plugin')
let pathsToClean = [
@@ -24,4 +25,5 @@ environment.plugins.set(
// jquery: "jquery/src/jquery",
// }
+environment.loaders.append('coffee', coffee)
module.exports = environment
diff --git a/config/webpack/loaders/coffee.js b/config/webpack/loaders/coffee.js
new file mode 100644
index 000000000..4666716dc
--- /dev/null
+++ b/config/webpack/loaders/coffee.js
@@ -0,0 +1,6 @@
+module.exports = {
+ test: /\.coffee(\.erb)?$/,
+ use: [{
+ loader: 'coffee-loader'
+ }]
+}
diff --git a/db/migrate/20180126134944_add_kind_to_stop_areas.rb b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
new file mode 100644
index 000000000..08f54a6c5
--- /dev/null
+++ b/db/migrate/20180126134944_add_kind_to_stop_areas.rb
@@ -0,0 +1,6 @@
+class AddKindToStopAreas < ActiveRecord::Migration
+ def change
+ add_column :stop_areas, :kind, :string
+ Chouette::StopArea.where.not(kind: :non_commercial).update_all kind: :commercial
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 2c5520110..b2063539b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,13 +11,14 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20180111200406) do
+ActiveRecord::Schema.define(version: 20180126134944) 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
@@ -90,6 +91,8 @@ ActiveRecord::Schema.define(version: 20180111200406) do
t.integer "organisation_id", limit: 8
t.datetime "created_at"
t.datetime "updated_at"
+ t.integer "int_day_types"
+ t.date "excluded_dates", array: true
end
add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree
@@ -115,6 +118,7 @@ ActiveRecord::Schema.define(version: 20180111200406) 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
@@ -786,6 +790,7 @@ ActiveRecord::Schema.define(version: 20180111200406) do
t.datetime "updated_at"
t.string "stif_type"
t.integer "waiting_time"
+ t.string "kind"
end
add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree
diff --git a/package.json b/package.json
index 80ca22f83..802a2eef7 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
"babel-preset-react": "6.24.1",
"babelify": "8.0.0",
"bootstrap": "3",
- "coffeescript": "2.1.0",
+ "coffee-loader": "^0.9.0",
+ "coffeescript": "1.12.7",
"jquery": "3.2.1",
"lodash": "4.17.4",
"promise-polyfill": "7.0.0",
diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js
index 9515b57f2..d486c9af8 100644
--- a/spec/javascript/vehicle_journeys/actions_spec.js
+++ b/spec/javascript/vehicle_journeys/actions_spec.js
@@ -37,6 +37,47 @@ describe('when clicking on add button', () => {
expect(actions.openCreateModal()).toEqual(expectedAction)
})
})
+describe('when validating the form', () => {
+ it('should check that non-commercial stops have passing time', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(false)
+
+ state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "non_commercial",
+ departure_time: {
+ hour: "00",
+ minute: "01"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+
+ it('should not check that commercial stops', () => {
+ let state = [{
+ vehicle_journey_at_stops: [{
+ area_kind: "commercial",
+ departure_time: {
+ hour: "00",
+ minute: "00"
+ }
+ }]
+ }]
+
+ expect(actions.validate(dispatch, state)).toEqual(true)
+ })
+})
describe('when using select2 to pick a journey pattern', () => {
it('should create an action to select a journey pattern inside modal', () => {
let selectedJP = {
diff --git a/spec/models/chouette/area_type_spec.rb b/spec/models/chouette/area_type_spec.rb
index 67d218df8..28325dd0a 100644
--- a/spec/models/chouette/area_type_spec.rb
+++ b/spec/models/chouette/area_type_spec.rb
@@ -4,7 +4,9 @@ RSpec.describe Chouette::AreaType do
describe "::ALL" do
it "includes all supported types" do
- expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda gdl) )
+ expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda gdl deposit border service_area relief other) )
+ expect(Chouette::AreaType::COMMERCIAL).to match_array( %i(zdep zder zdlp zdlr lda gdl) )
+ expect(Chouette::AreaType::NON_COMMERCIAL).to match_array( %i( deposit border service_area relief other) )
end
end
diff --git a/spec/models/chouette/stop_area_spec.rb b/spec/models/chouette/stop_area_spec.rb
index a90e5d816..32ee5a3a6 100644
--- a/spec/models/chouette/stop_area_spec.rb
+++ b/spec/models/chouette/stop_area_spec.rb
@@ -10,10 +10,20 @@ describe Chouette::StopArea, :type => :model do
it { should belong_to(:stop_area_referential) }
it { should validate_presence_of :name }
+ it { should validate_presence_of :kind }
it { should validate_numericality_of :latitude }
it { should validate_numericality_of :longitude }
it { is_expected.to be_versioned }
+ describe "#area_type" do
+ it "should validate the value is correct regarding to the kind" do
+ expect(build(:stop_area, kind: :commercial, area_type: :gdl)).to be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :relief)).to be_valid
+ expect(build(:stop_area, kind: :commercial, area_type: :relief)).to_not be_valid
+ expect(build(:stop_area, kind: :non_commercial, area_type: :gdl)).to_not be_valid
+ end
+ end
+
# describe ".latitude" do
# it "should accept -90 value" do
# subject = create :stop_area, :area_type => "BoardingPosition"
diff --git a/yarn.lock b/yarn.lock
index e95ee9a63..d17ae1d52 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1404,13 +1404,19 @@ code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
+coffee-loader@^0.9.0:
+ version "0.9.0"
+ resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.9.0.tgz#6deabd336062ddc6d773da4dfd16367fc7107bd6"
+ dependencies:
+ loader-utils "^1.0.2"
+
coffee-script@~1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.10.0.tgz#12938bcf9be1948fa006f92e0c4c9e81705108c0"
-coffeescript@2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-2.1.0.tgz#8cb7ce12021ab9f84d8c524f54edbd6141374606"
+coffeescript@1.12.7:
+ version "1.12.7"
+ resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
color-convert@^1.3.0, color-convert@^1.8.2, color-convert@^1.9.0:
version "1.9.0"