From f6f52147fcec3b9283dc2890cfb05b0fb19bff33 Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 26 Jan 2018 12:49:23 +0100 Subject: Refs #5741 @2h; Add a map of all routes on a line#show --- app/javascript/helpers/routes_map.coffee | 157 ++++++++++++++++++++++ app/javascript/packs/referential_lines/show.js | 10 ++ app/javascript/packs/routes/show.js | 123 +---------------- app/javascript/routes/components/StopPointList.js | 4 +- 4 files changed, 174 insertions(+), 120 deletions(-) create mode 100644 app/javascript/helpers/routes_map.coffee create mode 100644 app/javascript/packs/referential_lines/show.js (limited to 'app/javascript') 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 = $("") + labelsContainer.appendTo $("##{@target}") + @vectorPtsLayer = null + @vectorEdgesLayer = null + @vectorLnsLayer = null + Object.keys(@routes).forEach (id)=> + route = @routes[id] + label = $("
  • #{route.name}") + 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/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js new file mode 100644 index 000000000..99c5072ef --- /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/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 +} -- cgit v1.2.3 From 22c38fb750843f0c74996175a6bd17a1f20a943c Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 26 Jan 2018 16:17:22 +0100 Subject: Refs #5750 @1h; Add a "kind" attribute to StopAreas This determines if the StopArea is commercial or not The useless fields are hidden in the form for the non-commercials ones --- app/javascript/helpers/master_slave.coffee | 18 ++++++++++++++++++ app/javascript/packs/stop_areas/new.js | 3 +++ 2 files changed, 21 insertions(+) create mode 100644 app/javascript/helpers/master_slave.coffee create mode 100644 app/javascript/packs/stop_areas/new.js (limited to 'app/javascript') diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee new file mode 100644 index 000000000..11f6bca7e --- /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.data().master + console.log master + 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").attr "disabled", !selected + master.change toggle + toggle() + # $slave.toggle master.val() == $slave.data().value + +export default MasterSlave 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") -- cgit v1.2.3 From 05bc96db48a0a84fd2c50e457dc767f88950a9b4 Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 29 Jan 2018 08:45:02 +0100 Subject: Refs #5750 @1h; Manage non-commercial StopAreas - Add a `kind` attribute - Hide irrelevant fields in the form --- app/javascript/helpers/master_slave.coffee | 8 ++++---- app/javascript/helpers/stop_area_header_manager.js | 4 +++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee index 11f6bca7e..4866a55e3 100644 --- a/app/javascript/helpers/master_slave.coffee +++ b/app/javascript/helpers/master_slave.coffee @@ -3,16 +3,16 @@ class MasterSlave $(selector).find('[data-master]').each (i, slave)-> $slave = $(slave) master = $($slave.data().master) - console.log $slave.data().master - console.log 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").attr "disabled", !selected + $slave.find("input, select").filter(":not([data-slave-force-disabled])").attr "disabled", !selected master.change toggle toggle() - # $slave.toggle master.val() == $slave.data().value export default MasterSlave 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 {
    @@ -27,6 +27,8 @@ export default class StopAreaHeaderManager { {sp.time_zone_formatted_offset &&  ({sp.time_zone_formatted_offset}) } + {sp.area_kind == 'non_commercial' && + }
    -- cgit v1.2.3 From ddd83906ce4fab3d6dce0c404ec39c3b500ba96f Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 29 Jan 2018 10:32:05 +0100 Subject: Refs #5750; Add a validation on VehicleJourneys Ensure a time is set for all non-commercial stops --- app/javascript/vehicle_journeys/actions/index.js | 26 ++++++++++++++++++++++ .../components/SaveVehicleJourneys.js | 2 +- .../vehicle_journeys/components/VehicleJourney.js | 3 +++ .../vehicle_journeys/components/VehicleJourneys.js | 2 +- .../containers/SaveVehicleJourneys.js | 3 +++ .../vehicle_journeys/reducers/vehicleJourneys.js | 2 ++ 6 files changed, 36 insertions(+), 2 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js index 2675328e3..b01158212 100644 --- a/app/javascript/vehicle_journeys/actions/index.js +++ b/app/javascript/vehicle_journeys/actions/index.js @@ -380,6 +380,32 @@ const actions = { } }) }, + + validate : (dispatch, vehicleJourneys, next) => { + let valid = true + let vj, vjas + for (vj of vehicleJourneys){ + vj.errors = false + for(vjas of vj.vehicle_journey_at_stops){ + vjas.errors = null + if (vjas.area_kind == "non_commercial" && parseInt(vjas.departure_time.hour) == 0 && parseInt(vjas.departure_time.minute) == 0){ + vjas.errors = "Champ requis" + vj.errors = true + valid = false + } + } + } + dispatch(actions.didValidateVehicleJourneys(vehicleJourneys)) + if(valid){ + 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 { /> + {vj.errors &&
    + {vj.errors} +
    } )} 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 { )} - { _.some(this.props.vehicleJourneys, 'errors') && ( + { this.props.vehicleJourneys.errors && this.props.vehicleJourneys.errors.length && _.some(this.props.vehicleJourneys, 'errors') && (
    Erreur : {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 } -- cgit v1.2.3 From bb62bc2028f142e953035680b2483ee6029711ae Mon Sep 17 00:00:00 2001 From: Zog Date: Wed, 31 Jan 2018 11:14:23 +0100 Subject: Disable immature feature --- app/javascript/packs/referential_lines/show.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript') diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js index 99c5072ef..542188018 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() -- cgit v1.2.3 From c463c3a950246c4c2660ce7df1c1ea8f2acbe578 Mon Sep 17 00:00:00 2001 From: Zog Date: Wed, 31 Jan 2018 11:17:02 +0100 Subject: Refs #5750; Remove useless validation --- app/javascript/vehicle_journeys/actions/index.js | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'app/javascript') diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js index b01158212..4a4ec371d 100644 --- a/app/javascript/vehicle_journeys/actions/index.js +++ b/app/javascript/vehicle_journeys/actions/index.js @@ -382,23 +382,8 @@ const actions = { }, validate : (dispatch, vehicleJourneys, next) => { - let valid = true - let vj, vjas - for (vj of vehicleJourneys){ - vj.errors = false - for(vjas of vj.vehicle_journey_at_stops){ - vjas.errors = null - if (vjas.area_kind == "non_commercial" && parseInt(vjas.departure_time.hour) == 0 && parseInt(vjas.departure_time.minute) == 0){ - vjas.errors = "Champ requis" - vj.errors = true - valid = false - } - } - } dispatch(actions.didValidateVehicleJourneys(vehicleJourneys)) - if(valid){ - actions.submitVehicleJourneys(dispatch, vehicleJourneys, next) - } + actions.submitVehicleJourneys(dispatch, vehicleJourneys, next) }, didValidateVehicleJourneys : (vehicleJourneys) => ({ -- cgit v1.2.3