diff options
| author | Zog | 2018-02-05 16:02:26 +0100 |
|---|---|---|
| committer | Alban Peignier | 2018-02-19 21:12:18 +0100 |
| commit | a82f54c2b4a4022c28ca753822d6144baf2a3644 (patch) | |
| tree | d919b146ecde00969709e9ab6e27f92483ef1b97 | |
| parent | 06acf89e18059ddab8d5817f897652c910d0627f (diff) | |
| download | chouette-core-a82f54c2b4a4022c28ca753822d6144baf2a3644.tar.bz2 | |
Refs #5853 @2h; Add a detailed calendars view on VJs editor
6 files changed, 162 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..7c3aea5ba 100644 --- a/app/assets/stylesheets/modules/_vj_collection.sass +++ b/app/assets/stylesheets/modules/_vj_collection.sass @@ -86,6 +86,19 @@ &: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 + &.active .fa + transform: rotate(90deg) + .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 +116,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..58a9d5fec 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-caret-right'></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 |
