diff options
Diffstat (limited to 'app/javascript/helpers')
| -rw-r--r-- | app/javascript/helpers/master_slave.coffee | 16 | ||||
| -rw-r--r-- | app/javascript/helpers/routes_map.coffee | 161 | ||||
| -rw-r--r-- | app/javascript/helpers/save_button.js | 47 | ||||
| -rw-r--r-- | app/javascript/helpers/stop_area_header_manager.js | 56 | 
4 files changed, 280 insertions, 0 deletions
| diff --git a/app/javascript/helpers/master_slave.coffee b/app/javascript/helpers/master_slave.coffee new file mode 100644 index 000000000..81bebe36a --- /dev/null +++ b/app/javascript/helpers/master_slave.coffee @@ -0,0 +1,16 @@ +class MasterSlave +  constructor: (selector)-> +    $(selector).find('[data-master]').each (i, slave)-> +      $slave = $(slave) +      master = $($slave.data().master) +      $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..6834406fc --- /dev/null +++ b/app/javascript/helpers/routes_map.coffee @@ -0,0 +1,161 @@ +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)])) +      }) +    ] + +    prevStop = null +    stops.forEach (stop, i) => +      if stop.longitude && stop.latitude +        if prevStop +          geoColLns.push new ol.Feature +            geometry: new ol.geom.LineString([ +              ol.proj.fromLonLat([parseFloat(prevStop.longitude), parseFloat(prevStop.latitude)]), +              ol.proj.fromLonLat([parseFloat(stop.longitude), parseFloat(stop.latitude)]) +            ]) +        prevStop = stop + +        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/save_button.js b/app/javascript/helpers/save_button.js new file mode 100644 index 000000000..7e0bd5bbe --- /dev/null +++ b/app/javascript/helpers/save_button.js @@ -0,0 +1,47 @@ +import React, { PropTypes, Component } from 'react' + +export default class SaveButton extends Component{ +  constructor(props){ +    super(props) +  } + +  btnDisabled(){ +    return !this.props.status.fetchSuccess || this.props.status.isFetching +  } + +  btnClass(){ +    let className = ['btn btn-default'] +    if(this.btnDisabled()){ +      className.push('disabled') +    } +    return className.join(' ') +  } + +  render() { +    if (!this.hasPolicy()) { +      return false +    }else{ +      return ( +        <div className='row mt-md'> +          <div className='col-lg-12 text-right'> +            <form className={this.formClassName() + ' formSubmitr ml-xs'} onSubmit={e => {e.preventDefault()}}> +              <div className="btn-group sticky-actions"> +                <button +                  className={this.btnClass()} +                  type='button' +                  disabled={this.btnDisabled()} +                  onClick={e => { +                    e.preventDefault() +                    this.props.editMode ? this.submitForm() : this.props.onEnterEditMode() +                  }} +                > +                  {this.props.editMode ? "Valider" : "Editer"} +                </button> +              </div> +            </form> +          </div> +        </div> +      ) +    } +  } +} diff --git a/app/javascript/helpers/stop_area_header_manager.js b/app/javascript/helpers/stop_area_header_manager.js new file mode 100644 index 000000000..5b18e2f63 --- /dev/null +++ b/app/javascript/helpers/stop_area_header_manager.js @@ -0,0 +1,56 @@ +import React, { Component } from 'react' + +export default class StopAreaHeaderManager { +  constructor(ids_list, stopPointsList, features) { +    this.ids_list = ids_list +    this.stopPointsList = stopPointsList +    this.features = features +  } + +  hasFeature(key) { +    return this.features[key] +  } + +  stopPointHeader(object_id) { +    let index = this.ids_list.indexOf(object_id) +    let sp = this.stopPointsList[index] +    let showHeadline = this.showHeader(object_id) +    return ( +      <div +        className={(showHeadline) ? 'headlined' : ''} +        data-headline={showHeadline} +        title={sp.city_name ? sp.city_name + ' (' + sp.zip_code +')' : ""} +      > +        <span> +          <span> +            {sp.name} +            {sp.time_zone_formatted_offset && <span className="small"> +               ({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> +    ) +  } + +  showHeader(object_id) { +    let showHeadline = false +    let headline = "" +    let attribute_to_check = this.hasFeature('long_distance_routes') ? "country_code" : "city_name" +    let index = this.ids_list.indexOf(object_id) +    let sp = this.stopPointsList[index] +    let previousBreakpoint = this.stopPointsList[index - 1] +    if(sp == undefined){ +      console.log("STOP_POINT NOT FOUND: " + object_id) +      console.log("AVAILABLE IDS:" + this.ids_list) +      return +    } +    if(index == 0 || (sp[attribute_to_check] != previousBreakpoint[attribute_to_check])){ +      showHeadline = true +      headline = this.hasFeature('long_distance_routes') ? sp.country_name : sp.city_name +    } +    return showHeadline ? headline : "" +  } +} | 
