aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert2017-04-25 17:19:10 +0200
committerRobert2017-04-25 17:19:10 +0200
commitb28038e7895be940c667f2ca29cfc3212d1aba79 (patch)
tree6afb54d980ae9e25fb89311e59e848f947863b5f
parent40ca2fc7a724d1ba3d7d95d5cd842e38c3774faf (diff)
parent4912577341d05526b5442f081660760c506e150c (diff)
downloadchouette-core-b28038e7895be940c667f2ca29cfc3212d1aba79.tar.bz2
Merge branch 'master' of github.com:af83/stif-boiv
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js1
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/actions/index.js56
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js48
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/Metas.js6
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js43
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/SaveTimetable.js7
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/containers/App.js2
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/containers/ConfirmModal.js30
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/index.js1
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js8
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js9
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js1
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js1
-rw-r--r--app/assets/javascripts/main_menu.coffee11
-rw-r--r--app/assets/stylesheets/modules/_timetables.sass10
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/calendars_controller.rb14
-rw-r--r--app/controllers/errors_controller.rb8
-rw-r--r--app/controllers/journey_patterns_collections_controller.rb8
-rw-r--r--app/controllers/time_tables_controller.rb19
-rw-r--r--app/helpers/newapplication_helper.rb2
-rw-r--r--app/views/calendars/_filters.html.slim5
-rw-r--r--app/views/errors/forbidden.html.slim (renamed from app/views/errors/not_allowed.html.slim)6
-rw-r--r--app/views/time_tables/_filter.html.slim4
-rw-r--r--app/views/time_tables/_form.html.slim102
-rw-r--r--app/views/time_tables/edit.html.slim3
-rw-r--r--app/views/time_tables/index.html.slim7
-rw-r--r--app/views/time_tables/new.html.slim11
-rw-r--r--config/locales/time_tables.fr.yml4
-rw-r--r--config/routes.rb10
-rw-r--r--spec/controllers/errors_controller_spec.rb41
-rw-r--r--spec/features/calendars_spec.rb2
-rw-r--r--spec/javascripts/time_table/reducers/metas_spec.js9
-rw-r--r--spec/views/time_tables/new.html.erb_spec.rb11
34 files changed, 321 insertions, 181 deletions
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 93dfa8c6b..090e22721 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/SaveJourneyPattern.js
@@ -10,6 +10,7 @@ class SaveJourneyPattern extends Component{
componentDidUpdate(prevProps, prevState) {
if(prevProps.status.isFetching == true){
+ $(window).scrollTop(0);
submitMover();
}
}
diff --git a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
index 8af08f97a..4a3cfc061 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
@@ -5,10 +5,23 @@ const actions = {
let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa']
return weekDays.map((day, i) => str.indexOf(day) !== -1)
},
-
+ arrayToStrDayTypes: (arr) => {
+ let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa']
+ let str = ''
+ arr.map((dayActive, i) => {
+ if(dayActive){
+ str += weekDays[i]
+ }
+ })
+ return str
+ },
fetchingApi: () =>({
type: 'FETCH_API'
}),
+ receiveErrors : (json) => ({
+ type: "RECEIVE_ERRORS",
+ json
+ }),
unavailableServer: () => ({
type: 'UNAVAILABLE_SERVER'
}),
@@ -103,7 +116,13 @@ const actions = {
day,
dayTypes
}),
-
+ openConfirmModal : (callback) => ({
+ type : 'OPEN_CONFIRM_MODAL',
+ callback
+ }),
+ closeModal : () => ({
+ type : 'CLOSE_MODAL'
+ }),
monthName(strDate) {
let monthList = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"]
var date = new Date(strDate)
@@ -211,6 +230,39 @@ const actions = {
}
})
},
+ submitTimetable: (dispatch, timetable, metas, next) => {
+ dispatch(actions.fetchingApi())
+ let strDayTypes = actions.arrayToStrDayTypes(metas.day_types)
+ metas.day_types= strDayTypes
+ let sentState = _.assign({}, timetable, metas)
+ let urlJSON = window.location.pathname.split('/', 5).join('/')
+ let hasError = false
+ fetch(urlJSON, {
+ credentials: 'same-origin',
+ method: 'PATCH',
+ contentType: 'application/json; charset=utf-8',
+ Accept: 'application/json',
+ body: JSON.stringify(sentState),
+ headers: {
+ 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
+ }
+ }).then(response => {
+ if(!response.ok) {
+ hasError = true
+ }
+ return response.json()
+ }).then((json) => {
+ if(hasError == true) {
+ dispatch(actions.receiveErrors(json))
+ } else {
+ if(next) {
+ dispatch(next)
+ } else {
+ dispatch(actions.receiveTimeTables(json))
+ }
+ }
+ })
+ }
}
module.exports = actions
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js
new file mode 100644
index 000000000..c2229d991
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js
@@ -0,0 +1,48 @@
+var React = require('react')
+var Component = require('react').Component
+var PropTypes = require('react').PropTypes
+
+const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, journeyPatterns}) => (
+ <div className={ 'modal fade ' + ((modal.type == 'confirm') ? 'in' : '') } id='ConfirmModal'>
+ <div className='modal-container'>
+ <div className='modal-dialog'>
+ <div className='modal-content'>
+ <div className='modal-header'>
+ <h4 className='modal-title'>Confirmation</h4>
+ </div>
+ <div className='modal-body'>
+ <div className='mt-md mb-md'>
+ <p>Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?</p>
+ </div>
+ </div>
+ <div className='modal-footer'>
+ <button
+ className='btn btn-link'
+ data-dismiss='modal'
+ type='button'
+ onClick= {() => {onModalCancel(modal.confirmModal.callback)}}
+ >
+ Ne pas valider
+ </button>
+ <button
+ className='btn btn-primary'
+ data-dismiss='modal'
+ type='button'
+ onClick = {() => {onModalAccept(modal.confirmModal.callback, journeyPatterns)}}
+ >
+ Valider
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+)
+
+ConfirmModal.propTypes = {
+ modal: PropTypes.object.isRequired,
+ onModalAccept: PropTypes.func.isRequired,
+ onModalCancel: PropTypes.func.isRequired
+}
+
+module.exports = ConfirmModal
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
index 7807c3ef6..7add0ddfd 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
@@ -19,6 +19,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec
type='text'
className='form-control'
value={metas.comment}
+ required='required'
onChange={(e) => (onUpdateComment(e.currentTarget.value))}
/>
</div>
@@ -90,6 +91,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec
<span>{metas.calendar.name}</span>
</div>
</div>
+
{/* day_types */}
<div className="form-group">
<label htmlFor="" className="control-label col-sm-4">
@@ -98,7 +100,9 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec
<div className="col-sm-8">
<div className="form-group labelled-checkbox-group">
{metas.day_types.map((day, i) =>
- <div className="lcbx-group-item"
+ <div
+ className='lcbx-group-item'
+ data-wday={'day_' + i}
key={i}
>
<div className="checkbox">
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
index 82b0d9950..5beb80573 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
@@ -36,29 +36,28 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod
<div className="row">
<div className="col lg-6 col-lg-offset-3">
<div className='subform'>
- <div className="nested-head">
- <div className="wrapper">
- <div>
- <div className="form-group">
- <label htmlFor="" className="control-label required">
- Début de période
- <abbr title="requis">*</abbr>
- </label>
- </div>
- </div>
- <div>
- <div className="form-group">
- <label htmlFor="" className="control-label required">
- Fin de période
- <abbr title="requis">*</abbr>
- </label>
- </div>
- </div>
- </div>
- </div>
-
{modal.modalProps.active &&
<div>
+ <div className="nested-head">
+ <div className="wrapper">
+ <div>
+ <div className="form-group">
+ <label htmlFor="" className="control-label required">
+ Début de période
+ <abbr title="requis">*</abbr>
+ </label>
+ </div>
+ </div>
+ <div>
+ <div className="form-group">
+ <label htmlFor="" className="control-label required">
+ Fin de période
+ <abbr title="requis">*</abbr>
+ </label>
+ </div>
+ </div>
+ </div>
+ </div>
<div className="nested-fields">
<div className="wrapper">
<div>
@@ -116,7 +115,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod
</div>
}
{!modal.modalProps.active &&
- <div className="links nested-linker">
+ <div className="text-right">
<button
type='button'
className='btn btn-outline-primary add_fields'
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/SaveTimetable.js b/app/assets/javascripts/es6_browserified/time_tables/components/SaveTimetable.js
index f8832476d..98b355fcb 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/SaveTimetable.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/SaveTimetable.js
@@ -10,6 +10,7 @@ class SaveTimetable extends Component{
componentDidUpdate(prevProps, prevState) {
if(prevProps.status.isFetching == true){
+ $(window).scrollTop(0);
submitMover();
}
}
@@ -22,15 +23,15 @@ class SaveTimetable extends Component{
return (
<div className='row mt-md'>
<div className='col-lg-12 text-right'>
- <form className='formSubmitr ml-xs' onSubmit={e => {e.preventDefault()}}>
+ <form className='time_tables formSubmitr ml-xs' onSubmit={e => {e.preventDefault()}}>
<button
className='btn btn-default'
type='button'
onClick={e => {
e.preventDefault()
- actions.submitTimeTable(this.props.dispatch, this.props.timetable, this.props.metas)
+ actions.submitTimetable(this.props.dispatch, this.props.timetable, this.props.metas)
}}
- >
+ >
Valider
</button>
</form>
diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js
index fee169ac3..7c75377ea 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js
@@ -7,6 +7,7 @@ var Timetable = require('./Timetable')
var Navigate = require('./Navigate')
var PeriodForm = require('./PeriodForm')
var SaveTimetable = require('./SaveTimetable')
+var ConfirmModal = require('./ConfirmModal')
class App extends Component {
componentDidMount(){
@@ -22,6 +23,7 @@ class App extends Component {
<Timetable />
<PeriodForm />
<SaveTimetable />
+ <ConfirmModal />
</div>
</div>
)
diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/ConfirmModal.js b/app/assets/javascripts/es6_browserified/time_tables/containers/ConfirmModal.js
new file mode 100644
index 000000000..8095e1e7c
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/containers/ConfirmModal.js
@@ -0,0 +1,30 @@
+var actions = require('../actions')
+var connect = require('react-redux').connect
+var ConfirmModal = require('../components/ConfirmModal')
+
+const mapStateToProps = (state) => {
+ return {
+ modal: state.modal,
+ journeyPatterns: state.journeyPatterns
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onModalAccept: (next, timetable, metas, state) =>{
+ dispatch(actions.fetchingApi())
+ actions.submitTimetable(dispatch, timetable, metas, next)
+ },
+ onModalCancel: (next) =>{
+ dispatch(actions.fetchingApi())
+ dispatch(next)
+ },
+ onModalClose: () =>{
+ dispatch(actions.closeModal())
+ }
+ }
+}
+
+const ConfirmModalContainer = connect(mapStateToProps, mapDispatchToProps)(ConfirmModal)
+
+module.exports = ConfirmModalContainer
diff --git a/app/assets/javascripts/es6_browserified/time_tables/index.js b/app/assets/javascripts/es6_browserified/time_tables/index.js
index 132b1dd95..174cede5c 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/index.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/index.js
@@ -13,6 +13,7 @@ var promise = require('redux-promise')
var initialState = {
status: {
+ actionType: window.actionType,
policy: window.perms,
fetchSuccess: true,
isFetching: false
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js
index 474c70ea5..56486a105 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js
@@ -11,6 +11,14 @@ let period_start = '', period_end = ''
const modal = (state = {}, action) => {
switch (action.type) {
+ case 'OPEN_CONFIRM_MODAL':
+ $('#ConfirmModal').modal('show')
+ return _.assign({}, state, {
+ type: 'confirm',
+ confirmModal: {
+ callback: action.callback,
+ }
+ })
case 'CLOSE_PERIOD_FORM':
newModalProps = _.assign({}, state.modalProps, {active: false})
return _.assign({}, state, {modalProps: newModalProps})
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js
index 35b9b3cd8..660484c58 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js
@@ -16,6 +16,15 @@ const pagination = (state = {}, action) => {
case 'CHANGE_PAGE':
toggleOnConfirmModal()
return _.assign({}, state, {currentPage : action.page, stateChanged: false})
+ case 'INCLUDE_DATE_IN_PERIOD':
+ case 'EXCLUDE_DATE_FROM_PERIOD':
+ case 'DELETE_PERIOD':
+ case 'VALIDATE_PERIOD_FORM':
+ case 'UPDATE_COMMENT':
+ case 'UPDATE_COLOR':
+ case 'UPDATE_DAY_TYPES':
+ toggleOnConfirmModal('modal')
+ return _.assign({}, state, {stateChanged: true})
default:
return state
}
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 bd34ae114..f494ab92b 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/SaveVehicleJourneys.js
@@ -10,6 +10,7 @@ class SaveVehicleJourneys extends Component{
componentDidUpdate(prevProps, prevState) {
if(prevProps.status.isFetching == true) {
+ $(window).scrollTop(0);
submitMover();
}
}
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 0645fdd19..63a666d90 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js
@@ -59,6 +59,7 @@ class VehicleJourney extends Component {
<input
id={this.props.index}
name={this.props.index}
+ style={{display: 'none'}}
onChange={(e) => this.props.onSelectVehicleJourney(this.props.index)}
type='checkbox'
disabled={this.props.value.deletable}
diff --git a/app/assets/javascripts/main_menu.coffee b/app/assets/javascripts/main_menu.coffee
index 2e0cd3470..f6266f06b 100644
--- a/app/assets/javascripts/main_menu.coffee
+++ b/app/assets/javascripts/main_menu.coffee
@@ -6,6 +6,7 @@ $(document).on 'turbolinks:load', ->
link = []
ptitleCont = ""
+
$el = $('#main_nav')
# Opening/closing left-side menu
$el.find('.openMenu').on 'click', (e) ->
@@ -19,10 +20,7 @@ $(document).on 'turbolinks:load', ->
selectedItem.closest('.panel-collapse').addClass 'in'
selectedItem.closest('.panel-title').children('a').attr('aria-expanded') == true
- # Sticky content
-
- # Sticky behavior
- $(document).on 'scroll', ->
+ sticker = () ->
limit = 51
if $(window).scrollTop() >= limit
@@ -43,6 +41,7 @@ $(document).on 'turbolinks:load', ->
$('#menu_top').children('.menu-content').after(stickyContent)
if link.length == 0
link = $('.page-action .small').next()
+
$('.sticky-paction .small').after(link)
else
@@ -52,3 +51,7 @@ $(document).on 'turbolinks:load', ->
if !$('.page-action').find('.formSubmitr').length
$('.page-action .small').after(link)
$('.sticky-content').remove()
+
+ sticker();
+ # Sticky behavior
+ $(document).on 'scroll', sticker
diff --git a/app/assets/stylesheets/modules/_timetables.sass b/app/assets/stylesheets/modules/_timetables.sass
index ed92796f9..03dba3e23 100644
--- a/app/assets/stylesheets/modules/_timetables.sass
+++ b/app/assets/stylesheets/modules/_timetables.sass
@@ -199,5 +199,11 @@
.wrapper > div:last-child
width: auto
- .nested-head + *
- border-top: 2px solid $darkgrey
+ // Daytypes
+ .labelled-checkbox-group
+ > .lcbx-group-item
+ float: left
+
+ &[data-wday='day_0']
+ float: none
+ margin: 0 5px
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 2bdf8078a..f2c9b4c6f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -22,7 +22,7 @@ class ApplicationController < ActionController::Base
protected
def user_not_authorized
- render :file => "#{Rails.root}/public/403.html", :status => :forbidden, :layout => false
+ redirect_to forbidden_path
end
def current_organisation
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index 3e7a05231..c33aa9373 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -1,7 +1,7 @@
class CalendarsController < BreadcrumbController
include PolicyChecker
defaults resource_class: Calendar
-
+ before_action :ransack_contains_date, only: [:index]
respond_to :html
respond_to :js, only: :index
@@ -39,5 +39,17 @@ class CalendarsController < BreadcrumbController
calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction
@calendars = calendars.paginate(page: params[:page])
end
+
+ def ransack_contains_date
+ # 3 parts to date object, in order to use in ransackable_scopes
+ if params[:q] && !params[:q]['contains_date(1i)'].empty?
+ date =[]
+ ['contains_date(1i)', 'contains_date(2i)', 'contains_date(3i)'].each do |key|
+ date << params[:q][key]
+ params[:q].delete(key)
+ end
+ params[:q]['contains_date'] = Date.parse(date.join('-'))
+ end
+ end
end
diff --git a/app/controllers/errors_controller.rb b/app/controllers/errors_controller.rb
index accf119a3..252b8fdfa 100644
--- a/app/controllers/errors_controller.rb
+++ b/app/controllers/errors_controller.rb
@@ -1,14 +1,14 @@
class ErrorsController < ApplicationController
def not_found
- render template: 'errors/not_found', status: 404, formats: [:html]
+ render status: 404
end
def server_error
- render template: 'errors/server_error', status: 500, formats: [:html]
+ render status: 500
end
- def not_allowed
- render template: 'errors/not_found', status: 403, formats: [:html]
+ def forbidden
+ render status: 403
end
end
diff --git a/app/controllers/journey_patterns_collections_controller.rb b/app/controllers/journey_patterns_collections_controller.rb
index ba54ddf26..7b97e1408 100644
--- a/app/controllers/journey_patterns_collections_controller.rb
+++ b/app/controllers/journey_patterns_collections_controller.rb
@@ -1,14 +1,19 @@
class JourneyPatternsCollectionsController < ChouetteController
+ defaults :resource_class => Chouette::JourneyPattern
+ before_action :user_permissions, only: :show
+
respond_to :html
respond_to :json
- before_action :user_permissions, only: :show
belongs_to :referential do
belongs_to :line, :parent_class => Chouette::Line do
belongs_to :route, :parent_class => Chouette::Route
end
end
+
+ alias_method :vehicle_journeys, :collection
alias_method :route, :parent
+ alias_method :vehicle_journey, :resource
def show
@q = route.journey_patterns.search(params[:q]).result(distinct: true).includes(:stop_points)
@@ -40,6 +45,7 @@ class JourneyPatternsCollectionsController < ChouetteController
}
end
@stop_points_list = @stop_points_list.sort_by {|a| a[:position] }
+ build_breadcrumb :index
end
def user_permissions
diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb
index eedfef07c..b23345607 100644
--- a/app/controllers/time_tables_controller.rb
+++ b/app/controllers/time_tables_controller.rb
@@ -99,6 +99,7 @@ class TimeTablesController < ChouetteController
params[:q].delete("tag_search")
scope = select_time_tables.tagged_with(tags, :wild => true, :any => true) if tags.any?
end
+ scope = ransack_periode(scope)
@q = scope.search(params[:q])
if sort_column && sort_direction
@@ -126,6 +127,24 @@ class TimeTablesController < ChouetteController
end
private
+ # Fake ransack filter
+ def ransack_periode scope
+ return scope unless params[:q]
+ periode = params[:q]
+ return scope if periode['end_date_lteq(1i)'].empty? || periode['start_date_gteq(1i)'].empty?
+
+ begin_range = Date.civil(periode["start_date_gteq(1i)"].to_i, periode["start_date_gteq(2i)"].to_i, periode["start_date_gteq(3i)"].to_i)
+ end_range = Date.civil(periode["end_date_lteq(1i)"].to_i, periode["end_date_lteq(2i)"].to_i, periode["end_date_lteq(3i)"].to_i)
+
+ if begin_range > end_range
+ flash.now[:error] = t('referentials.errors.validity_period')
+ else
+ @begin_range = begin_range
+ @end_range = end_range
+ end
+ scope
+ end
+
def sort_column
referential.time_tables.column_names.include?(params[:sort]) ? params[:sort] : 'comment'
end
diff --git a/app/helpers/newapplication_helper.rb b/app/helpers/newapplication_helper.rb
index 42fca489f..f03228d73 100644
--- a/app/helpers/newapplication_helper.rb
+++ b/app/helpers/newapplication_helper.rb
@@ -16,7 +16,7 @@ module NewapplicationHelper
end
columns.map do |k, v|
- if ["ID Codif", "Oid", "OiD", "ID Reflex", "Arrêt de départ", "Arrêt d'arrivée", "Période de validité englobante"].include? k
+ if ["ID Codif", "Oid", "OiD", "ID Reflex", "Arrêt de départ", "Arrêt d'arrivée", "Période de validité englobante", "Période englobante", "Nombre de courses associées", "Journées d'application"].include? k
hcont << content_tag(:th, k)
else
hcont << content_tag(:th, sortable_columns(collection, k))
diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim
index 4fc11b5c7..d8707ba0f 100644
--- a/app/views/calendars/_filters.html.slim
+++ b/app/views/calendars/_filters.html.slim
@@ -9,12 +9,11 @@
.ffg-row
.form-group.has_switch style='width: 260px'
= f.label Calendar.human_attribute_name(:shared), class: 'col-sm-4 control-label'
- = f.input :shared, as: :boolean, checked_value: true, unchecked_value: false, label: content_tag(:span, '', class: 'switch-label', data: {checkedValue: t('true'), uncheckedValue: t('false')}), wrapper_html: { class: 'col-sm-8' }
+ = f.input :shared_true, as: :boolean, checked_value: true, unchecked_value: false, label: content_tag(:span, '', class: 'switch-label', data: {checkedValue: t('true'), uncheckedValue: t('false')}), wrapper_html: { class: 'col-sm-8' }
.form-group
= f.label Calendar.human_attribute_name(:date), class: 'control-label'
- = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date' }, class: 'form-control'
-
+ = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date' }, class: 'form-control', include_blank: true
.actions
= link_to 'Effacer', calendars_path, class: 'btn btn-link'
= f.submit 'Filtrer', id: 'filter_btn', class: 'btn btn-default'
diff --git a/app/views/errors/not_allowed.html.slim b/app/views/errors/forbidden.html.slim
index 6c94328cc..4ca3a6dbf 100644
--- a/app/views/errors/not_allowed.html.slim
+++ b/app/views/errors/forbidden.html.slim
@@ -11,11 +11,11 @@
- 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/time_tables/_filter.html.slim b/app/views/time_tables/_filter.html.slim
index b5d8185f0..d29c628a9 100644
--- a/app/views/time_tables/_filter.html.slim
+++ b/app/views/time_tables/_filter.html.slim
@@ -17,8 +17,8 @@
.form-group.togglable
= f.label @time_tables.human_attribute_name(:bounding_dates), required: false, class: 'control-label'
.filter_menu
- = f.input :start_date_gteq, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date filter_menu-item' }
- = f.input :end_date_lteq, as: :date, label: t('simple_form.to'), wrapper_html: { class: 'date filter_menu-item' }
+ = f.input :start_date_gteq, as: :date, label: t('simple_form.from'), wrapper_html: { class: 'date filter_menu-item' }, default: @begin_range, include_blank: @begin_range ? false : true
+ = f.input :end_date_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
diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim
deleted file mode 100644
index 97df72fd3..000000000
--- a/app/views/time_tables/_form.html.slim
+++ /dev/null
@@ -1,102 +0,0 @@
-= 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-group
- = form.label @time_table.human_attribute_name(:color), required: false, class: 'control-label col-sm-4'
-
- .col-sm-8
- .dropdown.color_selector
- button.btn.btn-default.dropdown-toggle type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"
- span.fa.fa-circle.mr-xs style="color:#{@time_table.color.nil? ? 'transparent' : @time_table.color}"
- span.caret
-
- = form.input :color, as: :radio_buttons, label: false, collection: ["", "#9B9B9B", "#FFA070", "#C67300", "#7F551B", "#41CCE3", "#09B09C", "#3655D7", "#6321A0", "#E796C6", "#DD2DAA"], input_html: {class: 'color_selector'}, label_method: lambda{|c| ("<span class='fa fa-circle' style='color:" + (c.empty? ? 'transparent' : c) + "'></span>").html_safe}, wrapper_html: { class: 'dropdown-menu', 'aria-labelledby': "dropdownMenu1"}, include_blank: true
-
- / = form.input :tag_list, as: :tags
-
- .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-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
- #time_tables
- .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, partial: 'date_fields', 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 |q|
- = render "excluded_date_fields", f: q
-
- .links.nested-linker
- = link_to_add_association t("time_tables.actions.add_excluded_date"), form, :dates, partial: 'excluded_date_fields', 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/edit.html.slim b/app/views/time_tables/edit.html.slim
index 7f4cd18df..f129cd63a 100644
--- a/app/views/time_tables/edit.html.slim
+++ b/app/views/time_tables/edit.html.slim
@@ -9,4 +9,7 @@
.container-fluid
#periods
+= javascript_tag do
+ | window.actionType = "#{raw params[:action]}"
+
= javascript_include_tag 'es6_browserified/time_tables/index.js'
diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim
index 4e803e18f..01b65653c 100644
--- a/app/views/time_tables/index.html.slim
+++ b/app/views/time_tables/index.html.slim
@@ -15,8 +15,11 @@
.row
.col-lg-12
= table_builder @time_tables,
- { :comment => 'comment', :color => Proc.new{|tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' },
- "Période de validité englobante" => Proc.new{ |tt| tt.bounding_dates.empty? ? '-' : t('bounding_dates', debut: l(tt.bounding_dates.min), end: l(tt.bounding_dates.max)) }, :calendar => Proc.new{ |tt| tt.calendar ? tt.calendar.try(:name) : '-' }, :updated_at => Proc.new {|tt| l(tt.updated_at, format: :short)} },
+ { :color => Proc.new{|tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' }, :comment => 'comment',
+ "Période englobante" => Proc.new{ |tt| tt.bounding_dates.empty? ? '-' : t('bounding_dates', debut: l(tt.bounding_dates.min), end: l(tt.bounding_dates.max)) },
+ "Nombre de courses associées" => Proc.new{ |tt| tt.vehicle_journeys.count },
+ "Journées d'application" => Proc.new{ |tt| (%w(monday tuesday wednesday thursday friday saturday sunday).collect{|d| tt.send(d) ? t("calendars.days.#{d}") : '' }).reject{|a| a.empty?}.join(', ').html_safe },
+ :calendar => Proc.new{ |tt| tt.calendar ? tt.calendar.try(:name) : '-' }, :updated_at => Proc.new {|tt| l(tt.updated_at, format: :short)} },
[:show, :edit, :duplicate, :delete],
[],
'table has-search'
diff --git a/app/views/time_tables/new.html.slim b/app/views/time_tables/new.html.slim
index 8770a59b2..6a0faade8 100644
--- a/app/views/time_tables/new.html.slim
+++ b/app/views/time_tables/new.html.slim
@@ -1,12 +1,15 @@
/ PageHeader
= pageheader 'map-marker',
- t('time_tables.new.title'),
+ t("time_tables.#{params[:action]}.title"),
'',
''
/ 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'
+ #periods
+
+= javascript_tag do
+ | window.actionType = "#{params[:action]}"
+
+= javascript_include_tag 'es6_browserified/time_tables/index.js'
diff --git a/config/locales/time_tables.fr.yml b/config/locales/time_tables.fr.yml
index 12b1b9aee..812d8cdd2 100644
--- a/config/locales/time_tables.fr.yml
+++ b/config/locales/time_tables.fr.yml
@@ -22,6 +22,8 @@ fr:
add_excluded_date: "Ajouter une date exclue"
new:
title: "Ajouter un calendrier"
+ duplicate:
+ title: "Dupliquer un calendrier"
edit:
title: "Editer le calendrier %{time_table}"
show:
@@ -84,7 +86,7 @@ fr:
creator_id: "Créé par"
calendars: "Calendrier"
calendar_details: "Données du calendrier"
- calendar: Calendrier
+ calendar: Modèle de calendrier
dates: "Dates particulières"
date: "Le"
excluded_dates: "Dates exclues"
diff --git a/config/routes.rb b/config/routes.rb
index 538c069ed..8415d49df 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -213,11 +213,9 @@ ChouetteIhm::Application.routes.draw do
get '/help/(*slug)' => 'help#show'
- if Rails.env.production?
- 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
+ match '/404', to: 'errors#not_found', via: :all, as: 'not_found'
+ match '/403', to: 'errors#forbidden', via: :all, as: 'forbidden'
+ match '/422', to: 'errors#server_error', via: :all, as: 'unprocessable_entity'
+ match '/500', to: 'errors#server_error', via: :all, as: 'server_error'
end
diff --git a/spec/controllers/errors_controller_spec.rb b/spec/controllers/errors_controller_spec.rb
new file mode 100644
index 000000000..7f95d5470
--- /dev/null
+++ b/spec/controllers/errors_controller_spec.rb
@@ -0,0 +1,41 @@
+require 'spec_helper'
+
+RSpec.describe ErrorsController, type: :controller do
+ login_user
+
+ describe 'GET not_found' do
+ before(:each) { get 'not_found' }
+
+ it 'renders the not_found template' do
+ expect(response).to render_template('not_found')
+ end
+
+ it 'returns 404 status code' do
+ expect(response).to have_http_status(404)
+ end
+ end
+
+ describe 'GET forbidden' do
+ before(:each) { get 'forbidden' }
+
+ it 'renders the forbidden template' do
+ expect(response).to render_template('forbidden')
+ end
+
+ it 'returns 403 status code' do
+ expect(response).to have_http_status(403)
+ end
+ end
+
+ describe 'GET server_error' do
+ before(:each) { get 'server_error' }
+
+ it 'renders the server_error template' do
+ expect(response).to render_template('server_error')
+ end
+
+ it 'returns 500 status code' do
+ expect(response).to have_http_status(500)
+ end
+ end
+end
diff --git a/spec/features/calendars_spec.rb b/spec/features/calendars_spec.rb
index 8bca4965d..d4234fc50 100644
--- a/spec/features/calendars_spec.rb
+++ b/spec/features/calendars_spec.rb
@@ -29,7 +29,7 @@ describe 'Calendars', type: :feature do
shared_calendar = create :calendar, organisation_id: 1, shared: true
visit calendars_path
# select I18n.t('true'), from: 'q[shared]'
- find(:css, '#q_shared').set(true)
+ find(:css, '#q_shared_true').set(true)
click_button 'filter_btn'
expect(page).to have_content(shared_calendar.short_name)
expect(page).not_to have_content(calendars.first.short_name)
diff --git a/spec/javascripts/time_table/reducers/metas_spec.js b/spec/javascripts/time_table/reducers/metas_spec.js
index e3729dc2a..6f83abfec 100644
--- a/spec/javascripts/time_table/reducers/metas_spec.js
+++ b/spec/javascripts/time_table/reducers/metas_spec.js
@@ -5,10 +5,9 @@ let state = {}
describe('status reducer', () => {
beforeEach(() => {
state = {
- comment: 'test',
- day_types: [true, true, true, true, true, true, true],
- tags: ['t1'],
- color: 'blue'
+ comment: 'test',
+ day_types: [true, true, true, true, true, true, true],
+ color: 'blue'
}
})
@@ -25,7 +24,7 @@ describe('status reducer', () => {
type: 'UPDATE_DAY_TYPES',
index: 0
})
- ).toEqual(Object.assign({}, state, {day_types: arr}))
+ ).toEqual(Object.assign({}, state, {day_types: arr, calendar: {name: 'Aucun'}}))
})
it('should handle UPDATE_COMMENT', () => {
diff --git a/spec/views/time_tables/new.html.erb_spec.rb b/spec/views/time_tables/new.html.erb_spec.rb
index 6053d9862..9be4c4781 100644
--- a/spec/views/time_tables/new.html.erb_spec.rb
+++ b/spec/views/time_tables/new.html.erb_spec.rb
@@ -8,14 +8,5 @@ describe "/time_tables/new", :type => :view do
allow(view).to receive_messages(current_organisation: referential.organisation)
end
- describe "form" do
-
- it "should render input for comment" do
- render
- expect(rendered).to have_selector("form") do
- with_selector "input[type=text][comment=?]", time_table.comment
- end
- end
-
- end
+ # No more test for the form, as it is now managed by React/Redux.
end