aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZog2018-02-05 16:02:26 +0100
committerAlban Peignier2018-02-19 21:12:18 +0100
commita82f54c2b4a4022c28ca753822d6144baf2a3644 (patch)
treed919b146ecde00969709e9ab6e27f92483ef1b97
parent06acf89e18059ddab8d5817f897652c910d0627f (diff)
downloadchouette-core-a82f54c2b4a4022c28ca753822d6144baf2a3644.tar.bz2
Refs #5853 @2h; Add a detailed calendars view on VJs editor
-rw-r--r--app/assets/stylesheets/components/_tables.sass4
-rw-r--r--app/assets/stylesheets/modules/_vj_collection.sass61
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js14
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourney.js38
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourneys.js62
-rw-r--r--app/views/vehicle_journeys/show.rabl6
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