diff options
| author | Alban Peignier | 2018-02-19 21:19:34 +0100 | 
|---|---|---|
| committer | GitHub | 2018-02-19 21:19:34 +0100 | 
| commit | 0e44fcc6b5f97436e3956ae113d8cf56c54053f4 (patch) | |
| tree | e56df23c053c82d8d499c70d2692b426ed782a6a | |
| parent | 06acf89e18059ddab8d5817f897652c910d0627f (diff) | |
| parent | 3ff86c41e136fa58cb1bc2b2f772ba5a9f23a4bb (diff) | |
| download | chouette-core-0e44fcc6b5f97436e3956ae113d8cf56c54053f4.tar.bz2 | |
Merge pull request #286 from af83/5853-detailed-calendar-view-in-vjs-index
Add a detailed calendars view on VJs editor. Refs #5853 
7 files changed, 169 insertions, 23 deletions
| diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass index 1e02ad586..ef19bd538 100644 --- a/app/assets/stylesheets/components/_tables.sass +++ b/app/assets/stylesheets/components/_tables.sass @@ -374,6 +374,8 @@      .th        text-align: right        border-top-color: transparent +      > div:not(.btn-group) +        min-height: 20px      .td > .headlined        &:before @@ -408,7 +410,7 @@        .th          > div:not(.btn-group) -          min-height: 19px +          min-height: 20px          > *:first-child            padding-right: 30px diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass index d99c67bd7..d9079daa2 100644 --- a/app/assets/stylesheets/modules/_vj_collection.sass +++ b/app/assets/stylesheets/modules/_vj_collection.sass @@ -86,6 +86,20 @@          &:after            bottom: 50% + +  .table-2entries .t2e-head +    .detailed-timetables +      .fa +        margin-right: 5px +    .detailed-timetables-bt +      text-decoration: none +      .fa +        margin-right: 5px +        color: $red +        transition: transform 0.1s +      &.active .fa +        transform: rotate(180deg) +    .table-2entries .t2e-head > .td:nth-child(2) > div,    .table-2entries .t2e-head > .td:last-child > div,    .table-2entries.no_result .t2e-head > .td:last-child > div @@ -103,6 +117,54 @@        top: 50%        margin-top: -8px +  .detailed-timetables +    padding-top: 10px +    text-align: left +    margin-bottom: -5px + +    & > div +      position: relative +      border-left: 1px solid $lightgrey +      padding-left: 10px +      a +        text-decoration: none +        border: none +      &:before +        position: absolute +        left: 0px +        top: 0 +        right: -8px +        content: "" +        border-top: 1px solid $lightgrey +      font-size: 0.8em +      height: 44px +      position: relative +      padding-bottom: 5px + +      p +        margin: 0 +      p:first-child +        padding-top: 8px +        font-weight: bold + +  .t2e-item-list .detailed-timetables > div +    border-left: none +    &:after +      top: 50% +      left: 50% +      content: "" +      border: 1px solid black +      width: 20px +      height: 20px +      margin-left: -10px +      margin-top: -10px +      position: absolute +      border-radius: 20px +    &.active:after +      background: black +    &:before +      left: -8px +    // Errors    .table-2entries .t2e-item-list      .t2e-item diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js index 4ca8bd73b..51ee666e8 100644 --- a/app/javascript/vehicle_journeys/actions/index.js +++ b/app/javascript/vehicle_journeys/actions/index.js @@ -348,21 +348,11 @@ const actions = {              var purchaseWindows = []              let tt              for (tt of val.time_tables){ -              timeTables.push({ -                objectid: tt.objectid, -                comment: tt.comment, -                id: tt.id, -                color: tt.color -              }) +              timeTables.push(tt)              }              if(val.purchase_windows){                for (tt of val.purchase_windows){ -                purchaseWindows.push({ -                  objectid: tt.objectid, -                  name: tt.name, -                  id: tt.id, -                  color: tt.color -                }) +                purchaseWindows.push(tt)                }              }              let vjasWithDelta = val.vehicle_journey_at_stops.map((vjas, i) => { diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js index 4a9432231..e11e91497 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js @@ -48,12 +48,24 @@ export default class VehicleJourney extends Component {      }    } +  hasTimeTable(time_tables, tt) { +    let found = false +    time_tables.map((t, index) => { +      if(t.id == tt.id){ +        found = true +        return +      } +    }) +    return found +  } +    isDisabled(bool1, bool2) {      return (bool1 || bool2)    }    render() {      this.previousCity = undefined +    let detailed_calendars = this.hasFeature('detailed_calendars') && !this.disabled      let {time_tables, purchase_windows} = this.props.value      return ( @@ -68,20 +80,20 @@ export default class VehicleJourney extends Component {            <div>{this.props.value.published_journey_name && this.props.value.published_journey_name != I18n.t('undefined') ? this.props.value.published_journey_name : '-'}</div>            <div>{this.props.value.journey_pattern.short_id || '-'}</div>            <div>{this.props.value.company ? this.props.value.company.name : '-'}</div> +          { this.hasFeature('purchase_windows') && +            <div> +            {purchase_windows.slice(0,3).map((tt, i)=> +              <span key={i} className='vj_tt'>{this.purchaseWindowURL(tt)}</span> +            )} +            {purchase_windows.length > 3 && <span className='vj_tt'> + {purchase_windows.length - 3}</span>} +            </div> +          }            <div>              {time_tables.slice(0,3).map((tt, i)=>                <span key={i} className='vj_tt'>{this.timeTableURL(tt)}</span>              )}              {time_tables.length > 3 && <span className='vj_tt'> + {time_tables.length - 3}</span>}            </div> -          { this.hasFeature('purchase_windows') && -            <div> -              {purchase_windows.slice(0,3).map((tt, i)=> -                <span key={i} className='vj_tt'>{this.purchaseWindowURL(tt)}</span> -              )} -              {purchase_windows.length > 3 && <span className='vj_tt'> + {purchase_windows.length - 3}</span>} -            </div> -          }            {!this.props.disabled && <div className={(this.props.value.deletable ? 'disabled ' : '') + 'checkbox'}>              <input                id={this.props.index} @@ -94,7 +106,16 @@ export default class VehicleJourney extends Component {              ></input>              <label htmlFor={this.props.index}></label>            </div>} +            {this.props.disabled && <VehicleJourneyInfoButton vehicleJourney={this.props.value} />} + +          { detailed_calendars && +            <div className="detailed-timetables hidden"> +            {this.props.allTimeTables.map((tt, i) => +              <div key={i} className={(this.hasTimeTable(time_tables, tt) ? "active" : "inactive")}></div> +            )} +            </div> +          }          </div>          {this.props.value.vehicle_journey_at_stops.map((vj, i) =>            <div key={i} className='td text-center'> @@ -174,4 +195,5 @@ VehicleJourney.propTypes = {    onUpdateTime: PropTypes.func.isRequired,    onSelectVehicleJourney: PropTypes.func.isRequired,    vehicleJourneys: PropTypes.object.isRequired, +  allTimeTables: PropTypes.array.isRequired,  } diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js index 01e07ee0c..843aec1a8 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js @@ -12,6 +12,7 @@ export default class VehicleJourneys extends Component {        this.stopPoints(),        this.props.filters.features      ) +    this.toggleTimetables = this.toggleTimetables.bind(this)    }    isReturn() { @@ -48,9 +49,35 @@ export default class VehicleJourneys extends Component {      return this.headerManager.showHeader(object_id)    } +  allTimeTables() { +    if(this._allTimeTables){ +      return this._allTimeTables +    } +    let keys = [] +    this._allTimeTables = [] +    this.vehicleJourneysList().map((vj, index) => { +      vj.time_tables.map((tt, _) => { +        if(keys.indexOf(tt.id) < 0){ +            keys.push(tt.id) +            this._allTimeTables.push(tt) +        } +      }) +    }) +    return this._allTimeTables +  } + +  toggleTimetables(e) { +    $('.table-2entries .detailed-timetables').toggleClass('hidden') +    $('.table-2entries .detailed-timetables-bt').toggleClass('active') +    this.componentDidUpdate() +    e.preventDefault() +    false +  } +    componentDidUpdate(prevProps, prevState) {      if(this.props.status.isFetching == false){        $('.table-2entries').each(function() { +        $(this).find('.th').css('height', 'auto')          var refH = []          var refCol = [] @@ -91,9 +118,19 @@ export default class VehicleJourneys extends Component {      }    } +  timeTableURL(tt) { +    let refURL = window.location.pathname.split('/', 3).join('/') +    let ttURL = refURL + '/time_tables/' + tt.id + +    return ( +      <a href={ttURL} title='Voir le calendrier'><span className='fa fa-calendar' style={{color: (tt.color ? tt.color : '#4B4B4B')}}></span>{tt.days || tt.comment}</a> +    ) +  } +    render() {      this.previousBreakpoint = undefined - +    this._allTimeTables = null +    let detailed_calendars = this.hasFeature('detailed_calendars') && !this.isReturn() && (this.allTimeTables().length > 0)      if(this.props.status.isFetching == true) {        return (          <div className="isLoading" style={{marginTop: 80, marginBottom: 80}}> @@ -133,8 +170,28 @@ export default class VehicleJourneys extends Component {                    <div>{I18n.attribute_name("vehicle_journey", "name")}</div>                    <div>{I18n.attribute_name("vehicle_journey", "journey_pattern_id")}</div>                    <div>{I18n.model_name("company")}</div> -                  <div>{I18n.model_name("time_table", "plural": true)}</div>                    { this.hasFeature('purchase_windows') && <div>{I18n.model_name("purchase_window", "plural": true)}</div> } +                  <div> +                    { detailed_calendars && +                      <a href='#' onClick={this.toggleTimetables} className='detailed-timetables-bt'> +                        <span className='fa fa-angle-up'></span> +                        {I18n.model_name("time_table", "plural": true)} +                      </a> +                    } +                    { !detailed_calendars && I18n.model_name("time_table", "plural": true)} +                  </div> +                  { !this.isReturn() && +                    <div className="detailed-timetables hidden"> +                      {this.allTimeTables().map((tt, i)=> +                        <div key={i}> +                          <p> +                            {this.timeTableURL(tt)} +                          </p> +                          <p>{tt.bounding_dates}</p> +                        </div> +                      )} +                    </div> +                  }                  </div>                  {this.stopPoints().map((sp, i) =>{                    return ( @@ -159,6 +216,7 @@ export default class VehicleJourneys extends Component {                        onSelectVehicleJourney={this.props.onSelectVehicleJourney}                        vehicleJourneys={this}                        disabled={this.isReturn()} +                      allTimeTables={this.allTimeTables()}                        />                    )}                  </div> diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl index 546c851a4..bb26ce797 100644 --- a/app/views/vehicle_journeys/show.rabl +++ b/app/views/vehicle_journeys/show.rabl @@ -23,6 +23,12 @@ end  child(:time_tables, :object_root => false) do |time_tables|    attributes :id, :objectid, :comment, :color +  node(:days) do |tt| +    tt.display_day_types +  end +  node(:bounding_dates) do |tt| +    tt.presenter.time_table_bounding +  end    child(:calendar) do      attributes :id, :name, :date_ranges, :dates, :shared    end diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap index cdd34cbbd..818845ec8 100644 --- a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap +++ b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap @@ -33,6 +33,9 @@ exports[`stopPointHeader should display the city name 1`] = `            <div>              calendrier            </div> +          <div +            className="detailed-timetables hidden" +          />          </div>          <div            className="td" @@ -123,6 +126,9 @@ exports[`stopPointHeader with the "long_distance_routes" feature should display            <div>              calendrier            </div> +          <div +            className="detailed-timetables hidden" +          />          </div>          <div            className="td" | 
