aboutsummaryrefslogtreecommitdiffstats
path: root/app/javascript
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript')
-rw-r--r--app/javascript/helpers/CustomFieldsInputs.js (renamed from app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js)26
-rw-r--r--app/javascript/helpers/polyfills.js4
-rw-r--r--app/javascript/helpers/routes_map.coffee130
-rw-r--r--app/javascript/helpers/save_button.js2
-rw-r--r--app/javascript/journey_patterns/actions/index.js66
-rw-r--r--app/javascript/journey_patterns/components/ConfirmModal.js8
-rw-r--r--app/javascript/journey_patterns/components/CreateModal.js24
-rw-r--r--app/javascript/journey_patterns/components/EditModal.js50
-rw-r--r--app/javascript/journey_patterns/components/JourneyPattern.js49
-rw-r--r--app/javascript/journey_patterns/components/JourneyPatterns.js21
-rw-r--r--app/javascript/journey_patterns/components/Navigate.js3
-rw-r--r--app/javascript/journey_patterns/containers/AddJourneyPattern.js3
-rw-r--r--app/javascript/journey_patterns/containers/JourneyPatternList.js3
-rw-r--r--app/javascript/journey_patterns/containers/Modal.js3
-rw-r--r--app/javascript/journey_patterns/reducers/index.js3
-rw-r--r--app/javascript/journey_patterns/reducers/journeyPatterns.js16
-rw-r--r--app/javascript/packs/calendars/edit.js2
-rw-r--r--app/javascript/packs/exports/new.js5
-rw-r--r--app/javascript/packs/journey_patterns/index.js5
-rw-r--r--app/javascript/packs/referential_lines/show.js4
-rw-r--r--app/javascript/packs/referential_overview/overview.js2
-rw-r--r--app/javascript/packs/routes/edit.js32
-rw-r--r--app/javascript/packs/routes/show.js2
-rw-r--r--app/javascript/packs/stop_areas/new.js2
-rw-r--r--app/javascript/packs/time_tables/edit.js2
-rw-r--r--app/javascript/packs/vehicle_journeys/index.js4
-rw-r--r--app/javascript/routes/components/App.js9
-rw-r--r--app/javascript/routes/components/BSelect2.js13
-rw-r--r--app/javascript/routes/components/OlMap.js30
-rw-r--r--app/javascript/routes/components/StopPoint.js12
-rw-r--r--app/javascript/routes/components/StopPointList.js2
-rw-r--r--app/javascript/routes/containers/AddStopPoint.js2
-rw-r--r--app/javascript/routes/index.js6
-rw-r--r--app/javascript/routes/reducers/stopPoints.js6
-rw-r--r--app/javascript/time_tables/actions/index.js17
-rw-r--r--app/javascript/time_tables/components/ConfirmModal.js8
-rw-r--r--app/javascript/time_tables/components/ErrorModal.js8
-rw-r--r--app/javascript/time_tables/components/Metas.js9
-rw-r--r--app/javascript/time_tables/components/PeriodForm.js8
-rw-r--r--app/javascript/time_tables/components/PeriodManager.js8
-rw-r--r--app/javascript/time_tables/components/SaveTimetable.js2
-rw-r--r--app/javascript/time_tables/components/TagsSelect2.js8
-rw-r--r--app/javascript/time_tables/components/Timetable.js14
-rw-r--r--app/javascript/time_tables/containers/App.js1
-rw-r--r--app/javascript/time_tables/containers/Metas.js1
-rw-r--r--app/javascript/time_tables/reducers/metas.js6
-rw-r--r--app/javascript/vehicle_journeys/actions/index.js56
-rw-r--r--app/javascript/vehicle_journeys/components/ConfirmModal.js4
-rw-r--r--app/javascript/vehicle_journeys/components/Filters.js5
-rw-r--r--app/javascript/vehicle_journeys/components/Navigate.js3
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourney.js67
-rw-r--r--app/javascript/vehicle_journeys/components/VehicleJourneys.js115
-rw-r--r--app/javascript/vehicle_journeys/components/tools/CreateModal.js26
-rw-r--r--app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js2
-rw-r--r--app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js12
-rw-r--r--app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js8
-rw-r--r--app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js18
-rw-r--r--app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js9
-rw-r--r--app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js12
-rw-r--r--app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js9
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js5
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js4
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js4
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js4
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/fr.js9
-rw-r--r--app/javascript/vehicle_journeys/components/tools/select2s/language.js9
-rw-r--r--app/javascript/vehicle_journeys/containers/VehicleJourneysList.js8
-rw-r--r--app/javascript/vehicle_journeys/reducers/modal.js4
-rw-r--r--app/javascript/vehicle_journeys/reducers/vehicleJourneys.js24
69 files changed, 704 insertions, 354 deletions
diff --git a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js b/app/javascript/helpers/CustomFieldsInputs.js
index 90d72a801..abc8097d5 100644
--- a/app/javascript/vehicle_journeys/components/tools/CustomFieldsInputs.js
+++ b/app/javascript/helpers/CustomFieldsInputs.js
@@ -27,6 +27,32 @@ export default class CustomFieldsInputs extends Component {
)
}
+ stringInput(cf){
+ return(
+ <input
+ type='text'
+ ref={'custom_fields.' + cf.code}
+ className='form-control'
+ disabled={this.props.disabled}
+ value={cf.value}
+ onChange={(e) => {this.props.onUpdate(cf.code, e.target.value); this.forceUpdate()} }
+ />
+ )
+ }
+
+ integerInput(cf){
+ return(
+ <input
+ type='number'
+ ref={'custom_fields.' + cf.code}
+ className='form-control'
+ disabled={this.props.disabled}
+ value={cf.value}
+ onChange={(e) => {this.props.onUpdate(cf.code, e.target.value); this.forceUpdate()} }
+ />
+ )
+ }
+
render() {
return (
<div>
diff --git a/app/javascript/helpers/polyfills.js b/app/javascript/helpers/polyfills.js
new file mode 100644
index 000000000..93e3e9846
--- /dev/null
+++ b/app/javascript/helpers/polyfills.js
@@ -0,0 +1,4 @@
+import 'promise-polyfill/src/polyfill'
+import 'es6-symbol/implement'
+import 'polyfill-array-includes'
+import 'whatwg-fetch'
diff --git a/app/javascript/helpers/routes_map.coffee b/app/javascript/helpers/routes_map.coffee
index 6834406fc..de6196372 100644
--- a/app/javascript/helpers/routes_map.coffee
+++ b/app/javascript/helpers/routes_map.coffee
@@ -1,3 +1,65 @@
+RoutesLayersButton = (options) ->
+ menu = options.menu
+
+ toggleMenu = (e)=>
+ $(menu.element).toggleClass 'hidden'
+ button.innerHTML = if button.innerHTML == "+" then "-" else "+"
+
+ button = document.createElement("button")
+ button.innerHTML = "+"
+ button.addEventListener('click', toggleMenu, false)
+ button.addEventListener('touchstart', toggleMenu, false)
+ button.className = "ol-routes-layers-button"
+
+ element = document.createElement('div');
+ element.className = 'ol-control ol-routes-layers-button-wrapper';
+
+ element.appendChild(button)
+
+ ol.control.Control.call(this, {
+ element
+ target: options.target
+ })
+
+ol.inherits RoutesLayersButton, ol.control.Control
+
+RoutesLayersControl = (routes, routes_map) ->
+
+ element = document.createElement('div')
+ element.className = 'ol-unselectable ol-routes-layers hidden'
+ Object.keys(routes).forEach (id)=>
+ route = routes[id]
+ route.active = false
+ label = document.createElement('a')
+ label.title = route.name
+ label.className = ''
+ label.innerHTML = route.name
+ element.appendChild label
+ label.addEventListener "click", =>
+ route.active = !route.active
+ $(label).toggleClass "active"
+ route.active
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active)
+ routes_map.fitZoom()
+ label.addEventListener "mouseenter", =>
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(true)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(true)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(true)
+
+ label.addEventListener "mouseleave", =>
+ route.vectorPtsLayer.setStyle routes_map.defaultStyles(route.active)
+ route.vectorEdgesLayer.setStyle routes_map.edgeStyles(route.active)
+ route.vectorLnsLayer.setStyle routes_map.lineStyle(route.active)
+
+
+ ol.control.Control.call(this, {
+ element
+ })
+
+ol.inherits RoutesLayersControl, ol.control.Control
+
class RoutesMap
constructor: (@target)->
@initMap()
@@ -20,6 +82,7 @@ class RoutesMap
addRoute: (route)->
geoColPts = []
geoColLns = []
+ route.active = true
@routes[route.id] = route if route.id
stops = route.stops || route
geoColEdges = [
@@ -77,68 +140,49 @@ class RoutesMap
@map.addLayer vectorEdgesLayer
@map.addLayer vectorLnsLayer
- lineStyle: (highlighted=false)->
+ lineStyle: (active=false)->
new ol.style.Style
stroke: new ol.style.Stroke
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 3
+ color: '#007fbb'
+ width: if active then 3 else 0
- edgeStyles: (highlighted=false)->
+ edgeStyles: (active=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
+ color: '#007fbb'
+ width: if active then 3 else 0
fill: new ol.style.Fill
- color: if highlighted then "#ed7f00" else '#007fbb'
- width: 2
+ color: '#007fbb'
+ width: if active then 3 else 0
- defaultStyles: (highlighted=false)->
+ defaultStyles: (active=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
+ color: '#007fbb'
+ width: if active then 3 else 0
fill: new ol.style.Fill
color: '#ffffff'
- width: 2
+ width: if active then 3 else 0
addRoutesLabels: ->
- labelsContainer = $("<ul class='routes-labels'></ul>")
- labelsContainer.appendTo $("##{@target}")
- @vectorPtsLayer = null
- @vectorEdgesLayer = null
- @vectorLnsLayer = null
+ menu = new RoutesLayersControl(@routes, this)
+ @map.addControl menu
+ @map.addControl new RoutesLayersButton(menu: menu)
+
+ fitZoom: ()->
+ area = []
+ found = false
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
+ if route.active
+ found = true
+ route.stops.forEach (stop, i) =>
+ area.push [parseFloat(stop.longitude), parseFloat(stop.latitude)]
+ area = @area unless found
boundaries = ol.extent.applyTransform(
ol.extent.boundingExtent(area), ol.proj.getTransform('EPSG:4326', 'EPSG:3857')
)
diff --git a/app/javascript/helpers/save_button.js b/app/javascript/helpers/save_button.js
index 7e0bd5bbe..af5ee54a8 100644
--- a/app/javascript/helpers/save_button.js
+++ b/app/javascript/helpers/save_button.js
@@ -35,7 +35,7 @@ export default class SaveButton extends Component{
this.props.editMode ? this.submitForm() : this.props.onEnterEditMode()
}}
>
- {this.props.editMode ? "Valider" : "Editer"}
+ {this.props.editMode ? I18n.t('actions.submit') : I18n.t('actions.edit')}
</button>
</div>
</form>
diff --git a/app/javascript/journey_patterns/actions/index.js b/app/javascript/journey_patterns/actions/index.js
index a70a2e6f2..a813f4b9e 100644
--- a/app/javascript/journey_patterns/actions/index.js
+++ b/app/javascript/journey_patterns/actions/index.js
@@ -1,10 +1,3 @@
-import Promise from 'promise-polyfill'
-
-// To add to window
-if (!window.Promise) {
- window.Promise = Promise;
-}
-
const actions = {
enterEditMode: () => ({
type: "ENTER_EDIT_MODE"
@@ -20,6 +13,12 @@ const actions = {
type: "RECEIVE_ERRORS",
json
}),
+ receiveRouteCosts: (costs, key, index) => ({
+ type: "RECEIVE_ROUTE_COSTS",
+ costs,
+ key,
+ index
+ }),
unavailableServer : () => ({
type: 'UNAVAILABLE_SERVER'
}),
@@ -37,7 +36,7 @@ const actions = {
}),
updateCheckboxValue : (e, index) => ({
type : 'UPDATE_CHECKBOX_VALUE',
- id : e.currentTarget.id,
+ position : e.currentTarget.id,
index
}),
checkConfirmModal : (event, callback, stateChanged,dispatch) => {
@@ -189,15 +188,19 @@ const actions = {
dispatch(actions.unavailableServer())
} else {
if(json.length != 0){
- let val
- for (val of json){
- for (let stop_point of val.route_short_description.stop_points){
+ let j = 0
+ while(j < json.length){
+ let val = json[j]
+ let i = 0
+ while(i < val.route_short_description.stop_points.length){
+ let stop_point = val.route_short_description.stop_points[i]
stop_point.checked = false
val.stop_area_short_descriptions.map((element) => {
if(element.stop_area_short_description.id === stop_point.id){
stop_point.checked = true
}
})
+ i ++
}
journeyPatterns.push(
_.assign({}, val, {
@@ -206,6 +209,7 @@ const actions = {
deletable: false
})
)
+ j ++
}
}
window.currentItemsLength = journeyPatterns.length
@@ -213,6 +217,46 @@ const actions = {
}
})
},
+ fetchRouteCosts: (dispatch, key, index) => {
+ if(actions.fetchingRouteCosts){
+ // A request is already sent, wait for it
+ if(!actions.waitingForRouteCosts){
+ actions.waitingForRouteCosts = []
+ }
+ actions.waitingForRouteCosts.push([key, index])
+ return
+ }
+
+ if(actions.routeCostsCache) {
+ // Dispatch asynchronously to prevent warning when
+ // this executes during `render()`
+ requestAnimationFrame(() => {
+ dispatch(actions.receiveRouteCosts(
+ actions.routeCostsCache,
+ key,
+ index
+ ))
+ })
+ } else {
+ actions.fetchingRouteCosts = true
+ fetch(window.routeCostsUrl, {
+ credentials: 'same-origin',
+ }).then(response => {
+ return response.json()
+ }).then(json => {
+ let costs = json.costs ? json.costs : {}
+ actions.routeCostsCache = costs
+
+ dispatch(actions.receiveRouteCosts(costs, key, index))
+ if(actions.waitingForRouteCosts){
+ actions.waitingForRouteCosts.map(function(item, i) {
+ dispatch(actions.receiveRouteCosts(costs, item[0], item[1]))
+ })
+ }
+ actions.fetchingRouteCosts = false
+ })
+ }
+ },
getChecked : (jp) => {
return jp.filter((obj) => {
return obj.checked
diff --git a/app/javascript/journey_patterns/components/ConfirmModal.js b/app/javascript/journey_patterns/components/ConfirmModal.js
index ccd0a9384..fdf32649f 100644
--- a/app/javascript/journey_patterns/components/ConfirmModal.js
+++ b/app/javascript/journey_patterns/components/ConfirmModal.js
@@ -9,11 +9,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Confirmation</h4>
+ <h4 className='modal-title'>{I18n.t('journey_patterns.show.confirmation')}</h4>
</div>
<div className='modal-body'>
<div className='mt-md mb-md'>
- <p>Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?</p>
+ <p>{I18n.t('journey_patterns.show.confirm_page_change')}</p>
</div>
</div>
<div className='modal-footer'>
@@ -23,7 +23,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalCancel(modal.confirmModal.callback) }}
>
- Ne pas valider
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
@@ -31,7 +31,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalAccept(modal.confirmModal.callback, journeyPatterns) }}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</div>
diff --git a/app/javascript/journey_patterns/components/CreateModal.js b/app/javascript/journey_patterns/components/CreateModal.js
index a6c1b608a..51f6f6c1b 100644
--- a/app/javascript/journey_patterns/components/CreateModal.js
+++ b/app/javascript/journey_patterns/components/CreateModal.js
@@ -1,15 +1,17 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../actions'
+import CustomFieldsInputs from '../../helpers/CustomFieldsInputs'
export default class CreateModal extends Component {
constructor(props) {
super(props)
+ this.custom_fields = _.assign({}, this.props.custom_fields)
}
handleSubmit() {
if(actions.validateFields(this.refs) == true) {
- this.props.onAddJourneyPattern(this.refs)
+ this.props.onAddJourneyPattern(_.assign({}, this.refs, {custom_fields: this.custom_fields}))
this.props.onModalClose()
$('#NewJourneyPatternModal').modal('hide')
}
@@ -38,14 +40,14 @@ export default class CreateModal extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Ajouter une mission</h4>
+ <h4 className='modal-title'>{I18n.t('journey_patterns.actions.new')}</h4>
</div>
{(this.props.modal.type == 'create') && (
<form>
<div className='modal-body'>
<div className='form-group'>
- <label className='control-label is-required'>Nom</label>
+ <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>
<input
type='text'
ref='name'
@@ -57,7 +59,7 @@ export default class CreateModal extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
<div className='form-group'>
- <label className='control-label is-required'>Nom public</label>
+ <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}</label>
<input
type='text'
ref='published_name'
@@ -69,7 +71,7 @@ export default class CreateModal extends Component {
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
<div className='form-group'>
- <label className='control-label'>Code mission</label>
+ <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>
<input
type='text'
ref='registration_number'
@@ -78,8 +80,14 @@ export default class CreateModal extends Component {
/>
</div>
</div>
+ <CustomFieldsInputs
+ values={this.props.custom_fields}
+ onUpdate={(code, value) => this.custom_fields[code]["value"] = value}
+ disabled={false}
+ />
</div>
</div>
+
<div className='modal-footer'>
<button
className='btn btn-link'
@@ -87,14 +95,14 @@ export default class CreateModal extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</form>
@@ -120,4 +128,4 @@ CreateModal.propTypes = {
onOpenCreateModal: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired,
onAddJourneyPattern: PropTypes.func.isRequired
-} \ No newline at end of file
+}
diff --git a/app/javascript/journey_patterns/components/EditModal.js b/app/javascript/journey_patterns/components/EditModal.js
index c960cb41c..a23a57f96 100644
--- a/app/javascript/journey_patterns/components/EditModal.js
+++ b/app/javascript/journey_patterns/components/EditModal.js
@@ -1,33 +1,44 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../actions'
+import CustomFieldsInputs from '../../helpers/CustomFieldsInputs'
export default class EditModal extends Component {
constructor(props) {
super(props)
+ this.updateValue = this.updateValue.bind(this)
}
handleSubmit() {
if(actions.validateFields(this.refs) == true) {
- this.props.saveModal(this.props.modal.modalProps.index, this.refs)
+ this.props.saveModal(this.props.modal.modalProps.index, _.assign({}, this.refs, {custom_fields: this.custom_fields}))
$('#JourneyPatternModal').modal('hide')
}
}
+ updateValue(attribute, e) {
+ actions.resetValidation(e.currentTarget)
+ this.props.modal.modalProps.journeyPattern[attribute] = e.target.value
+ this.forceUpdate()
+ }
+
renderModalTitle() {
if (this.props.editMode) {
return (
<h4 className='modal-title'>
- Editer la mission
+ {I18n.t('journey_patterns.actions.edit')}
{this.props.modal.type == 'edit' && <em> "{this.props.modal.modalProps.journeyPattern.name}"</em>}
</h4>
)
} else {
- return <h4 className='modal-title'> Informations </h4>
+ return <h4 className='modal-title'> {I18n.t('journey_patterns.show.informations')} </h4>
}
}
render() {
+ if(this.props.modal.modalProps.journeyPattern){
+ this.custom_fields = _.assign({}, this.props.modal.modalProps.journeyPattern.custom_fields)
+ }
return (
<div className={ 'modal fade ' + ((this.props.modal.type == 'edit') ? 'in' : '') } id='JourneyPatternModal'>
<div className='modal-container'>
@@ -41,15 +52,15 @@ export default class EditModal extends Component {
<form>
<div className='modal-body'>
<div className='form-group'>
- <label className='control-label is-required'>Nom</label>
+ <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'name')}</label>
<input
type='text'
ref='name'
className='form-control'
disabled={!this.props.editMode}
id={this.props.modal.modalProps.index}
- defaultValue={this.props.modal.modalProps.journeyPattern.name}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ value={this.props.modal.modalProps.journeyPattern.name}
+ onChange={(e) => this.updateValue('name', e)}
required
/>
</div>
@@ -57,42 +68,49 @@ export default class EditModal extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
<div className='form-group'>
- <label className='control-label is-required'>Nom public</label>
+ <label className='control-label is-required'>{I18n.attribute_name('journey_pattern', 'published_name')}</label>
<input
type='text'
ref='published_name'
className='form-control'
disabled={!this.props.editMode}
id={this.props.modal.modalProps.index}
- defaultValue={this.props.modal.modalProps.journeyPattern.published_name}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ value={this.props.modal.modalProps.journeyPattern.published_name}
+ onChange={(e) => this.updateValue('published_name', e)}
required
/>
</div>
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
<div className='form-group'>
- <label className='control-label'>Code mission</label>
+ <label className='control-label'>{I18n.attribute_name('journey_pattern', 'registration_number')}</label>
<input
type='text'
ref='registration_number'
className='form-control'
disabled={!this.props.editMode}
id={this.props.modal.modalProps.index}
- defaultValue={this.props.modal.modalProps.journeyPattern.registration_number}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ value={this.props.modal.modalProps.journeyPattern.registration_number}
+ onChange={(e) => this.updateValue('registration_number', e)}
/>
</div>
</div>
</div>
+ <div className='row'>
+ <CustomFieldsInputs
+ values={this.props.modal.modalProps.journeyPattern.custom_fields}
+ onUpdate={(code, value) => this.custom_fields[code]["value"] = value}
+ disabled={!this.props.editMode}
+ />
+ </div>
<div>
- <label className='control-label'>Signature métier</label>
+ <label className='control-label'>{I18n.attribute_name('journey_pattern', 'checksum')}</label>
<input
type='text'
ref='checksum'
className='form-control'
disabled='disabled'
- defaultValue={this.props.modal.modalProps.journeyPattern.checksum}
+ value={this.props.modal.modalProps.journeyPattern.checksum}
/>
</div>
</div>
@@ -105,14 +123,14 @@ export default class EditModal extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
}
diff --git a/app/javascript/journey_patterns/components/JourneyPattern.js b/app/javascript/journey_patterns/components/JourneyPattern.js
index 35765b99a..4eba80030 100644
--- a/app/javascript/journey_patterns/components/JourneyPattern.js
+++ b/app/javascript/journey_patterns/components/JourneyPattern.js
@@ -23,7 +23,7 @@ export default class JourneyPattern extends Component{
let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid
return (
- <a href={vjURL}>Horaires des courses</a>
+ <a href={vjURL}>{I18n.t('journey_patterns.journey_pattern.vehicle_journey_at_stops')}</a>
)
}
@@ -45,7 +45,7 @@ export default class JourneyPattern extends Component{
<input
onChange = {(e) => this.props.onCheckboxChange(e)}
type='checkbox'
- id={sp.id}
+ id={sp.position}
checked={sp.checked}
disabled={(this.props.value.deletable || this.props.status.policy['journey_patterns.update'] == false || this.props.editMode == false) ? 'disabled' : ''}
>
@@ -74,17 +74,21 @@ export default class JourneyPattern extends Component{
return !this.props.status.policy[`journey_patterns.${action}`]
}
- totals(){
+ totals(onlyCommercial=false){
let totalTime = 0
let totalDistance = 0
let from = null
this.props.value.stop_points.map((stopPoint, i) =>{
- if(from && stopPoint.checked){
+ let usePoint = stopPoint.checked
+ if(onlyCommercial && (i == 0 || i == this.props.value.stop_points.length - 1) && stopPoint.kind == "non_commercial"){
+ usePoint = false
+ }
+ if(from && usePoint){
let [costsKey, costs, time, distance] = this.getTimeAndDistanceBetweenStops(from, stopPoint.id)
totalTime += time
totalDistance += distance
}
- if(stopPoint.checked){
+ if(usePoint){
from = stopPoint.id
}
})
@@ -93,12 +97,24 @@ export default class JourneyPattern extends Component{
getTimeAndDistanceBetweenStops(from, to){
let costsKey = from + "-" + to
- let costs = this.props.value.costs[costsKey] || {distance: 0, time: 0}
+ let costs = this.getCosts(costsKey)
let time = costs['time'] || 0
let distance = costs['distance'] || 0
return [costsKey, costs, time, distance]
}
+ getCosts(costsKey) {
+ let cost = this.props.value.costs[costsKey]
+
+ if (cost) {
+ return cost
+ }
+
+ this.props.fetchRouteCosts(costsKey)
+
+ return { distance: 0, time: 0 }
+ }
+
formatDistance(distance){
return parseFloat(Math.round(distance * 100) / 100).toFixed(2) + " km"
}
@@ -109,25 +125,33 @@ export default class JourneyPattern extends Component{
}
else{
let hours = parseInt(time/60)
- return hours + " h " + (time - 60*hours)
+ let minutes = (time - 60*hours)
+ return hours + " h " + (minutes > 0 ? minutes : '')
}
}
render() {
this.previousSpId = undefined
- let [totalTime, totalDistance] = this.totals()
+ let [totalTime, totalDistance] = this.totals(false)
+ let [commercialTotalTime, commercialTotalDistance] = this.totals(true)
return (
<div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.object_id ? '' : ' to_record') + (this.props.value.errors ? ' has-error': '') + (this.hasFeature('costs_in_journey_patterns') ? ' with-costs' : '')}>
<div className='th'>
<div className='strong mb-xs'>{this.props.value.object_id ? this.props.value.short_id : '-'}</div>
<div>{this.props.value.registration_number}</div>
- <div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div>
+ <div>{I18n.t('journey_patterns.show.stop_points_count', {count: actions.getChecked(this.props.value.stop_points).length})}</div>
{this.hasFeature('costs_in_journey_patterns') &&
<div className="small row totals">
<span className="col-md-6"><i className="fa fa-arrows-h"></i>{totalDistance}</span>
<span className="col-md-6"><i className="fa fa-clock-o"></i>{totalTime}</span>
</div>
}
+ {this.hasFeature('costs_in_journey_patterns') &&
+ <div className="small row totals commercial">
+ <span className="col-md-6"><i className="fa fa-arrows-h"></i>{commercialTotalDistance}</span>
+ <span className="col-md-6"><i className="fa fa-clock-o"></i>{commercialTotalTime}</span>
+ </div>
+ }
<div className={this.props.value.deletable ? 'btn-group disabled' : 'btn-group'}>
<div
className={this.props.value.deletable ? 'btn dropdown-toggle disabled' : 'btn dropdown-toggle'}
@@ -143,7 +167,7 @@ export default class JourneyPattern extends Component{
data-toggle='modal'
data-target='#JourneyPatternModal'
>
- {this.props.editMode ? 'Editer' : 'Consulter'}
+ {this.props.editMode ? I18n.t('actions.edit') : I18n.t('actions.show')}
</button>
</li>
<li className={this.props.value.object_id ? '' : 'disabled'}>
@@ -159,7 +183,7 @@ export default class JourneyPattern extends Component{
this.props.onDeleteJourneyPattern(this.props.index)}
}
>
- <span className='fa fa-trash'></span>Supprimer
+ <span className='fa fa-trash'></span>{I18n.t('actions.destroy')}
</button>
</li>
</ul>
@@ -215,5 +239,6 @@ JourneyPattern.propTypes = {
onCheckboxChange: PropTypes.func.isRequired,
onOpenEditModal: PropTypes.func.isRequired,
onDeleteJourneyPattern: PropTypes.func.isRequired,
- journeyPatterns: PropTypes.object.isRequired
+ journeyPatterns: PropTypes.object.isRequired,
+ fetchRouteCosts: PropTypes.func.isRequired
}
diff --git a/app/javascript/journey_patterns/components/JourneyPatterns.js b/app/javascript/journey_patterns/components/JourneyPatterns.js
index 31727fefc..91c783189 100644
--- a/app/javascript/journey_patterns/components/JourneyPatterns.js
+++ b/app/javascript/journey_patterns/components/JourneyPatterns.js
@@ -84,14 +84,14 @@ export default class JourneyPatterns extends Component {
<div className='col-lg-12'>
{(this.props.status.fetchSuccess == false) && (
<div className="alert alert-danger mt-sm">
- <strong>Erreur : </strong>
- la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème
+ <strong>{I18n.t('error')} : </strong>
+ {I18n.t('journeys_patterns.journey_pattern.fetching_error')}
</div>
)}
{ _.some(this.props.journeyPatterns, 'errors') && (
<div className="alert alert-danger mt-sm">
- <strong>Erreur : </strong>
+ <strong> {I18n.t('error')} : </strong>
{this.props.journeyPatterns.map((jp, index) =>
jp.errors && jp.errors.map((err, i) => {
return (
@@ -107,9 +107,14 @@ export default class JourneyPatterns extends Component {
<div className={'table table-2entries mt-sm mb-sm' + ((this.props.journeyPatterns.length > 0) ? '' : ' no_result')}>
<div className='t2e-head w20'>
<div className='th'>
- <div className='strong mb-xs'>ID Mission</div>
- <div>Code mission</div>
- <div>Nb arrêts</div>
+ <div className='strong mb-xs'>{I18n.t('objectid')}</div>
+ <div>{I18n.attribute_name('journey_pattern', 'registration_number')}</div>
+ <div>{I18n.attribute_name('journey_pattern', 'stop_points')}</div>
+ { this.hasFeature('costs_in_journey_patterns') &&
+ <div>
+ <div>{I18n.attribute_name('journey_pattern', 'full_journey_time')}</div>
+ <div>{I18n.attribute_name('journey_pattern', 'commercial_journey_time')}</div>
+ </div> }
</div>
{this.props.stopPointsList.map((sp, i) =>{
return (
@@ -133,6 +138,7 @@ export default class JourneyPatterns extends Component {
status= {this.props.status}
editMode= {this.props.editMode}
journeyPatterns= {this}
+ fetchRouteCosts={(costsKey) => this.props.fetchRouteCosts(costsKey, index)}
/>
)}
</div>
@@ -151,5 +157,6 @@ JourneyPatterns.propTypes = {
status: PropTypes.object.isRequired,
onCheckboxChange: PropTypes.func.isRequired,
onLoadFirstPage: PropTypes.func.isRequired,
- onOpenEditModal: PropTypes.func.isRequired
+ onOpenEditModal: PropTypes.func.isRequired,
+ fetchRouteCosts: PropTypes.func.isRequired
}
diff --git a/app/javascript/journey_patterns/components/Navigate.js b/app/javascript/journey_patterns/components/Navigate.js
index 78f324a7d..9e454da5e 100644
--- a/app/javascript/journey_patterns/components/Navigate.js
+++ b/app/javascript/journey_patterns/components/Navigate.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
+import capitalize from 'lodash/capitalize'
import actions from '../actions'
export default function Navigate({ dispatch, journeyPatterns, pagination, status }) {
@@ -17,7 +18,7 @@ export default function Navigate({ dispatch, journeyPatterns, pagination, status
<div className='row'>
<div className='col-lg-12 text-right'>
<div className='pagination'>
- Liste des missions {firstItemOnPage} à {(lastItemOnPage < pagination.totalCount) ? lastItemOnPage : pagination.totalCount} sur {pagination.totalCount}
+ {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('journey_pattern', { plural: true })), from: firstItemOnPage, to: lastItemOnPage, count: pagination.totalCount})}
<form className='page_links' onSubmit={e => {
e.preventDefault()
}}>
diff --git a/app/javascript/journey_patterns/containers/AddJourneyPattern.js b/app/javascript/journey_patterns/containers/AddJourneyPattern.js
index b093fd111..9e85afd5e 100644
--- a/app/javascript/journey_patterns/containers/AddJourneyPattern.js
+++ b/app/javascript/journey_patterns/containers/AddJourneyPattern.js
@@ -7,7 +7,8 @@ const mapStateToProps = (state) => {
modal: state.modal,
journeyPatterns: state.journeyPatterns,
editMode: state.editMode,
- status: state.status
+ status: state.status,
+ custom_fields: state.custom_fields
}
}
diff --git a/app/javascript/journey_patterns/containers/JourneyPatternList.js b/app/javascript/journey_patterns/containers/JourneyPatternList.js
index d338345f2..539b6b54c 100644
--- a/app/javascript/journey_patterns/containers/JourneyPatternList.js
+++ b/app/javascript/journey_patterns/containers/JourneyPatternList.js
@@ -29,6 +29,9 @@ const mapDispatchToProps = (dispatch) => {
onUpdateJourneyPatternCosts: (index, costs) =>{
dispatch(actions.updateJourneyPatternCosts(index, costs))
},
+ fetchRouteCosts: (key, index) => {
+ actions.fetchRouteCosts(dispatch, key, index)
+ },
}
}
diff --git a/app/javascript/journey_patterns/containers/Modal.js b/app/javascript/journey_patterns/containers/Modal.js
index 33ee8583c..fc04843e4 100644
--- a/app/javascript/journey_patterns/containers/Modal.js
+++ b/app/javascript/journey_patterns/containers/Modal.js
@@ -7,7 +7,8 @@ const mapStateToProps = (state) => {
return {
editMode: state.editMode,
modal: state.modal,
- journeyPattern: state.journeyPattern
+ journeyPattern: state.journeyPattern,
+ custom_fields: state.custom_fields,
}
}
diff --git a/app/javascript/journey_patterns/reducers/index.js b/app/javascript/journey_patterns/reducers/index.js
index 2ffaf86d4..d3a1d29a2 100644
--- a/app/javascript/journey_patterns/reducers/index.js
+++ b/app/javascript/journey_patterns/reducers/index.js
@@ -12,7 +12,8 @@ const journeyPatternsApp = combineReducers({
journeyPatterns,
pagination,
stopPointsList,
- modal
+ modal,
+ custom_fields: (state = [], action) => state
})
export default journeyPatternsApp
diff --git a/app/javascript/journey_patterns/reducers/journeyPatterns.js b/app/javascript/journey_patterns/reducers/journeyPatterns.js
index 1ce069522..1a6a27da6 100644
--- a/app/javascript/journey_patterns/reducers/journeyPatterns.js
+++ b/app/javascript/journey_patterns/reducers/journeyPatterns.js
@@ -22,7 +22,7 @@ const journeyPattern = (state = {}, action) =>{
}
case 'UPDATE_CHECKBOX_VALUE':
var updatedStopPoints = state.stop_points.map((s) => {
- if (String(s.id) == action.id) {
+ if (String(s.position) == action.position) {
return _.assign({}, s, {checked : !s.checked})
}else {
return s
@@ -40,6 +40,17 @@ export default function journeyPatterns (state = [], action) {
return [...action.json]
case 'RECEIVE_ERRORS':
return [...action.json]
+ case 'RECEIVE_ROUTE_COSTS':
+ return state.map((j, i) =>{
+ if(i == action.index) {
+ const new_costs = Object.assign({}, j.costs)
+ new_costs[action.key] = action.costs[action.key] ||
+ {distance: 0, time: 0}
+ return _.assign({}, j, {costs: new_costs})
+ } else {
+ return j
+ }
+ })
case 'GO_TO_PREVIOUS_PAGE':
$('#ConfirmModal').modal('hide')
if(action.pagination.page > 1){
@@ -92,7 +103,8 @@ export default function journeyPatterns (state = [], action) {
return _.assign({}, j, {
name: action.data.name.value,
published_name: action.data.published_name.value,
- registration_number: action.data.registration_number.value
+ registration_number: action.data.registration_number.value,
+ custom_fields: action.data.custom_fields,
})
} else {
return j
diff --git a/app/javascript/packs/calendars/edit.js b/app/javascript/packs/calendars/edit.js
index bd09657ec..0c46313b9 100644
--- a/app/javascript/packs/calendars/edit.js
+++ b/app/javascript/packs/calendars/edit.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
diff --git a/app/javascript/packs/exports/new.js b/app/javascript/packs/exports/new.js
new file mode 100644
index 000000000..b113cc709
--- /dev/null
+++ b/app/javascript/packs/exports/new.js
@@ -0,0 +1,5 @@
+import '../../helpers/polyfills'
+
+import MasterSlave from "../../helpers/master_slave"
+
+new MasterSlave("form")
diff --git a/app/javascript/packs/journey_patterns/index.js b/app/javascript/packs/journey_patterns/index.js
index 367a8830f..bd7df2634 100644
--- a/app/javascript/packs/journey_patterns/index.js
+++ b/app/javascript/packs/journey_patterns/index.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
@@ -32,7 +34,8 @@ var initialState = {
type: '',
modalProps: {},
confirmModal: {}
- }
+ },
+ custom_fields: window.custom_fields
}
// const loggerMiddleware = createLogger()
diff --git a/app/javascript/packs/referential_lines/show.js b/app/javascript/packs/referential_lines/show.js
index 542188018..523f2040f 100644
--- a/app/javascript/packs/referential_lines/show.js
+++ b/app/javascript/packs/referential_lines/show.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import clone from '../../helpers/clone'
import RoutesMap from '../../helpers/routes_map'
@@ -6,5 +8,5 @@ routes = JSON.parse(decodeURIComponent(routes))
var map = new RoutesMap('routes_map')
map.addRoutes(routes)
-// map.addRoutesLabels()
+map.addRoutesLabels()
map.fitZoom()
diff --git a/app/javascript/packs/referential_overview/overview.js b/app/javascript/packs/referential_overview/overview.js
index 59c326e9a..03da12ef3 100644
--- a/app/javascript/packs/referential_overview/overview.js
+++ b/app/javascript/packs/referential_overview/overview.js
@@ -1 +1,3 @@
+import '../../helpers/polyfills'
+
import ReferentialOverview from '../../referential_overview'
diff --git a/app/javascript/packs/routes/edit.js b/app/javascript/packs/routes/edit.js
index b787bec97..0512b7aff 100644
--- a/app/javascript/packs/routes/edit.js
+++ b/app/javascript/packs/routes/edit.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import React from 'react'
import PropTypes from 'prop-types'
@@ -29,6 +31,7 @@ const getInitialState = () => {
state.push({
stoppoint_id: v.stoppoint_id,
stoparea_id: v.stoparea_id,
+ stoparea_kind: v.stoparea_kind,
user_objectid: v.user_objectid,
short_name: v.short_name ? v.short_name.replace("&#39;", "\'") : '',
area_type: v.area_type,
@@ -39,8 +42,8 @@ const getInitialState = () => {
name: v.name ? v.name.replace("&#39;", "\'") : '',
registration_number: v.registration_number,
text: fancyText,
- for_boarding: v.for_boarding || "normal",
- for_alighting: v.for_alighting || "normal",
+ for_boarding: v.for_boarding,
+ for_alighting: v.for_alighting,
longitude: v.longitude || 0,
latitude: v.latitude || 0,
comment: v.comment ? v.comment.replace("&#39;", "\'") : '',
@@ -55,12 +58,25 @@ const getInitialState = () => {
}
var initialState = { stopPoints: getInitialState() }
-const loggerMiddleware = createLogger()
-let store = createStore(
- reducers,
- initialState,
- applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
-)
+let store = null
+
+if(Object.assign){
+ const loggerMiddleware = createLogger()
+ store = createStore(
+ reducers,
+ initialState,
+ applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+ )
+}
+else{
+ // IE
+ store = createStore(
+ reducers,
+ initialState,
+ applyMiddleware(thunkMiddleware, promise)
+ )
+}
+
render(
<Provider store={store}>
diff --git a/app/javascript/packs/routes/show.js b/app/javascript/packs/routes/show.js
index c20de0800..e8e068ddd 100644
--- a/app/javascript/packs/routes/show.js
+++ b/app/javascript/packs/routes/show.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import clone from '../../helpers/clone'
import RoutesMap from '../../helpers/routes_map'
diff --git a/app/javascript/packs/stop_areas/new.js b/app/javascript/packs/stop_areas/new.js
index ffe702cdb..b113cc709 100644
--- a/app/javascript/packs/stop_areas/new.js
+++ b/app/javascript/packs/stop_areas/new.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import MasterSlave from "../../helpers/master_slave"
new MasterSlave("form")
diff --git a/app/javascript/packs/time_tables/edit.js b/app/javascript/packs/time_tables/edit.js
index cf058d501..873bdea50 100644
--- a/app/javascript/packs/time_tables/edit.js
+++ b/app/javascript/packs/time_tables/edit.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
diff --git a/app/javascript/packs/vehicle_journeys/index.js b/app/javascript/packs/vehicle_journeys/index.js
index e6867cb17..0b4351d26 100644
--- a/app/javascript/packs/vehicle_journeys/index.js
+++ b/app/javascript/packs/vehicle_journeys/index.js
@@ -1,3 +1,5 @@
+import '../../helpers/polyfills'
+
import React from 'react'
import { render } from 'react-dom'
import { Provider } from 'react-redux'
@@ -9,7 +11,7 @@ import { enableBatching } from '../../vehicle_journeys/batch'
// logger, DO NOT REMOVE
// var applyMiddleware = require('redux').applyMiddleware
-// var createLogger = require('redux-logger')
+// import { createLogger } from 'redux-logger';
// var thunkMiddleware = require('redux-thunk').default
// var promise = require('redux-promise')
diff --git a/app/javascript/routes/components/App.js b/app/javascript/routes/components/App.js
index 26e69bf53..6f8cdf749 100644
--- a/app/javascript/routes/components/App.js
+++ b/app/javascript/routes/components/App.js
@@ -3,14 +3,9 @@ import PropTypes from 'prop-types'
import AddStopPoint from '../containers/AddStopPoint'
import VisibleStopPoints from'../containers/VisibleStopPoints'
import clone from '../../helpers/clone'
-const I18n = clone(window , "I18n", true)
export default class App extends Component {
- getChildContext() {
- return { I18n }
- }
-
render() {
return (
<div>
@@ -20,7 +15,3 @@ export default class App extends Component {
)
}
}
-
-App.childContextTypes = {
- I18n: PropTypes.object
-}
diff --git a/app/javascript/routes/components/BSelect2.js b/app/javascript/routes/components/BSelect2.js
index 035bce155..90f288944 100644
--- a/app/javascript/routes/components/BSelect2.js
+++ b/app/javascript/routes/components/BSelect2.js
@@ -10,13 +10,14 @@ var path = window.location.pathname.split('/', 3).join('/')
export default class BSelect3 extends Component {
- constructor(props, context) {
- super(props, context)
+ constructor(props) {
+ super(props)
}
onChange(e) {
this.props.onChange(this.props.index, {
text: e.currentTarget.textContent,
stoparea_id: e.currentTarget.value,
+ stoparea_kind: e.params.data.kind,
user_objectid: e.params.data.user_objectid,
longitude: e.params.data.longitude,
latitude: e.params.data.latitude,
@@ -85,7 +86,7 @@ class BSelect2 extends Component{
onSelect={ this.props.onSelect }
ref='newSelect'
options={{
- placeholder: this.context.I18n.t("routes.edit.select2.placeholder"),
+ placeholder: I18n.t("routes.edit.select2.placeholder"),
allowClear: true,
language: 'fr', /* Doesn't seem to work... :( */
theme: 'bootstrap',
@@ -128,8 +129,4 @@ class BSelect2 extends Component{
/>
)
}
-}
-
-BSelect2.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/routes/components/OlMap.js b/app/javascript/routes/components/OlMap.js
index 4beb02872..16fec0e87 100644
--- a/app/javascript/routes/components/OlMap.js
+++ b/app/javascript/routes/components/OlMap.js
@@ -3,8 +3,8 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class OlMap extends Component{
- constructor(props, context){
- super(props, context)
+ constructor(props){
+ super(props)
}
fetchApiURL(id){
@@ -115,40 +115,40 @@ export default class OlMap extends Component{
<strong>{this.props.value.olMap.json.name}</strong>
</p>
<p>
- <strong>{this.context.I18n.t('routes.edit.map.stop_point_type')} : </strong>
+ <strong>{I18n.t('routes.edit.map.stop_point_type')} : </strong>
{this.props.value.olMap.json.area_type}
</p>
<p>
- <strong>{this.context.I18n.t('routes.edit.map.short_name')} : </strong>
+ <strong>{I18n.t('routes.edit.map.short_name')} : </strong>
{this.props.value.olMap.json.short_name}
</p>
<p>
- <strong>{this.context.I18n.t('id_reflex')} : </strong>
+ <strong>{I18n.t('id_reflex')} : </strong>
{this.props.value.olMap.json.user_objectid}
</p>
- <p><strong>{this.context.I18n.t('routes.edit.map.coordinates')} : </strong></p>
+ <p><strong>{I18n.t('routes.edit.map.coordinates')} : </strong></p>
<p style={{paddingLeft: 10, marginTop: 0}}>
- <em>{this.context.I18n.t('routes.edit.map.proj')}.: </em>WSG84<br/>
- <em>{this.context.I18n.t('routes.edit.map.lat')}.: </em>{this.props.value.olMap.json.latitude} <br/>
- <em>{this.context.I18n.t('routes.edit.map.lon')}.: </em>{this.props.value.olMap.json.longitude}
+ <em>{I18n.t('routes.edit.map.proj')}.: </em>WSG84<br/>
+ <em>{I18n.t('routes.edit.map.lat')}.: </em>{this.props.value.olMap.json.latitude} <br/>
+ <em>{I18n.t('routes.edit.map.lon')}.: </em>{this.props.value.olMap.json.longitude}
</p>
<p>
- <strong>{this.context.I18n.t('routes.edit.map.postal_code')} : </strong>
+ <strong>{I18n.t('routes.edit.map.postal_code')} : </strong>
{this.props.value.olMap.json.zip_code}
</p>
<p>
- <strong>{this.context.I18n.t('routes.edit.map.city')} : </strong>
+ <strong>{I18n.t('routes.edit.map.city')} : </strong>
{this.props.value.olMap.json.city_name}
</p>
<p>
- <strong>{this.context.I18n.t('routes.edit.map.comment')} : </strong>
+ <strong>{I18n.t('routes.edit.map.comment')} : </strong>
{this.props.value.olMap.json.comment}
</p>
{(this.props.value.stoparea_id != this.props.value.olMap.json.stoparea_id) &&(
<div className='btn btn-outline-primary btn-sm'
onClick= {() => {this.props.onUpdateViaOlMap(this.props.index, this.props.value.olMap.json)}}
- >{this.context.I18n.t('actions.select')}</div>
+ >{I18n.t('actions.select')}</div>
)}
</div>
<div className='map_content'>
@@ -164,7 +164,3 @@ export default class OlMap extends Component{
OlMap.propTypes = {
}
-
-OlMap.contextTypes = {
- I18n: PropTypes.object
-}
diff --git a/app/javascript/routes/components/StopPoint.js b/app/javascript/routes/components/StopPoint.js
index af51a6bb4..916052b42 100644
--- a/app/javascript/routes/components/StopPoint.js
+++ b/app/javascript/routes/components/StopPoint.js
@@ -4,7 +4,9 @@ import PropTypes from 'prop-types'
import BSelect2 from './BSelect2'
import OlMap from './OlMap'
-export default function StopPoint(props, {I18n}) {
+import { defaultAttribute } from '../actions'
+
+export default function StopPoint(props) {
return (
<div className='nested-fields'>
<div className='wrapper'>
@@ -40,13 +42,13 @@ export default function StopPoint(props, {I18n}) {
<div
className={'btn btn-link' + (props.first ? ' disabled' : '')}
- onClick={props.onMoveUpClick}
+ onClick={props.first ? null : props.onMoveUpClick}
>
<span className='fa fa-arrow-up'></span>
</div>
<div
className={'btn btn-link' + (props.last ? ' disabled' : '')}
- onClick={props.onMoveDownClick}
+ onClick={props.last ? null : props.onMoveDownClick}
>
<span className='fa fa-arrow-down'></span>
</div>
@@ -90,7 +92,3 @@ StopPoint.propTypes = {
index: PropTypes.number,
value: PropTypes.object
}
-
-StopPoint.contextTypes = {
- I18n: PropTypes.object
-}
diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js
index b227abdea..9bc5e02d1 100644
--- a/app/javascript/routes/components/StopPointList.js
+++ b/app/javascript/routes/components/StopPointList.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import StopPoint from './StopPoint'
-export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange, onSelectChange, onToggleMap, onToggleEdit, onSelectMarker, onUnselectMarker, onUpdateViaOlMap }, {I18n}) {
+export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange, onSelectChange, onToggleMap, onToggleEdit, onSelectMarker, onUnselectMarker, onUpdateViaOlMap }) {
return (
<div className='subform'>
<div className='nested-head'>
diff --git a/app/javascript/routes/containers/AddStopPoint.js b/app/javascript/routes/containers/AddStopPoint.js
index fd9227ff3..4b169807d 100644
--- a/app/javascript/routes/containers/AddStopPoint.js
+++ b/app/javascript/routes/containers/AddStopPoint.js
@@ -11,7 +11,7 @@ let AddStopPoint = ({ dispatch }) => {
dispatch(actions.addStop())
}}>
<button type="submit" className="btn btn-outline-primary">
- Ajouter un arrêt
+ {I18n.t('stop_areas.actions.new')}
</button>
</form>
</div>
diff --git a/app/javascript/routes/index.js b/app/javascript/routes/index.js
index febae7d54..fc99a3086 100644
--- a/app/javascript/routes/index.js
+++ b/app/javascript/routes/index.js
@@ -22,10 +22,12 @@ const getInitialState = () => {
let fancyText = v.name.replace("&#39;", "\'")
if(v.zip_code && v.city_name)
fancyText += ", " + v.zip_code + " " + v.city_name.replace("&#39;", "\'")
+ forAlightingAndBoarding = v.stoparea_kind === 'commercial' ? 'normal' : 'forbidden'
state.push({
stoppoint_id: v.stoppoint_id,
stoparea_id: v.stoparea_id,
+ stoparea_kind: v.stoparea_kind,
user_objectid: v.user_objectid,
short_name: v.short_name ? v.short_name.replace("&#39;", "\'") : '',
area_type: v.area_type,
@@ -36,8 +38,8 @@ const getInitialState = () => {
name: v.name ? v.name.replace("&#39;", "\'") : '',
registration_number: v.registration_number,
text: fancyText,
- for_boarding: v.for_boarding || "normal",
- for_alighting: v.for_alighting || "normal",
+ for_boarding: v.for_boarding || forAlightingAndBoarding,
+ for_alighting: v.for_alighting || forAlightingAndBoarding,
longitude: v.longitude || 0,
latitude: v.latitude || 0,
comment: v.comment ? v.comment.replace("&#39;", "\'") : '',
diff --git a/app/javascript/routes/reducers/stopPoints.js b/app/javascript/routes/reducers/stopPoints.js
index 0b42b504f..54142338d 100644
--- a/app/javascript/routes/reducers/stopPoints.js
+++ b/app/javascript/routes/reducers/stopPoints.js
@@ -61,6 +61,7 @@ const stopPoints = (state = [], action) => {
case 'UPDATE_INPUT_VALUE':
return state.map( (t, i) => {
if (i === action.index) {
+ let forAlightingAndBoarding = action.text.stoparea_kind === 'commercial' ? 'normal' : 'forbidden'
return _.assign(
{},
t,
@@ -68,6 +69,7 @@ const stopPoints = (state = [], action) => {
stoppoint_id: t.stoppoint_id,
text: action.text.text,
stoparea_id: action.text.stoparea_id,
+ stoparea_kind: action.text.stoparea_kind,
user_objectid: action.text.user_objectid,
latitude: action.text.latitude,
longitude: action.text.longitude,
@@ -76,7 +78,9 @@ const stopPoints = (state = [], action) => {
area_type: action.text.area_type,
city_name: action.text.city_name,
comment: action.text.comment,
- registration_number: action.text.registration_number
+ registration_number: action.text.registration_number,
+ for_alighting: forAlightingAndBoarding,
+ for_boarding: forAlightingAndBoarding
}
)
} else {
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 98b9eab4b..a5c454a18 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -4,7 +4,6 @@ import reject from 'lodash/reject'
import some from 'lodash/some'
import every from 'lodash/every'
import clone from '../../helpers/clone'
-const I18n = clone(window, "I18n")
const actions = {
weekDays: (index) => {
@@ -192,10 +191,13 @@ const actions = {
isInPeriod: (periods, date) => {
date = new Date(date)
- for (let period of periods) {
+ let i = 0;
+ while(i < periods.length){
+ let period = periods[i]
let begin = new Date(period.period_start)
let end = new Date(period.period_end)
if (date >= begin && date <= end) return true
+ i++
}
return false
@@ -236,12 +238,14 @@ const actions = {
let error = ''
start = new Date(start)
end = new Date(end)
-
- for (let day of in_days) {
+ let i = 0;
+ while(i < in_days){
+ let day = in_days[i]
if (start <= new Date(day.date) && end >= new Date(day.date)) {
error = I18n.t('time_tables.edit.error_submit.dates_overlaps')
break
}
+ i ++
}
return error
},
@@ -307,10 +311,11 @@ const actions = {
})
},
errorModalKey: (periods, dayTypes) => {
- const withoutPeriodsWithDaysTypes = reject(periods, 'deleted').length == 0 && some(dayTypes) && "withoutPeriodsWithDaysTypes"
+ // const withoutPeriodsWithDaysTypes = reject(periods, 'deleted').length == 0 && some(dayTypes) && "withoutPeriodsWithDaysTypes"
const withPeriodsWithoutDayTypes = reject(periods, 'deleted').length > 0 && every(dayTypes, dt => dt == false) && "withPeriodsWithoutDayTypes"
- return (withoutPeriodsWithDaysTypes || withPeriodsWithoutDayTypes) && (withoutPeriodsWithDaysTypes ? "withoutPeriodsWithDaysTypes" : "withPeriodsWithoutDayTypes")
+ // return (withoutPeriodsWithDaysTypes || withPeriodsWithoutDayTypes) && (withoutPeriodsWithDaysTypes ? "withoutPeriodsWithDaysTypes" : "withPeriodsWithoutDayTypes")
+ return withPeriodsWithoutDayTypes
},
errorModalMessage: (errorKey) => {
diff --git a/app/javascript/time_tables/components/ConfirmModal.js b/app/javascript/time_tables/components/ConfirmModal.js
index 4e8583bc0..e4219348d 100644
--- a/app/javascript/time_tables/components/ConfirmModal.js
+++ b/app/javascript/time_tables/components/ConfirmModal.js
@@ -2,7 +2,7 @@ import React from 'react'
import PropTypes from 'prop-types'
-export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}, {I18n}) {
+export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}) {
return (
<div className={'modal fade ' + ((modal.type == 'confirm') ? 'in' : '')} id='ConfirmModal'>
<div className='modal-container'>
@@ -45,8 +45,4 @@ ConfirmModal.propTypes = {
modal: PropTypes.object.isRequired,
onModalAccept: PropTypes.func.isRequired,
onModalCancel: PropTypes.func.isRequired
-}
-
-ConfirmModal.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/ErrorModal.js b/app/javascript/time_tables/components/ErrorModal.js
index 8af12f1d1..a512d28fd 100644
--- a/app/javascript/time_tables/components/ErrorModal.js
+++ b/app/javascript/time_tables/components/ErrorModal.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import actions from '../actions'
-export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
+export default function ErrorModal({dispatch, modal, onModalClose}) {
return (
<div className={'modal fade ' + ((modal.type == 'error') ? 'in' : '')} id='ErrorModal'>
<div className='modal-container'>
@@ -37,8 +37,4 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
ErrorModal.propTypes = {
modal: PropTypes.object.isRequired,
onModalClose: PropTypes.func.isRequired
-}
-
-ErrorModal.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/Metas.js b/app/javascript/time_tables/components/Metas.js
index 08a6e26fe..186af540a 100644
--- a/app/javascript/time_tables/components/Metas.js
+++ b/app/javascript/time_tables/components/Metas.js
@@ -4,7 +4,7 @@ import PropTypes from 'prop-types'
import actions from '../actions'
import TagsSelect2 from './TagsSelect2'
-export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}, {I18n}) {
+export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}) {
let colorList = ["", "#9B9B9B", "#FFA070", "#C67300", "#7F551B", "#41CCE3", "#09B09C", "#3655D7", "#6321A0", "#E796C6", "#DD2DAA"]
return (
<div className='form-horizontal'>
@@ -76,7 +76,6 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
<label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'tag_list')}</label>
<div className="col-sm-8">
<TagsSelect2
- initialTags={metas.initial_tags}
tags={metas.tags}
onSelect2Tags={(e) => onSelect2Tags(e)}
onUnselect2Tags={(e) => onUnselect2Tags(e)}
@@ -134,8 +133,4 @@ Metas.propTypes = {
onUpdateColor: PropTypes.func.isRequired,
onSelect2Tags: PropTypes.func.isRequired,
onUnselect2Tags: PropTypes.func.isRequired
-}
-
-Metas.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/PeriodForm.js b/app/javascript/time_tables/components/PeriodForm.js
index d17a246f7..36ed6cfdf 100644
--- a/app/javascript/time_tables/components/PeriodForm.js
+++ b/app/javascript/time_tables/components/PeriodForm.js
@@ -33,7 +33,7 @@ const makeYearsOptions = (yearSelected) => {
return arr
}
-export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}, {I18n}) {
+export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}) {
return (
<div className="container-fluid">
<div className="row">
@@ -143,8 +143,4 @@ PeriodForm.propTypes = {
onUpdatePeriodForm: PropTypes.func.isRequired,
onValidatePeriodForm: PropTypes.func.isRequired,
timetable: PropTypes.object.isRequired
-}
-
-PeriodForm.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/PeriodManager.js b/app/javascript/time_tables/components/PeriodManager.js
index 6b817fe73..6871d0b9b 100644
--- a/app/javascript/time_tables/components/PeriodManager.js
+++ b/app/javascript/time_tables/components/PeriodManager.js
@@ -55,7 +55,7 @@ export default class PeriodManager extends Component {
type='button'
onClick={() => this.props.onOpenEditPeriodForm(this.props.value, this.props.index)}
>
- Modifier
+ {I18n.t('actions.edit')}
</button>
</li>
<li className='delete-action'>
@@ -64,7 +64,7 @@ export default class PeriodManager extends Component {
onClick={() => this.props.onDeletePeriod(this.props.index, this.props.metas.day_types)}
>
<span className='fa fa-trash'></span>
- Supprimer
+ {I18n.t('actions.destroy')}
</button>
</li>
</ul>
@@ -79,8 +79,4 @@ PeriodManager.propTypes = {
currentDate: PropTypes.object.isRequired,
onDeletePeriod: PropTypes.func.isRequired,
onOpenEditPeriodForm: PropTypes.func.isRequired
-}
-
-PeriodManager.contextTypes = {
- I18n: PropTypes.object
} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/SaveTimetable.js b/app/javascript/time_tables/components/SaveTimetable.js
index 704590abd..468f1773b 100644
--- a/app/javascript/time_tables/components/SaveTimetable.js
+++ b/app/javascript/time_tables/components/SaveTimetable.js
@@ -26,7 +26,7 @@ export default class SaveTimetable extends Component{
}
}}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</form>
</div>
diff --git a/app/javascript/time_tables/components/TagsSelect2.js b/app/javascript/time_tables/components/TagsSelect2.js
index 43cf59fdf..fe610ed58 100644
--- a/app/javascript/time_tables/components/TagsSelect2.js
+++ b/app/javascript/time_tables/components/TagsSelect2.js
@@ -27,7 +27,7 @@ export default class TagsSelect2 extends Component {
return (
<Select2
value={(this.props.tags.length) ? map(this.props.tags, 'id') : undefined}
- data={(this.props.initialTags.length) ? this.mapKeys(this.props.initialTags) : undefined}
+ data={(this.props.tags.length) ? this.mapKeys(this.props.tags) : undefined}
onSelect={(e) => this.props.onSelect2Tags(e)}
onUnselect={(e) => setTimeout( () => this.props.onUnselect2Tags(e, 150))}
multiple={true}
@@ -40,7 +40,7 @@ export default class TagsSelect2 extends Component {
allowClear: true,
theme: 'bootstrap',
width: '100%',
- placeholder: this.context.I18n.t('time_tables.edit.select2.tag.placeholder'),
+ placeholder: I18n.t('time_tables.edit.select2.tag.placeholder'),
ajax: {
url: origin + path + '/tags.json',
dataType: 'json',
@@ -75,7 +75,3 @@ export default class TagsSelect2 extends Component {
const formatRepo = (props) => {
if(props.name) return props.name
}
-
-TagsSelect2.contextTypes = {
- I18n: PropTypes.object
-} \ No newline at end of file
diff --git a/app/javascript/time_tables/components/Timetable.js b/app/javascript/time_tables/components/Timetable.js
index 991f31435..3779fa2d0 100644
--- a/app/javascript/time_tables/components/Timetable.js
+++ b/app/javascript/time_tables/components/Timetable.js
@@ -31,11 +31,11 @@ export default class Timetable extends Component {
<div className="table table-2entries mb-sm">
<div className="t2e-head w20">
<div className="th">
- <div className="strong">{this.context.I18n.t('time_tables.edit.synthesis')}</div>
+ <div className="strong">{I18n.t('time_tables.edit.synthesis')}</div>
</div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.day_types')}</span></div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.periods')}</span></div>
- <div className="td"><span>{this.context.I18n.t('time_tables.edit.exceptions')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.day_types')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.periods')}</span></div>
+ <div className="td"><span>{I18n.t('time_tables.edit.exceptions')}</span></div>
</div>
<div className="t2e-item-list w80">
<div>
@@ -109,8 +109,4 @@ Timetable.propTypes = {
onDeletePeriod: PropTypes.func.isRequired,
onExcludeDateFromPeriod: PropTypes.func.isRequired,
onIncludeDateInPeriod: PropTypes.func.isRequired
-}
-
-Timetable.contextTypes = {
- I18n: PropTypes.object
-}
+} \ No newline at end of file
diff --git a/app/javascript/time_tables/containers/App.js b/app/javascript/time_tables/containers/App.js
index 5963f8f1d..c12e33ef5 100644
--- a/app/javascript/time_tables/containers/App.js
+++ b/app/javascript/time_tables/containers/App.js
@@ -10,7 +10,6 @@ import SaveTimetable from './SaveTimetable'
import ConfirmModal from './ConfirmModal'
import ErrorModal from './ErrorModal'
import clone from '../../helpers/clone'
-const I18n = clone(window, "I18n", true)
class App extends Component {
componentDidMount(){
diff --git a/app/javascript/time_tables/containers/Metas.js b/app/javascript/time_tables/containers/Metas.js
index ebccf556e..7bc3ef4e1 100644
--- a/app/javascript/time_tables/containers/Metas.js
+++ b/app/javascript/time_tables/containers/Metas.js
@@ -24,6 +24,7 @@ const mapDispatchToProps = (dispatch) => {
},
onSelect2Tags: (e) => {
e.preventDefault()
+ $(e.target).find('[data-select2-tag]').remove()
dispatch(actions.select2Tags(e.params.data))
},
onUnselect2Tags: (e) => {
diff --git a/app/javascript/time_tables/reducers/metas.js b/app/javascript/time_tables/reducers/metas.js
index 51e1ec149..012f29511 100644
--- a/app/javascript/time_tables/reducers/metas.js
+++ b/app/javascript/time_tables/reducers/metas.js
@@ -31,11 +31,13 @@ export default function metas(state = {}, action) {
return assign({}, state, {color: action.color})
case 'UPDATE_SELECT_TAG':
let tags = [...state.tags]
- tags.push(action.selectedItem)
+ if(tags.length == 0 || tags[tags.length-1].name != action.selectedItem.name){
+ tags.push(action.selectedItem)
+ }
return assign({}, state, {tags: tags})
case 'UPDATE_UNSELECT_TAG':
return assign({}, state, {tags: filter(state.tags, (t) => (t.id != action.selectedItem.id))})
default:
return state
}
-} \ No newline at end of file
+}
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index e67753e4b..70d6e953a 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -1,9 +1,3 @@
-import Promise from 'promise-polyfill'
-
-// To add to window
-if (!window.Promise) {
- window.Promise = Promise;
-}
import { batchActions } from '../batch'
const actions = {
@@ -54,16 +48,10 @@ const actions = {
}),
selectJPCreateModal : (selectedJP) => ({
type : 'SELECT_JP_CREATE_MODAL',
- selectedItem: {
- id: selectedJP.id,
+ selectedItem: _.assign({}, selectedJP, {
objectid: selectedJP.object_id,
- short_id: selectedJP.short_id,
- name: selectedJP.name,
- published_name: selectedJP.published_name,
- stop_areas: selectedJP.stop_area_short_descriptions,
- costs: selectedJP.costs,
- full_schedule: selectedJP.full_schedule
- }
+ stop_areas: selectedJP.stop_area_short_descriptions
+ })
}),
openEditModal : (vehicleJourney) => ({
type : 'EDIT_VEHICLEJOURNEY_MODAL',
@@ -113,14 +101,9 @@ const actions = {
type : 'EDIT_PURCHASE_WINDOWS_VEHICLEJOURNEY_MODAL',
vehicleJourneys
}),
- selectPurchaseWindowsModal: (selectedWindow) =>({
+ selectPurchaseWindowsModal: (selectedItem) =>({
type: 'SELECT_PURCHASE_WINDOW_MODAL',
- selectedItem:{
- id: selectedWindow.id,
- name: selectedWindow.name,
- color: selectedWindow.color,
- objectid: selectedWindow.objectid
- }
+ selectedItem
}),
addSelectedPurchaseWindow: () => ({
type: 'ADD_SELECTED_PURCHASE_WINDOW'
@@ -203,24 +186,24 @@ const actions = {
let field = fields[key]
if(field.validity && !field.validity.valid){
valid = false
- $(field).parent().addClass('has-error').children('.help-block').remove()
+ $(field).parent().parent().addClass('has-error').children('.help-block').remove()
$(field).parent().append("<span class='small help-block'>" + field.validationMessage + "</span>")
}
})
-
return valid
},
toggleArrivals : () => ({
type: 'TOGGLE_ARRIVALS',
}),
- updateTime : (val, subIndex, index, timeUnit, isDeparture, isArrivalsToggled) => ({
+ updateTime : (val, subIndex, index, timeUnit, isDeparture, isArrivalsToggled, enforceConsistency=false) => ({
type: 'UPDATE_TIME',
val,
subIndex,
index,
timeUnit,
isDeparture,
- isArrivalsToggled
+ isArrivalsToggled,
+ enforceConsistency
}),
resetStateFilters: () => ({
type: 'RESET_FILTERS'
@@ -344,16 +327,23 @@ const actions = {
if(hasError == true) {
dispatch(actions.unavailableServer())
} else {
- let val
- for (val of json.vehicle_journeys){
+ let i = 0
+ while(i < json.vehicle_journeys.length){
+ let val = json.vehicle_journeys[i]
+ i++
var timeTables = []
var purchaseWindows = []
- let tt
- for (tt of val.time_tables){
+ let k = 0
+ while(k < val.time_tables.length){
+ let tt = val.time_tables[k]
+ k++
timeTables.push(tt)
}
if(val.purchase_windows){
- for (tt of val.purchase_windows){
+ k = 0
+ while(k < val.purchase_windows.length){
+ let tt = val.purchase_windows[k]
+ k++
purchaseWindows.push(tt)
}
}
@@ -487,10 +477,10 @@ const actions = {
vjas.delta = delta
return vjas
},
- adjustSchedule: (action, schedule) => {
+ adjustSchedule: (action, schedule, enforceConsistency=false) => {
// we enforce that the departure time remains after the arrival time
actions.getDelta(schedule)
- if(schedule.delta < 0){
+ if(enforceConsistency && schedule.delta < 0){
if(action.isDeparture){
schedule.arrival_time = schedule.departure_time
}
diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js
index 75e8a3932..330b4e02f 100644
--- a/app/javascript/vehicle_journeys/components/ConfirmModal.js
+++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js
@@ -16,7 +16,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalCancel(modal.confirmModal.callback) }}
>
- Ne pas valider
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-danger'
@@ -24,7 +24,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalAccept(modal.confirmModal.callback, vehicleJourneys) }}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</div>
diff --git a/app/javascript/vehicle_journeys/components/Filters.js b/app/javascript/vehicle_journeys/components/Filters.js
index ae3ab3476..1e43a490e 100644
--- a/app/javascript/vehicle_journeys/components/Filters.js
+++ b/app/javascript/vehicle_journeys/components/Filters.js
@@ -33,6 +33,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
{/* Calendriers */}
<div className='form-group w33'>
<TimetableSelect2
+ placeholder={I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.timetable')}
onSelect2Timetable={onSelect2Timetable}
hasRoute={true}
chunkURL={("/autocomplete_time_tables.json?route_id=" + String(window.route_id))}
@@ -145,12 +146,12 @@ export default function Filters({filters, pagination, missions, onFilter, onRese
<span
className='btn btn-link'
onClick={(e) => onResetFilters(e, pagination)}>
- Effacer
+ {I18n.t('actions.erase')}
</span>
<span
className='btn btn-default'
onClick={(e) => onFilter(e, pagination)}>
- Filtrer
+ {I18n.t('actions.filter')}
</span>
</div>
</div>
diff --git a/app/javascript/vehicle_journeys/components/Navigate.js b/app/javascript/vehicle_journeys/components/Navigate.js
index 24843babc..e79823e49 100644
--- a/app/javascript/vehicle_journeys/components/Navigate.js
+++ b/app/javascript/vehicle_journeys/components/Navigate.js
@@ -1,5 +1,6 @@
import React, { Component } from 'react'
import PropTypes from 'prop-types'
+import capitalize from 'lodash/capitalize'
import actions from'../actions'
export default function Navigate({ dispatch, vehicleJourneys, pagination, status, filters}) {
@@ -17,7 +18,7 @@ export default function Navigate({ dispatch, vehicleJourneys, pagination, status
if(status.fetchSuccess == true) {
return (
<div className="pagination">
- {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})}
+ {I18n.t('will_paginate.page_entries_info.multi_page', { model: capitalize(I18n.model_name('vehicle_journey', { plural: true })), from: minVJ, to: maxVJ, count: pagination.totalCount })}
<form className='page_links' onSubmit={e => {e.preventDefault()}}>
<button
onClick={e => {
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index 7db0cee1c..5eb73de0e 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -10,6 +10,10 @@ export default class VehicleJourney extends Component {
this.previousCity = undefined
}
+ journey_length() {
+ return this.props.value.journey_pattern.journey_length + "km"
+ }
+
cityNameChecker(sp) {
return this.props.vehicleJourneys.showHeader(sp.stop_point_objectid)
}
@@ -48,6 +52,14 @@ export default class VehicleJourney extends Component {
}
}
+ displayDelta(delta) {
+ if(delta > 99){
+ return "+"
+ }
+ return delta
+ }
+
+
hasTimeTable(time_tables, tt) {
let found = false
time_tables.map((t, index) => {
@@ -59,14 +71,35 @@ export default class VehicleJourney extends Component {
return found
}
+ hasPurchaseWindow(purchase_windows, window) {
+ return this.hasTimeTable(purchase_windows, window)
+ }
+
isDisabled(bool1, bool2) {
return (bool1 || bool2)
}
+ extraHeaderValue(header) {
+ if(header.type == "custom_field"){
+ let field = this.props.value.custom_fields[header["name"]]
+ if(field.field_type == "list"){
+ return field.options.list_values[field.value]
+ }
+ else{
+ return field.value
+ }
+ }
+ else{
+ return this.props.value[header["name"]]
+ }
+ }
+
render() {
this.previousCity = undefined
let detailed_calendars = this.hasFeature('detailed_calendars') && !this.disabled
let detailed_calendars_shown = $('.detailed-timetables-bt').hasClass('active')
+ let detailed_purchase_windows = this.hasFeature('detailed_purchase_windows') && !this.disabled
+ let detailed_purchase_windows_shown = $('.detailed-purchase-windows-bt').hasClass('active')
let {time_tables, purchase_windows} = this.props.value
return (
@@ -81,6 +114,16 @@ 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.props.extraHeaders.map((header, i) =>
+ <div key={i}>{this.extraHeaderValue(header)}</div>
+ )
+ }
+ { this.hasFeature('journey_length_in_vehicle_journeys') &&
+ <div>
+ {this.journey_length()}
+ </div>
+ }
{ this.hasFeature('purchase_windows') &&
<div>
{purchase_windows.slice(0,3).map((tt, i)=>
@@ -89,6 +132,13 @@ export default class VehicleJourney extends Component {
{purchase_windows.length > 3 && <span className='vj_tt'> + {purchase_windows.length - 3}</span>}
</div>
}
+ { detailed_purchase_windows &&
+ <div className={"detailed-purchase-windows" + (detailed_purchase_windows_shown ? "" : " hidden")}>
+ {this.props.allPurchaseWindows.map((w, i) =>
+ <div key={i} className={(this.hasPurchaseWindow(purchase_windows, w) ? "active" : "inactive")}></div>
+ )}
+ </div>
+ }
<div>
{time_tables.slice(0,3).map((tt, i)=>
<span key={i} className='vj_tt'>{this.timeTableURL(tt)}</span>
@@ -117,6 +167,8 @@ export default class VehicleJourney extends Component {
)}
</div>
}
+
+
</div>
{this.props.value.vehicle_journey_at_stops.map((vj, i) =>
<div key={i} className='td text-center'>
@@ -132,6 +184,7 @@ export default class VehicleJourney extends Component {
disabled={!this.props.editMode || this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false}
readOnly={!this.props.editMode && !vj.dummy}
onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', false, false)}}
+ onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', false, false, true)}}
value={vj.arrival_time['hour']}
/>
<span>:</span>
@@ -143,6 +196,7 @@ export default class VehicleJourney extends Component {
disabled={!this.props.editMode || this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false}
readOnly={!this.props.editMode && !vj.dummy}
onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'minute', false, false)}}
+ onBlur={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'minute', false, false, true)}}
value={vj.arrival_time['minute']}
/>
</span>
@@ -150,7 +204,7 @@ export default class VehicleJourney extends Component {
}
<div className={(this.columnHasDelta() ? '' : 'hidden')}>
{(vj.delta != 0) &&
- <span className='sb sb-chrono sb-lg text-warning' data-textinside={vj.delta}></span>
+ <span className='sb sb-chrono sb-lg text-warning' data-textinside={this.displayDelta(vj.delta)}></span>
}
</div>
<div data-headline={I18n.t("vehicle_journeys.form.departure_at")}>
@@ -163,6 +217,7 @@ export default class VehicleJourney extends Component {
disabled={!this.props.editMode || this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false}
readOnly={!this.props.editMode && !vj.dummy}
onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', true, this.props.filters.toggleArrivals)}}
+ onBlur={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', true, this.props.filters.toggleArrivals, true)}}
value={vj.departure_time['hour']}
/>
<span>:</span>
@@ -174,13 +229,11 @@ export default class VehicleJourney extends Component {
disabled={!this.props.editMode || this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false}
readOnly={!this.props.editMode && !vj.dummy}
onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, "minute", true, this.props.filters.toggleArrivals)}}
+ onBlur={(e) => {this.props.onUpdateTime(e, i, this.props.index, "minute", true, this.props.filters.toggleArrivals, true)}}
value={vj.departure_time['minute']}
/>
- </span>
- </div>
- {vj.errors && <div className="errors">
- {vj.errors}
- </div>}
+ </span>
+ </div>
</div>
</div>
)}
@@ -197,4 +250,6 @@ VehicleJourney.propTypes = {
onSelectVehicleJourney: PropTypes.func.isRequired,
vehicleJourneys: PropTypes.object.isRequired,
allTimeTables: PropTypes.array.isRequired,
+ allPurchaseWindows: PropTypes.array.isRequired,
+ extraHeaders: PropTypes.array.isRequired,
}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
index 384afba17..27e147b37 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.togglePurchaseWindows = this.togglePurchaseWindows.bind(this)
this.toggleTimetables = this.toggleTimetables.bind(this)
}
@@ -49,26 +50,55 @@ export default class VehicleJourneys extends Component {
return this.headerManager.showHeader(object_id)
}
- allTimeTables() {
- if(this._allTimeTables){
- return this._allTimeTables
- }
- let keys = []
+ getPurchaseWindowsAndTimeTables(){
+ let timetables_keys = []
+ let windows_keys = []
this._allTimeTables = []
+ this._allPurchaseWindows = []
this.vehicleJourneysList().map((vj, index) => {
vj.time_tables.map((tt, _) => {
- if(keys.indexOf(tt.id) < 0){
- keys.push(tt.id)
+ if(timetables_keys.indexOf(tt.id) < 0){
+ timetables_keys.push(tt.id)
this._allTimeTables.push(tt)
}
})
+ vj.purchase_windows.map((tt, _) => {
+ if(windows_keys.indexOf(tt.id) < 0){
+ windows_keys.push(tt.id)
+ this._allPurchaseWindows.push(tt)
+ }
+ })
})
+ }
+
+ allTimeTables() {
+ if(! this._allTimeTables){
+ this.getPurchaseWindowsAndTimeTables()
+ }
return this._allTimeTables
}
+ allPurchaseWindows() {
+ if(!this._allPurchaseWindows){
+ this.getPurchaseWindowsAndTimeTables()
+ }
+
+ return this._allPurchaseWindows
+ }
+
toggleTimetables(e) {
- $('.table-2entries .detailed-timetables').toggleClass('hidden')
- $('.table-2entries .detailed-timetables-bt').toggleClass('active')
+ let root = $(this.refs['vehicleJourneys'])
+ root.find('.table-2entries .detailed-timetables').toggleClass('hidden')
+ root.find('.table-2entries .detailed-timetables-bt').toggleClass('active')
+ this.componentDidUpdate()
+ e.preventDefault()
+ false
+ }
+
+ togglePurchaseWindows(e) {
+ let root = $(this.refs['vehicleJourneys'])
+ root.find('.table-2entries .detailed-purchase-windows').toggleClass('hidden')
+ root.find('.table-2entries .detailed-purchase-windows-bt').toggleClass('active')
this.componentDidUpdate()
e.preventDefault()
false
@@ -127,10 +157,29 @@ export default class VehicleJourneys extends Component {
)
}
+ purchaseWindowURL(tt) {
+ let refURL = window.location.pathname.split('/', 3).join('/')
+ let ttURL = refURL + '/purchase_windows/' + tt.id
+ return (
+ <a href={ttURL} title='Voir le calendrier commercial'><span className='fa fa-calendar' style={{color: (tt.color ? tt.color : '#4B4B4B')}}></span>{tt.name}</a>
+ )
+ }
+
+ extraHeaderLabel(header) {
+ if(header["type"] == "custom_field"){
+ return this.props.customFields[header["name"]]["name"]
+ }
+ else{
+ return I18n.attribute_name("vehicle_journey", header)
+ }
+ }
+
render() {
this.previousBreakpoint = undefined
this._allTimeTables = null
+ this._allPurchaseWindows = null
let detailed_calendars = this.hasFeature('detailed_calendars') && !this.isReturn() && (this.allTimeTables().length > 0)
+ let detailed_purchase_windows = this.hasFeature('detailed_purchase_windows') && !this.isReturn() && (this.allPurchaseWindows().length > 0)
if(this.props.status.isFetching == true) {
return (
<div className="isLoading" style={{marginTop: 80, marginBottom: 80}}>
@@ -139,7 +188,7 @@ export default class VehicleJourneys extends Component {
)
} else {
return (
- <div className='row'>
+ <div className='row' ref='vehicleJourneys'>
<div className='col-lg-12'>
{(this.props.status.fetchSuccess == false) && (
<div className='alert alert-danger mt-sm'>
@@ -148,7 +197,7 @@ export default class VehicleJourneys extends Component {
</div>
)}
- { this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && (
+ { _.some(this.vehicleJourneysList(), 'errors') && (
<div className="alert alert-danger mt-sm">
<strong>{I18n.tc("error")}</strong>
{this.vehicleJourneysList().map((vj, index) =>
@@ -170,17 +219,49 @@ 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>
- { this.hasFeature('purchase_windows') && <div>{I18n.model_name("purchase_window", "plural": true)}</div> }
+ {
+ this.props.extraHeaders.map((header, i) =>
+ <div key={i}>{this.extraHeaderLabel(header)}</div>
+ )
+ }
+ { this.hasFeature('journey_length_in_vehicle_journeys') &&
+ <div>
+ {I18n.attribute_name("vehicle_journey", "journey_length")}
+ </div>
+ }
+ { this.hasFeature('purchase_windows') &&
+ <div>
+ { detailed_purchase_windows &&
+ <a href='#' onClick={this.togglePurchaseWindows} className='detailed-purchase-windows-bt'>
+ <span className='fa fa-angle-up'></span>
+ {I18n.model_name("purchase_window", {"plural": true})}
+ </a>
+ }
+ { !detailed_purchase_windows && I18n.model_name("purchase_window", {"plural": true})}
+ </div>
+ }
+ { detailed_purchase_windows &&
+ <div className="detailed-purchase-windows hidden">
+ {this.allPurchaseWindows().map((tt, i)=>
+ <div key={i}>
+ <p>
+ {this.purchaseWindowURL(tt)}
+ </p>
+ <p>{tt.bounding_dates.join(' > ')}</p>
+ </div>
+ )}
+ </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)}
+ {I18n.model_name("time_table", {"plural": true})}
</a>
}
- { !detailed_calendars && I18n.model_name("time_table", "plural": true)}
+ { !detailed_calendars && I18n.model_name("time_table", {"plural": true})}
</div>
- { !this.isReturn() &&
+ { detailed_calendars &&
<div className="detailed-timetables hidden">
{this.allTimeTables().map((tt, i)=>
<div key={i}>
@@ -217,6 +298,8 @@ export default class VehicleJourneys extends Component {
vehicleJourneys={this}
disabled={this.isReturn()}
allTimeTables={this.allTimeTables()}
+ allPurchaseWindows={this.allPurchaseWindows()}
+ extraHeaders={this.props.extraHeaders}
/>
)}
</div>
@@ -232,6 +315,8 @@ export default class VehicleJourneys extends Component {
VehicleJourneys.propTypes = {
status: PropTypes.object.isRequired,
filters: PropTypes.object.isRequired,
+ extraHeaders: PropTypes.array.isRequired,
+ customFields: PropTypes.object.isRequired,
stopPointsList: PropTypes.array.isRequired,
onLoadFirstPage: PropTypes.func.isRequired,
onUpdateTime: PropTypes.func.isRequired,
diff --git a/app/javascript/vehicle_journeys/components/tools/CreateModal.js b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
index 24d9a23c2..1d470cd43 100644
--- a/app/javascript/vehicle_journeys/components/tools/CreateModal.js
+++ b/app/javascript/vehicle_journeys/components/tools/CreateModal.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import actions from '../../actions'
import MissionSelect2 from './select2s/MissionSelect2'
import CompanySelect2 from './select2s/CompanySelect2'
-import CustomFieldsInputs from './CustomFieldsInputs'
+import CustomFieldsInputs from '../../../helpers/CustomFieldsInputs'
export default class CreateModal extends Component {
constructor(props) {
@@ -12,7 +12,13 @@ export default class CreateModal extends Component {
}
handleSubmit() {
- if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0]) && this.props.modal.modalProps.selectedJPModal) {
+ if(!this.props.modal.modalProps.selectedJPModal){
+ let field = $('#NewVehicleJourneyModal').find(".vjCreateSelectJP")
+ field.parent().parent().addClass('has-error').children('.help-block').remove()
+ field.parent().append("<span class='small help-block'>" + I18n.t("simple_form.required.text") + "</span>")
+ return
+ }
+ if (actions.validateFields(...this.refs, $('.vjCreateSelectJP')[0])) {
this.props.onAddVehicleJourney(_.assign({}, this.refs, {custom_fields: this.custom_fields}), this.props.modal.modalProps.selectedJPModal, this.props.stopPointsList, this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company)
this.props.onModalClose()
$('#NewVehicleJourneyModal').modal('hide')
@@ -41,7 +47,7 @@ export default class CreateModal extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Ajouter une course</h4>
+ <h4 className='modal-title'>{I18n.t('vehicle_journeys.actions.new')}</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -51,7 +57,7 @@ export default class CreateModal extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label'>Nom de la course</label>
+ <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'journey_name')}</label>
<input
type='text'
ref='published_journey_name'
@@ -62,7 +68,7 @@ export default class CreateModal extends Component {
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label'>Nom du transporteur</label>
+ <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company_name')}</label>
<CompanySelect2
company = {this.props.modal.modalProps.vehicleJourney && this.props.modal.modalProps.vehicleJourney.company || undefined}
onSelect2Company = {(e) => this.props.onSelect2Company(e)}
@@ -72,7 +78,7 @@ export default class CreateModal extends Component {
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label is-required'>Nom public de la mission</label>
+ <label className='control-label is-required'>{I18n.attribute_name('vehicle_journey', 'journey_pattern_published_name')}</label>
<MissionSelect2
selection={this.props.modal.modalProps}
onSelect2JourneyPattern={this.props.onSelect2JourneyPattern}
@@ -83,7 +89,7 @@ export default class CreateModal extends Component {
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label'>Numéro de train</label>
+ <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'published_journey_identifier')}</label>
<input
type='text'
ref='published_journey_identifier'
@@ -99,7 +105,7 @@ export default class CreateModal extends Component {
/>
{ this.props.modal.modalProps.selectedJPModal && this.props.modal.modalProps.selectedJPModal.full_schedule && <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label'>Heure de départ</label>
+ <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'start_time')}</label>
<div className='input-group time'>
<input
type='number'
@@ -136,14 +142,14 @@ export default class CreateModal extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</form>
diff --git a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js
index 4815003d3..b1ce3786b 100644
--- a/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/tools/DeleteVehicleJourneys.js
@@ -13,7 +13,7 @@ export default function DeleteVehicleJourneys({onDeleteVehicleJourneys, vehicleJ
e.preventDefault()
onDeleteVehicleJourneys()
}}
- title='Supprimer'
+ title={ I18n.t('actions.delete') }
>
<span className='fa fa-trash'></span>
</button>
diff --git a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
index 102a87d85..d7e48bf08 100644
--- a/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
@@ -93,7 +93,7 @@ export default class DuplicateVehicleJourney extends Component {
<div className='modal-content'>
<div className='modal-header'>
<h4 className='modal-title'>
- Dupliquer { actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'plusieurs courses' : 'une course' }
+ {I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate', { count: actions.getSelected(this.props.vehicleJourneys).length })}
</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -102,7 +102,7 @@ export default class DuplicateVehicleJourney extends Component {
<form className='form-horizontal'>
<div className='modal-body'>
<div className={'form-group ' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? 'hidden' : '' )}>
- <label className='control-label is-required col-sm-8'>Horaire de départ indicatif</label>
+ <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.start_time')}</label>
<span className="col-sm-4">
<span className={'input-group time' + (actions.getSelected(this.props.vehicleJourneys).length > 1 ? ' disabled' : '')}>
<input
@@ -133,7 +133,7 @@ export default class DuplicateVehicleJourney extends Component {
</div>
<div className='form-group'>
- <label className='control-label is-required col-sm-8'>Nombre de courses à créer et dupliquer</label>
+ <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.number')}</label>
<div className="col-sm-4">
<input
type='number'
@@ -152,7 +152,7 @@ export default class DuplicateVehicleJourney extends Component {
</div>
<div className='form-group'>
- <label className='control-label is-required col-sm-8'>Décalage à partir duquel on créé les courses</label>
+ <label className='control-label is-required col-sm-8'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.duplicate.delta')}</label>
<span className="col-sm-4">
<input
type='number'
@@ -178,7 +178,7 @@ export default class DuplicateVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className={'btn btn-primary ' + (this.state.additional_time == 0 && this.state.originalDT.hour == this.state.duplicate_time_hh && this.state.originalDT.minute == this.state.duplicate_time_mm ? 'disabled' : '')}
@@ -186,7 +186,7 @@ export default class DuplicateVehicleJourney extends Component {
onClick={this.handleSubmit}
disabled={this.disableValidateButton()}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</form>
diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
index d3c01f154..60d982845 100644
--- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -2,7 +2,7 @@ import React, { Component } from 'react'
import PropTypes from 'prop-types'
import actions from '../../actions'
import CompanySelect2 from './select2s/CompanySelect2'
-import CustomFieldsInputs from './CustomFieldsInputs'
+import CustomFieldsInputs from '../../../helpers/CustomFieldsInputs'
export default class EditVehicleJourney extends Component {
constructor(props) {
@@ -96,7 +96,7 @@ export default class EditVehicleJourney extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
<div className='form-group'>
- <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company')}</label>
+ <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'published_journey_identifier')}</label>
<input
type='text'
ref='published_journey_identifier'
@@ -173,14 +173,14 @@ export default class EditVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
}
diff --git a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js
index 880542216..ef58916f4 100644
--- a/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/NotesEditVehicleJourney.js
@@ -31,23 +31,23 @@ export default class NotesEditVehicleJourney extends Component {
type='button'
className='btn btn-outline-danger btn-xs'
onClick={() => this.props.onToggleFootnoteModal(lf, false)}
- ><span className="fa fa-trash"></span> Retirer</button>
+ ><span className="fa fa-trash"></span>{I18n.t('actions.remove')}</button>
} else {
return <button
type='button'
className='btn btn-outline-primary btn-xs'
onClick={() => this.props.onToggleFootnoteModal(lf, true)}
- ><span className="fa fa-plus"></span> Ajouter</button>
+ ><span className="fa fa-plus"></span>{I18n.t('actions.add')}</button>
}
}
renderAssociatedFN() {
if (this.footnotes().associated.length == 0) {
- return <h3>Aucune note associée</h3>
+ return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_footnotes')}</h3>
} else {
return (
<div>
- <h3>Notes associées :</h3>
+ <h3>{I18n.t('vehicle_journeys.form.purchase_windows')} :</h3>
{this.footnotes().associated.map((lf, i) =>
<div
key={i}
@@ -68,13 +68,13 @@ export default class NotesEditVehicleJourney extends Component {
}
renderToAssociateFN() {
- if (window.line_footnotes.length == 0) return <h3>La ligne ne possède pas de notes</h3>
+ if (window.line_footnotes.length == 0) return <h3>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_line_footnotes')}</h3>
if (this.footnotes().to_associate.length == 0) return false
return (
<div>
- <h3 className='mt-lg'>Sélectionnez les notes à associer à cette course :</h3>
+ <h3 className='mt-lg'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.select_footnotes')} :</h3>
{this.footnotes().to_associate.map((lf, i) =>
<div key={i} className='panel panel-default'>
<div className='panel-heading'>
@@ -111,7 +111,7 @@ export default class NotesEditVehicleJourney extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Notes</h4>
+ <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.footnotes')}</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -130,14 +130,14 @@ export default class NotesEditVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
}
diff --git a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js
index ce9a4cde9..5fc925f4c 100644
--- a/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/PurchaseWindowsEditVehicleJourney.js
@@ -44,7 +44,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Calendriers commerciaux associés</h4>
+ <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.purchase_windows')}</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -58,7 +58,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {
<div className='wrapper'>
<div>
<div className='form-group'>
- <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? "Aucun calendrier commercial associé" : "Calendriers commerciaux associés"}</label>
+ <label className='control-label'>{this.props.modal.modalProps.purchase_windows.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_purchase_windows') : I18n.t('vehicle_journeys.form.purchase_windows')}</label>
</div>
</div>
<div></div>
@@ -95,6 +95,7 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {
<div className='wrapper'>
<div>
<TimetableSelect2
+ placeholder={I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.purchase_window')}
onSelect2Timetable={this.props.onSelect2Timetable}
chunkURL={'/autocomplete_purchase_windows.json'}
searchKey={"name_or_objectid_cont_any"}
@@ -117,14 +118,14 @@ export default class PurchaseWindowsEditVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
}
diff --git a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js
index 6574bfa2d..bc3d8db34 100644
--- a/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/ShiftVehicleJourney.js
@@ -27,6 +27,7 @@ export default class ShiftVehicleJourney extends Component {
}
render() {
+ let id = this.props.modal.type == 'shift' && actions.getSelected(this.props.vehicleJourneys)[0].short_id
if(this.props.status.isFetching == true) {
return false
}
@@ -48,10 +49,7 @@ export default class ShiftVehicleJourney extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Mettre à jour une course</h4>
- {(this.props.modal.type == 'shift') && (
- <em>Mettre à jour les horaires de la course {actions.getSelected(this.props.vehicleJourneys)[0].short_id}</em>
- )}
+ <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.slide_title', {id: id})}</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -61,7 +59,7 @@ export default class ShiftVehicleJourney extends Component {
<div className='row'>
<div className='col-lg-4 col-lg-offset-4 col-md-4 col-md-offset-4 col-sm-4 col-sm-offset-4 col-xs-12'>
<div className='form-group'>
- <label className='control-label is-required'>Avec un décalage de</label>
+ <label className='control-label is-required'>{I18n.t('vehicle_journeys.form.slide_delta')}</label>
<input
type='number'
style={{'width': 104}}
@@ -85,14 +83,14 @@ export default class ShiftVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className={'btn btn-primary ' + (this.state.additional_time == 0 ? 'disabled' : '')}
type='button'
onClick={this.handleSubmit.bind(this)}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
</form>
diff --git a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
index f21480563..594140c76 100644
--- a/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
@@ -44,7 +44,7 @@ export default class TimetablesEditVehicleJourney extends Component {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>Calendriers associés</h4>
+ <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.time_tables')}</h4>
<span type="button" className="close modal-close" data-dismiss="modal">&times;</span>
</div>
@@ -58,7 +58,7 @@ export default class TimetablesEditVehicleJourney extends Component {
<div className='wrapper'>
<div>
<div className='form-group'>
- <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? "Aucun calendrier associé" : "Calendriers associés"}</label>
+ <label className='control-label'>{this.props.modal.modalProps.timetables.length == 0 ? I18n.t('vehicle_journeys.vehicle_journeys_matrix.no_associated_timetables'): I18n.t('vehicle_journeys.form.time_tables')}</label>
</div>
</div>
<div></div>
@@ -97,6 +97,7 @@ export default class TimetablesEditVehicleJourney extends Component {
<div className='wrapper'>
<div>
<TimetableSelect2
+ placeholder={I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.timetable')}
onSelect2Timetable={this.props.onSelect2Timetable}
chunkURL={'/autocomplete_time_tables.json'}
searchKey={"unaccented_comment_or_objectid_cont_any"}
@@ -119,14 +120,14 @@ export default class TimetablesEditVehicleJourney extends Component {
type='button'
onClick={this.props.onModalClose}
>
- Annuler
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
type='button'
onClick={this.handleSubmit}
>
- Valider
+ {I18n.t('actions.submit')}
</button>
</div>
}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
index 5c7f75d99..60ad439b8 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/CompanySelect2.js
@@ -16,6 +16,7 @@ export default class BSelect4 extends Component {
}
render() {
+ let placeHolder = I18n.t('')
return (
<Select2
data={(this.props.company) ? [this.props.company.name] : undefined}
@@ -29,8 +30,8 @@ export default class BSelect4 extends Component {
allowClear: true,
theme: 'bootstrap',
width: '100%',
- placeholder: 'Filtrer par transporteur...',
- language: require('./fr'),
+ placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.affect_company'),
+ language: require('./language'),
ajax: {
url: origin + path + '/companies.json' + '?line_id=' + line,
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
index 72dbd0152..cec39ab4e 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/MissionSelect2.js
@@ -74,8 +74,8 @@ export default class BSelect4 extends Component {
width: '100%',
escapeMarkup: function (markup) { return markup; },
templateResult: formatRepo,
- placeholder: 'Filtrer par code, nom ou OID de mission...',
- language: require('./fr'),
+ placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.journey_pattern'),
+ language: require('./language'),
allowClear: false,
escapeMarkup: function (markup) { return markup; },
}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
index 0339455ca..919853a71 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/TimetableSelect2.js
@@ -26,8 +26,8 @@ export default class BSelect4 extends Component {
allowClear: false,
theme: 'bootstrap',
width: '100%',
- placeholder: 'Filtrer par calendrier...',
- language: require('./fr'),
+ placeholder: this.props.placeholder,
+ language: require('./language'),
ajax: {
url: origin + path + this.props.chunkURL,
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
index ccb4c9595..50a941b6d 100644
--- a/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/VJSelect2.js
@@ -25,9 +25,9 @@ export default class BSelect4b extends Component {
options={{
allowClear: false,
theme: 'bootstrap',
- placeholder: 'Filtrer par ID course...',
+ placeholder: I18n.t('vehicle_journeys.vehicle_journeys_matrix.filters.id'),
width: '100%',
- language: require('./fr'),
+ language: require('./language'),
ajax: {
url: origin + path + '/vehicle_journeys.json',
dataType: 'json',
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/fr.js b/app/javascript/vehicle_journeys/components/tools/select2s/fr.js
deleted file mode 100644
index 20154d412..000000000
--- a/app/javascript/vehicle_journeys/components/tools/select2s/fr.js
+++ /dev/null
@@ -1,9 +0,0 @@
-module.exports = {
- errorLoading:function(){return"Les résultats ne peuvent pas être chargés."},
- inputTooLong:function(e){var t=e.input.length-e.maximum,n="Supprimez "+t+" caractère";return t!==1&&(n+="s"),n},
- inputTooShort:function(e){var t=e.minimum-e.input.length,n="Saisissez "+t+" caractère";return t!==1&&(n+="s"),n},
- loadingMore:function(){return"Chargement de résultats supplémentaires…"},
- maximumSelected:function(e){var t="Vous pouvez seulement sélectionner "+e.maximum+" élément";return e.maximum!==1&&(t+="s"),t},
- noResults:function(){return"Aucun résultat trouvé"},
- searching:function(){return"Recherche en cours…"}
-}
diff --git a/app/javascript/vehicle_journeys/components/tools/select2s/language.js b/app/javascript/vehicle_journeys/components/tools/select2s/language.js
new file mode 100644
index 000000000..9d587f96e
--- /dev/null
+++ b/app/javascript/vehicle_journeys/components/tools/select2s/language.js
@@ -0,0 +1,9 @@
+module.exports = {
+ errorLoading: () => I18n.t('select2.error_loading'),
+ inputTooLong: (e) => I18n.t('select2.input_too_short', { count: e.input.length - e.maximum}),
+ inputTooShort: (e) => I18n.t('select2.input_too_long', { count: e.minimum - e.input.length }),
+ loadingMore: () => I18n.t('select2.loading_more'),
+ maximumSelected: (e) => I18n.t('select2.maximum_selected', {count: e.maximum}),
+ noResults: () => I18n.t('select2.no_results'),
+ searching: () => I18n.t('select2.searching')
+}
diff --git a/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js b/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
index 76d1c3a78..f21e2c87e 100644
--- a/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
+++ b/app/javascript/vehicle_journeys/containers/VehicleJourneysList.js
@@ -10,7 +10,9 @@ const mapStateToProps = (state) => {
status: state.status,
filters: state.filters,
stopPointsList: state.stopPointsList,
- returnStopPointsList: state.returnStopPointsList
+ returnStopPointsList: state.returnStopPointsList,
+ extraHeaders: window.extra_headers,
+ customFields: window.custom_fields,
}
}
@@ -20,8 +22,8 @@ const mapDispatchToProps = (dispatch) => {
dispatch(actions.fetchingApi())
actions.fetchVehicleJourneys(dispatch, undefined, undefined, filters.queryString, routeUrl)
},
- onUpdateTime: (e, subIndex, index, timeUnit, isDeparture, isArrivalsToggled) => {
- dispatch(actions.updateTime(e.target.value, subIndex, index, timeUnit, isDeparture, isArrivalsToggled))
+ onUpdateTime: (e, subIndex, index, timeUnit, isDeparture, isArrivalsToggled, enforceConsistency=false) => {
+ dispatch(actions.updateTime(e.target.value, subIndex, index, timeUnit, isDeparture, isArrivalsToggled, enforceConsistency))
},
onSelectVehicleJourney: (index) => {
dispatch(actions.selectVehicleJourney(index))
diff --git a/app/javascript/vehicle_journeys/reducers/modal.js b/app/javascript/vehicle_journeys/reducers/modal.js
index bcfc6ea0b..84567ec0d 100644
--- a/app/javascript/vehicle_journeys/reducers/modal.js
+++ b/app/javascript/vehicle_journeys/reducers/modal.js
@@ -164,7 +164,9 @@ export default function modal(state = {}, action) {
confirmModal: {}
}
case 'SELECT_JP_CREATE_MODAL':
- newModalProps = _.assign({}, state.modalProps, {selectedJPModal : action.selectedItem})
+ let selected = action.selectedItem
+ delete selected["element"]
+ newModalProps = _.assign({}, state.modalProps, {selectedJPModal : selected})
return _.assign({}, state, {modalProps: newModalProps})
case 'SHIFT_VEHICLEJOURNEY_MODAL':
return {
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index 8705b3cf2..b02c19a69 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -9,32 +9,35 @@ const vehicleJourney= (state = {}, action, keep) => {
return _.assign({}, state, {selected: false})
case 'ADD_VEHICLEJOURNEY':
let pristineVjasList = []
- let prevSp = action.stopPointsList[0]
+ let prevSp
let current_time = {
hour: 0,
minute: 0
}
let computeSchedule = false
- let userTZOffet = 0
+ let initTZOffet = 0
if(action.data["start_time.hour"] && action.data["start_time.hour"].value && action.data["start_time.hour"].value.length > 0 && action.data["start_time.minute"] && action.selectedJourneyPattern.full_schedule && action.selectedJourneyPattern.costs){
computeSchedule = true
- userTZOffet = action.data["tz_offset"] && parseInt(action.data["tz_offset"].value) || 0
- current_time.hour = parseInt(action.data["start_time.hour"].value) + parseInt(userTZOffet / 60)
+ initTZOffet = - action.stopPointsList[0].time_zone_offset / 60 || 0
+ current_time.hour = parseInt(action.data["start_time.hour"].value) + parseInt(initTZOffet / 60)
current_time.minute = 0
if(action.data["start_time.minute"].value){
- current_time.minute = parseInt(action.data["start_time.minute"].value) + (userTZOffet - 60 * parseInt(userTZOffet / 60))
+ current_time.minute = parseInt(action.data["start_time.minute"].value) + (initTZOffet - 60 * parseInt(initTZOffet / 60))
}
}
_.each(action.stopPointsList, (sp) =>{
let inJourney = false
let newVjas
if(computeSchedule){
- if(action.selectedJourneyPattern.costs[prevSp.stop_area_id + "-" + sp.stop_area_id]){
+ if(prevSp && action.selectedJourneyPattern.costs[prevSp.stop_area_id + "-" + sp.stop_area_id]){
let delta = parseInt(action.selectedJourneyPattern.costs[prevSp.stop_area_id + "-" + sp.stop_area_id].time)
current_time = actions.addMinutesToTime(current_time, delta)
prevSp = sp
inJourney = true
}
+ if(!prevSp){
+ prevSp = sp
+ }
let offsetHours = sp.time_zone_offset / 3600
let offsetminutes = sp.time_zone_offset/60 - 60*offsetHours
newVjas = {
@@ -90,6 +93,11 @@ const vehicleJourney= (state = {}, action, keep) => {
}
})
+ let lastStop = action.selectedJourneyPattern.stop_areas && action.selectedJourneyPattern.stop_areas[action.selectedJourneyPattern.stop_areas.length - 1]
+ if(lastStop && lastStop.stop_area_short_description.id == sp.id){
+ newVjas.departure_time = newVjas.arrival_time
+ }
+
if(newVjas.dummy){
newVjas.departure_time = {hour: "00", minute: "00"}
newVjas.arrival_time = {hour: "00", minute: "00"}
@@ -148,11 +156,11 @@ const vehicleJourney= (state = {}, action, keep) => {
newSchedule.departure_time[action.timeUnit] = actions.pad(action.val, action.timeUnit)
if(!action.isArrivalsToggled)
newSchedule.arrival_time[action.timeUnit] = newSchedule.departure_time[action.timeUnit]
- newSchedule = actions.adjustSchedule(action, newSchedule)
+ newSchedule = actions.adjustSchedule(action, newSchedule, action.enforceConsistency)
return _.assign({}, state.vehicle_journey_at_stops[action.subIndex], {arrival_time: newSchedule.arrival_time, departure_time: newSchedule.departure_time, delta: newSchedule.delta})
}else{
newSchedule.arrival_time[action.timeUnit] = actions.pad(action.val, action.timeUnit)
- newSchedule = actions.adjustSchedule(action, newSchedule)
+ newSchedule = actions.adjustSchedule(action, newSchedule, action.enforceConsistency)
return _.assign({}, state.vehicle_journey_at_stops[action.subIndex], {arrival_time: newSchedule.arrival_time, departure_time: newSchedule.departure_time, delta: newSchedule.delta})
}
}else{