diff options
| author | RobertDober | 2017-04-06 19:00:24 +0200 |
|---|---|---|
| committer | RobertDober | 2017-04-07 07:07:26 +0200 |
| commit | dc515f5eda324baae5a9583f1be433ac7dcd2915 (patch) | |
| tree | 850f26f59c5f9420bd3a1ed32179c6e5e20676e2 | |
| parent | 2a682f54f583a985809ba9ba1e33a1608f9f63b0 (diff) | |
| parent | 7ac766fb016108429730248f1a8bfd5065e8c31b (diff) | |
| download | chouette-core-dc515f5eda324baae5a9583f1be433ac7dcd2915.tar.bz2 | |
db:schema:dump
158 files changed, 1415 insertions, 1002 deletions
@@ -160,6 +160,7 @@ end group :test, :development, :dev do gem 'fabrication', '~> 2.14.1' gem 'ffaker', '~> 2.1.0' + gem 'faker' end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index 67aa8c87c..1ed5de7ae 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -202,6 +202,8 @@ GEM factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) + faker (1.7.3) + i18n (~> 0.5) fakeweb (1.3.0) faraday (0.9.1) multipart-post (>= 1.2, < 3) @@ -606,6 +608,7 @@ DEPENDENCIES enumerize (~> 0.10.0) fabrication (~> 2.14.1) factory_girl_rails (~> 4.0) + faker fakeweb faraday (~> 0.9.1) faraday_middleware (~> 0.9.1) diff --git a/app/assets/fonts/sBoiv/sboiv.eot b/app/assets/fonts/sBoiv/sboiv.eot Binary files differindex f3df36d9a..0bc305533 100644 --- a/app/assets/fonts/sBoiv/sboiv.eot +++ b/app/assets/fonts/sBoiv/sboiv.eot diff --git a/app/assets/fonts/sBoiv/sboiv.svg b/app/assets/fonts/sBoiv/sboiv.svg index c506dee04..018422b09 100644 --- a/app/assets/fonts/sBoiv/sboiv.svg +++ b/app/assets/fonts/sBoiv/sboiv.svg @@ -8,5 +8,7 @@ <missing-glyph horiz-adv-x="1024" /> <glyph unicode=" " horiz-adv-x="512" d="" /> <glyph unicode="" glyph-name="update-vj" d="M1017.856 448c0 266.935-216.393 483.328-483.328 483.328v-99.84c211.677-0.291 383.197-171.81 383.488-383.46zM918.016 448c0-0.071 0-0.154 0-0.238 0-211.795-171.693-383.488-383.488-383.488-187.627 0-343.782 134.745-376.977 312.746l-102.767 2.371c29.828-240.928 233.283-425.583 479.866-425.583 266.935 0 483.328 216.393 483.328 483.328 0 3.82-0.044 7.629-0.132 11.427zM534.528 755.2c169.662 0 307.2-137.538 307.2-307.2h-307.2zM460.8 669.184c-0.283-17.134-14.098-30.949-31.205-31.232h-136.731v-136.192c0.003-0.152 0.004-0.332 0.004-0.512 0-17.249-13.983-31.232-31.232-31.232-0.001 0-0.003 0-0.004 0h-62.976c-17.31 0.288-31.232 14.388-31.232 31.74 0 0.001 0 0.003 0 0.004v136.192h-136.192c-17.249 0-31.232 13.983-31.232 31.232v62.976c0 17.249 13.983 31.232 31.232 31.232h136.192v136.704c0.283 17.134 14.098 30.949 31.205 31.232h63.003c17.249 0 31.232-13.983 31.232-31.232v-136.704h136.192c0.001 0 0.003 0 0.004 0 17.352 0 31.452-13.922 31.74-31.205z" /> -<glyph unicode="" glyph-name="chrono" horiz-adv-x="931" d="M440.957-64c243.751 0 440.957 196.267 440.957 438.857 0 225.524-171.483 412.038-391.962 436.419v51.2h73.493v97.524h-244.976v-97.524h73.493v-51.2c-220.478-24.381-391.962-209.676-391.962-436.419 0-242.59 197.206-438.857 440.957-438.857zM756.974 864.917l-71.043-70.705c71.043-41.448 131.062-101.181 172.708-171.886l71.055 70.705c-44.108 69.486-104.115 128-172.72 171.886z" /> +<glyph unicode="" glyph-name="preparing" d="M1011.173 614.391l-80.38 80.38c-7.765 8.206-18.731 13.312-30.889 13.312-0.12 0-0.239 0-0.359-0.001-0.129 0.002-0.303 0.003-0.478 0.003-11.951 0-22.708-5.119-30.194-13.284l-56.856-56.347 142.328-142.84 56.829 54.781c7.9 7.644 12.802 18.341 12.802 30.183 0 0.188-0.001 0.376-0.004 0.563 0.035 0.625 0.055 1.389 0.055 2.159 0 12.137-4.911 23.128-12.854 31.092zM504.32 330.758v-142.84h142.84l285.17 285.681-142.328 142.328zM805.872 544.251l-185.847-185.847c-0.834-0.338-1.802-0.535-2.816-0.535s-1.982 0.196-2.868 0.553c-0.285-0.079-0.672-0.113-1.067-0.113-3.676 0-6.656 2.98-6.656 6.656 0 0.395 0.034 0.782 0.1 1.159-0.322 0.797-0.505 1.765-0.505 2.776s0.183 1.979 0.518 2.873l188.387 183.741c0.834 0.338 1.802 0.535 2.816 0.535s1.982-0.196 2.868-0.553c0.285 0.079 0.672 0.113 1.067 0.113 3.676 0 6.656-2.98 6.656-6.656 0-0.395-0.034-0.782-0.1-1.159-0.528-1.405-1.409-2.616-2.539-3.532zM592.38 231.948v44.030h-44.030v36.862l31.23 31.23 80.38-80.38-31.23-31.23zM0.028 239.627h416.234v-51.197h-416.234v51.197z" /> +<glyph unicode="" glyph-name="current-ref" d="M530.92 258.291l-70.054 71.588c-17.993 18.204-42.963 29.478-70.566 29.478s-52.573-11.274-70.557-29.468l-30.178 30.159c18.419 18.312 29.902 43.583 30.169 71.537-0.795 26.578-11.995 50.343-29.636 67.527l-70.586 71.609c-17.861 17.868-42.538 28.92-69.798 28.92s-51.937-11.052-69.798-28.92l-51.134-51.134c-17.868-17.861-28.92-42.538-28.92-69.798s11.052-51.937 28.92-69.798l74.145-69.543c17.993-18.204 42.963-29.478 70.566-29.478s52.573 11.274 70.557 29.468l30.178-30.159c-18.419-18.312-29.902-43.583-30.169-71.537-0.004-0.365-0.006-0.734-0.006-1.105 0-25.692 9.92-49.067 26.139-66.504l70.511-71.528c17.835-17.716 42.411-28.665 69.543-28.665s51.708 10.949 69.549 28.67l51.128 51.129c17.992 17.803 29.134 42.5 29.134 69.798s-11.142 51.995-29.126 69.791zM241.499 405.047c-11.25 11.25-20.965 24.545-38.351 24.545-18.074 0-32.726-14.652-32.726-32.726 0-17.386 13.295-27.101 24.545-38.351-5.924-6.606-14.486-10.742-24.015-10.742-0.186 0-0.372 0.002-0.557 0.005-0.198-0.006-0.464-0.009-0.731-0.009-8.851 0-16.88 3.513-22.771 9.221l-71.068 71.58c-5.845 5.909-9.456 14.038-9.456 23.010s3.61 17.101 9.459 23.013l51.131 51.131c6.103 5.703 14.326 9.204 23.366 9.204 0.055 0 0.11 0 0.164 0 0.003 0 0.017 0 0.031 0 9.168 0 17.47-3.712 23.483-9.716l69.543-72.1c6.338-6.063 10.278-14.588 10.278-24.033s-3.94-17.97-10.266-24.021zM493.592 188.748c-0.074-9.007-3.775-17.135-9.713-23.007l-51.137-51.137c-5.96-5.4-13.905-8.705-22.623-8.705-0.317 0-0.631 0.004-0.946 0.013-0.18-0.007-0.446-0.010-0.713-0.010-8.851 0-16.88 3.513-22.771 9.221l-69.022 72.092c-6.338 6.063-10.278 14.588-10.278 24.033s3.94 17.97 10.266 24.021c11.262-11.238 20.977-24.533 38.363-24.533 0.611-0.041 1.326-0.064 2.045-0.064 18.074 0 32.726 14.652 32.726 32.726 0 0.023 0 0.045 0 0.068 0 17.382-13.295 27.097-24.545 38.347 5.712 7.509 14.519 12.409 24.486 12.782 0.070 0.002 0.084 0.002 0.098 0.002 9.168 0 17.47-3.712 23.483-9.716l71.077-71.077c5.998-5.856 9.719-14.023 9.719-23.059 0-0.163-0.001-0.325-0.004-0.487zM1013.117 794.18l-51.134 51.134c-6.502 6.632-15.554 10.743-25.567 10.743s-19.066-4.111-25.561-10.737l-245.451-243.917-107.894 108.405c-6.502 6.632-15.554 10.743-25.567 10.743s-19.066-4.111-25.561-10.737l-51.14-51.14c-6.632-6.502-10.743-15.554-10.743-25.567s4.111-19.066 10.737-25.561l135.512-133.978 51.134-51.134c6.502-6.632 15.554-10.743 25.567-10.743s19.066 4.111 25.561 10.737l51.14 51.14 268.967 269.99c6.632 6.502 10.743 15.554 10.743 25.567s-4.111 19.066-10.737 25.561z" /> +<glyph unicode="" glyph-name="chrono" horiz-adv-x="931" d="M440.957-64c243.751 0 440.957 196.267 440.957 438.857 0 225.524-171.483 412.038-391.962 436.419v51.2h73.493v97.524h-244.976v-97.524h73.493v-51.2c-220.478-24.381-391.962-209.676-391.962-436.419 0-242.59 197.206-438.857 440.957-438.857zM756.974 864.917l-71.043-70.705c71.043-41.448 131.062-101.181 172.708-171.886l71.055 70.705c-44.108 69.486-104.115 128-172.72 171.886z" /> </font></defs></svg>
\ No newline at end of file diff --git a/app/assets/fonts/sBoiv/sboiv.ttf b/app/assets/fonts/sBoiv/sboiv.ttf Binary files differindex f2b70a1cf..21c79549a 100644 --- a/app/assets/fonts/sBoiv/sboiv.ttf +++ b/app/assets/fonts/sBoiv/sboiv.ttf diff --git a/app/assets/fonts/sBoiv/sboiv.woff b/app/assets/fonts/sBoiv/sboiv.woff Binary files differindex 8ede810d8..fa2e097d7 100644 --- a/app/assets/fonts/sBoiv/sboiv.woff +++ b/app/assets/fonts/sBoiv/sboiv.woff diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 3bce3ec7d..b90f7539d 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -21,3 +21,5 @@ //= require footable/footable.sort //= require_directory ./plugins //= require_directory . +require('whatwg-fetch') +require('babel-polyfill') diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js index 81bf2dcbe..dae62d3e1 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var React = require('react') var PropTypes = require('react').PropTypes var Select2 = require('react-select2') @@ -27,6 +28,23 @@ class BSelect3 extends React.Component{ }) } + parsedText(data) { + let a = data.replace('</em></small>', '') + let b = a.split('<small><em>') + if (b.length > 1) { + return ( + <span> + {b[0]} + <small><em>{b[1]}</em></small> + </span> + ) + } else { + return ( + <span>{data}</span> + ) + } + } + render() { if(this.props.value.edit) return ( @@ -48,7 +66,7 @@ class BSelect3 extends React.Component{ href={origin + path + '/stop_areas/' + this.props.value.stoparea_id} title="Voir l'arrêt" > - {this.props.value.text} + {this.parsedText(this.props.value.text)} </a> ) } @@ -84,7 +102,7 @@ class BSelect2 extends React.Component{ processResults: function(data, params) { return { results: data.map( - item => Object.assign( + item => _.assign( {}, item, { text: item.name + ", " + item.zip_code + " " + item.short_city_name + " <small><em>(" + item.user_objectid + ")</em></small>" } diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js b/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js index 76142b0e1..0eca5f3ff 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var React = require('react') var Component = require('react').Component var PropTypes = require('react').PropTypes @@ -96,7 +97,7 @@ class OlMap extends Component{ return false } } - let data = Object.assign({}, e.selected[0].getProperties(), {geometry: undefined}); + let data = _.assign({}, e.selected[0].getProperties(), {geometry: undefined}); this.props.onSelectMarker(this.props.index, data) } else { diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js b/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js index de95759e1..48f77b8e9 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js @@ -7,7 +7,9 @@ const StopPoint = (props) => { return ( <div className='nested-fields'> <div className='wrapper'> - <div style={{width: 90}}>{props.value.user_objectid}</div> + <div style={{width: 90}}> + <span>{props.value.user_objectid}</span> + </div> <div> <BSelect2 id={'route_stop_points_' + props.id} value={props.value} onChange={props.onChange} index={props.index} /> @@ -47,12 +49,12 @@ const StopPoint = (props) => { > <span className='fa fa-arrow-down'></span> </div> - + <div className='btn btn-link' onClick={props.onToggleEdit} > - <span className={'fa' + (props.value.edit ? ' fa-undo' : ' fa-pencil')}></span> + <span className={'fa' + (props.value.edit ? ' fa-check' : ' fa-pencil')}></span> </div> <div className='btn btn-link' diff --git a/app/assets/javascripts/es6_browserified/itineraries/form_helper.js b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js index d48718841..0baba27ef 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/form_helper.js +++ b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js @@ -1,8 +1,9 @@ const addInput = (name, value, index) => { let form = document.querySelector('form') let input = document.createElement('input') + let formatedName = 'route[stop_points_attributes]['+ index.toString()+']['+name+']' input.setAttribute('type', 'hidden') - input.setAttribute('name', `route[stop_points_attributes][${index}][${name}]`) + input.setAttribute('name', formatedName) input.setAttribute('value', value) form.appendChild(input) } diff --git a/app/assets/javascripts/es6_browserified/itineraries/index.js b/app/assets/javascripts/es6_browserified/itineraries/index.js index e4a28ab49..57c63a97b 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/index.js @@ -17,21 +17,21 @@ const getInitialState = () => { let datas = JSON.parse(decodeURIComponent(window.itinerary_stop)) datas.map(function(v, i) { - let fancyText = v.name + let fancyText = v.name.replace("'", "\'") if(v.zip_code && v.city_name) - fancyText += ", " + v.zip_code + " " + v.city_name + fancyText += ", " + v.zip_code + " " + v.city_name.replace("'", "\'") state.push({ stoppoint_id: v.stoppoint_id, stoparea_id: v.stoparea_id, user_objectid: v.user_objectid, - short_name: v.short_name, + short_name: v.short_name.replace("'", "\'"), area_type: v.area_type, index: i, edit: false, - city_name: v.city_name, + city_name: v.city_name.replace("'", "\'"), zip_code: v.zip_code, - name: v.name, + name: v.name.replace("'", "\'"), registration_number: v.registration_number, text: fancyText, for_boarding: v.for_boarding || "normal", @@ -65,7 +65,7 @@ render( document.querySelector('input[name=commit]').addEventListener('click', (event)=>{ let state = store.getState() - for (let [i, stopPoint] of state.stopPoints.entries()){ + state.stopPoints.map((stopPoint, i) => { if (stopPoint.stoppoint_id == undefined){ stopPoint.stoppoint_id = "" } @@ -74,5 +74,5 @@ document.querySelector('input[name=commit]').addEventListener('click', (event)=> addInput('position',i, i) addInput('for_boarding',stopPoint.for_boarding, i) addInput('for_alighting',stopPoint.for_alighting, i) - } + }) }) diff --git a/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js b/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js index 6fc5c165f..79b9648a6 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js +++ b/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var addInput = require('../form_helper') const stopPoint = (state = {}, action, length) => { @@ -60,7 +61,7 @@ const stopPoints = (state = [], action) => { return state.map( (t, i) => { if (i === action.index) { updateFormForDeletion(t) - return Object.assign( + return _.assign( {}, t, { @@ -84,7 +85,7 @@ const stopPoints = (state = [], action) => { case 'UPDATE_SELECT_VALUE': return state.map( (t, i) => { if (i === action.index) { - let stopState = Object.assign({}, t) + let stopState = _.assign({}, t) stopState[action.select_id] = action.select_value return stopState } else { @@ -94,7 +95,7 @@ const stopPoints = (state = [], action) => { case 'TOGGLE_EDIT': return state.map((t, i) => { if (i === action.index){ - return Object.assign({}, t, {edit: !t.edit}) + return _.assign({}, t, {edit: !t.edit}) } else { return t } @@ -103,19 +104,19 @@ const stopPoints = (state = [], action) => { return state.map( (t, i) => { if (i === action.index){ let val = !t.olMap.isOpened - let jsonData = val ? Object.assign({}, t, {olMap: undefined}) : {} - let stateMap = Object.assign({}, t.olMap, {isOpened: val, json: jsonData}) - return Object.assign({}, t, {olMap: stateMap}) + let jsonData = val ? _.assign({}, t, {olMap: undefined}) : {} + let stateMap = _.assign({}, t.olMap, {isOpened: val, json: jsonData}) + return _.assign({}, t, {olMap: stateMap}) }else { - let emptyMap = Object.assign({}, t.olMap, {isOpened: false, json : {}}) - return Object.assign({}, t, {olMap: emptyMap}) + let emptyMap = _.assign({}, t.olMap, {isOpened: false, json : {}}) + return _.assign({}, t, {olMap: emptyMap}) } }) case 'SELECT_MARKER': return state.map((t, i) => { if (i === action.index){ - let stateMap = Object.assign({}, t.olMap, {json: action.data}) - return Object.assign({}, t, {olMap: stateMap}) + let stateMap = _.assign({}, t.olMap, {json: action.data}) + return _.assign({}, t, {olMap: stateMap}) } else { return t } @@ -123,16 +124,16 @@ const stopPoints = (state = [], action) => { case 'UNSELECT_MARKER': return state.map((t, i) => { if (i === action.index){ - let stateMap = Object.assign({}, t.olMap, {json: {}}) - return Object.assign({}, t, {olMap: stateMap}) + let stateMap = _.assign({}, t.olMap, {json: {}}) + return _.assign({}, t, {olMap: stateMap}) } else { return t } }) case 'CLOSE_MAP': return state.map( (t, i) => { - let emptyMap = Object.assign({}, t.olMap, {isOpened: false, json: {}}) - return Object.assign({}, t, {olMap: emptyMap}) + let emptyMap = _.assign({}, t.olMap, {isOpened: false, json: {}}) + return _.assign({}, t, {olMap: emptyMap}) }) default: return state diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js index a31f89841..709686f21 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js @@ -1,3 +1,10 @@ +var Promise = require('promise-polyfill') + +// To add to window +if (!window.Promise) { + window.Promise = Promise; +} + const actions = { receiveJourneyPatterns : (json) => ({ type: "RECEIVE_JOURNEY_PATTERNS", @@ -101,7 +108,8 @@ const actions = { submitJourneyPattern : (dispatch, state, next) => { dispatch(actions.fetchingApi()) let urlJSON = window.location.pathname + ".json" - let req = new Request(urlJSON, { + let hasError = false + fetch(urlJSON, { credentials: 'same-origin', method: 'PATCH', contentType: 'application/json; charset=utf-8', @@ -110,10 +118,7 @@ const actions = { headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } - }) - let hasError = false - fetch(req) - .then(response => { + }).then(response => { if(!response.ok) { hasError = true } @@ -158,12 +163,10 @@ const actions = { str = '.json?page=' + page.toString() } let urlJSON = window.location.pathname + str - let req = new Request(urlJSON, { - credentials: 'same-origin', - }) let hasError = false - fetch(req) - .then(response => { + fetch(urlJSON, { + credentials: 'same-origin', + }).then(response => { if(response.status == 500) { hasError = true } diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js index 573ebf228..aa2d208df 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/CreateModal.js @@ -17,7 +17,7 @@ class CreateModal extends Component { } render() { - if(this.props.status.isFetching == true) { + if(this.props.status.isFetching == true || this.props.status.policy['journey_patterns.edit'] == false) { return false } if(this.props.status.fetchSuccess == true) { diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js index 3dae38d74..d9f6d5550 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js @@ -14,7 +14,7 @@ class JourneyPattern extends Component{ let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid return ( - <a href={vjURL}>Horaires des courses</a> + <a data-no-turbolink="true" href={vjURL}>Horaires des courses</a> ) } @@ -34,7 +34,7 @@ class JourneyPattern extends Component{ type='checkbox' id={sp.id} checked={sp.checked} - disabled={this.props.value.deletable ? 'disabled' : ''} + disabled={(this.props.value.deletable || this.props.status.policy['journey_patterns.edit'] == false) ? 'disabled' : ''} > </input> <span className='radio-label'></span> @@ -74,29 +74,30 @@ class JourneyPattern extends Component{ <span className='fa fa-cog'></span> </div> <ul className='dropdown-menu'> - <li className={this.props.value.deletable ? 'disabled' : ''}> - <a - href='#' + <li className={(this.props.value.deletable || this.props.status.policy['journey_patterns.edit'] == false) ? 'disabled' : ''}> + <button + type='button' onClick={this.props.onOpenEditModal} data-toggle='modal' data-target='#JourneyPatternModal' > Editer - </a> + </button> </li> <li className={this.props.value.object_id ? '' : 'disabled'}> {this.vehicleJourneyURL(this.props.value.object_id)} </li> - <li className='delete-action'> - <a - href='#' + <li className={'delete-action' + ((this.props.status.policy['journey_patterns.edit'] == false)? ' disabled' : '')}> + <button + type='button' + disabled={(this.props.status.policy['journey_patterns.edit'] == false)? 'disabled' : ''} onClick={(e) => { e.preventDefault() this.props.onDeleteJourneyPattern(this.props.index)} } > - <span className='fa fa-trash'></span>Supprimer - </a> + <span className='fa fa-trash'></span>Supprimer + </button> </li> </ul> </div> diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js index 37a0a5126..e0557d651 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPatterns.js @@ -116,6 +116,7 @@ class JourneyPatterns extends Component{ onCheckboxChange= {(e) => this.props.onCheckboxChange(e, index)} onOpenEditModal= {() => this.props.onOpenEditModal(index, journeyPattern)} onDeleteJourneyPattern={() => this.props.onDeleteJourneyPattern(index)} + status= {this.props.status} /> )} </div> diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js index 839d8f72e..3ca860e2e 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js @@ -7,7 +7,6 @@ let Navigate = ({ dispatch, journeyPatterns, pagination, status }) => { let firstPage = 1 let lastPage = Math.ceil(pagination.totalCount / window.journeyPatternsPerPage) - let ItemLength = window.journeyPatternLength let firstItemOnPage = firstPage + (pagination.perPage * (pagination.page - firstPage)) let lastItemOnPage = firstItemOnPage + (pagination.perPage - firstPage) @@ -19,7 +18,7 @@ let Navigate = ({ dispatch, journeyPatterns, pagination, status }) => { <div className='row'> <div className='col-lg-12 text-right'> <div className='pagination'> - Liste des missions {firstItemOnPage} à {(lastItemOnPage < ItemLength) ? lastItemOnPage : ItemLength} sur {ItemLength} + Liste des missions {firstItemOnPage} à {(lastItemOnPage < pagination.totalCount) ? lastItemOnPage : pagination.totalCount} sur {pagination.totalCount} <form className='page_links' onSubmit={e => { e.preventDefault() }}> diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js index 6e09430a0..93dfa8c6b 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js @@ -15,7 +15,7 @@ class SaveJourneyPattern extends Component{ } render() { - if(this.props.status.isFetching == true) { + if(this.props.status.isFetching == true || (this.props.status.policy['journey_patterns.edit'] == false)) { return false } if(this.props.status.fetchSuccess == true) { diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/index.js index a2e1c2fb6..b06957e0f 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/index.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/index.js @@ -13,6 +13,7 @@ var App = require('./components/App') var initialState = { status: { + policy: window.perms, fetchSuccess: true, isFetching: false }, diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js index 92381f018..d4f7257d7 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/journeyPatterns.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var actions = require("../actions") const journeyPattern = (state = {}, action) => { @@ -21,12 +22,12 @@ const journeyPattern = (state = {}, action) => { case 'UPDATE_CHECKBOX_VALUE': var updatedStopPoints = state.stop_points.map((s) => { if (String(s.id) == action.id) { - return Object.assign({}, s, {checked : !s.checked}) + return _.assign({}, s, {checked : !s.checked}) }else { return s } }) - return Object.assign({}, state, {stop_points: updatedStopPoints}) + return _.assign({}, state, {stop_points: updatedStopPoints}) default: return state } @@ -61,7 +62,7 @@ const journeyPatterns = (state = [], action) => { case 'DELETE_JOURNEYPATTERN': return state.map((j, i) =>{ if(i == action.index) { - return Object.assign({}, j, {deletable: true}) + return _.assign({}, j, {deletable: true}) } else { return j } @@ -74,7 +75,7 @@ const journeyPatterns = (state = [], action) => { case 'SAVE_MODAL': return state.map((j, i) =>{ if(i == action.index) { - return Object.assign({}, j, { + return _.assign({}, j, { name: action.data.name.value, published_name: action.data.published_name.value, registration_number: action.data.registration_number.value diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js index cb274d767..86cfb5a25 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/modal.js @@ -1,8 +1,9 @@ +var _ = require('lodash') const modal = (state = {}, action) => { switch (action.type) { case 'OPEN_CONFIRM_MODAL': $('#ConfirmModal').modal('show') - return Object.assign({}, state, { + return _.assign({}, state, { type: 'confirm', confirmModal: { callback: action.callback, @@ -24,9 +25,9 @@ const modal = (state = {}, action) => { confirmModal: {} } case 'DELETE_JOURNEYPATTERN': - return Object.assign({}, state, { type: '' }) + return _.assign({}, state, { type: '' }) case 'SAVE_MODAL': - return Object.assign({}, state, { type: '' }) + return _.assign({}, state, { type: '' }) case 'CLOSE_MODAL': return { type: '', diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js index 48d95fdea..0714ca843 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/pagination.js @@ -1,26 +1,27 @@ +var _ = require('lodash') const pagination = (state = {}, action) => { switch (action.type) { case 'RECEIVE_JOURNEY_PATTERNS': - return Object.assign({}, state, {stateChanged: false}) + return _.assign({}, state, {stateChanged: false}) case 'GO_TO_PREVIOUS_PAGE': if (action.pagination.page > 1){ toggleOnConfirmModal() - return Object.assign({}, state, {page : action.pagination.page - 1, stateChanged: false}) + return _.assign({}, state, {page : action.pagination.page - 1, stateChanged: false}) } return state case 'GO_TO_NEXT_PAGE': if (state.totalCount - (action.pagination.page * action.pagination.perPage) > 0){ toggleOnConfirmModal() - return Object.assign({}, state, {page : action.pagination.page + 1, stateChanged: false}) + return _.assign({}, state, {page : action.pagination.page + 1, stateChanged: false}) } return state case 'UPDATE_CHECKBOX_VALUE': case 'ADD_JOURNEYPATTERN': case 'SAVE_MODAL': toggleOnConfirmModal('modal') - return Object.assign({}, state, {stateChanged: true}) + return _.assign({}, state, {stateChanged: true}) case 'UPDATE_TOTAL_COUNT': - return Object.assign({}, state, {totalCount : state.totalCount - action.diff }) + return _.assign({}, state, {totalCount : state.totalCount - action.diff }) default: return state } diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js index 973fab0f9..6241777da 100644 --- a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js +++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js @@ -1,13 +1,14 @@ +var _ = require('lodash') var actions = require("../actions") const status = (state = {}, action) => { switch (action.type) { case 'UNAVAILABLE_SERVER': - return Object.assign({}, state, {fetchSuccess: false}) + return _.assign({}, state, {fetchSuccess: false}) case 'FETCH_API': - return Object.assign({}, state, {isFetching: true}) + return _.assign({}, state, {isFetching: true}) case 'RECEIVE_JOURNEY_PATTERNS': - return Object.assign({}, state, {fetchSuccess: true, isFetching: false}) + return _.assign({}, state, {fetchSuccess: true, isFetching: false}) default: return state } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js index 14e127d3c..9abaf9d0f 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js @@ -1,3 +1,9 @@ +var Promise = require('promise-polyfill') + +// To add to window +if (!window.Promise) { + window.Promise = Promise; +} var batchActions = require('../batch').batchActions const actions = { @@ -271,12 +277,10 @@ const actions = { if (queryString){ urlJSON = urlJSON + sep + queryString } - let req = new Request(urlJSON, { - credentials: 'same-origin', - }) let hasError = false - fetch(req) - .then(response => { + fetch(urlJSON, { + credentials: 'same-origin', + }).then(response => { if(response.status == 500) { hasError = true } @@ -322,7 +326,8 @@ const actions = { submitVehicleJourneys : (dispatch, state, next) => { dispatch(actions.fetchingApi()) let urlJSON = window.location.pathname + "_collection.json" - let req = new Request(urlJSON, { + let hasError = false + fetch(urlJSON, { credentials: 'same-origin', method: 'PATCH', contentType: 'application/json; charset=utf-8', @@ -331,10 +336,7 @@ const actions = { headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } - }) - let hasError = false - fetch(req) - .then(response => { + }).then(response => { if(!response.ok) { hasError = true } @@ -360,13 +362,29 @@ const actions = { return obj.selected }) }, - pad: (d) => { + simplePad: (d) => { if(d.toString().length == 1){ return (d < 10) ? '0' + d.toString() : d.toString(); }else{ return d.toString() } }, + pad: (d, timeUnit) => { + let val = d.toString() + if(d.toString().length == 1){ + val = (d < 10) ? '0' + d.toString() : d.toString(); + } + if(val.length > 2){ + val = val.substr(1) + } + if(timeUnit == 'minute' && parseInt(val) > 59){ + val = '59' + } + if(timeUnit == 'hour' && parseInt(val) > 23){ + val = '23' + } + return val + }, encodeParams: (params) => { let esc = encodeURIComponent let queryString = Object.keys(params).map((k) => esc(k) + '=' + esc(params[k])).join('&') @@ -388,20 +406,61 @@ const actions = { return vjas }, checkSchedules: (schedule) => { + let hours = 0 + let minutes = 0 if (parseInt(schedule.departure_time.minute) > 59){ - schedule.departure_time.minute = actions.pad(parseInt(schedule.departure_time.minute) - 60) - schedule.departure_time.hour = actions.pad(parseInt(schedule.departure_time.hour) + 1) + hours = Math.floor(parseInt(schedule.departure_time.minute) / 60) + minutes = parseInt(schedule.departure_time.minute) % 60 + schedule.departure_time.minute = actions.simplePad(minutes, 'minute') + schedule.departure_time.hour = parseInt(schedule.departure_time.hour) + hours } if (parseInt(schedule.arrival_time.minute) > 59){ - schedule.arrival_time.minute = actions.pad(parseInt(schedule.arrival_time.minute) - 60) - schedule.arrival_time.hour = actions.pad(parseInt(schedule.arrival_time.hour) + 1) + hours = Math.floor(parseInt(schedule.arrival_time.minute) / 60) + minutes = parseInt(schedule.arrival_time.minute) % 60 + schedule.arrival_time.minute = actions.simplePad(minutes, 'minute') + schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) + hours + } + if (parseInt(schedule.departure_time.minute) < 0){ + hours = Math.floor(parseInt(schedule.departure_time.minute) / 60) + minutes = (parseInt(schedule.departure_time.minute) % 60) + 60 + schedule.departure_time.minute = actions.simplePad(minutes, 'minute') + schedule.departure_time.hour = parseInt(schedule.departure_time.hour) + hours + } + if (parseInt(schedule.arrival_time.minute) < 0){ + hours = Math.floor(parseInt(schedule.arrival_time.minute) / 60) + minutes = (parseInt(schedule.arrival_time.minute) % 60) + 60 + schedule.arrival_time.minute = actions.simplePad(minutes, 'minute') + schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) + hours } - if (parseInt(schedule.departure_time.hour) > 23){ - schedule.departure_time.hour = actions.pad(parseInt(schedule.departure_time.hour) - 24) + + if(schedule.departure_time.hour > 23){ + schedule.departure_time.hour = '23' + schedule.departure_time.minute = '59' + } + if(schedule.arrival_time.hour > 23){ + schedule.arrival_time.hour = '23' + schedule.arrival_time.minute = '59' } - if (parseInt(schedule.arrival_time.hour) > 23){ - schedule.arrival_time.hour = actions.pad(parseInt(schedule.arrival_time.hour) - 24) + + if(schedule.departure_time.hour < 0){ + schedule.departure_time.hour = '00' + schedule.departure_time.minute = '00' } + if(schedule.arrival_time.hour > 23){ + schedule.arrival_time.hour = '00' + schedule.arrival_time.minute = '00' + } + + schedule.departure_time.hour = actions.simplePad(parseInt(schedule.departure_time.hour), 'hour') + schedule.arrival_time.hour = actions.simplePad(parseInt(schedule.arrival_time.hour), 'hour') + // if (parseInt(schedule.departure_time.hour) > 23){ + // schedule.departure_time.hour = parseInt(schedule.departure_time.hour) - 24 + // } + // if (parseInt(schedule.arrival_time.hour) > 23){ + // schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) - 24 + // } + // schedule.departure_time.hour = actions.pad(schedule.departure_time.hour, 'hour') + // schedule.arrival_time.hour = actions.pad(schedule.arrival_time.hour, 'hour') } } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js index b22e1d826..bd34ae114 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js @@ -15,7 +15,7 @@ class SaveVehicleJourneys extends Component{ } render() { - if(this.props.status.isFetching == true) { + if(this.props.status.isFetching == true || this.props.filters.policy['vehicle_journeys.edit'] == false) { return false } if(this.props.status.fetchSuccess == true) { @@ -46,7 +46,8 @@ class SaveVehicleJourneys extends Component{ SaveVehicleJourneys.propTypes = { vehicleJourneys: PropTypes.array.isRequired, page: PropTypes.number.isRequired, - status: PropTypes.object.isRequired + status: PropTypes.object.isRequired, + filters: PropTypes.object.isRequired } module.exports = SaveVehicleJourneys diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js index c88dda5f4..0645fdd19 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js @@ -54,31 +54,33 @@ class VehicleJourney extends Component { <div key={i}>{this.timeTableURL(tt.id)}</div> )} - <div className={(this.props.value.deletable ? 'disabled ' : '') + 'checkbox'}> - <input - id={this.props.index} - name={this.props.index} - onChange={(e) => this.props.onSelectVehicleJourney(this.props.index)} - type='checkbox' - disabled={this.props.value.deletable} - checked={this.props.value.selected} - ></input> - <label htmlFor={this.props.index}></label> - </div> - </div> + {(this.props.filters.policy['vehicle_journeys.edit'] == true) && + <div className={(this.props.value.deletable ? 'disabled ' : '') + 'checkbox'}> + <input + id={this.props.index} + name={this.props.index} + onChange={(e) => this.props.onSelectVehicleJourney(this.props.index)} + type='checkbox' + disabled={this.props.value.deletable} + checked={this.props.value.selected} + ></input> + <label htmlFor={this.props.index}></label> + </div> + } + </div> {this.props.value.vehicle_journey_at_stops.map((vj, i) => <div key={i} className='td text-center'> - <div className={'cellwrap' + (this.cityNameChecker(vj) ? ' headlined' : '')}> + <div className={'cellwrap' + (vj.dummy ? ' headlined' : '') + (this.cityNameChecker(vj) ? ' headlined' : '')}> {this.props.filters.toggleArrivals && - <div data-headline='Départ à'> - <span className={((this.props.value.deletable && (!vj.dummy)) ? 'disabled ' : '') + 'input-group time'}> + <div data-headline='Arrivée à'> + <span className={((this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false) ? 'disabled ' : '') + 'input-group time'}> <input type='number' min='00' max='23' className='form-control' - disabled={(this.props.value.deletable && (!vj.dummy))} + disabled={(this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false)} onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', false, false)}} value={vj.arrival_time['hour']} /> @@ -88,7 +90,7 @@ class VehicleJourney extends Component { min='00' max='59' className='form-control' - disabled={((this.props.value.deletable) && (!vj.dummy))} + disabled={((this.isDisabled(this.props.value.deletable), vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false)} onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'minute', false, false)}} value={vj.arrival_time['minute']} /> @@ -100,14 +102,14 @@ class VehicleJourney extends Component { <span className='sb sb-chrono sb-lg text-warning' data-textinside={vj.delta}></span> } </div> - <div data-headline='Arrivée à'> - <span className={(this.isDisabled(this.props.value.deletable, vj.dummy) ? 'disabled ' : '') + 'input-group time'}> + <div data-headline='Départ à'> + <span className={((this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false) ? 'disabled ' : '') + 'input-group time'}> <input type='number' min='00' max='23' className='form-control' - disabled={this.isDisabled(this.props.value.deletable, vj.dummy)} + disabled={(this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false)} onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, 'hour', true, this.props.filters.toggleArrivals)}} value={vj.departure_time['hour']} /> @@ -117,7 +119,7 @@ class VehicleJourney extends Component { min='00' max='59' className='form-control' - disabled={this.isDisabled(this.props.value.deletable, vj.dummy)} + disabled={(this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.edit'] == false)} onChange={(e) => {this.props.onUpdateTime(e, i, this.props.index, "minute", true, this.props.filters.toggleArrivals)}} value={vj.departure_time['minute']} /> diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CalendarsEditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CalendarsEditVehicleJourney.js index 19a5af869..e32c873e6 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CalendarsEditVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CalendarsEditVehicleJourney.js @@ -22,15 +22,15 @@ class CalendarsEditVehicleJourney extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={(actions.getSelected(this.props.vehicleJourneys).length > 0 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} + <button + type='button' + disabled={(actions.getSelected(this.props.vehicleJourneys).length > 0 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} data-toggle='modal' data-target='#CalendarsEditVehicleJourneyModal' onClick={() => this.props.onOpenCalendarsEditModal(actions.getSelected(this.props.vehicleJourneys))} > <span className='fa fa-calendar'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'duplicate') ? 'in' : '') } id='CalendarsEditVehicleJourneyModal'> <div className='modal-container'> diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js index 2150287ba..1273921e7 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js @@ -25,22 +25,22 @@ class CreateModal extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={((this.props.filters.policy['vehicle_journeys.create']) ? '' : 'disabled')} + <button + type='button' + disabled={((this.props.filters.policy['vehicle_journeys.edit'] == true) ? '' : 'disabled')} data-toggle='modal' data-target='#NewVehicleJourneyModal' onClick={this.props.onOpenCreateModal} > <span className='fa fa-plus'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'create') ? 'in' : '') } id='NewVehicleJourneyModal'> <div className='modal-container'> <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> - <h4 className='modal-title'>Ajouter une mission</h4> + <h4 className='modal-title'>Ajouter une course</h4> </div> {(this.props.modal.type == 'create') && ( diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DeleteVehicleJourneys.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DeleteVehicleJourneys.js index e2425cc22..c98b794a8 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DeleteVehicleJourneys.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DeleteVehicleJourneys.js @@ -5,9 +5,9 @@ var actions = require('../../actions') const DeleteVehicleJourneys = ({onDeleteVehicleJourneys, vehicleJourneys, filters}) => { return ( <li className='st_action'> - <a - href='#' - className={(actions.getSelected(vehicleJourneys).length > 0 && filters.policy['vehicle_journeys.destroy']) ? '' : 'disabled'} + <button + type='button' + disabled={(actions.getSelected(vehicleJourneys).length > 0 && filters.policy['vehicle_journeys.destroy']) ? '' : 'disabled'} onClick={e => { e.preventDefault() onDeleteVehicleJourneys() @@ -15,7 +15,7 @@ const DeleteVehicleJourneys = ({onDeleteVehicleJourneys, vehicleJourneys, filter title='Supprimer' > <span className='fa fa-trash'></span> - </a> + </button> </li> ) } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js index b0cb1c850..7448aa06e 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js @@ -23,15 +23,15 @@ class DuplicateVehicleJourney extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={((actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled')} + <button + type='button' + disabled={((actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled')} data-toggle='modal' data-target='#DuplicateVehicleJourneyModal' onClick={this.props.onOpenDuplicateModal} > <span className='fa fa-files-o'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'duplicate') ? 'in' : '') } id='DuplicateVehicleJourneyModal'> <div className='modal-container'> @@ -68,7 +68,7 @@ class DuplicateVehicleJourney extends Component { <input type='number' ref='additional_time' - min='0' + min='-59' max='59' className='form-control' onKeyDown={(e) => actions.resetValidation(e.currentTarget)} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js index f7726dad9..12814bad1 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js @@ -24,15 +24,15 @@ class EditVehicleJourney extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} + <button + type='button' + disabled={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} data-toggle='modal' data-target='#EditVehicleJourneyModal' onClick={() => this.props.onOpenEditModal(actions.getSelected(this.props.vehicleJourneys)[0])} > <span className='fa fa-info'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'duplicate') ? 'in' : '') } id='EditVehicleJourneyModal'> <div className='modal-container'> diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/NotesEditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/NotesEditVehicleJourney.js index 7c5df3333..ca8b2ec7d 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/NotesEditVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/NotesEditVehicleJourney.js @@ -44,15 +44,15 @@ class NotesEditVehicleJourney extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} + <button + type='button' + disabled={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} data-toggle='modal' data-target='#NotesEditVehicleJourneyModal' onClick={() => this.props.onOpenNotesEditModal(actions.getSelected(this.props.vehicleJourneys)[0])} > <span className='fa fa-sticky-note'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'duplicate') ? 'in' : '') } id='NotesEditVehicleJourneyModal'> <div className='modal-container'> diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js index a373ed1e5..ee7d01cf5 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js @@ -23,15 +23,15 @@ class ShiftVehicleJourney extends Component { if(this.props.status.fetchSuccess == true) { return ( <li className='st_action'> - <a - href='#' - className={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} + <button + type='button' + disabled={(actions.getSelected(this.props.vehicleJourneys).length == 1 && this.props.filters.policy['vehicle_journeys.edit']) ? '' : 'disabled'} data-toggle='modal' data-target='#ShiftVehicleJourneyModal' onClick={this.props.onOpenShiftModal} > <span className='sb sb-update-vj'></span> - </a> + </button> <div className={ 'modal fade ' + ((this.props.modal.type == 'shift') ? 'in' : '') } id='ShiftVehicleJourneyModal'> <div className='modal-container'> @@ -54,7 +54,7 @@ class ShiftVehicleJourney extends Component { <input type='number' ref='additional_time' - min='0' + min='-59' max='59' className='form-control' onKeyDown={(e) => actions.resetValidation(e.currentTarget)} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js index d9c7d7296..7837cdbff 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var React = require('react') var PropTypes = require('react').PropTypes var Select2 = require('react-select2') @@ -38,7 +39,7 @@ class BSelect4 extends React.Component{ return { results: data.map( - item => Object.assign( + item => _.assign( {}, item, {text: item.name} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js index 2b4e1cd80..75cbd1f3c 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/MissionSelect2.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var React = require('react') var PropTypes = require('react').PropTypes var Select2 = require('react-select2') @@ -37,7 +38,7 @@ class BSelect4 extends React.Component{ processResults: function(data, params) { return { results: data.map( - item => Object.assign( + item => _.assign( {}, item, {text: item.published_name} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js index fd1e30afb..c28d8e06f 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/TimetableSelect2.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var React = require('react') var PropTypes = require('react').PropTypes var Select2 = require('react-select2') @@ -38,7 +39,7 @@ class BSelect4 extends React.Component{ return { results: data.map( - item => Object.assign( + item => _.assign( {}, item, {text: item.comment} diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/SaveVehicleJourneys.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/SaveVehicleJourneys.js index 5af30ab82..87bbe5353 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/SaveVehicleJourneys.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/SaveVehicleJourneys.js @@ -7,7 +7,8 @@ const mapStateToProps = (state) => { return { vehicleJourneys: state.vehicleJourneys, page: state.pagination.page, - status: state.status + status: state.status, + filters: state.filters } } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js index 5b5ba0788..0fcb3489e 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js @@ -1,3 +1,4 @@ +var _ = require('lodash') var actions = require("../actions") let newQuery, newInterval @@ -14,37 +15,37 @@ const filters = (state = {}, action) => { minute: '59' } } - newQuery = Object.assign({}, state.query, {interval: interval, journeyPattern: {}, timetable: {}, withoutSchedule: false }) - return Object.assign({}, state, {query: newQuery, queryString: ''}) + newQuery = _.assign({}, state.query, {interval: interval, journeyPattern: {}, timetable: {}, withoutSchedule: false }) + return _.assign({}, state, {query: newQuery, queryString: ''}) case 'TOGGLE_WITHOUT_SCHEDULE': - newQuery = Object.assign({}, state.query, {withoutSchedule: !state.query.withoutSchedule}) - return Object.assign({}, state, {query: newQuery}) + newQuery = _.assign({}, state.query, {withoutSchedule: !state.query.withoutSchedule}) + return _.assign({}, state, {query: newQuery}) case 'UPDATE_END_TIME_FILTER': newInterval = JSON.parse(JSON.stringify(state.query.interval)) - newInterval.end[action.unit] = actions.pad(action.val) + newInterval.end[action.unit] = actions.pad(action.val, action.unit) if(parseInt(newInterval.start.hour + newInterval.start.minute) < parseInt(newInterval.end.hour + newInterval.end.minute)){ - newQuery = Object.assign({}, state.query, {interval: newInterval}) - return Object.assign({}, state, {query: newQuery}) + newQuery = _.assign({}, state.query, {interval: newInterval}) + return _.assign({}, state, {query: newQuery}) }else{ return state } case 'UPDATE_START_TIME_FILTER': newInterval = JSON.parse(JSON.stringify(state.query.interval)) - newInterval.start[action.unit] = actions.pad(action.val) + newInterval.start[action.unit] = actions.pad(action.val, action.unit) if(parseInt(newInterval.start.hour + newInterval.start.minute) < parseInt(newInterval.end.hour + newInterval.end.minute)){ - newQuery = Object.assign({}, state.query, {interval: newInterval}) - return Object.assign({}, state, {query: newQuery}) + newQuery = _.assign({}, state.query, {interval: newInterval}) + return _.assign({}, state, {query: newQuery}) }else{ return state } case 'SELECT_TT_FILTER': - newQuery = Object.assign({}, state.query, {timetable : action.selectedItem}) - return Object.assign({}, state, {query: newQuery}) + newQuery = _.assign({}, state.query, {timetable : action.selectedItem}) + return _.assign({}, state, {query: newQuery}) case 'SELECT_JP_FILTER': - newQuery = Object.assign({}, state.query, {journeyPattern : action.selectedItem}) - return Object.assign({}, state, {query: newQuery}) + newQuery = _.assign({}, state.query, {journeyPattern : action.selectedItem}) + return _.assign({}, state, {query: newQuery}) case 'TOGGLE_ARRIVALS': - return Object.assign({}, state, {toggleArrivals: !state.toggleArrivals}) + return _.assign({}, state, {toggleArrivals: !state.toggleArrivals}) case 'QUERY_FILTER_VEHICLEJOURNEYS': actions.fetchVehicleJourneys(action.dispatch, undefined, undefined, state.queryString) return state @@ -53,10 +54,11 @@ const filters = (state = {}, action) => { 'q[journey_pattern_id_eq]': state.query.journeyPattern.id || undefined, 'q[time_tables_id_eq]': state.query.timetable.id || undefined, 'q[vehicle_journey_at_stops_departure_time_gteq]': (state.query.interval.start.hour + ':' + state.query.interval.start.minute), - 'q[vehicle_journey_at_stops_departure_time_lteq]': (state.query.interval.end.hour + ':' + state.query.interval.end.minute) + 'q[vehicle_journey_at_stops_departure_time_lteq]': (state.query.interval.end.hour + ':' + state.query.interval.end.minute), + 'q[vehicle_journey_without_u2]' : state.toggleArrivals } let queryString = actions.encodeParams(params) - return Object.assign({}, state, {queryString: queryString}) + return _.assign({}, state, {queryString: queryString}) default: return state } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js index a36aaa4fe..3b13ab9de 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js @@ -4,14 +4,14 @@ const modal = (state = {}, action) => { switch (action.type) { case 'OPEN_CONFIRM_MODAL': $('#ConfirmModal').modal('show') - return Object.assign({}, state, { + return _.assign({}, state, { type: 'confirm', confirmModal: { callback: action.callback, } }) case 'EDIT_NOTES_VEHICLEJOURNEY_MODAL': - let vehicleJourneyModal = Object.assign({}, action.vehicleJourney) + let vehicleJourneyModal = _.assign({}, action.vehicleJourney) return { type: 'notes_edit', modalProps: { @@ -26,7 +26,7 @@ const modal = (state = {}, action) => { }else{ newModalProps.vehicleJourney.footnotes = newModalProps.vehicleJourney.footnotes.filter((f) => {return f.id != action.footnote.id }) } - return Object.assign({}, state, {modalProps: newModalProps}) + return _.assign({}, state, {modalProps: newModalProps}) case 'EDIT_VEHICLEJOURNEY_MODAL': return { type: 'edit', @@ -55,11 +55,11 @@ const modal = (state = {}, action) => { confirmModal: {} } case 'SELECT_CP_EDIT_MODAL': - newModalProps = Object.assign({}, state.modalProps, {selectedCompany : action.selectedItem}) - return Object.assign({}, state, {modalProps: newModalProps}) + newModalProps = _.assign({}, state.modalProps, {selectedCompany : action.selectedItem}) + return _.assign({}, state, {modalProps: newModalProps}) case 'SELECT_TT_CALENDAR_MODAL': - newModalProps = Object.assign({}, state.modalProps, {selectedTimetable : action.selectedItem}) - return Object.assign({}, state, {modalProps: newModalProps}) + newModalProps = _.assign({}, state.modalProps, {selectedTimetable : action.selectedItem}) + return _.assign({}, state, {modalProps: newModalProps}) case 'ADD_SELECTED_TIMETABLE': if(state.modalProps.selectedTimetable){ newModalProps = JSON.parse(JSON.stringify(state.modalProps)) @@ -77,7 +77,7 @@ const modal = (state = {}, action) => { if (!_.find(newModalProps.timetables, newModalProps.selectedTimetable)){ newModalProps.timetables.push(newModalProps.selectedTimetable) } - return Object.assign({}, state, {modalProps: newModalProps}) + return _.assign({}, state, {modalProps: newModalProps}) } case 'DELETE_CALENDAR_MODAL': newModalProps = JSON.parse(JSON.stringify(state.modalProps)) @@ -97,7 +97,7 @@ const modal = (state = {}, action) => { }) newModalProps.vehicleJourneys = vehicleJourneysModal newModalProps.timetables = timetablesModal - return Object.assign({}, state, {modalProps: newModalProps}) + return _.assign({}, state, {modalProps: newModalProps}) case 'CREATE_VEHICLEJOURNEY_MODAL': return { type: 'create', @@ -105,8 +105,8 @@ const modal = (state = {}, action) => { confirmModal: {} } case 'SELECT_JP_CREATE_MODAL': - newModalProps = Object.assign({}, state.modalProps, {selectedJPModal : action.selectedItem}) - return Object.assign({}, state, {modalProps: newModalProps}) + newModalProps = _.assign({}, state.modalProps, {selectedJPModal : action.selectedItem}) + return _.assign({}, state, {modalProps: newModalProps}) case 'SHIFT_VEHICLEJOURNEY_MODAL': return { type: 'shift', diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js index 31c855a2f..ee59fca6d 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js @@ -1,27 +1,28 @@ +var _ = require('lodash') const pagination = (state = {}, action) => { switch (action.type) { case 'RECEIVE_JOURNEY_PATTERNS': - return Object.assign({}, state, {stateChanged: false}) + return _.assign({}, state, {stateChanged: false}) case 'GO_TO_PREVIOUS_PAGE': if (action.pagination.page > 1){ - return Object.assign({}, state, {page : action.pagination.page - 1, stateChanged: false}) + return _.assign({}, state, {page : action.pagination.page - 1, stateChanged: false}) } return state case 'GO_TO_NEXT_PAGE': if (state.totalCount - (action.pagination.page * action.pagination.perPage) > 0){ - return Object.assign({}, state, {page : action.pagination.page + 1, stateChanged: false}) + return _.assign({}, state, {page : action.pagination.page + 1, stateChanged: false}) } return state case 'ADD_VEHICLEJOURNEY': case 'UPDATE_TIME': toggleOnConfirmModal('modal') - return Object.assign({}, state, {stateChanged: true}) + return _.assign({}, state, {stateChanged: true}) case 'RESET_PAGINATION': - return Object.assign({}, state, {page: 1, stateChanged: false}) + return _.assign({}, state, {page: 1, stateChanged: false}) case 'RECEIVE_TOTAL_COUNT': - return Object.assign({}, state, {totalCount: action.total}) + return _.assign({}, state, {totalCount: action.total}) case 'UPDATE_TOTAL_COUNT': - return Object.assign({}, state, {totalCount : state.totalCount - action.diff }) + return _.assign({}, state, {totalCount : state.totalCount - action.diff }) default: return state } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/status.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/status.js index 3351aec4f..e658e164e 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/status.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/status.js @@ -1,13 +1,16 @@ +var _ = require('lodash') var actions = require("../actions") const status = (state = {}, action) => { switch (action.type) { case 'UNAVAILABLE_SERVER': - return Object.assign({}, state, {fetchSuccess: false}) + return _.assign({}, state, {fetchSuccess: false}) case 'FETCH_API': - return Object.assign({}, state, {isFetching: true}) + return _.assign({}, state, {isFetching: true}) case 'RECEIVE_VEHICLE_JOURNEYS': - return Object.assign({}, state, {fetchSuccess: true, isFetching: false}) + return _.assign({}, state, {fetchSuccess: true, isFetching: false}) + case 'RECEIVE_ERRORS': + return _.assign({}, state, {fetchSuccess: true, isFetching: false}) default: return state } diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js index ae98b6743..ba3d58c22 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js @@ -4,9 +4,9 @@ var actions = require("../actions") const vehicleJourney= (state = {}, action) => { switch (action.type) { case 'SELECT_VEHICLEJOURNEY': - return Object.assign({}, state, {selected: !state.selected}) + return _.assign({}, state, {selected: !state.selected}) case 'CANCEL_SELECTION': - return Object.assign({}, state, {selected: false}) + return _.assign({}, state, {selected: false}) case 'ADD_VEHICLEJOURNEY': let pristineVjasList = [] _.each(action.stopPointsList, (sp) =>{ @@ -47,45 +47,56 @@ const vehicleJourney= (state = {}, action) => { case 'SHIFT_VEHICLEJOURNEY': let shiftedArray, shiftedSchedule, shiftedVjas shiftedArray = state.vehicle_journey_at_stops.map((vjas, i) => { - shiftedSchedule = { - departure_time: { - hour: vjas.departure_time.hour, - minute: String(parseInt(vjas.departure_time.minute) + parseInt(action.data.additional_time.value)) - }, - arrival_time: { - hour: vjas.arrival_time.hour, - minute: String(parseInt(vjas.arrival_time.minute) + parseInt(action.data.additional_time.value)) + if (!vjas.dummy){ + shiftedSchedule = { + departure_time: { + hour: vjas.departure_time.hour, + minute: actions.simplePad(parseInt(vjas.departure_time.minute) + parseInt(action.data.additional_time.value)) + }, + arrival_time: { + hour: vjas.arrival_time.hour, + minute: actions.simplePad(parseInt(vjas.arrival_time.minute) + parseInt(action.data.additional_time.value)) + } } + actions.checkSchedules(shiftedSchedule) + shiftedVjas = _.assign({}, state.vehicle_journey_at_stops[i], shiftedSchedule) + delete shiftedVjas['id'] + return _.assign({}, state.vehicle_journey_at_stops[i], shiftedVjas) + }else { + return vjas } - actions.checkSchedules(shiftedSchedule) - shiftedVjas = Object.assign({}, state.vehicle_journey_at_stops[i], shiftedSchedule) - return Object.assign({}, state.vehicle_journey_at_stops[i], shiftedVjas) }) - return Object.assign({}, state, {vehicle_journey_at_stops: shiftedArray}) + return _.assign({}, state, {vehicle_journey_at_stops: shiftedArray}) case 'UPDATE_TIME': let vj, vjas, vjasArray, newSchedule vjasArray = state.vehicle_journey_at_stops.map((vjas, i) =>{ if(i == action.subIndex){ newSchedule = { - departure_time: Object.assign({}, vjas.departure_time), - arrival_time: Object.assign({}, vjas.arrival_time) + departure_time: _.assign({}, vjas.departure_time), + arrival_time: _.assign({}, vjas.arrival_time) } if (action.isDeparture){ - newSchedule.departure_time[action.timeUnit] = actions.pad(action.val) + newSchedule.departure_time[action.timeUnit] = actions.pad(action.val, action.timeUnit) if(!action.isArrivalsToggled) - newSchedule.arrival_time[action.timeUnit] = actions.pad(action.val) + newSchedule.arrival_time[action.timeUnit] = actions.pad(action.val, action.timeUnit) newSchedule = actions.getDelta(newSchedule) - return Object.assign({}, state.vehicle_journey_at_stops[action.subIndex], {arrival_time: newSchedule.arrival_time, departure_time: newSchedule.departure_time, delta: newSchedule.delta}) + if(newSchedule.delta < 0){ + return vjas + } + 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) + newSchedule.arrival_time[action.timeUnit] = actions.pad(action.val, action.timeUnit) newSchedule = actions.getDelta(newSchedule) - return Object.assign({}, state.vehicle_journey_at_stops[action.subIndex], {arrival_time: newSchedule.arrival_time, departure_time: newSchedule.departure_time, delta: newSchedule.delta}) + if(newSchedule.delta < 0){ + return vjas + } + return _.assign({}, state.vehicle_journey_at_stops[action.subIndex], {arrival_time: newSchedule.arrival_time, departure_time: newSchedule.departure_time, delta: newSchedule.delta}) } }else{ return vjas } }) - return Object.assign({}, state, {vehicle_journey_at_stops: vjasArray}) + return _.assign({}, state, {vehicle_journey_at_stops: vjasArray}) default: return state } @@ -115,7 +126,7 @@ const vehicleJourneys = (state = [], action) => { case 'EDIT_VEHICLEJOURNEY': return state.map((vj, i) => { if (vj.selected){ - return Object.assign({}, vj, { + return _.assign({}, vj, { company: action.selectedCompany, published_journey_name: action.data.published_journey_name.value, published_journey_identifier: action.data.published_journey_identifier.value, @@ -127,7 +138,7 @@ const vehicleJourneys = (state = [], action) => { case 'EDIT_VEHICLEJOURNEY_NOTES': return state.map((vj, i) => { if (vj.selected){ - return Object.assign({}, vj, { + return _.assign({}, vj, { footnotes: action.footnotes }) }else{ @@ -137,7 +148,7 @@ const vehicleJourneys = (state = [], action) => { case 'EDIT_VEHICLEJOURNEYS_CALENDARS': return state.map((vj,i) =>{ if(vj.selected){ - let updatedVJ = Object.assign({}, vj) + let updatedVJ = _.assign({}, vj) action.vehicleJourneys.map((vjm, j) =>{ if(vj.objectid == vjm.objectid){ updatedVJ.time_tables = vjm.time_tables @@ -160,11 +171,12 @@ const vehicleJourneys = (state = [], action) => { let dupeVj let dupes = [] let selectedIndex + let val = action.data.additional_time.value state.map((vj, i) => { if(vj.selected){ selectedIndex = i for (i = 0; i< action.data.duplicate_number.value; i++){ - action.data.additional_time.value *= (i + 1) + action.data.additional_time.value = val * (i + 1) dupeVj = vehicleJourney(vj, action) dupeVj.published_journey_name = dupeVj.published_journey_name + '-' + i dupeVj.selected = false @@ -179,7 +191,7 @@ const vehicleJourneys = (state = [], action) => { case 'DELETE_VEHICLEJOURNEYS': return state.map((vj, i) =>{ if (vj.selected){ - return Object.assign({}, vj, {deletable: true, selected: false}) + return _.assign({}, vj, {deletable: true, selected: false}) } else { return vj } diff --git a/app/assets/javascripts/forms.coffee b/app/assets/javascripts/forms.coffee index c8dd69581..9d884edcd 100644 --- a/app/assets/javascripts/forms.coffee +++ b/app/assets/javascripts/forms.coffee @@ -1,3 +1,7 @@ +# IE fix +isIE = false || !!document.documentMode +isEdge = !isIE && !!window.StyleMedia + @togglableFilter = -> $('.form-filter').on 'click', '.form-group.togglable', (e)-> if $(e.target).hasClass('togglable') || $(e.target).parent().hasClass('togglable') @@ -23,17 +27,15 @@ $('.formSubmitr').appendTo('.page-action') - # IE fix - isIE = false || !!document.documentMode - isEdge = !isIE && !!window.StyleMedia - if isIE || isEdge - $('.formSubmitr').each -> - target = $(this).attr('form') - - $(this).on 'click', -> - $('#' + target).submit() + $('.formSubmitr').off() $(document).on 'ready page:load', togglableFilter $(document).on 'ready page:load', submitMover $(document).on 'ready page:load', switchInput + +if isIE || isEdge + $(document).on 'click', '.formSubmitr', (e)-> + e.preventDefault() + target = $(this).attr('form') + $('#' + target).submit() diff --git a/app/assets/javascripts/main_menu.coffee b/app/assets/javascripts/main_menu.coffee index ed8ac655e..9357cff34 100644 --- a/app/assets/javascripts/main_menu.coffee +++ b/app/assets/javascripts/main_menu.coffee @@ -1,4 +1,11 @@ $(document).on 'ready page:load', -> + + link = [] + ptitleCont = "" + $(document).on 'page:before-change', -> + link = [] + ptitleCont = "" + $el = $('#main_nav') # Opening/closing left-side menu $el.find('.openMenu').on 'click', (e) -> @@ -12,32 +19,35 @@ $(document).on 'ready page:load', -> selectedItem.closest('.panel-collapse').addClass 'in' selectedItem.closest('.panel-title').children('a').attr('aria-expanded') == true + # Sticky content # Sticky behavior $(document).on 'scroll', -> limit = 51 - data = "" - $('.page-action').children().each -> - data += $(this)[0].outerHTML - - stickyContent = '<div class="sticky-content">' - stickyContent += '<div class="sticky-ptitle">' + $(".page-title").html() + '</div>' - stickyContent += '<div class="sticky-paction">' + data + '</div>' - stickyContent += '</div>' + if $(window).scrollTop() >= limit + if ($('.page-action .small').length > 0) + data = $('.page-action .small')[0].innerHTML - # console.log stickyContent + if ($(".page-title").length > 0) + ptitleCont = $(".page-title").html() - if $(window).scrollTop() >= limit + stickyContent = '<div class="sticky-content">' + stickyContent += '<div class="sticky-ptitle">' + ptitleCont + '</div>' + stickyContent += '<div class="sticky-paction"><div class="small">' + data + '</div></div>' + stickyContent += '</div>' $('#main_nav').addClass 'sticky' if $('#menu_top').find('.sticky-content').length == 0 - $('#menu_top').children('.menu-content').after(stickyContent) - # $('.sticky-paction .small').after($('.formSubmitr')) + if ptitleCont.length > 0 + $('#menu_top').children('.menu-content').after(stickyContent) + if link.length == 0 + link = $('.page-action .small').next() + $('.sticky-paction .small').after(link) else $('#main_nav').removeClass 'sticky' if $('#menu_top').find('.sticky-content').length > 0 - # $('.page-action .small').after($('.formSubmitr')) + $('.page-action .small').after(link) $('.sticky-content').remove() diff --git a/app/assets/javascripts/routes.coffee b/app/assets/javascripts/routes.coffee new file mode 100644 index 000000000..2e36061b8 --- /dev/null +++ b/app/assets/javascripts/routes.coffee @@ -0,0 +1,8 @@ +$(document).on("change", '#route_wayback', (e) -> + way = if $(this).is(':checked') then "backward" else "straight_forward" + $('.opposite_route').hide().find('select').prop('disabled', true) + + field = $(".opposite_route.#{way}") + if field.length + field.removeClass('hidden').show().find('select').prop('disabled', false) +) diff --git a/app/assets/javascripts/select2.coffee b/app/assets/javascripts/select2.coffee index edd4c476d..e20ef8d32 100644 --- a/app/assets/javascripts/select2.coffee +++ b/app/assets/javascripts/select2.coffee @@ -7,5 +7,13 @@ placeholder: target.data('select2ed-placeholder') allowClear: true + $('select.form-control.tags').each -> + target = $(this) + target.select2 + theme: 'bootstrap' + language: 'fr' + allowClear: true + tags: true + $(document).on 'ready page:load', select_2 diff --git a/app/assets/stylesheets/_layout.sass b/app/assets/stylesheets/_layout.sass index 83efe60d9..c19d9b054 100644 --- a/app/assets/stylesheets/_layout.sass +++ b/app/assets/stylesheets/_layout.sass @@ -20,7 +20,7 @@ body padding: 40px 35px 0 35px .page_content - padding: 35px + padding: 35px 35px 95px 35px .separator display: block diff --git a/app/assets/stylesheets/components/_alerts.sass b/app/assets/stylesheets/components/_alerts.sass index f05a4f39f..923b67cbc 100644 --- a/app/assets/stylesheets/components/_alerts.sass +++ b/app/assets/stylesheets/components/_alerts.sass @@ -14,6 +14,13 @@ .fa + span margin-left: 10px + p a + border-color: inherit + + &:hover + color: inherit + border-color: inherit + &.alert-dismissible padding-right: 70px diff --git a/app/assets/stylesheets/components/_buttons.sass b/app/assets/stylesheets/components/_buttons.sass index 00551f7cb..f128512f5 100644 --- a/app/assets/stylesheets/components/_buttons.sass +++ b/app/assets/stylesheets/components/_buttons.sass @@ -113,12 +113,13 @@ table, .table border-radius: 0 box-shadow: 0 0 3px rgba($darkgrey, 0.25) - > li > a + > li > a, > li > button padding: 5px 15px > li.delete-action - > a + > a, > button + display: block position: relative margin-top: 11px diff --git a/app/assets/stylesheets/components/_dropdown.sass b/app/assets/stylesheets/components/_dropdown.sass index ee26aaeb5..eb2cc8f74 100644 --- a/app/assets/stylesheets/components/_dropdown.sass +++ b/app/assets/stylesheets/components/_dropdown.sass @@ -3,6 +3,20 @@ //-------------// .dropdown-menu - > .disabled > a + > li > button + display: block + width: 100% + text-align: left + border: none + background-color: transparent + color: #333 + + &:hover, &:focus + color: #262626 + background-color: whitesmoke + + > .disabled > a, > .disabled > button + cursor: not-allowed &, &:hover, &:focus color: rgba($darkgrey, 0.5) + background-color: transparent diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass index 95d699c71..f2c76c9c1 100644 --- a/app/assets/stylesheets/components/_forms.sass +++ b/app/assets/stylesheets/components/_forms.sass @@ -77,6 +77,24 @@ input border-color: #4cae4c box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px #5cb85c +// BS horizontal form label positionning fix +.form-horizontal + .form-group + position: relative + + > .control-label + &[class*='col-sm-'] + float: none + padding-top: 0 + position: absolute + left: 0 + right: 0 + top: 50% + transform: translateY(-50%) + + + [class*='col-sm-'] + float: right + // Search bar .search_bar position: relative @@ -520,8 +538,13 @@ table, .table white-space: nowrap overflow: auto + > .checkbox-wrapper + width: 100% + height: auto + margin: 0 + $cbx-size-xs: 14px - > .checkbox + > .checkbox, > .checkbox-wrapper > .checkbox width: 100% height: auto margin: 0 @@ -547,7 +570,7 @@ table, .table padding-right: $cbx-size-xs + 10 position: relative - > .fa:last-child + > .fa:last-child, > .sb:last-child position: absolute top: 50% right: 0 @@ -641,6 +664,56 @@ table, .table .control-label.time min-width: 60px +// Form group checkboxes +$grp-cbx-size: 34px +.form-group.labelled-checkbox-group + margin: 0 + + > .lcbx-group-item + display: inline-block + margin: 0 5px + + > .checkbox + display: block + width: $grp-cbx-size + height: $grp-cbx-size + line-height: $grp-cbx-size + margin: 0 + padding: 0 + + > label + position: relative + min-height: 0 + padding: 0 + margin: 0 + + > input + &[type='checkbox']:not(:checked), &[type='checkbox']:checked + position: absolute + left: -9999px + margin: 0 + + + .lcbx-group-item-label + position: relative + cursor: pointer + font-weight: bold + display: inline-block + vertical-align: top + width: $grp-cbx-size + height: $grp-cbx-size + line-height: $grp-cbx-size - 2px + text-align: center + margin: 0 + background-color: rgba($grey, 0.15) + color: rgba($grey, 0.5) + border: 1px solid rgba($grey, 0.5) + border-radius: 3px + + &[type='checkbox']:checked + .lcbx-group-item-label + background-color: $blue + border-color: $blue + color: #fff + // Nested fields .nested-fields margin: 0 @@ -722,7 +795,7 @@ table, .table margin: 0 padding: 0 5px - + .nested-fields + + .nested-fields, + .links.nested-linker border-top: 2px solid $darkgrey .wrapper diff --git a/app/assets/stylesheets/components/_labels.sass b/app/assets/stylesheets/components/_labels.sass index 3514bce81..9607a97b8 100644 --- a/app/assets/stylesheets/components/_labels.sass +++ b/app/assets/stylesheets/components/_labels.sass @@ -8,7 +8,15 @@ font-weight: inherit padding: 0.35em 0.4em border-radius: 2px + border: 1px solid + + + .label + margin-left: 0.5em &.label-default - background-color: rgba(#fff, 0.3) - color: #fff + background-color: #fff + color: $darkgrey + border-color: rgba($grey, 0.5) + + &.disabled + color: rgba($grey, 0.5) diff --git a/app/assets/stylesheets/components/_main_nav.sass b/app/assets/stylesheets/components/_main_nav.sass index 32a7617c1..5bfa312c7 100644 --- a/app/assets/stylesheets/components/_main_nav.sass +++ b/app/assets/stylesheets/components/_main_nav.sass @@ -317,6 +317,7 @@ $menuW: 300px display: none .sticky-content + height: $menuH padding: 0 50px 0 75px margin-top: -4px @@ -325,9 +326,34 @@ $menuW: 300px &.sticky-ptitle width: 60% + height: $menuH h1 - margin: 0 + position: relative + line-height: 1.1 + white-space: nowrap + max-height: 1.1em + margin: 0 -1.4em 0 0 + padding: 0 1.4em 0 0 + overflow: hidden + + &:before + content: '[...]' + font-size: 0.65em + position: absolute + z-index: 5 + right: 0 + bottom: 4px + + &:after + content: '' + position: absolute + z-index: 5 + right: 0 + width: 1.4em + height: 1em + margin-top: 0.2em + background-color: $blue .small.fa color: #fff diff --git a/app/assets/stylesheets/components/_page_header.sass b/app/assets/stylesheets/components/_page_header.sass index 8ca9f3faa..18985083d 100644 --- a/app/assets/stylesheets/components/_page_header.sass +++ b/app/assets/stylesheets/components/_page_header.sass @@ -26,7 +26,30 @@ width: 100% h1 - margin: 0 + position: relative + line-height: 1.1 + max-height: 2.2em + margin: 0 -1.4em 0 0 + padding: 0 1.4em 0 0 + overflow: hidden + + &:before + content: '[...]' + font-size: 0.65em + position: absolute + z-index: 5 + right: 0 + bottom: 4px + + &:after + content: '' + position: absolute + z-index: 5 + right: 0 + width: 1.4em + height: 1em + margin-top: 0.2em + background-color: $blue .small.fa color: #fff diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass index a18009ba1..d366b2122 100644 --- a/app/assets/stylesheets/components/_tables.sass +++ b/app/assets/stylesheets/components/_tables.sass @@ -12,8 +12,9 @@ > a position: relative + display: block color: $darkgrey - padding-right: 18px + padding-right: 20px &:hover, &:focus text-decoration: none @@ -24,7 +25,7 @@ display: block height: 14px width: 8px - right: 0 + right: 10px top: 50% margin-top: -7px @@ -49,6 +50,14 @@ padding: 6px 8px vertical-align: middle + > .td-block + white-space: nowrap + + > .fa:first-child, > .sb:first-child + margin-right: 0.5em + > .fa:last-child, > .sb:last-child + margin-left: 0.5em + > a display: block margin: -6px -8px @@ -109,13 +118,15 @@ height: 35px margin: 5px - > a + > a, > button display: block height: 35px + width: 100% text-align: center line-height: 35px border-radius: 50% background-color: $blue + border: none color: #fff &:focus @@ -130,7 +141,7 @@ &:hover background-color: darken($red, 5%) - &.disabled + &.disabled, &:disabled &, &[title='Supprimer'], &:hover, &:focus background-color: rgba($grey, 0.3) cursor: not-allowed diff --git a/app/assets/stylesheets/main/time_tables.sass b/app/assets/stylesheets/main/time_tables.sass index de2ae8253..6918bec1e 100644 --- a/app/assets/stylesheets/main/time_tables.sass +++ b/app/assets/stylesheets/main/time_tables.sass @@ -28,13 +28,13 @@ z-index: 100001 .validity_out - color: $brand-danger + color: red .validity_out_soon - color: $brand-warning + color: orange .validity_regular - color: $brand-success + color: green span.included_day_type font-weight: bolder diff --git a/app/assets/stylesheets/modules/_routes_stopoints.sass b/app/assets/stylesheets/modules/_routes_stopoints.sass index 029221605..735e91df7 100644 --- a/app/assets/stylesheets/modules/_routes_stopoints.sass +++ b/app/assets/stylesheets/modules/_routes_stopoints.sass @@ -7,36 +7,43 @@ padding-left: 20px .nested-fields + height: 100% > .wrapper + height: 100% > div:first-child position: relative padding-left: 20px /* intial value is 10 */ + overflow: hidden - &:before - content: '' - display: block - width: 10px - height: 10px - background-color: #fff - border: 2px solid $blue - border-radius: 50% - position: absolute - z-index: 5 - left: 0 - top: 50% - margin-top: -5px + span + position: relative - &:after - content: '' - display: block - width: 4px - margin: 0 3px - background-color: rgba($grey, 0.5) - position: absolute - z-index: 3 - top: 0 - left: 0 - bottom: 0 + &:before + content: '' + display: block + width: 10px + height: 10px + background-color: #fff + border: 2px solid $blue + border-radius: 50% + position: absolute + z-index: 5 + left: -20px + top: 50% + margin-top: -5px + box-sizing: border-box + + &:after + content: '' + display: block + width: 4px + margin: 0 3px + background-color: rgba($grey, 0.5) + position: absolute + z-index: 3 + top: -100px + left: -20px + bottom: -100px + .map_container > .map_metas @@ -55,11 +62,11 @@ bottom: 0 left: 5px - &:last-child > .wrapper > div:first-child - &:after - bottom: 50% + &:last-child > .wrapper:last-child > div:first-child + span:after + bottom: 5px .nested-fields:first-child > .wrapper > div:first-child, .nested-head + .nested-fields > .wrapper > div:first-child - &:after - top: 50% + span:after + top: 5px diff --git a/app/assets/stylesheets/typography/_fonts.sass b/app/assets/stylesheets/typography/_fonts.sass index c715fa2ab..0cc387d74 100644 --- a/app/assets/stylesheets/typography/_fonts.sass +++ b/app/assets/stylesheets/typography/_fonts.sass @@ -35,6 +35,6 @@ //-- sBoiv --// @font-face font-family: 'sboiv' - src: url(asset-path('sBoiv/sboiv.woff')) format('woff'), url(asset-path('sBoiv/sboiv.ttf')) format('ttf') + src: url(asset-path('sBoiv/sboiv.woff?vhxdui')) format('woff'), url(asset-path('sBoiv/sboiv.ttf?vhxdui')) format('ttf') font-weight: normal font-style: normal diff --git a/app/assets/stylesheets/typography/_sboiv.sass b/app/assets/stylesheets/typography/_sboiv.sass index 3e8eb2868..1f89bad74 100644 --- a/app/assets/stylesheets/typography/_sboiv.sass +++ b/app/assets/stylesheets/typography/_sboiv.sass @@ -18,6 +18,8 @@ &[data-textinside] position: relative + // width: 1em + // height: 1em &:after content: attr(data-textinside) font-family: $base-font-family @@ -50,8 +52,15 @@ &.sb-5x font-size: 5em + .sb-update-vj:before content: '\e900' -.sb-chrono:before +.sb-preparing:before content: '\e901' + +.sb-current-ref:before + content: '\e902' + +.sb-chrono:before + content: '\e903' diff --git a/app/controllers/autocomplete_stop_areas_controller.rb b/app/controllers/autocomplete_stop_areas_controller.rb index 6daa8a169..e35a545ae 100644 --- a/app/controllers/autocomplete_stop_areas_controller.rb +++ b/app/controllers/autocomplete_stop_areas_controller.rb @@ -10,7 +10,7 @@ class AutocompleteStopAreasController < InheritedResources::Base protected def collection - scope = referential.stop_areas + scope = referential.stop_areas.where(deleted_at: nil) scope = scope.physical if physical_filter? if target_type? scope = scope.where(area_type: params[:target_type]) diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 94fa9d944..70c5c1a0d 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -1,4 +1,5 @@ class ImportsController < BreadcrumbController + skip_before_action :authenticate_user!, only: [:download] defaults resource_class: Import, collection_name: 'imports', instance_name: 'import' respond_to :html belongs_to :workbench diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb index 51cc48c2a..2963a8ad7 100644 --- a/app/controllers/journey_patterns_collections_controller.rb +++ b/app/controllers/journey_patterns_collections_controller.rb @@ -1,6 +1,7 @@ class JourneyPatternsCollectionsController < ChouetteController respond_to :html respond_to :json + before_action :user_permissions, only: :show belongs_to :referential do belongs_to :line, :parent_class => Chouette::Line do @@ -41,6 +42,15 @@ class JourneyPatternsCollectionsController < ChouetteController @stop_points_list = @stop_points_list.sort_by {|a| a[:position] } end + def user_permissions + @perms = {}.tap do |perm| + ['journey_patterns.create', 'journey_patterns.edit', 'journey_patterns.destroy'].each do |name| + perm[name] = current_user.permissions.include?(name) + end + end + @perms = @perms.to_json + end + def update state = JSON.parse request.raw_post Chouette::JourneyPattern.state_update route, state diff --git a/app/controllers/line_footnotes_controller.rb b/app/controllers/line_footnotes_controller.rb index 8f7a38512..7bc048731 100644 --- a/app/controllers/line_footnotes_controller.rb +++ b/app/controllers/line_footnotes_controller.rb @@ -1,15 +1,15 @@ -class LineFootnotesController < ChouetteController - defaults :resource_class => Chouette::Line, :instance_name => 'line' +class LineFootnotesController < BreadcrumbController + defaults :resource_class => Chouette::Line include PolicyChecker before_action :check_policy, only: [:edit, :update, :destroy] respond_to :json, :only => :show - belongs_to :referential def show show! do build_breadcrumb :show end + @footnotes = @line.footnotes end def edit @@ -37,7 +37,6 @@ class LineFootnotesController < ChouetteController def resource @referential = Referential.find params[:referential_id] @line = @referential.lines.find params[:line_id] - @footnotes = @line.footnotes end def line_params diff --git a/app/controllers/lines_controller.rb b/app/controllers/lines_controller.rb index cce01e334..7eedaeb05 100644 --- a/app/controllers/lines_controller.rb +++ b/app/controllers/lines_controller.rb @@ -92,7 +92,7 @@ class LinesController < BreadcrumbController private def sort_column - line_referential.lines.column_names.include?(params[:sort]) ? params[:sort] : 'number' + (Chouette::Line.column_names + ['companies.name', 'networks.name']).include?(params[:sort]) ? params[:sort] : 'number' end def sort_direction %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index ed20a6d17..ce875b6ba 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -1,7 +1,7 @@ class ReferentialsController < BreadcrumbController defaults :resource_class => Referential include PolicyChecker - before_action :check_policy, :only => [:edit, :update] # overrides default + before_action :check_policy, :only => [:edit, :update, :archive, :unarchive] # overrides default respond_to :html respond_to :json, :only => :show diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 6a38b022d..a1aadf883 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -9,8 +9,7 @@ class RoutesController < ChouetteController belongs_to :referential do belongs_to :line, :parent_class => Chouette::Line, :optional => true, :polymorphic => true end - - before_action :define_candidate_opposite_routes, only: [:new, :edit, :create, :update] + before_action :define_candidate_opposite_routes, only: [:new, :edit] def index index! do |format| @@ -66,11 +65,11 @@ class RoutesController < ChouetteController end end -# def update -# update! do |success, failure| -# success.html { redirect_to referential_line_path(@referential,@line) } -# end -# end + # def update + # update! do |success, failure| + # success.html { redirect_to referential_line_path(@referential,@line) } + # end + # end protected alias_method :route, :resource @@ -86,12 +85,13 @@ class RoutesController < ChouetteController end def define_candidate_opposite_routes - @candidate_opposite_routes = - if params[:id] - resource.line.routes.where("id <> ?", resource) - else - parent.routes.select(&:persisted?) - end + scope = if params[:id] + parent.routes.where(opposite_route: [nil, resource]).where('id <> ?', resource.id) + else + parent.routes.where(opposite_route: nil) + end + @forward = scope.where(wayback: :straight_forward) + @backward = scope.where(wayback: :backward) end private diff --git a/app/controllers/routing_constraint_zones_controller.rb b/app/controllers/routing_constraint_zones_controller.rb index c39c50326..bc3dcdfd4 100644 --- a/app/controllers/routing_constraint_zones_controller.rb +++ b/app/controllers/routing_constraint_zones_controller.rb @@ -11,7 +11,7 @@ class RoutingConstraintZonesController < ChouetteController private def routing_constraint_zone_params - params.require(:routing_constraint_zone).permit(:name, { stop_area_ids: [] }, :line_id, :objectid, :object_version, :creator_id) + params.require(:routing_constraint_zone).permit(:name, { stop_area_ids: [] }, :line_id, :route_id, :objectid, :object_version, :creator_id) end end diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb index bdde5d3ab..50c925eac 100644 --- a/app/controllers/time_tables_controller.rb +++ b/app/controllers/time_tables_controller.rb @@ -117,6 +117,26 @@ class TimeTablesController < ChouetteController private def time_table_params - params.require(:time_table).permit( :objectid, :object_version, :creator_id, :calendar_id, :version, :comment, :int_day_types, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday, :sunday, :start_date, :end_date, { :dates_attributes => [:date, :in_out, :id, :_destroy] }, { :periods_attributes => [:period_start, :period_end, :_destroy, :id] }, :tag_list, :tag_search ) + params.require(:time_table).permit( + :objectid, + :object_version, + :creator_id, + :calendar_id, + :version, :comment, + :int_day_types, + :monday, + :tuesday, + :wednesday, + :thursday, + :friday, + :saturday, + :sunday, + :start_date, + :end_date, + { :dates_attributes => [:date, :in_out, :id, :_destroy] }, + { :periods_attributes => [:period_start, :period_end, :_destroy, :id] }, + {tag_list: []}, + :tag_search + ) end end diff --git a/app/controllers/workbenches_controller.rb b/app/controllers/workbenches_controller.rb index 7f108b266..1424fe03c 100644 --- a/app/controllers/workbenches_controller.rb +++ b/app/controllers/workbenches_controller.rb @@ -5,12 +5,17 @@ class WorkbenchesController < BreadcrumbController respond_to :html, only: [:show] def show - scope = params[:q] ? resource.all_referentials : resource.referentials.ready + scope = resource.all_referentials scope = ransack_associated_lines(scope) + scope = ransack_periode(scope) + scope = ransack_status(scope) - @q = ransack_periode(scope).ransack(params[:q]) - @q.organisation_name_eq_any ||= current_organisation.name unless params[:q] - @wbench_refs = sort_result(@q.result).paginate(page: params[:page], per_page: 30) + # Ignore archived_at_not_null/archived_at_null managed by ransack_status scope + q_for_result = + scope.ransack(params[:q].merge(archived_at_not_null: nil, archived_at_null: nil)) + @wbench_refs = sort_result(q_for_result.result).paginate(page: params[:page], per_page: 30) + + @q = scope.ransack(params[:q]) show! do build_breadcrumb :show end @@ -44,6 +49,8 @@ class WorkbenchesController < BreadcrumbController def query_params if params[:q].present? params[:q].delete_if { |query, value| value.blank? } + else + params[:q] = { "archived_at_not_null"=>"1", "archived_at_null"=>"1" } end end @@ -68,8 +75,36 @@ class WorkbenchesController < BreadcrumbController if begin_range > end_range flash.now[:error] = t('referentials.errors.validity_period') else - scope = scope.in_periode(begin_range..end_range) + scope = scope.in_periode(begin_range..end_range) + @begin_range = begin_range + @end_range = end_range + end + scope + end + + # Fake (again) ransack filter + def ransack_status scope + return scope unless params[:q] + + archived_at_not_null = params[:q]['archived_at_not_null'] == '1' + archived_at_null = params[:q]['archived_at_null'] == '1' + + if !archived_at_not_null and !archived_at_null + return scope.none end + + if archived_at_not_null and archived_at_null + return scope + end + + if archived_at_null + return scope.where(archived_at: nil) + end + + if archived_at_not_null + return scope.where("archived_at is not null") + end + scope end end diff --git a/app/helpers/breadcrumb_helper.rb b/app/helpers/breadcrumb_helper.rb index 3a742d0dc..1f8690f38 100644 --- a/app/helpers/breadcrumb_helper.rb +++ b/app/helpers/breadcrumb_helper.rb @@ -159,7 +159,6 @@ module BreadcrumbHelper add_breadcrumb breadcrumb_label(@line), line_referential_line_path(@line_referential, @line),:title => breadcrumb_tooltip(@line) if action == :edit else referential_breadcrumb - add_breadcrumb Chouette::Line.model_name.human(:count => 2).capitalize, referential_lines_path(@referential) unless action == :index add_breadcrumb breadcrumb_label(@line), referential_line_path(@referential, @line),:title => breadcrumb_tooltip(@line) if action == :edit end end diff --git a/app/helpers/newapplication_helper.rb b/app/helpers/newapplication_helper.rb index c9da544d1..c4b8ee7ab 100644 --- a/app/helpers/newapplication_helper.rb +++ b/app/helpers/newapplication_helper.rb @@ -30,6 +30,7 @@ module NewapplicationHelper body = content_tag :tbody do collection.collect do |item| + content_tag :tr do bcont = [] @@ -54,6 +55,7 @@ module NewapplicationHelper if current_referential lnk << current_referential lnk << item.line if item.respond_to? :line + lnk << item.route.line if item.class.to_s == 'Chouette::RoutingConstraintZone' lnk << item if item.class.to_s == 'Chouette::RoutingConstraintZone' lnk << item if item.respond_to? :line_referential lnk << item.stop_area if item.respond_to? :stop_area @@ -105,6 +107,7 @@ module NewapplicationHelper if current_referential polymorph_url << current_referential polymorph_url << item.line if item.respond_to? :line + polymorph_url << item.route.line if item.class.to_s == 'Chouette::RoutingConstraintZone' polymorph_url << item if item.class.to_s == 'Chouette::RoutingConstraintZone' polymorph_url << item if item.respond_to? :line_referential polymorph_url << item.stop_area if item.respond_to? :stop_area diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb index d5d36ffa3..4a9215653 100644 --- a/app/helpers/routes_helper.rb +++ b/app/helpers/routes_helper.rb @@ -13,8 +13,14 @@ module RoutesHelper end end + def input_opposite_route_id_css(route, way) + css = ['opposite_route', way] + css << 'hidden' if route.wayback.send("#{way}?") + css + end + def route_json_for_edit(route) - route.stop_points.includes(:stop_area).map do |stop_point| + route.stop_points.includes(:stop_area).order(:position).map do |stop_point| stop_area_attributes = stop_point.stop_area.attributes.slice("name","city_name", "zip_code", "registration_number", "longitude", "latitude", "area_type") stop_area_attributes["short_name"] = truncate(stop_area_attributes["name"], :length => 30) || "" stop_point_attributes = stop_point.attributes.slice("for_boarding","for_alighting") diff --git a/app/helpers/time_tables_helper.rb b/app/helpers/time_tables_helper.rb index 9fdb791b1..b1175d359 100644 --- a/app/helpers/time_tables_helper.rb +++ b/app/helpers/time_tables_helper.rb @@ -1,3 +1,9 @@ module TimeTablesHelper + + def month_periode_enum(years) + start_date = Date.today - years.years + end_date = Date.today + years.years + (start_date..end_date).map(&:beginning_of_month).uniq.map(&:to_s) + end end diff --git a/app/inputs/tags_input.rb b/app/inputs/tags_input.rb index 4fbf0465f..1dc6129ee 100644 --- a/app/inputs/tags_input.rb +++ b/app/inputs/tags_input.rb @@ -1,19 +1,16 @@ -class TagsInput < Formtastic::Inputs::StringInput - - def to_html - input_wrapping do - label_html << - '<span id="tagsContainer"></span>'.html_safe << - builder.text_field(method, input_html_options) - end +class TagsInput < SimpleForm::Inputs::CollectionInput + enable :placeholder + + def input(wrapper_options = {}) + @collection ||= @builder.object.send(attribute_name) + label_method, value_method = detect_collection_methods + + merged_input_options = merge_wrapper_options(input_html_options, wrapper_options) + merged_input_options.reverse_merge!(multiple: true) + + @builder.collection_select( + attribute_name, collection, value_method, label_method, + input_options, merged_input_options + ) end - - def input_html_options - super.merge({ - :required => nil, - :autofocus => nil, - :class => 'tm-input', - }) - end - end diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb index 27a37a7f4..50dd9b1b3 100644 --- a/app/models/chouette/line.rb +++ b/app/models/chouette/line.rb @@ -20,14 +20,13 @@ class Chouette::Line < Chouette::ActiveRecord has_many :routes, :dependent => :destroy has_many :journey_patterns, :through => :routes has_many :vehicle_journeys, :through => :journey_patterns + has_many :routing_constraint_zones, through: :routes has_and_belongs_to_many :group_of_lines, :class_name => 'Chouette::GroupOfLine', :order => 'group_of_lines.name' has_many :footnotes, :inverse_of => :line, :validate => :true, :dependent => :destroy accepts_nested_attributes_for :footnotes, :reject_if => :all_blank, :allow_destroy => true - has_many :routing_constraint_zones - attr_reader :group_of_line_tokens # validates_presence_of :network diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index a2a199942..688f8774e 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -5,7 +5,7 @@ class Chouette::Route < Chouette::TridentActiveRecord extend ActiveModel::Naming enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east) - enumerize :wayback, in: %i(straight_forward backward) + enumerize :wayback, in: %i(straight_forward backward), default: :backward # FIXME http://jira.codehaus.org/browse/JRUBY-6358 self.primary_key = "id" @@ -16,6 +16,7 @@ class Chouette::Route < Chouette::TridentActiveRecord belongs_to :line + has_many :routing_constraint_zones has_many :journey_patterns, :dependent => :destroy has_many :vehicle_journeys, :dependent => :destroy do def timeless @@ -29,7 +30,7 @@ class Chouette::Route < Chouette::TridentActiveRecord end end belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id - has_many :stop_points, :dependent => :destroy do + has_many :stop_points, -> { order("position") }, :dependent => :destroy do def find_by_stop_area(stop_area) stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id) where( :stop_area_id => stop_area_ids).first or @@ -91,7 +92,6 @@ class Chouette::Route < Chouette::TridentActiveRecord validate :check_opposite_route def check_opposite_route return unless opposite_route && opposite_wayback - unless opposite_route_candidates.include?(opposite_route) errors.add(:opposite_route_id, :invalid) end diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index 681069416..2c8583ec1 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -1,8 +1,8 @@ class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord - belongs_to :line + belongs_to :route has_array_of :stop_areas, class_name: 'Chouette::StopArea' - validates_presence_of :name, :stop_area_ids, :line_id + validates_presence_of :name, :stop_area_ids, :route_id validates :stop_areas, length: { minimum: 2 } self.primary_key = 'id' diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb index 7afdc4529..df474f2c4 100644 --- a/app/models/chouette/time_table.rb +++ b/app/models/chouette/time_table.rb @@ -43,6 +43,16 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord [Chouette::TimeTable.maximum(:end_date)].compact.max end + def month_inspect(date) + (date.beginning_of_month..date.end_of_month).map do |d| + { + day: I18n.l(d, format: '%A'), + wday: d.wday, + mday: d.mday + } + end + end + def save_shortcuts shortcuts_update self.update_column(:start_date, start_date) diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb index 0aab9d0ed..a4a363348 100644 --- a/app/models/chouette/vehicle_journey.rb +++ b/app/models/chouette/vehicle_journey.rb @@ -56,21 +56,28 @@ module Chouette at_stops end + def create_or_find_vjas_from_state vjas + return vehicle_journey_at_stops.find(vjas['id']) if vjas['id'] + stop_point = Chouette::StopPoint.find_by(objectid: vjas['stop_point_objectid']) + stop = vehicle_journey_at_stops.create(stop_point: stop_point) + vjas['id'] = stop.id + vjas['new_record'] = true + stop + end + def update_vjas_from_state state state.each do |vjas| next if vjas["dummy"] - stop = vehicle_journey_at_stops.find(vjas['id']) if vjas['id'] - if stop - params = {}.tap do |el| - ['arrival_time', 'departure_time'].each do |field| - time = "#{vjas[field]['hour']}:#{vjas[field]['minute']}" - el[field.to_sym] = Time.parse("2000-01-01 #{time}:00 UTC") - end + params = {}.tap do |el| + ['arrival_time', 'departure_time'].each do |field| + time = "#{vjas[field]['hour']}:#{vjas[field]['minute']}" + el[field.to_sym] = Time.parse("2000-01-01 #{time}:00 UTC") end - stop.update_attributes(params) - vjas.delete('errors') - vjas['errors'] = stop.errors if stop.errors.any? end + stop = create_or_find_vjas_from_state(vjas) + stop.update_attributes(params) + vjas.delete('errors') + vjas['errors'] = stop.errors if stop.errors.any? end end @@ -85,13 +92,22 @@ module Chouette vj.update_attributes(state_permited_attributes(item)) item['errors'] = vj.errors if vj.errors.any? end + + # Delete ids of new object from state if we had to rollback if state.any? {|item| item['errors']} - state.map {|item| item.delete('objectid') if item['new_record']} + state.map do |item| + item.delete('objectid') if item['new_record'] + item['vehicle_journey_at_stops'].map {|vjas| vjas.delete('id') if vjas['new_record'] } + end raise ::ActiveRecord::Rollback end end - state.map {|item| item.delete('new_record')} + # Remove new_record flag && deleted item from state if transaction has been saved + state.map do |item| + item.delete('new_record') + item['vehicle_journey_at_stops'].map {|vjas| vjas.delete('new_record') } + end state.delete_if {|item| item['deletable']} end diff --git a/app/models/import.rb b/app/models/import.rb index c407daa78..d0736ab0b 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -4,11 +4,12 @@ class Import < ActiveRecord::Base belongs_to :referential extend Enumerize - enumerize :status, in: %i(new pending successful failed canceled) + enumerize :status, in: %i(new pending successful failed running aborted canceled) validates :file, presence: true before_create do self.token_download = SecureRandom.urlsafe_base64 + self.status = Import.status.new end end diff --git a/app/models/netex_import.rb b/app/models/netex_import.rb index 27f5846af..0da008d2e 100644 --- a/app/models/netex_import.rb +++ b/app/models/netex_import.rb @@ -1,3 +1,13 @@ +require 'net/http' class NetexImport < Import + after_create :launch_java_import + def launch_java_import + logger.warn "Call iev get #{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}" + begin + Net::HTTP.get(Rails.configuration.iev_url, "/boiv_iev/referentials/importer/new?id=#{id}") + rescue + logger.error("IEV server error") + end + end end diff --git a/app/models/referential.rb b/app/models/referential.rb index 1b02bdd7a..b6a83c6c3 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -224,8 +224,7 @@ class Referential < ActiveRecord::Base def metadatas_lines if metadatas.present? - scope = workbench ? workbench.lines : associated_lines - scope.where(id: metadatas.pluck(:line_ids).flatten) + associated_lines.where(id: metadatas.pluck(:line_ids).flatten) else Chouette::Line.none end diff --git a/app/models/user.rb b/app/models/user.rb index bc2d5e8ea..2633fdacb 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,7 +39,7 @@ class User < ActiveRecord::Base self.name = extra[:full_name] self.email = extra[:email] self.organisation = Organisation.sync_update extra[:organisation_code], extra[:organisation_name], extra[:functional_scope] - self.permissions = @@edit_offer_permissions if extra[:permissions] && extra[:permissions].find { |permission| permission == 'boiv:edit-offer' } + self.permissions = extra[:permissions].include?('boiv:edit-offer') ? @@edit_offer_permissions : [] end def self.portail_api_request @@ -66,8 +66,8 @@ class User < ActiveRecord::Base user.email = el['email'] user.locked_at = el['locked_at'] user.organisation = Organisation.sync_update el['organization_code'], el['organization_name'], el['functional_scope'] - user.permissions = @@edit_offer_permissions if el['permissions'] && el['permissions'].find { |permission| permission == 'boiv:edit-offer' } user.synced_at = Time.now + user.permissions = el['permissions'].include?('boiv:edit-offer') ? @@edit_offer_permissions : [] user.save puts "✓ user #{user.username} has been updated" unless Rails.env.test? end diff --git a/app/policies/referential_policy.rb b/app/policies/referential_policy.rb index 074aaec8b..1175ba5c6 100644 --- a/app/policies/referential_policy.rb +++ b/app/policies/referential_policy.rb @@ -17,8 +17,13 @@ class ReferentialPolicy < ApplicationPolicy edit? && !record.archived? end - def new? ; create? end - def destroy? ; edit? end + def archive? + edit? + end + + def unarchive? ; archive? end + def new? ; create? end + def destroy? ; edit? end end diff --git a/app/views/companies/index.html.slim b/app/views/companies/index.html.slim index 95597903b..8605a213b 100644 --- a/app/views/companies/index.html.slim +++ b/app/views/companies/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @companies.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @companies - .row .col-lg-12 = search_form_for @q, url: line_referential_companies_path(@line_referential), html: {method: :get}, class: 'form form-filter' do |f| diff --git a/app/views/errors/not_allowed.html.slim b/app/views/errors/not_allowed.html.slim new file mode 100644 index 000000000..6c94328cc --- /dev/null +++ b/app/views/errors/not_allowed.html.slim @@ -0,0 +1,21 @@ +/ PageHeader += pageheader 'bug', + 'Erreur 403', + '' + +.page_content + .container-fluid + .row + .col-lg-12 + .alert.alert-danger + - if I18n.locale == :fr + p + strong = "Désolé, la page demandée la page n'est pas accessible avec votre profil utilisateur." + + p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO." + + - else + p + strong = "You are not allowed to access the page you were looking for." + + p = "You can still continue the use the IBOO application. Thank you for understanding." diff --git a/app/views/errors/not_found.html.slim b/app/views/errors/not_found.html.slim index 913362251..6348ea1be 100644 --- a/app/views/errors/not_found.html.slim +++ b/app/views/errors/not_found.html.slim @@ -1,31 +1,21 @@ -.error - h2 = "Désolé, la page demandée n'existe pas" +/ PageHeader += pageheader 'bug', + 'Erreur 404', + '' - a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank" - = "N'hésitez pas à nous décrire le problème" - = ", nous essaierons de le résoudre." - br - = "Merci d'avance" - br - - = "Vous pouvez néanmoins continuer à utiliser l'application CHOUETTE" - br - br - br - br - br - - h2 = "The page you were looking for doesn't exist." - - = "You may have mistyped the address or the page may have moved." - br - - a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank" - = "Please describe us what happened" - = ", we'll try to come back with an answer." - br - = "Thank you." - br - br - = "You can still continue the use the CHOUETTE application." - br
\ No newline at end of file +.page_content + .container-fluid + .row + .col-lg-12 + .alert.alert-danger + - if I18n.locale == :fr + p + strong = "Désolé, la page demandée n'existe pas." + + p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO." + + - else + p + strong = "The page you were looking for doesn't exist." + + p = "You can still continue the use the IBOO application. Thank you for understanding." diff --git a/app/views/errors/server_error.html.slim b/app/views/errors/server_error.html.slim index b11176421..09884dc29 100644 --- a/app/views/errors/server_error.html.slim +++ b/app/views/errors/server_error.html.slim @@ -1,33 +1,21 @@ -.error - h2 = "Désolé, une erreur est survenue" +/ PageHeader += pageheader 'bug', + 'Erreur serveur', + '' - a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank" - = "N'hésitez pas à nous décrire le problème" - = ", nous essaierons de le résoudre." - br - = "Merci d'avance" - br - br - - = "Vous pouvez néanmoins continuer à utiliser l'application CHOUETTE" - br - br - br - br - br - - h2 = "We're sorry, but something went wrong." - - = "You may have mistyped the address or the page may have moved." - br - - a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank" - = "Please describe us what happened" - = ", we'll try to come back with an answer." - br - = "Thank you." - br - br - - = "You can still continue the use the CHOUETTE application." - br
\ No newline at end of file +.page_content + .container-fluid + .row + .col-lg-12 + .alert.alert-danger + - if I18n.locale == :fr + p + strong = "Désolé, une erreur est survenue." + + p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO." + + - else + p + strong = "We're sorry, but something went wrong." + + p = "You can still continue the use the IBOO application. Thank you for understanding." diff --git a/app/views/journey_patterns_collections/show.html.slim b/app/views/journey_patterns_collections/show.html.slim index 0d09817e8..b5607090f 100644 --- a/app/views/journey_patterns_collections/show.html.slim +++ b/app/views/journey_patterns_collections/show.html.slim @@ -2,7 +2,7 @@ = pageheader 'map-marker', "Missions de #{@route.try(:stop_points).first.try(:stop_area).name} vers #{@route.try(:stop_points).last.try(:stop_area).name}", 'Lorem ipsum dolor sit amet', - (@journey_patterns.any? ? t('last_update', time: l(@journey_patterns.last.updated_at, format: :short)) : '') + '' / PageContent .page_content @@ -11,9 +11,10 @@ .col-lg-12 #journey_patterns - = javascript_tag do | window.stopPoints = #{(@stop_points_list.to_json).html_safe}; | window.journeyPatternLength = #{@journey_patterns.total_entries()}; - | window.journeyPatternsPerPage = #{@ppage} + | window.journeyPatternsPerPage = #{@ppage}; + | window.perms = #{raw @perms} + = javascript_include_tag 'es6_browserified/journey_patterns/index.js' diff --git a/app/views/line_footnotes/edit.html.slim b/app/views/line_footnotes/edit.html.slim index f368ea918..fcd7a47e0 100644 --- a/app/views/line_footnotes/edit.html.slim +++ b/app/views/line_footnotes/edit.html.slim @@ -19,4 +19,4 @@ .links.nested-linker = link_to_add_association t('footnotes.actions.add_footnote'), form, :footnotes, class: 'btn btn-outline-primary' - = form.button :submit, class: 'btn btn-default formSubmitr', form: 'notes_form' + = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'notes_form' diff --git a/app/views/line_footnotes/show.html.slim b/app/views/line_footnotes/show.html.slim index 36eebe288..6ad721711 100644 --- a/app/views/line_footnotes/show.html.slim +++ b/app/views/line_footnotes/show.html.slim @@ -2,7 +2,7 @@ = pageheader 'map-marker', "Notes sur la ligne #{@line.name}", 'Lorem ipsum dolor sit amet', - (@line.footnotes.any? ? t('last_update', time: l(@line.footnotes.last.updated_at, format: :short)) : ''), + '', (policy(@line).update_footnote? ? link_to(t('actions.edit'), edit_referential_line_footnotes_path(@referential, @line), class: 'btn btn-primary') : '') / PageContent diff --git a/app/views/lines/index.html.slim b/app/views/lines/index.html.slim index f8956ad62..ce4930d92 100644 --- a/app/views/lines/index.html.slim +++ b/app/views/lines/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @lines.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @lines - .row .col-lg-12 = render 'filters' @@ -24,8 +20,8 @@ { 'Oid' => Proc.new { |n| n.objectid.local_id }, :number => 'number', :name => 'name', - :network => Proc.new { |n| n.try(:network).try(:name) }, - :company => Proc.new { |n| n.try(:company).try(:name) }, + 'networks.name' => Proc.new { |n| n.try(:network).try(:name) }, + 'companies.name' => Proc.new { |n| n.try(:company).try(:name) }, :transport_mode => Proc.new { |n| n.transport_mode.nil? ? '-' : t("enumerize.line.transport_mode.#{n.try(:transport_mode)}") }, :transport_submode => Proc.new { |n| n.transport_submode.nil? ? '-' : t("enumerize.line.transport_submode.#{n.try(:transport_submode)}") } }, [:show, :delete], diff --git a/app/views/networks/index.html.slim b/app/views/networks/index.html.slim index 2aa636ded..7381b62f4 100644 --- a/app/views/networks/index.html.slim +++ b/app/views/networks/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @networks.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @networks - .row .col-lg-12 = search_form_for @q, url: line_referential_networks_path(@line_referential), html: {method: :get}, class: 'form form-filter' do |f| diff --git a/app/views/referential_companies/index.html.slim b/app/views/referential_companies/index.html.slim index 9375c6492..7a033fb5f 100644 --- a/app/views/referential_companies/index.html.slim +++ b/app/views/referential_companies/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @companies.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @companies - .row .col-lg-12 = search_form_for @q, url: referential_companies_path(@referential), html: {method: :get}, class: 'form form-filter' do |f| diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim index cd15cb0e0..78a504863 100644 --- a/app/views/referential_lines/show.html.slim +++ b/app/views/referential_lines/show.html.slim @@ -46,10 +46,6 @@ .row .col-lg-12 - if params[:q].present? or @routes.any? - / .row.mb-sm - / .col-lg-12.text-right - / = new_pagination @routes - .row .col-lg-12 = search_form_for @q, url: referential_line_path(@referential, @line), class: 'form form-filter' do |f| diff --git a/app/views/referential_networks/index.html.slim b/app/views/referential_networks/index.html.slim index 30a86d9b2..38ffb836a 100644 --- a/app/views/referential_networks/index.html.slim +++ b/app/views/referential_networks/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @networks.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @networks - .row .col-lg-12 = search_form_for @q, url: referential_networks_path(@referential), html: {method: :get}, class: 'form form-filter' do |f| diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim index f12f47aa4..04f93738e 100644 --- a/app/views/referentials/show.html.slim +++ b/app/views/referentials/show.html.slim @@ -3,24 +3,26 @@ @referential.name, 'Lorem ipsum dolor sit amet', t('last_update', time: l(@referential.updated_at, format: :short)), - link_to(t('actions.edit'), edit_referential_path(@referential), class: 'btn btn-default') do + ((@referential.archived? || !policy(@referential).edit?) ? '' : link_to(t('actions.edit'), edit_referential_path(@referential), class: 'btn btn-default')) do / Below is secundary actions & optional contents (filters, ...) .row.mb-sm .col-lg-12.text-right - / Actions are: controler, rapport de controle, dupliquer, purger, conserver, supprimer - = link_to t('actions.clone'), new_referential_path(from: @referential.id), class: 'btn btn-primary' + - if policy(@referential).new? + = link_to t('actions.clone'), new_referential_path(from: @referential.id), class: 'btn btn-primary' - button.btn.btn-primary type='button' data-toggle='modal' data-target='#purgeModal' Purger + - if policy(@referential).edit? + button.btn.btn-primary type='button' data-toggle='modal' data-target='#purgeModal' Purger - - if @referential.archived? - = link_to t('actions.unarchive'), unarchive_referential_path(@referential.id), method: :put, class: 'btn btn-primary' - - else - = link_to t('actions.archive'), archive_referential_path(@referential.id), method: :put, class: 'btn btn-primary' + - if @referential.archived? + = link_to t('actions.unarchive'), unarchive_referential_path(@referential.id), method: :put, class: 'btn btn-primary' + - else + = link_to t('actions.archive'), archive_referential_path(@referential.id), method: :put, class: 'btn btn-primary' - = link_to referential_path(@referential), method: :delete, data: {confirm: t('referentials.actions.destroy_confirm')}, class: 'btn btn-primary' do - span.fa.fa-trash - span = t('actions.destroy') + - if policy(@referential).destroy? + = link_to referential_path(@referential), method: :delete, data: {confirm: t('referentials.actions.destroy_confirm')}, class: 'btn btn-primary' do + span.fa.fa-trash + span = t('actions.destroy') / PageContent .page_content @@ -34,10 +36,6 @@ @referential.human_attribute_name(:published_at) => '-' } - if params[:q].present? or @reflines.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @reflines - .row .col-lg-12 = render 'filters' diff --git a/app/views/referentials/show.js.slim b/app/views/referentials/show.js.slim deleted file mode 100644 index 5e47bf935..000000000 --- a/app/views/referentials/show.js.slim +++ /dev/null @@ -1,19 +0,0 @@ -| $(function() { -| var ref, update_infos, update_referential_details, _i, _len, _ref, _results; -| update_infos = function(json) { -| var info, update_info; -| info = $('#referential_' + json.referential_id); -| update_info = function(key, value) { -| if (key.match(/_count$/)) { -| return $(info.find('.' + key)[0]).text(value); -| } -| }; -| return $.each(json, update_info); -| }; -| update_referential_details = function() { -| return $.getJSON("#{referential_path(@referential, format: :json)}", update_infos); -| }; -| _results = []; -| _results.push(update_referential_details()); -| return _results; -| }); diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim index 2603f64cb..ad389c482 100644 --- a/app/views/routes/_form.html.slim +++ b/app/views/routes/_form.html.slim @@ -9,7 +9,11 @@ = f.label :wayback, class: 'col-sm-4 control-label' = f.input :wayback, as: :boolean, checked_value: :straight_forward, unchecked_value: :backward, label: content_tag(:span, @route.wayback_text, class: 'switch-label', data: {checkedValue: t('enumerize.route.direction.straight_forward'), uncheckedValue: t('enumerize.route.direction.backward')}), wrapper_html: { class: 'col-sm-8'} - = f.input :opposite_route_id, collection: @candidate_opposite_routes + = f.input :opposite_route_id, collection: @forward, disabled: @route.wayback.straight_forward?, wrapper_html: {class: input_opposite_route_id_css(@route, 'straight_forward')} + + = f.input :opposite_route_id, collection: @backward, disabled: @route.wayback.backward?, wrapper_html: {class: input_opposite_route_id_css(@route, 'backward')} + + .separator diff --git a/app/views/routing_constraint_zones/_form.html.slim b/app/views/routing_constraint_zones/_form.html.slim index afc993a0f..f72dd1471 100644 --- a/app/views/routing_constraint_zones/_form.html.slim +++ b/app/views/routing_constraint_zones/_form.html.slim @@ -4,6 +4,9 @@ = f.input :name .row .col-lg-6.col-sm-12 + = f.input :route_id, collection: @line.routes + .row + .col-lg-6.col-sm-12 / Temporarily limit the collection to 10 items... otherwise it kills RoR = f.input :stop_area_ids, as: :select, collection: Chouette::StopArea.limit(10), selected: @routing_constraint_zone.stop_area_ids, label: Chouette::StopArea.model_name.human.pluralize.capitalize, label_method: :name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Sélection de arrêts', 'multiple': 'multiple', style: 'width: 100%' } diff --git a/app/views/routing_constraint_zones/index.html.slim b/app/views/routing_constraint_zones/index.html.slim index 9061fbdfd..e8da0f974 100644 --- a/app/views/routing_constraint_zones/index.html.slim +++ b/app/views/routing_constraint_zones/index.html.slim @@ -1,7 +1,7 @@ = title_tag Chouette::RoutingConstraintZone.model_name.human.pluralize(:fr) - if policy(Chouette::RoutingConstraintZone).create? && @referential.organisation == current_organisation - = link_to t('routing_constraint_zones.actions.new'), new_referential_line_routing_constraint_zone_path + = link_to t('routing_constraint_zones.actions.new'), new_referential_line_routing_constraint_zone_path(@referential, @line) - if @routing_constraint_zones.any? = table_builder @routing_constraint_zones, diff --git a/app/views/routing_constraint_zones/show.html.slim b/app/views/routing_constraint_zones/show.html.slim index 0f88f5b3f..7b7b63623 100644 --- a/app/views/routing_constraint_zones/show.html.slim +++ b/app/views/routing_constraint_zones/show.html.slim @@ -5,8 +5,8 @@ p = @routing_constraint_zone.name p - label => "#{Chouette::Line.model_name.human.capitalize} : " - = link_to @routing_constraint_zone.line.name, referential_line_path(@referential, @line) + label => "#{Chouette::Route.model_name.human.capitalize} : " + = link_to @routing_constraint_zone.route.name, referential_line_route_path(@referential, @line, @routing_constraint_zone.route) p label => "#{Chouette::StopArea.model_name.human.pluralize.capitalize} : " diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim index 4d062e6c8..c9ff2cecd 100644 --- a/app/views/stop_areas/index.html.slim +++ b/app/views/stop_areas/index.html.slim @@ -9,10 +9,6 @@ .page_content .container-fluid - if params[:q].present? or @stop_areas.any? - .row.mb-sm - .col-lg-12.text-right - = new_pagination @stop_areas - .row .col-lg-12 = render 'filters' diff --git a/app/views/time_tables/_date_fields.html.slim b/app/views/time_tables/_date_fields.html.slim index f17fcaa2c..1599dd7ff 100644 --- a/app/views/time_tables/_date_fields.html.slim +++ b/app/views/time_tables/_date_fields.html.slim @@ -1,5 +1,14 @@ -= f.inputs class: 'nested-fields date' do - = f.label @time_table.human_attribute_name("date"), class: 'col-md-1' - = f.input :date, as: :date_picker, :label => false, :input_html => { class: 'form-control col-md-3' } - = f.input :in_out, as: :hidden, :input_html => {:value => true} - = link_to_remove_association t('actions.destroy'), f, class: "col-md-3"
\ No newline at end of file +.nested-fields + - if f.object.errors.has_key? :base + .row + .col-lg-12 + .alert.alert-danger + - f.object.errors[:base].each do |message| + p.small = message + + .wrapper + div + = f.input :date, as: :date, label: false, wrapper_html: { class: 'date' } + = f.input :in_out, as: :hidden, :input_html => {:value => true} + div + = link_to_remove_association '', f, class: 'fa fa-trash', data: { confirm: 'Etes-vous sûr(e) ?' }, title: t('actions.delete') diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim index 8652f7cb5..f97e63d33 100644 --- a/app/views/time_tables/_form.html.slim +++ b/app/views/time_tables/_form.html.slim @@ -1,73 +1,100 @@ -= semantic_form_for [@referential, @time_table] do |form| - = form.inputs do - = form.input :comment, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.comment")} - = form.input :version - = form.input :tag_search, as: :tags, :input_html => { :id => "tag_search",:placeholder => t("formtastic.placeholders.time_table.tag_search") } - = form.input :tag_list, as: :hidden, :input_html => { :id => "tag_list" } - = form.input :objectid, :required => !@time_table.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.objectid")} - - if @time_table.new_record? - = form.input :calendar, as: :select, collection: current_organisation.calendars - - h3.time_table_periods = @time_table.human_attribute_name("periods") - - #periods_content - = form.inputs class: 'day_type' do - label.day_type_label = @time_table.human_attribute_name("day_types") - = form.input :monday, as: :boolean, class: "others" - = form.input :tuesday, as: :boolean - = form.input :wednesday, as: :boolean - = form.input :thursday, as: :boolean - = form.input :friday, as: :boolean - = form.input :saturday, as: :boolean - = form.input :sunday, as: :boolean - - #periods - = form.semantic_fields_for :periods do |p| - == render "period_fields", :f => p - - = link_to_add_association t("time_tables.actions.add_period"), form, :periods , :"data-association-insertion-method" => "append", :"data-association-insertion-node" => "div#periods" - - h3.time_table_dates = @time_table.human_attribute_name("dates") - - #dates_content - #dates - = form.semantic_fields_for :dates, @time_table.dates.to_a.select {|d| d.in_out == true} do |p| - == render "date_fields", :f => p - - = link_to_add_association t("time_tables.actions.add_date"), form, :dates, :"data-association-insertion-method" => "append", :"partial" => "date_fields", :"data-association-insertion-node" => "div#dates" - - h3.time_table_dates = @time_table.human_attribute_name("excluded_dates") - - #excluded_dates_content - #excluded_dates - = form.semantic_fields_for :dates, @time_table.dates.to_a.select {|d| d.in_out == false} do |p| - == render "excluded_date_fields", :f => p - - = link_to_add_association t("time_tables.actions.add_excluded_date"), form, :dates, :"data-association-insertion-method" => "append", :"partial" => "excluded_date_fields", :"data-association-insertion-node" => "div#excluded_dates" - - = form.actions do - = form.action :submit, as: :button - = form.action :cancel, as: :link - -= javascript_tag "var items = #{ @time_table.tag_list.to_a };" - -javascript: - $("#tag_search").tagsManager({ - prefilled: items, - output: '#tag_list', - tagsContainer: '#tagsContainer' - }); - - var time_tables_tag_list = new Bloodhound({ - datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'), - queryTokenizer: Bloodhound.tokenizers.whitespace, - remote: "#{tags_referential_time_tables_path(@referential, format: 'json')}?tag=%QUERY", - }); - - time_tables_tag_list.initialize(); - - $("#tag_search").typeahead(null, { - name: 'time_tables_tag_list', - displayKey: 'name', - source: time_tables_tag_list.ttAdapter() - }); += simple_form_for [@referential, @time_table], html: {class: 'form-horizontal', id: 'timetable_form'}, wrapper: :horizontal_form do |form| + + .row + .col-lg-12 + = form.input :comment, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.comment")} + = form.input :tag_list, as: :tags + + / = form.input :version + / = form.input :objectid, :required => !@time_table.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.objectid")} + + .form-group + label.control-label.col-sm-4 + = "Journées d'applications pour les périodes ci-dessous" + + .col-sm-8 + .form-group.labelled-checkbox-group + = form.input :monday, as: :boolean, label: ("<span class='lcbx-group-item-label'>L</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :tuesday, as: :boolean, label: ("<span class='lcbx-group-item-label'>Ma</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :wednesday, as: :boolean, label: ("<span class='lcbx-group-item-label'>Me</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :thursday, as: :boolean, label: ("<span class='lcbx-group-item-label'>J</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :friday, as: :boolean, label: ("<span class='lcbx-group-item-label'>V</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :saturday, as: :boolean, label: ("<span class='lcbx-group-item-label'>S</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + = form.input :sunday, as: :boolean, label: ("<span class='lcbx-group-item-label'>D</span>").html_safe, wrapper_html: { class: 'lcbx-group-item' } + + - if @time_table.new_record? + = form.input :calendar, as: :select, collection: current_organisation.calendars + + .separator + .row + .col-lg-12 + #periods + .alert.alert-info + |Intégration statique (avant Reactux) du composant 'periodes' + + .separator + + .row + .col-lg-8.col-lg-offset-4 + .subform + .nested-head + .wrapper + div + .form-group + label.control-label.required + = t('simple_form.labels.referential.metadatas.periods.begin') + abbr title='requis' * + div + .form-group + label.control-label.required + = t('simple_form.labels.referential.metadatas.periods.end') + abbr title='requis' * + div + + = form.simple_fields_for :periods do |p| + = render "period_fields", f: p + + .links.nested-linker + = link_to_add_association t("time_tables.actions.add_period"), form, :periods, class: 'btn btn-outline-primary' + + .row + .col-lg-12.mb-sm.mt-md + #periods + .alert.alert-warning + |Les éléments ci-dessous sont à supprimer. + + .row + .col-lg-6.col-md-6.col-sm-12.col-xs-12 + .subform + .nested-head + .wrapper + div + .form-group + label.control-label + = @time_table.human_attribute_name("dates") + div + + = form.simple_fields_for :dates, @time_table.dates.to_a.select {|d| d.in_out == true} do |p| + = render "date_fields", f: p + + .links.nested-linker + = link_to_add_association t("time_tables.actions.add_date"), form, :dates, class: 'btn btn-outline-primary' + + .col-lg-6.col-md-6.col-sm-12.col-xs-12 + .subform + .nested-head + .wrapper + div + .form-group + label.control-label + = @time_table.human_attribute_name("excluded_dates") + div + + = form.simple_fields_for :dates, @time_table.dates.to_a.select {|d| d.in_out == false} do |p| + = render "excluded_date_fields", f: p + + .links.nested-linker + = link_to_add_association t("time_tables.actions.add_excluded_date"), form, :dates, class: 'btn btn-outline-primary' + + + = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'timetable_form' diff --git a/app/views/time_tables/_period_fields.html.slim b/app/views/time_tables/_period_fields.html.slim index cefa68df5..f879ded00 100644 --- a/app/views/time_tables/_period_fields.html.slim +++ b/app/views/time_tables/_period_fields.html.slim @@ -1,8 +1,15 @@ -= f.inputs class: 'nested-fields period' do - = f.label @time_table.human_attribute_name("period_start"), class: "col-md-1" - = f.input :period_start, as: :date_picker, :label => false, :input_html => { class: 'form-control col-md-3' } - - = f.label @time_table.human_attribute_name("period_end"), class: "col-md-1" - = f.input :period_end, as: :date_picker, :label => false, :input_html => { class: 'form-control col-md-3' } - - = link_to_remove_association t('actions.destroy'), f, class: "col-md-2"
\ No newline at end of file +.nested-fields + - if f.object.errors.has_key? :base + .row + .col-lg-12 + .alert.alert-danger + - f.object.errors[:base].each do |message| + p.small = message + + .wrapper + div + = f.input :period_start, as: :date, label: false, wrapper_html: { class: 'date' } + div + = f.input :period_end, as: :date, label: false, wrapper_html: { class: 'date' } + div + = link_to_remove_association '', f, class: 'fa fa-trash', data: { confirm: 'Etes-vous sûr(e) ?' }, title: t('actions.delete') diff --git a/app/views/time_tables/_periods.html.slim b/app/views/time_tables/_periods.html.slim deleted file mode 100644 index e3c6d5f39..000000000 --- a/app/views/time_tables/_periods.html.slim +++ /dev/null @@ -1,5 +0,0 @@ -ul.periods - - @time_table.periods.each do |tmp| - li.period - = "#{('time_tables.show.from')} #{l tmp.period_start}" - = "#{t('time_tables.show.to')} #{l tmp.period_end}"
\ No newline at end of file diff --git a/app/views/time_tables/_show_time_table.html.slim b/app/views/time_tables/_show_time_table.html.slim index 419d13c96..f92f02b54 100644 --- a/app/views/time_tables/_show_time_table.html.slim +++ b/app/views/time_tables/_show_time_table.html.slim @@ -1,94 +1,26 @@ -#time_table_show.time_table_show - p - span class="state-code #{@time_table.presenter.time_table_state_code}" - i.fa.fa-certificate - - label - - if @time_table.bounding_dates.empty? - = t(".resume_empty") - - else - = t(".resume", :start_date => l(@time_table.bounding_dates.min), :end_date => l(@time_table.bounding_dates.max)) - - p - label = "#{@time_table.human_attribute_name('tag_list')} : " - = @time_table.tag_list - - ul.nav.nav-tabs id="tabs" data-tabs="tabs" - li.active - a href="#time_tables" data-toggle="tab" - = @time_table.human_attribute_name("calendars") - - li - a href="#time_tables_datas" data-toggle="tab" - = @time_table.human_attribute_name("calendar_details") - - #my-tab-content.tab-content - #time_tables.tab-pane.active - #associated_calendar - => "#{t('calendars.standard_calendar')} : " - - if @time_table.calendar - = link_to @time_table.calendar.name, @time_table.calendar - - else - = '--' - - .well.legend - span.title = t(".legend") - span.label.excluded_date X - = t(".excluded_date") - span.label.overlaped_date X - = t(".overlap_date") - span.label.selected_date X - = t(".selected_date") - span.label.selected_period X - = t(".selected_period") - - #calendars - .year_choice - span.previous = link_to("<", referential_time_table_path(@referential, @time_table, year: (@year - 1)) ) - span.year = "#{@year}" - span.next = link_to(">", referential_time_table_path(@referential, @time_table, year: (@year + 1)) ) - - .calendar_helper - - cal = "" - - (1..12).each do |month| - - cal << calendar(year: @year, month: month, first_day_of_week: 1) do |d| - - if @time_table.excluded_date?(d) - - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day excluded_date"}] - - elsif @time_table.include_in_overlap_dates?(d) - - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day overlaped_date"}] - - elsif @time_table.include_in_dates?(d) - - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_date"}] - - elsif @time_table.include_in_periods?(d) - - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_period"}] - - = cal.html_safe - - #time_tables_datas.tab-pane - .summary - p - label = "#{@time_table.human_attribute_name('version')} : " - = @time_table.version - - p - label = "#{@time_table.human_attribute_name('day_types')} : " - - if @time_table.int_day_types & 508 == 0 - label = "#{@time_table.human_attribute_name('none')} : " - - else - - %w(monday tuesday wednesday thursday friday saturday sunday).each do |day_type| - span class="#{@time_table.send(day_type) ? 'included_day_type' :'excluded_day_type'}" - = @time_table.human_attribute_name(day_type) - - - if @time_table.periods.present? - h3.time_table_periods = @time_table.human_attribute_name("periods") - .periods.content - == render 'time_tables/periods' - - - if @time_table.dates.where("in_out = true").present? - h3.time_table_dates = @time_table.human_attribute_name("dates") - .dates.content - == render "time_tables/dates" - - - if @time_table.dates.where("in_out = false").present? - h3.time_table_dates = @time_table.human_attribute_name("excluded_dates") - .excluded_dates.content - == render "time_tables/excluded_dates" +.calendar_helper + - cal = "" + - (1..12).each do |month| + - cal << calendar(year: @year, month: month, first_day_of_week: 1, calendar_title: "#{I18n.t("date.month_names")[month]} #{@year}") do |d| + - if @time_table.excluded_date?(d) + - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day excluded_date"}] + - elsif @time_table.include_in_overlap_dates?(d) + - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day overlaped_date"}] + - elsif @time_table.include_in_dates?(d) + - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_date"}] + - elsif @time_table.include_in_periods?(d) + - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_period"}] + + = cal.html_safe + + +/ wip +- if @time_table.dates.where("in_out = true").present? + h3.time_table_dates = @time_table.human_attribute_name("dates") + .dates.content + == render "time_tables/dates" + +- if @time_table.dates.where("in_out = false").present? + h3.time_table_dates = @time_table.human_attribute_name("excluded_dates") + .excluded_dates.content + == render "time_tables/excluded_dates" diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim index 1746b48c7..4f7cab845 100644 --- a/app/views/time_tables/edit.html.slim +++ b/app/views/time_tables/edit.html.slim @@ -1,3 +1,12 @@ -= title_tag t('time_tables.edit.title', :time_table => @time_table.comment) +/ PageHeader += pageheader 'map-marker', + @time_table.comment, + '', + '' -== render 'form'
\ No newline at end of file +/ PageContent +.page_content + .container-fluid + .row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 + == render 'form' diff --git a/app/views/time_tables/index.js.slim b/app/views/time_tables/index.js.slim deleted file mode 100644 index bc9585c4b..000000000 --- a/app/views/time_tables/index.js.slim +++ /dev/null @@ -1 +0,0 @@ -| $('#time_tables').html("#{escape_javascript(render('time_tables'))}");
\ No newline at end of file diff --git a/app/views/time_tables/index.json.rabl b/app/views/time_tables/index.json.rabl deleted file mode 100644 index 443cb13a2..000000000 --- a/app/views/time_tables/index.json.rabl +++ /dev/null @@ -1,9 +0,0 @@ -collection @time_tables, :object_root => false - -node do |time_table| - { :id => time_table.id, :comment => time_table.comment, - :time_table_bounding => time_table_bounding( time_table), - :composition_info => composition_info(time_table), - :tags => time_table.tags.join(','), - :day_types => %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| time_table.send(d) }.map{ |d| time_table.human_attribute_name(d).first(2)}.join('')} -end diff --git a/app/views/time_tables/index.rabl b/app/views/time_tables/index.rabl new file mode 100644 index 000000000..d8b7c6e0c --- /dev/null +++ b/app/views/time_tables/index.rabl @@ -0,0 +1,2 @@ +collection @time_tables, :object_root => false +extends "time_tables/show" diff --git a/app/views/time_tables/show.html.slim b/app/views/time_tables/show.html.slim index 436886faa..54d26875e 100644 --- a/app/views/time_tables/show.html.slim +++ b/app/views/time_tables/show.html.slim @@ -1,27 +1,53 @@ - require 'calendar_helper' -= title_tag t('time_tables.show.title', :time_table => @time_table.comment ) +/ PageHeader += pageheader 'map-marker', + @time_table.comment, + '', + (policy(@time_table).edit? ? link_to(t('actions.edit'), edit_referential_time_table_path(@referential, @time_table), class: 'btn btn-default') : '') -== render 'time_table_combinations/combine' + / Below is secundary actions & optional contents (filters, ...) + .row.mb-sm + .col-lg-12.text-right + / - if policy(@time_table).create? && @referential.organisation == current_organisation + / = link_to t('time_tables.actions.new'), new_referential_time_table_path(@referential), class: 'btn btn-primary' -== render 'show_time_table' + /- if policy(@time_table).create? && @referential.organisation == current_organisation + = link_to t('actions.combine'), new_referential_time_table_time_table_combination_path(@referential, @time_table), {remote: true, 'data-toggle' => "modal", 'data-target' => '#modal_combine', class: 'btn btn-primary' } -- content_for :sidebar do - ul.actions - li - if policy(@time_table).create? && @referential.organisation == current_organisation - = link_to t('time_tables.actions.new'), new_referential_time_table_path(@referential), class: 'add' - li - - if policy(@time_table).edit? - = link_to t('time_tables.actions.edit'), edit_referential_time_table_path(@referential, @time_table), class: "edit" - li + = link_to t('actions.clone'), duplicate_referential_time_table_path(@referential, @time_table), class: 'btn btn-primary' + - if policy(@time_table).destroy? - = link_to t('time_tables.actions.destroy'), referential_time_table_path(@referential, @time_table), :method => :delete, :data => {:confirm => t('time_tables.actions.destroy_confirm')}, class: "remove" - li - - if policy(@time_table).create? && @referential.organisation == current_organisation - = link_to t('time_tables.actions.duplicate'), duplicate_referential_time_table_path(@referential, @time_table), class: "clone" - li - /- if policy(@time_table).create? && @referential.organisation == current_organisation - = link_to t('time_tables.actions.combine'), new_referential_time_table_time_table_combination_path(@referential, @time_table), {:remote => true, 'data-toggle' => "modal", 'data-target' => '#modal_combine', class: "merge"} + = link_to referential_time_table_path(@referential, @time_table), method: :delete, data: {confirm: t('time_tables.actions.destroy_confirm')}, class: 'btn btn-primary' do + span.fa.fa-trash + span = t('actions.destroy') + +/ PageContent +.page_content + .container-fluid + .row + .col-lg-6.col-md-6.col-sm-12.col-xs-12 + = definition_list t('metadatas'), + { "Période d'application" => (@time_table.bounding_dates.empty? ? '-' : t('bounding_dates', debut: l(@time_table.bounding_dates.min), end: l(@time_table.bounding_dates.max))), + 'Etiquettes' => @time_table.tag_list.collect{ |t| content_tag(:span, t, class: 'label label-default') }.join().html_safe, + 'Modèle de calendrier' => (@time_table.calendar ? link_to(@time_table.calendar.name, @time_table.calendar) : '-'), + "Journées d'application pour les périodes ci-dessous" => %w(monday tuesday wednesday thursday friday saturday sunday).collect{ |d| content_tag(:span, t("calendars.days.#{d}"), class: "label label-default #{@time_table.send(d) ? '' : 'disabled'}") }.join.html_safe } + + .row + .col-lg-12 + .pagination.pull-right + = @year + .page_links + = link_to '', referential_time_table_path(@referential, @time_table, year: (@year - 1)), class: 'previous_page' + = link_to '', referential_time_table_path(@referential, @time_table, year: (@year + 1)), class: 'next_page' + + .row + .col-lg-12 + / To update + = render 'show_time_table' - = creation_tag(@time_table) + .row + .col-lg-12 + / WTF ??! + = render 'time_table_combinations/combine' diff --git a/app/views/time_tables/show.rabl b/app/views/time_tables/show.rabl new file mode 100644 index 000000000..a4434c518 --- /dev/null +++ b/app/views/time_tables/show.rabl @@ -0,0 +1,24 @@ +object @time_table + +attributes :id, :comment +node do |tt| + { + time_table_bounding: tt.presenter.time_table_bounding, + tags: tt.tags.map(&:name), + day_types: %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| tt.send(d) }.map{ |d| tt.human_attribute_name(d).first(2)}.join(''), + current_month: tt.month_inspect(Date.today), + periode_range: month_periode_enum(3), + } +end + +child(:periods, object_root: false) do + attributes :id, :period_start, :period_end +end + +child(:dates, object_root: false) do + attributes :id, :date, :in_out +end + +child(:calendar) do + attributes :id, :name +end diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim index 6cdf1d7d5..92bc3951a 100644 --- a/app/views/vehicle_journeys/index.html.slim +++ b/app/views/vehicle_journeys/index.html.slim @@ -2,7 +2,7 @@ = pageheader 'map-marker', t('vehicle_journeys.index.title', route: @route.name ), 'Lorem ipsum dolor sit amet', - t('last_update', time: l(@vehicle_journeys.last.updated_at, format: :short)) do + '' do / PageContent .page_content diff --git a/app/views/workbenches/_filters.html.slim b/app/views/workbenches/_filters.html.slim index 7a962f927..7c5055963 100644 --- a/app/views/workbenches/_filters.html.slim +++ b/app/views/workbenches/_filters.html.slim @@ -13,7 +13,9 @@ .form-group.togglable = f.label @wbench_refs.human_attribute_name(:status), required: false, class: 'control-label' - = f.input :archived_at_not_null, label: ("<span>Conservé<span class='fa fa-archive'></span></span>").html_safe, as: :boolean, wrapper_html: { class: 'checkbox_list' }, input_html: { class: 'check_boxes' } + .form-group.checkbox_list + = f.input :archived_at_not_null, label: ("<span>Conservé<span class='fa fa-archive'></span></span>").html_safe, as: :boolean, wrapper_html: { class: 'checkbox-wrapper' } + = f.input :archived_at_null, label: ("<span>En préparation<span class='sb sb-lg sb-preparing'></span></span>").html_safe, as: :boolean, wrapper_html: { class: 'checkbox-wrapper' } .form-group.togglable = f.label 'Organisation(s)', required: false, class: 'control-label' @@ -23,8 +25,8 @@ = f.label @wbench_refs.human_attribute_name(:validity_period), required: false, class: 'control-label' .filter_menu = f.simple_fields_for :validity_period do |p| - = p.input :begin_gteq, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date filter_menu-item' }, include_blank: true - = p.input :end_lteq, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date filter_menu-item' }, include_blank: true + = p.input :begin_gteq, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true + = p.input :end_lteq, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date filter_menu-item' }, default: @end_range, include_blank: @end_range ? false : true .actions = link_to 'Effacer', @workbench, class: 'btn btn-link' diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index 93c9ae40d..2d13501b7 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -2,7 +2,7 @@ = pageheader 'map-marker', t('referentials.index.title'), 'Lorem ipsum dolor sit amet', - t('last_update', time: l(@workbench.updated_at, format: :short)) do + '' do / Below is secundary actions & optional contents (filters, ...) .row.mb-sm @@ -13,10 +13,6 @@ .page_content .container-fluid - if params[:q].present? or @wbench_refs.any? - / .row.mb-sm - / .col-lg-12.text-right - / = new_pagination @wbench_refs - .row .col-lg-12 = render 'filters' @@ -26,7 +22,7 @@ .col-lg-12 = table_builder @wbench_refs, { :name => 'name', - :status => Proc.new {|w| w.archived? ? ("<span class='fa fa-archive'></span> Conservé").html_safe : '-'}, + :status => Proc.new {|w| w.archived? ? ("<div class='td-block'><span class='fa fa-archive'></span><span>Conservé</span></div>").html_safe : ("<div class='td-block'><span class='sb sb-lg sb-preparing'></span><span>En préparation</span></div>").html_safe}, :organisation => Proc.new {|w| w.organisation.name}, :validity_period => Proc.new {|w| w.validity_period.nil? ? '-' : t('validity_range', debut: l(w.try(:validity_period).try(:begin), format: :short), end: l(w.try(:validity_period).try(:end), format: :short))}, :lines => Proc.new {|w| w.lines.count}, diff --git a/config/environments/development.rb b/config/environments/development.rb index 61a0b97e9..0b4eab7d2 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -78,6 +78,9 @@ Rails.application.configure do config.codifligne_url = "https://pprod.codifligne.stif.info" config.portal_url = "http://stif-boiv-staging.af83.priv" + # IEV url + config.iev_url = "localhost:8080" + # file to data for demo config.demo_data = "tmp/demo.zip" diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 8f0eb6c10..2c2632f40 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -39,7 +39,11 @@ Apartment.configure do |config| "Workbench", "CleanUp", "CleanUpResult", - "Calendar" + "Calendar", + "Import", + "NetexImport", + "ImportMessage", + "ImportResource" ] # use postgres schemas? @@ -56,7 +60,7 @@ Apartment.configure do |config| # config.append_environment = true # supply list of database names for migrations to run on - config.tenant_names = lambda{ Referential.pluck :slug } + config.tenant_names = lambda{ Referential.order("created_from_id asc").pluck(:slug) } end ## diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml index e4b0bcb28..a5fbbeb64 100644 --- a/config/locales/actions.en.yml +++ b/config/locales/actions.en.yml @@ -11,6 +11,7 @@ en: clone: 'Clone' clean_up: 'Clean up' sync: 'Synchronize' + combine: 'Combine' or: "or" cancel: "Cancel" search_hint: "Type in a search term" diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml index 0cd3de8e5..f6e4d74e2 100644 --- a/config/locales/actions.fr.yml +++ b/config/locales/actions.fr.yml @@ -12,6 +12,7 @@ fr: clone: 'Dupliquer' clean_up: 'Purger' sync: 'Synchroniser' + combine: 'Combiner' or: "ou" cancel: "Annuler" search_hint: "Entrez un texte à rechercher" diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml index cb63afde5..17dc8baf1 100644 --- a/config/locales/calendars.en.yml +++ b/config/locales/calendars.en.yml @@ -1,5 +1,13 @@ en: calendars: + days: + monday: M + tuesday: Tu + wednesday: W + thursday: Th + friday: F + saturday: Sa + sunday: Su standard_calendars: Standard calendars standard_calendar: Standard calendar actions: diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml index 81254c81e..32e3c66d2 100644 --- a/config/locales/calendars.fr.yml +++ b/config/locales/calendars.fr.yml @@ -1,5 +1,26 @@ fr: calendars: + days: + monday: L + tuesday: Ma + wednesday: Me + thursday: J + friday: V + saturday: S + sunday: D + months: + 1: Janvier + 2: Février + 3: Mars + 4: Avril + 5: Mai + 6: Juin + 7: Juillet + 8: Août + 9: Septembre + 10: Octobre + 11: Novembre + 12: Décembre standard_calendars: Calendriers standards standard_calendar: Calendrier standard actions: diff --git a/config/locales/en.yml b/config/locales/en.yml index 7c8e58505..5ed0b9ec5 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -16,4 +16,5 @@ en: last_update: 'Last update on<br>%{time}' last_sync: 'Last sync on %{time}' validity_range: '%{debut} > %{end}' - metadatas: 'Metadatas' + bounding_dates: '%{debut} > %{end}' + metadatas: 'Informations' diff --git a/config/locales/fr.yml b/config/locales/fr.yml index c48ba8835..db8a3608d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -16,4 +16,5 @@ fr: last_update: 'Dernière mise à jour<br>le %{time}' last_sync: 'Dernière mise à jour le %{time}' validity_range: '%{debut} > %{end}' - metadatas: 'Métadonnées' + bounding_dates: '%{debut} > %{end}' + metadatas: 'Informations' diff --git a/config/locales/lines.fr.yml b/config/locales/lines.fr.yml index 8012ff077..869ac8ce2 100644 --- a/config/locales/lines.fr.yml +++ b/config/locales/lines.fr.yml @@ -70,7 +70,7 @@ fr: name: "Nom de la ligne" published_name: "Nom public" number: "Nom court" - transport_mode: "Mode" + transport_mode: "Mode de transport" transport_submode: "Sous mode de transport" url: "Page web associée" color: "Couleur du tracé" diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml index 7151309eb..b9e337503 100644 --- a/config/locales/referentials.fr.yml +++ b/config/locales/referentials.fr.yml @@ -114,7 +114,7 @@ fr: referentials: deleted: "Les jeux de données on été supprimés" referential: - archived: "Le jeu de données a été correctement archivé" - unarchived: "Le jeu de données a été correctement désarchivé" - unarchived_failed: "Le jeu de données ne peut être désarchivé" + archived: "Le jeu de données a été correctement conservé" + unarchived: "Le jeu de données a été correctement déconservé" + unarchived_failed: "Le jeu de données ne peut être déconservé" deleted: "Le jeu de données a été correctement supprimé" diff --git a/config/routes.rb b/config/routes.rb index 33f3961b1..12dbf0986 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -211,8 +211,9 @@ ChouetteIhm::Application.routes.draw do get '/help/(*slug)' => 'help#show' - get '/404', :to => 'errors#not_found' - get '/422', :to => 'errors#server_error' - get '/500', :to => 'errors#server_error' + get '/404', to: 'errors#not_found' + get '/403', to: 'errors#not_allowed' + get '/422', to: 'errors#server_error' + get '/500', to: 'errors#server_error' end diff --git a/db/migrate/20170317114614_remove_stop_points_route_fk.rb b/db/migrate/20170317114614_remove_stop_points_route_fk.rb index ff191445a..b02516328 100644 --- a/db/migrate/20170317114614_remove_stop_points_route_fk.rb +++ b/db/migrate/20170317114614_remove_stop_points_route_fk.rb @@ -1,6 +1,6 @@ class RemoveStopPointsRouteFk < ActiveRecord::Migration def change - if foreign_keys(:stop_points).include?(:stoppoint_route_fkey) + if foreign_keys(:stop_points).any? { |f| f.options[:name] = :stoppoint_route_fkey } remove_foreign_key :stop_points, name: :stoppoint_route_fkey end end diff --git a/db/migrate/20170321141620_add_type_to_imports.rb b/db/migrate/20170321141620_add_type_to_imports.rb index cba497ad1..fc4619969 100644 --- a/db/migrate/20170321141620_add_type_to_imports.rb +++ b/db/migrate/20170321141620_add_type_to_imports.rb @@ -1,7 +1,7 @@ class AddTypeToImports < ActiveRecord::Migration def up add_column :imports, :type, :string - execute "update imports set type = 'netex_import' where type is null" + execute "update imports set type = 'NetexImport' where type is null" end def down diff --git a/db/migrate/20170322075010_delete_translations.rb b/db/migrate/20170322075010_delete_translations.rb index 76976f6b8..7005ffcaf 100644 --- a/db/migrate/20170322075010_delete_translations.rb +++ b/db/migrate/20170322075010_delete_translations.rb @@ -1,5 +1,7 @@ class DeleteTranslations < ActiveRecord::Migration def change - drop_table :translations + if table_exists?('translations') + drop_table :translations + end end end diff --git a/db/migrate/20170403155202_add_departure_arrival_day_offsets_to_vjas.rb b/db/migrate/20170403155202_add_departure_arrival_day_offsets_to_vjas.rb new file mode 100644 index 000000000..ac580b990 --- /dev/null +++ b/db/migrate/20170403155202_add_departure_arrival_day_offsets_to_vjas.rb @@ -0,0 +1,6 @@ +class AddDepartureArrivalDayOffsetsToVjas < ActiveRecord::Migration + def change + add_column :vehicle_journey_at_stops, :departure_day_offset, :integer + add_column :vehicle_journey_at_stops, :arrival_day_offset, :integer + end +end diff --git a/db/migrate/20170404122930_add_route_rm_line_from_routing_constraint_zone.rb b/db/migrate/20170404122930_add_route_rm_line_from_routing_constraint_zone.rb new file mode 100644 index 000000000..f53c0b503 --- /dev/null +++ b/db/migrate/20170404122930_add_route_rm_line_from_routing_constraint_zone.rb @@ -0,0 +1,6 @@ +class AddRouteRmLineFromRoutingConstraintZone < ActiveRecord::Migration + def change + remove_column :routing_constraint_zones, :line_id, :bigint + add_column :routing_constraint_zones, :route_id, :bigint + end +end diff --git a/db/schema.rb b/db/schema.rb index a6b237542..c49f52067 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170322075010) do +ActiveRecord::Schema.define(version: 20170404122930) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -543,16 +543,14 @@ ActiveRecord::Schema.define(version: 20170322075010) do create_table "routing_constraint_zones", force: true do |t| t.string "name" t.integer "stop_area_ids", array: true - t.integer "line_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" t.string "objectid", null: false t.integer "object_version", limit: 8 t.string "creator_id" + t.integer "route_id", limit: 8 end - add_index "routing_constraint_zones", ["line_id"], :name => "index_routing_constraint_zones_on_line_id" - create_table "routing_constraints_lines", id: false, force: true do |t| t.integer "stop_area_id", limit: 8 t.integer "line_id", limit: 8 @@ -781,6 +779,8 @@ ActiveRecord::Schema.define(version: 20170322075010) do t.time "departure_time" t.string "for_boarding" t.string "for_alighting" + t.integer "departure_day_offset" + t.integer "arrival_day_offset" end add_index "vehicle_journey_at_stops", ["stop_point_id"], :name => "index_vehicle_journey_at_stops_on_stop_pointid" @@ -849,8 +849,6 @@ ActiveRecord::Schema.define(version: 20170322075010) do add_foreign_key "stop_areas_stop_areas", "stop_areas", name: "stoparea_child_fkey", column: "child_id", dependent: :delete add_foreign_key "stop_areas_stop_areas", "stop_areas", name: "stoparea_parent_fkey", column: "parent_id", dependent: :delete - add_foreign_key "stop_points", "routes", name: "stoppoint_route_fkey", dependent: :delete - add_foreign_key "time_table_dates", "time_tables", name: "tm_date_fkey", dependent: :delete add_foreign_key "time_table_periods", "time_tables", name: "tm_period_fkey", dependent: :delete diff --git a/lib/activeattr_ext.rb b/lib/activeattr_ext.rb index b4c112b72..7803bbecc 100644 --- a/lib/activeattr_ext.rb +++ b/lib/activeattr_ext.rb @@ -28,7 +28,8 @@ module ActiveAttr::MultiParameterAttributes single_parameter_attributes.merge( multi_parameter_attributes.inject({}) do |hash, (key, args)| if args.all?(&:present?) - hash.merge(key => _attribute_type(key).new(*args)) + value = _attribute_type(key).new(*args) rescue nil + hash.merge(key => value) else hash end diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb index 68f7fc621..fee54f4c1 100644 --- a/lib/stif/reflex_synchronization.rb +++ b/lib/stif/reflex_synchronization.rb @@ -71,12 +71,15 @@ module Stif end def stop_area_area_type entry, method + from = method.last + from = 'r' if entry['OBJECT_STATUS'] == 'REFERENCE_OBJECT' + from = 'p' if entry['OBJECT_STATUS'] == 'LOCAL_OBJECT' + type = entry['TypeOfPlaceRef'] + if entry['type'] == 'Quay' - type = 'zder' if entry['OBJECT_STATUS'] == 'REFERENCE_OBJECT' - type = 'zdep' if entry['OBJECT_STATUS'] == 'LOCAL_OBJECT' + type = "zde#{from}" else - type = entry['TypeOfPlaceRef'] - type = "#{type.to_s}#{method.last}" unless type == 'LDA' + type = "zdl#{from}" if type != 'LDA' end type.downcase end diff --git a/lib/tasks/referential.rake b/lib/tasks/referential.rake new file mode 100644 index 000000000..caee2042a --- /dev/null +++ b/lib/tasks/referential.rake @@ -0,0 +1,56 @@ +# execution example: rake 'referential:create[3, 1896, '01-01-2017', '01-04-2017']' + +namespace :referential do + desc 'Create a referential and accompanying data' + task :create, [:workbench_id, :line_id, :start_date, :end_date] => [:environment] do |t, args| + workbench = Workbench.find_by!(id: args[:workbench_id]) + line = workbench.line_referential.lines.find_by!(id: args[:line_id]) + name = "Referential #{Faker::Name.unique.name}" + referential = workbench.referentials.create!(name: name, slug: name.downcase.parameterize.underscore, organisation: workbench.organisation, + prefix: Faker::Lorem.unique.characters(10)) + ReferentialMetadata.create!(referential: referential, line_ids: [args[:line_id]], periodes: [Date.parse(args[:start_date])..Date.parse(args[:end_date])]) + referential.switch + + routes = [] + stop_areas = workbench.stop_area_referential.stop_areas.last(10) + + 4.times do |i| + route_attrs = { line_id: args[:line_id].to_i, name: "Route #{Faker::Name.unique.name}" } + if i.even? + route_attrs[:wayback] = :straight_forward + route = Chouette::Route.create!(route_attrs) + route.stop_areas = stop_areas + else + route_attrs[:wayback] = :backward + route_attrs[:opposite_route] = Chouette::Route.last if i == 3 + route = Chouette::Route.create!(route_attrs) + route.stop_areas = stop_areas.reverse + end + route.save! + + journey_pattern = Chouette::JourneyPattern.create!(route: route, name: "Journey pattern #{Faker::Name.unique.name}") + journey_pattern.stop_points = stop_areas.inject([]) { |stop_points, stop_area| stop_points += stop_area.stop_points } + + 25.times do |j| + vehicle_journey = Chouette::VehicleJourney.create!(journey_pattern: journey_pattern, route: route, number: Faker::Number.unique.number(4)) + time = Time.current.at_noon + j.minutes + journey_pattern.stop_points.each_with_index do |stop_point, k| + vjas = Chouette::VehicleJourneyAtStop.create!(stop_point: stop_point, arrival_time: time + k.minutes, departure_time: time + k.minutes + 30.seconds) + end + end + + 2.times do |j| + name = "Calendar #{Faker::Name.unique.name}" + calendar = Calendar.create!(name: name, short_name: name.parameterize, organisation: workbench.organisation, + date_ranges: [(Date.parse(args[:start_date]) + j.days)..(Date.parse(args[:end_date]) - j.days)]) + Chouette::TimeTable.create!(comment: Faker::Lorem.sentence(3), calendar: calendar, start_date: Date.parse(args[:start_date]) + j.days, + end_date: Date.parse(args[:end_date]) - j.days) + end + end + + end +end + + + + diff --git a/package.json b/package.json index 019e63063..4e975de5c 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,14 @@ "babelify": "7.3.0", "browserify": "13.1.1", "browserify-incremental": "3.1.1", - "lodash": "^4.17.4", + "lodash": "4.17.4", + "promise-polyfill": "^6.0.2", "react": "15.3.2", "react-dom": "15.3.2", "react-redux": "4.4.5", "react-select2": "4.0.2", - "redux": "3.6.0" + "redux": "3.6.0", + "whatwg-fetch": "2.0.3" }, "license": "MIT", "engines": { diff --git a/public/403.html b/public/403.html deleted file mode 100644 index 34d6e6bad..000000000 --- a/public/403.html +++ /dev/null @@ -1,65 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <title>The page you were looking is forbidden (403)</title> - <meta name="viewport" content="width=device-width,initial-scale=1"> - <style> - body { - background-color: #EFEFEF; - color: #2E2F30; - text-align: center; - font-family: arial, sans-serif; - margin: 0; - } - - div.dialog { - width: 95%; - max-width: 33em; - margin: 4em auto 0; - } - - div.dialog > div { - border: 1px solid #CCC; - border-right-color: #999; - border-left-color: #999; - border-bottom-color: #BBB; - border-top: #B00100 solid 4px; - border-top-left-radius: 9px; - border-top-right-radius: 9px; - background-color: white; - padding: 7px 12% 0; - box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17); - } - - h1 { - font-size: 100%; - color: #730E15; - line-height: 1.5em; - } - - div.dialog > p { - margin: 0 0 1em; - padding: 1em; - background-color: #F7F7F7; - border: 1px solid #CCC; - border-right-color: #999; - border-left-color: #999; - border-bottom-color: #999; - border-bottom-left-radius: 4px; - border-bottom-right-radius: 4px; - border-top-color: #DADADA; - color: #666; - box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17); - } - </style> -</head> - -<body> - <!-- This file lives in public/403.html --> - <div class="dialog"> - <div> - <h1>The page you were looking is forbidden.</h1> - </div> - </div> -</body> -</html> diff --git a/public/404.html b/public/404.html deleted file mode 100644 index 72bd4129d..000000000 --- a/public/404.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <!-- <link href="assets/application.css" media="screen" rel="stylesheet" type="text/css" /> --> - <title>The page you were looking for doesn't exist (404)</title> - <style type="text/css"> - body { background-color: #fff; text-align: center; } - div.dialog { - width: 45em; - padding:1em; - margin: 2em auto 0 auto; - border: 1px solid #ccc; - border-right-color: #999; - border-bottom-color: #999; - } - h1 { font-size: 100%; color: #f00; line-height: 1.5em; font-weight: bold} - a,a:visited { text-decoration: underline; color: blue} - </style> -</head> - -<body> - <!-- This file lives in public/404.html - <div id="header"> - <div class="infos"> - <div class="logo"> - <a href="referentials"> - <img src="assets/logo_chouette.png" alt="Logo_chouette"> - </a> - </div> - </div> - </div>--> - <div class="dialog"> - <h1>Désolé, la page demandée n'existe pas</h1> - <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">N'hésitez pas à nous décrire le problème</a>, nous essaierons de le résoudre.<br/>Merci d'avance<br/> <br/> - Vous pouvez néanmoins continuer à utiliser l'application CHOUETTE<br/> - <a href="javascript:history.back()" >Retour</a><br/> - <!-- <a href="referentials" >Accueil</a> --> - <br/> <br/><br/> <br/> - <h1>The page you were looking for doesn't exist.</h1> - You may have mistyped the address or the page may have moved. <br/> - <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">Please describe us what happened</a>, we'll try to come back with an answer. <br/>Thank you. <br/> <br/> - You can still continue the use the CHOUETTE application. <br/> - <a href="javascript:history.back()" >Back</a><br/> - <!-- <a href="referentials" >Home</a> --> - </div> -</body> -</html> diff --git a/public/422.html b/public/422.html deleted file mode 100644 index ea857f263..000000000 --- a/public/422.html +++ /dev/null @@ -1,47 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <!-- <link href="assets/application.css" media="screen" rel="stylesheet" type="text/css" /> --> - <title>The change you wanted was rejected (422)</title> - <style type="text/css"> - body { background-color: #fff; text-align: center; } - div.dialog { - width: 45em; - padding:1em; - margin: 2em auto 0 auto; - border: 1px solid #ccc; - border-right-color: #999; - border-bottom-color: #999; - } - h1 { font-size: 100%; color: #f00; line-height: 1.5em; font-weight: bold} - a,a:visited { text-decoration: underline; color: blue} - </style> -</head> - -<body> - <!-- This file lives in public/422.html - <div id="header"> - <div class="infos"> - <div class="logo"> - <a href="referentials"> - <img src="assets/logo_chouette.png" alt="Logo_chouette"> - </a> - </div> - </div> - </div>--> - <div class="dialog"> - <h1>La modification demandée a été refusée</h1> - <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">N'hésitez pas à nous décrire le problème</a>, nous essaierons de le résoudre.<br/>Merci d'avance<br/> <br/> - Vous pouvez néanmoins continuer à utiliser l'application CHOUETTE<br/> - <a href="javascript:history.back()" >Retour</a><br/> - <!-- <a href="referentials" >Accueil</a> --> - <br/> <br/><br/> <br/> - <h1>The change you wanted was rejected.</h1> - Maybe you tried to change something you didn't have access to. <br/> - <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">Please describe us what happened</a>, we'll try to come back with an answer. <br/>Thank you. <br/> <br/> - You can still continue the use the CHOUETTE application. <br/> - <a href="javascript:history.back()" >Back</a><br/> - <!-- <a href="referentials" >Home</a> --> - </div> -</body> -</html> diff --git a/public/500.html b/public/500.html deleted file mode 100644 index 22a514e37..000000000 --- a/public/500.html +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE html>
-<html><head>
- <title>We're sorry, but something went wrong (500)</title>
- <style type="text/css">
- body { background-color: #fff; text-align: center; }
- div.dialog {
- width: 45em;
- padding:1em;
- margin: 2em auto 0 auto;
- border: 1px solid #ccc;
- border-right-color: #999;
- border-bottom-color: #999;
- }
- h1 { font-size: 100%; color: #f00; line-height: 1.5em; font-weight: bold}
- a,a:visited { text-decoration: underline; color: blue}
- </style>
-</head>
-
-<body>
- <!-- This file lives in public/500.html
- <div id="header">
- <div class="infos">
- <div class="logo">
- <a href="referentials">
- <img src="assets/logo_chouette.png" alt="Logo_chouette">
- </a>
- </div>
- </div>
- </div>-->
- <div class="dialog">
- <h1>Désolé, une erreur est survenue</h1>
- <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">N'hésitez pas à nous décrire le problème</a>, nous essaierons de le résoudre.<br/>Merci d'avance<br/> <br/>
- Vous pouvez néanmoins continuer à utiliser l'application CHOUETTE<br/>
- <a href="javascript:history.back()" >Retour</a><br/>
- <!-- <a href="referentials" >Accueil</a> -->
- <br/> <br/><br/> <br/>
- <h1>We're sorry, but something went wrong.</h1>
- <a href="http://www.chouette.mobi/spip.php?rubrique38" target="_blank">Please describe us what happened</a>, we'll try to come back with an answer. <br/>Thank you. <br/> <br/>
- You can still continue the use the CHOUETTE application. <br/>
- <a href="javascript:history.back()" >Back</a><br/>
- <!-- <a href="referentials" >Home</a> -->
- </div>
-</body>
-</html>
\ No newline at end of file diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb index 442a10bbd..1b4533fca 100644 --- a/spec/controllers/referentials_controller_spec.rb +++ b/spec/controllers/referentials_controller_spec.rb @@ -4,4 +4,23 @@ describe ReferentialsController, :type => :controller do login_user + let(:referential) { Referential.first } + let(:organisation) { create :organisation } + let(:other_referential) { create :referential, organisation: organisation } + + describe 'PUT archive' do + context "user's organisation matches referential's organisation" do + it 'returns http success' do + put :archive, id: referential.id + expect(response).to have_http_status(302) + end + end + + context "user's organisation doesn't match referential's organisation" do + it 'raises a ActiveRecord::RecordNotFound' do + expect { put :archive, id: other_referential.id }.to raise_error(ActiveRecord::RecordNotFound) + end + end + end + end diff --git a/spec/factories/chouette_routing_constraint_zones.rb b/spec/factories/chouette_routing_constraint_zones.rb index 9a2529483..2f707e6a6 100644 --- a/spec/factories/chouette_routing_constraint_zones.rb +++ b/spec/factories/chouette_routing_constraint_zones.rb @@ -2,6 +2,6 @@ FactoryGirl.define do factory :routing_constraint_zone, class: Chouette::RoutingConstraintZone do sequence(:name) { |n| "Routing constraint zone #{n}" } stop_area_ids { [create(:stop_area).id, create(:stop_area).id] } - association :line, factory: :line + association :route, factory: :route end end diff --git a/spec/features/referentials_spec.rb b/spec/features/referentials_spec.rb index 39c5adcd5..ebaf70bca 100644 --- a/spec/features/referentials_spec.rb +++ b/spec/features/referentials_spec.rb @@ -4,6 +4,8 @@ require 'spec_helper' describe "Referentials", :type => :feature do login_user + let(:referential) { Referential.first } + describe "index" do # FIXME #823 @@ -33,6 +35,28 @@ describe "Referentials", :type => :feature do end + describe "show" do + before(:each) { visit referential_path(referential) } + + it "displays referential" do + expect(page).to have_content(referential.name) + end + + context 'archived referential' do + it 'link to edit referetnial is not displayed' do + referential.archive! + visit referential_path(referential) + expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_path(referential)) + end + end + + context 'unarchived referential' do + it 'link to edit referetnial is displayed' do + expect(page).to have_link(I18n.t('actions.edit'), href: edit_referential_path(referential)) + end + end + end + describe "create" do it "should" do diff --git a/spec/features/routing_constraint_zones_spec.rb b/spec/features/routing_constraint_zones_spec.rb index d1c39e211..9e8c7dad4 100644 --- a/spec/features/routing_constraint_zones_spec.rb +++ b/spec/features/routing_constraint_zones_spec.rb @@ -6,7 +6,8 @@ describe 'RoutingConstraintZones', type: :feature do let(:referential) { Referential.first } let!(:line) { create :line } - let!(:routing_constraint_zones) { Array.new(2) { create :routing_constraint_zone, line: line } } + let!(:route) { create :route, line: line } + let!(:routing_constraint_zones) { Array.new(2) { create :routing_constraint_zone, route: route } } let(:routing_constraint_zone) { routing_constraint_zones.first } describe 'index' do diff --git a/spec/features/time_tables_spec.rb b/spec/features/time_tables_spec.rb index 8e0b62c89..9ace45f11 100644 --- a/spec/features/time_tables_spec.rb +++ b/spec/features/time_tables_spec.rb @@ -67,33 +67,33 @@ describe "TimeTables", :type => :feature do expect(page).to have_content(time_tables.first.comment) end - context 'user has permission to create time tables' do - it 'shows a create link for time tables' do - expect(page).to have_content(I18n.t('time_tables.actions.new')) - end - - it 'does not show link to duplicate the time table' do - expect(page).to have_content(I18n.t('time_tables.actions.duplicate')) - end - end + # context 'user has permission to create time tables' do + # it 'shows a create link for time tables' do + # expect(page).to have_content(I18n.t('time_tables.actions.new')) + # end + # + # it 'does not show link to duplicate the time table' do + # expect(page).to have_content(I18n.t('time_tables.actions.duplicate')) + # end + # end context 'user does not have permission to create time tables' do it 'does not show a create link for time tables' do @user.update_attribute(:permissions, []) visit referential_time_table_path(referential, time_table) - expect(page).not_to have_content(I18n.t('time_tables.actions.new')) + expect(page).not_to have_content(I18n.t('actions.new')) end it 'does not show link to duplicate the time table' do @user.update_attribute(:permissions, []) visit referential_time_table_path(referential, time_table) - expect(page).not_to have_content(I18n.t('time_tables.actions.duplicate')) + expect(page).not_to have_content(I18n.t('actions.duplicate')) end end context 'user has permission to edit time tables' do it 'shows the edit link for time table' do - expect(page).to have_content(I18n.t('time_tables.actions.edit')) + expect(page).to have_content(I18n.t('actions.edit')) end end @@ -101,13 +101,13 @@ describe "TimeTables", :type => :feature do it 'does not show the edit link for time table' do @user.update_attribute(:permissions, []) visit referential_time_table_path(referential, time_table) - expect(page).not_to have_content(I18n.t('time_tables.actions.edit')) + expect(page).not_to have_content(I18n.t('actions.edit')) end end context 'user has permission to destroy time tables' do it 'shows the destroy link for time table' do - expect(page).to have_content(I18n.t('time_tables.actions.destroy')) + expect(page).to have_content(I18n.t('actions.destroy')) end end @@ -115,7 +115,7 @@ describe "TimeTables", :type => :feature do it 'does not show a destroy link for time table' do @user.update_attribute(:permissions, []) visit referential_time_table_path(referential, time_table) - expect(page).not_to have_content(I18n.t('time_tables.actions.destroy')) + expect(page).not_to have_content(I18n.t('actions.destroy')) end end end @@ -125,8 +125,7 @@ describe "TimeTables", :type => :feature do visit referential_time_tables_path(referential) click_link "Ajouter un calendrier" fill_in "Nom", :with => "TimeTable 1" - fill_in "Identifiant Neptune", :with => "test:Timetable:1" - click_button("Créer calendrier") + click_button("Valider") expect(page).to have_content("TimeTable 1") end end @@ -134,9 +133,9 @@ describe "TimeTables", :type => :feature do describe "edit and return to show" do it "edit time_table" do visit referential_time_table_path(referential, subject) - click_link "Editer ce calendrier" + click_link "Editer" fill_in "Nom", :with => "TimeTable Modified" - click_button("Editer calendrier") + click_button("Valider") expect(page).to have_content("TimeTable Modified") end end diff --git a/spec/fixtures/users.json b/spec/fixtures/users.json index f4236a29e..6f50e402c 100644 --- a/spec/fixtures/users.json +++ b/spec/fixtures/users.json @@ -58,7 +58,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 5, "username": "laure.dubuc", @@ -71,7 +72,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 6, "username": "thomas.haddad", @@ -84,7 +86,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 7, "username": "jean-paul.lescouzeres", @@ -97,7 +100,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 8, "username": "xinhui.xu", @@ -110,7 +114,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 9, "username": "edouard.maffert", @@ -123,7 +128,8 @@ "locked_at": null, "profile": "Administrateur", "organization_name": "STIF", - "organization_code": "STIF" + "organization_code": "STIF", + "permissions": [] }, { "id": 9, "username": "vlatka.pavisic", @@ -152,7 +158,8 @@ "locked_at": null, "profile": "Référent IV Transporteur", "organization_name": "RATP", - "organization_code": "RATP" + "organization_code": "RATP", + "permissions": [] }, { "id": 11, "username": "jane.doe", @@ -165,5 +172,6 @@ "locked_at": "2016-08-05T12:34:03.995Z", "profile": "Référent IV Transporteur", "organization_name": "RATP", - "organization_code": "RATP" + "organization_code": "RATP", + "permissions": [] }] diff --git a/spec/javascripts/vehicle_journeys/reducers/filters_spec.js b/spec/javascripts/vehicle_journeys/reducers/filters_spec.js index 84608243b..94c2cb41f 100644 --- a/spec/javascripts/vehicle_journeys/reducers/filters_spec.js +++ b/spec/javascripts/vehicle_journeys/reducers/filters_spec.js @@ -144,7 +144,7 @@ describe('filters reducer', () => { }) it('should handle SELECT_JP_FILTER', () => { - let strResult = "q%5Bjourney_pattern_id_eq%5D=undefined&q%5Btime_tables_id_eq%5D=undefined&q%5Bvehicle_journey_at_stops_departure_time_gteq%5D=11%3A11&q%5Bvehicle_journey_at_stops_departure_time_lteq%5D=22%3A22" + let strResult = "q%5Bjourney_pattern_id_eq%5D=undefined&q%5Btime_tables_id_eq%5D=undefined&q%5Bvehicle_journey_at_stops_departure_time_gteq%5D=11%3A11&q%5Bvehicle_journey_at_stops_departure_time_lteq%5D=22%3A22&q%5Bvehicle_journey_without_u2%5D=false" expect( statusReducer(state, { type: 'CREATE_QUERY_STRING', diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb index d991538ba..f737872bf 100644 --- a/spec/models/chouette/routing_constraint_zone_spec.rb +++ b/spec/models/chouette/routing_constraint_zone_spec.rb @@ -6,7 +6,7 @@ describe Chouette::RoutingConstraintZone, type: :model do it { is_expected.to validate_presence_of :name } it { is_expected.to validate_presence_of :stop_area_ids } - it { is_expected.to validate_presence_of :line_id } + it { is_expected.to validate_presence_of :route_id } # shoulda matcher to validate length of array ? xit { is_expected.to validate_length_of(:stop_area_ids).is_at_least(2) } diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb index fab9cd5e8..c922731a7 100644 --- a/spec/models/chouette/vehicle_journey_spec.rb +++ b/spec/models/chouette/vehicle_journey_spec.rb @@ -1,23 +1,28 @@ require 'spec_helper' describe Chouette::VehicleJourney, :type => :model do describe "state_update" do + + def vehicle_journey_at_stop_to_state vjas + at_stop = {'stop_area_object_id' => vjas.stop_point.stop_area.objectid } + [:id, :connecting_service_id, :boarding_alighting_possibility].map do |att| + at_stop[att.to_s] = vjas.send(att) unless vjas.send(att).nil? + end + + [:arrival_time, :departure_time].map do |att| + at_stop[att.to_s] = { + 'hour' => vjas.send(att).strftime('%H'), + 'minute' => vjas.send(att).strftime('%M'), + } + end + at_stop + end + def vehicle_journey_to_state vj vj.attributes.slice('objectid', 'published_journey_name', 'journey_pattern_id', 'company_id').tap do |item| item['vehicle_journey_at_stops'] = [] - vj.vehicle_journey_at_stops.each do |vs| - at_stops = {'stop_area_object_id' => vs.stop_point.stop_area.objectid } - [:id, :connecting_service_id, :boarding_alighting_possibility].map do |att| - at_stops[att.to_s] = vs.send(att) unless vs.send(att).nil? - end - - [:arrival_time, :departure_time].map do |att| - at_stops[att.to_s] = { - 'hour' => vs.send(att).strftime('%H'), - 'minute' => vs.send(att).strftime('%M'), - } - end - item['vehicle_journey_at_stops'] << at_stops + vj.vehicle_journey_at_stops.each do |vjas| + item['vehicle_journey_at_stops'] << vehicle_journey_at_stop_to_state(vjas) end end end @@ -40,6 +45,20 @@ describe Chouette::VehicleJourney, :type => :model do expect(vj.published_journey_name).to eq 'dummy' end + it 'should save vehicle_journey_at_stops of newly created vj' do + new_vj = build(:vehicle_journey, objectid: nil, published_journey_name: 'dummy', route: route, journey_pattern: journey_pattern) + new_vj.vehicle_journey_at_stops << build(:vehicle_journey_at_stop, + :vehicle_journey => new_vj, + :stop_point => create(:stop_point), + :arrival_time => '2000-01-01 01:00:00 UTC', + :departure_time => '2000-01-01 03:00:00 UTC') + + collection << vehicle_journey_to_state(new_vj) + expect { + Chouette::VehicleJourney.state_update(route, collection) + }.to change {Chouette::VehicleJourneyAtStop.count}.by(1) + end + it 'should update vj journey_pattern' do state['journey_pattern'] = create(:journey_pattern).attributes.slice('id', 'name', 'objectid') Chouette::VehicleJourney.state_update(route, collection) diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index e34f368ae..a2855d086 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -4,7 +4,7 @@ RSpec.describe Import, :type => :model do it { should belong_to(:referential) } it { should belong_to(:workbench) } - it { should enumerize(:status).in(:new, :pending, :successful, :failed, :canceled) } + it { should enumerize(:status).in(:new, :pending, :successful, :failed, :canceled, :running, :aborted ) } it { should validate_presence_of(:file) } end diff --git a/spec/models/referential_metadata_spec.rb b/spec/models/referential_metadata_spec.rb index 7e61c54b1..ede589860 100644 --- a/spec/models/referential_metadata_spec.rb +++ b/spec/models/referential_metadata_spec.rb @@ -78,6 +78,10 @@ RSpec.describe ReferentialMetadata, :type => :model do expect(period("end(3i)"=>"18", "end(2i)"=>"2", "end(1i)"=>"2017").end).to eq(Date.new(2017,2,18)) end + it "should ignore invalid date" do + expect(period("end(3i)"=>"30", "end(2i)"=>"2", "end(1i)"=>"2017").end).to eq(nil) + end + it { is_expected.to validate_presence_of(:begin) } it { is_expected.to validate_presence_of(:end) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index f56680fc0..6925bb7e8 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -14,7 +14,7 @@ describe User, :type => :model do :organisation_code => '0083', :organisation_name => 'af83', :functional_scope => "[\"STIF:CODIFLIGNE:Line:C00840\", \"STIF:CODIFLIGNE:Line:C00086\"]", - :permissions => nil + :permissions => [] } ticket.user = "john.doe" ticket.success = true @@ -119,7 +119,7 @@ describe User, :type => :model do it 'should give edit permissions to user if user has "edit offer" permission in portail' do User.portail_sync expect(User.find_by(username: 'vlatka.pavisic').permissions).not_to be_empty - expect(User.find_by(username: 'pierre.vabre').permissions).to be_nil + expect(User.find_by(username: 'pierre.vabre').permissions).to be_empty end end end diff --git a/spec/support/devise.rb b/spec/support/devise.rb index f692edab8..0e3ceefac 100644 --- a/spec/support/devise.rb +++ b/spec/support/devise.rb @@ -39,9 +39,13 @@ module DeviseControllerHelper before(:each) do @request.env["devise.mapping"] = Devise.mappings[:user] organisation = Organisation.where(:code => "first").first_or_create(attributes_for(:organisation)) - user = create(:user, :organisation => organisation, - :permissions => ['routes.create', 'routes.edit', 'routes.destroy', 'journey_patterns.create', 'journey_patterns.edit', 'journey_patterns.destroy']) - sign_in user + @user = create(:user, :organisation => organisation, + :permissions => ['routes.create', 'routes.edit', 'routes.destroy', 'journey_patterns.create', 'journey_patterns.edit', 'journey_patterns.destroy', + 'vehicle_journeys.create', 'vehicle_journeys.edit', 'vehicle_journeys.destroy', 'time_tables.create', 'time_tables.edit', 'time_tables.destroy', + 'footnotes.edit', 'footnotes.create', 'footnotes.destroy', 'routing_constraint_zones.create', 'routing_constraint_zones.edit', 'routing_constraint_zones.destroy', + 'access_points.create', 'access_points.edit', 'access_points.destroy', 'access_links.create', 'access_links.edit', 'access_links.destroy', + 'connection_links.create', 'connection_links.edit', 'connection_links.destroy', 'route_sections.create', 'route_sections.edit', 'route_sections.destroy']) + sign_in @user end end end diff --git a/spec/views/time_tables/edit.html.erb_spec.rb b/spec/views/time_tables/edit.html.erb_spec.rb index 18c5d6d85..35d360042 100644 --- a/spec/views/time_tables/edit.html.erb_spec.rb +++ b/spec/views/time_tables/edit.html.erb_spec.rb @@ -5,9 +5,9 @@ describe "/time_tables/edit", :type => :view do let!(:time_table) { assign(:time_table, create(:time_table) ) } describe "test" do - it "should render h2 with the group comment" do - render - expect(rendered).to have_selector("h2", :text => Regexp.new(time_table.comment)) + it "should render h1 with the group comment" do + render + expect(rendered).to have_selector("h1", :text => Regexp.new(time_table.comment)) end end diff --git a/spec/views/time_tables/show.html.erb_spec.rb b/spec/views/time_tables/show.html.erb_spec.rb index 3b5d7f1f1..f429f9dec 100644 --- a/spec/views/time_tables/show.html.erb_spec.rb +++ b/spec/views/time_tables/show.html.erb_spec.rb @@ -13,18 +13,17 @@ describe "/time_tables/show", :type => :view do it "should render h2 with the time_table comment" do render - expect(rendered).to have_selector("h2", :text => Regexp.new(time_table.comment)) + expect(rendered).to have_selector("h1", :text => Regexp.new(time_table.comment)) end it "should render a link to edit the time_table" do render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_time_table_path(referential, time_table)}']") + expect(rendered).to have_selector(" a[href='#{view.edit_referential_time_table_path(referential, time_table)}']") end it "should render a link to remove the time_table" do render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_time_table_path(referential, time_table)}'][class='remove']") + expect(rendered).to have_selector(" a[href='#{view.referential_time_table_path(referential, time_table)}']") end end - |
