aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Haddad2017-02-16 17:14:45 +0100
committerThomas Haddad2017-02-16 17:15:49 +0100
commitbb693070b8f06bc9cb4845d27d58dfed9ce3411e (patch)
tree0c0e2f155e98daa609ca04ab09fd4fd63bae7e21
parent051b25a06ae9cb5fd19791688eac6ba40ab56396 (diff)
downloadchouette-core-bb693070b8f06bc9cb4845d27d58dfed9ce3411e.tar.bz2
Refs #2522: Add vehicleJourney via modal, and put it first (not select2 yet for mission_id)
Signed-off-by: Thomas Shawarma Haddad <thomas.haddad@af83.com>
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js34
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/CreateModal.js109
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/containers/AddVehicleJourney.js29
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/containers/Modal.js23
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js6
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js1
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js15
-rw-r--r--spec/javascripts/vehicle_journeys/actions_spec.js52
-rw-r--r--spec/javascripts/vehicle_journeys/reducers/modal_spec.js8
-rw-r--r--spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js21
11 files changed, 300 insertions, 0 deletions
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 817dbb81c..56ed1ef07 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
@@ -33,10 +33,44 @@ const actions = {
return callback
}
},
+ openCreateModal : () => ({
+ type : 'CREATE_VEHICLEJOURNEY_MODAL'
+ }),
+ addVehicleJourney : (data) => ({
+ type: 'ADD_VEHICLEJOURNEY',
+ data,
+ }),
openConfirmModal : (callback) => ({
type : 'OPEN_CONFIRM_MODAL',
callback
}),
+ closeModal : () => ({
+ type : 'CLOSE_MODAL'
+ }),
+ resetValidation: (target) => {
+ $(target).parent().removeClass('has-error').children('.help-block').remove()
+ },
+ validateFields : (fields) => {
+ const test = []
+
+ Object.keys(fields).map(function(key) {
+ test.push(fields[key].validity.valid)
+ })
+ if(test.indexOf(false) >= 0) {
+ // Form is invalid
+ test.map(function(item, i) {
+ if(item == false) {
+ const k = Object.keys(fields)[i]
+ $(fields[k]).parent().addClass('has-error').children('.help-block').remove()
+ $(fields[k]).parent().append("<span class='small help-block'>" + fields[k].validationMessage + "</span>")
+ }
+ })
+ return false
+ } else {
+ // Form is valid
+ return true
+ }
+ },
toggleArrivals : () => ({
type: 'TOGGLE_ARRIVALS',
}),
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js
index 7368d4de3..99c88930a 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js
@@ -4,12 +4,14 @@ var Navigate = require('../containers/Navigate')
var FiltersList = require('../containers/FiltersList')
var SaveVehicleJourneys = require('../containers/SaveVehicleJourneys')
var ConfirmModal = require('../containers/ConfirmModal')
+var AddVehicleJourney = require('../containers/AddVehicleJourney')
const App = () => (
<div>
<div className='clearfix' style={{ marginBottom: 10 }}>
<FiltersList />
<Navigate />
+ <AddVehicleJourney />
</div>
<VehicleJourneysList />
<SaveVehicleJourneys />
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/CreateModal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/CreateModal.js
new file mode 100644
index 000000000..34b1a3afc
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/CreateModal.js
@@ -0,0 +1,109 @@
+var React = require('react')
+var Component = require('react').Component
+var PropTypes = require('react').PropTypes
+var actions = require('../actions')
+
+class CreateModal extends Component {
+ constructor(props) {
+ super(props)
+ }
+
+ handleSubmit() {
+ if(actions.validateFields(this.refs) == true) {
+ this.props.onAddVehicleJourney(this.refs)
+ $('#NewVehicleJourneyModal').modal('hide')
+ }
+ }
+
+ render() {
+ if(this.props.status.isFetching == true) {
+ return false
+ }
+ if(this.props.status.fetchSuccess == true) {
+ return (
+ <div className='pull-right'>
+ <button
+ type='button'
+ className='btn btn-primary btn-sm'
+ data-toggle='modal'
+ data-target='#NewVehicleJourneyModal'
+ onClick={this.props.onOpenCreateModal}
+ >
+ <span className='fa fa-plus'></span> Ajouter une mission
+ </button>
+
+ <div className={ 'modal fade ' + ((this.props.modal.type == 'create') ? 'in' : '') } id='NewVehicleJourneyModal'>
+ <div className='modal-dialog'>
+ <div className='modal-content'>
+ <div className='modal-header clearfix'>
+ <h4>Ajouter une mission</h4>
+ </div>
+
+ {(this.props.modal.type == 'create') && (
+ <form>
+ <div className='modal-body'>
+ <div className='form-group'>
+ <label className='control-label is-required'>Nom de la course</label>
+ <input
+ type='text'
+ ref='comment'
+ className='form-control'
+ onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ required
+ />
+ </div>
+ <div className='row'>
+ <div className='col-lg-6 col-md-6 col-sm-6 col-xs-6'>
+ <div className='form-group'>
+ <label className='control-label is-required'>ID de la mission</label>
+ <input
+ type='text'
+ ref='journey_pattern_id'
+ className='form-control'
+ onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ required
+ />
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className='modal-footer'>
+ <button
+ className='btn btn-default'
+ data-dismiss='modal'
+ type='button'
+ onClick={this.props.onModalClose}
+ >
+ Annuler
+ </button>
+ <button
+ className='btn btn-danger'
+ type='button'
+ onClick={this.handleSubmit.bind(this)}
+ >
+ Valider
+ </button>
+ </div>
+ </form>
+ )}
+ </div>
+ </div>
+ </div>
+ </div>
+ )
+ } else {
+ return false
+ }
+ }
+}
+
+CreateModal.propTypes = {
+ index: PropTypes.number,
+ modal: PropTypes.object.isRequired,
+ status: PropTypes.object.isRequired,
+ onOpenCreateModal: PropTypes.func.isRequired,
+ onModalClose: PropTypes.func.isRequired,
+ onAddVehicleJourney: PropTypes.func.isRequired
+}
+
+module.exports = CreateModal
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/AddVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/AddVehicleJourney.js
new file mode 100644
index 000000000..a0ff923bf
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/AddVehicleJourney.js
@@ -0,0 +1,29 @@
+var actions = require('../actions')
+var connect = require('react-redux').connect
+var CreateModal = require('../components/CreateModal')
+
+const mapStateToProps = (state) => {
+ return {
+ modal: state.modal,
+ vehicleJourneys: state.vehicleJourneys,
+ status: state.status
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onModalClose: () =>{
+ dispatch(actions.closeModal())
+ },
+ onAddVehicleJourney: (data) =>{
+ dispatch(actions.addVehicleJourney(data))
+ },
+ onOpenCreateModal: () =>{
+ dispatch(actions.openCreateModal())
+ }
+ }
+}
+
+const AddVehicleJourney = connect(mapStateToProps, mapDispatchToProps)(CreateModal)
+
+module.exports = AddVehicleJourney
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/Modal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/Modal.js
new file mode 100644
index 000000000..13190b041
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/Modal.js
@@ -0,0 +1,23 @@
+var connect = require('react-redux').connect
+var EditModal = require('../components/EditModal')
+var CreateModal = require('../components/CreateModal')
+var actions = require('../actions')
+
+const mapStateToProps = (state) => {
+ return {
+ modal: state.modal,
+ journeyPattern: state.journeyPattern
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onModalClose: () =>{
+ dispatch(actions.closeModal())
+ }
+ }
+}
+
+const ModalContainer = connect(mapStateToProps, mapDispatchToProps)(CreateModal)
+
+module.exports = ModalContainer
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 bc9d448fe..127b69686 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js
@@ -8,6 +8,12 @@ const modal = (state = {}, action) => {
callback: action.callback,
}
})
+ case 'CREATE_VEHICLEJOURNEY_MODAL':
+ return {
+ type: 'create',
+ modalProps: {},
+ confirmModal: {}
+ }
case 'CLOSE_MODAL':
return {
type: '',
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 4ac2a4586..c9bcec6de 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/pagination.js
@@ -12,6 +12,7 @@ const pagination = (state = {}, action) => {
return Object.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})
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 b48ac33b3..ccf1efea1 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
@@ -2,6 +2,16 @@ var actions = require("../actions")
const vehicleJourney= (state = {}, action) => {
switch (action.type) {
+ case 'ADD_VEHICLEJOURNEY':
+ return {
+ journey_pattern_id: parseInt(action.data.journey_pattern_id.value),
+ comment: action.data.comment.value,
+ objectid: '',
+ footnotes: [],
+ time_tables: [],
+ vehicle_journey_at_stops: [],
+ deletable: false
+ }
case 'UPDATE_TIME':
let vj, vjas, vjasArray, newSchedule
vjasArray = state.vehicle_journey_at_stops.map((vjas, i) =>{
@@ -45,6 +55,11 @@ const vehicleJourneys = (state = [], action) => {
actions.fetchVehicleJourneys(action.dispatch, action.pagination.page, action.nextPage)
}
return state
+ case 'ADD_VEHICLEJOURNEY':
+ return [
+ vehicleJourney(state, action),
+ ...state
+ ]
case 'UPDATE_TIME':
return state.map((vj, i) =>{
if (i == action.index){
diff --git a/spec/javascripts/vehicle_journeys/actions_spec.js b/spec/javascripts/vehicle_journeys/actions_spec.js
index 5eb3abe45..9f3f5e168 100644
--- a/spec/javascripts/vehicle_journeys/actions_spec.js
+++ b/spec/javascripts/vehicle_journeys/actions_spec.js
@@ -29,6 +29,58 @@ describe('when receiveJourneyPatterns is triggered', () => {
expect(actions.receiveVehicleJourneys()).toEqual(expectedAction)
})
})
+describe('when clicking on add button', () => {
+ it('should create an action to open a create modal', () => {
+ const expectedAction = {
+ type: 'CREATE_VEHICLEJOURNEY_MODAL',
+ }
+ expect(actions.openCreateModal()).toEqual(expectedAction)
+ })
+})
+describe('when clicking on validate button inside create modal', () => {
+ it('should create an action to create a new journey pattern', () => {
+ const data = {}
+ const expectedAction = {
+ type: 'ADD_VEHICLEJOURNEY',
+ data
+ }
+ expect(actions.addVehicleJourney(data)).toEqual(expectedAction)
+ })
+})
+describe('when previous navigation button is clicked', () => {
+ it('should create an action to go to previous page', () => {
+ const nextPage = false
+ const pagination = {
+ totalCount: 25,
+ perPage: 12,
+ page:1
+ }
+ const expectedAction = {
+ type: 'GO_TO_PREVIOUS_PAGE',
+ dispatch,
+ pagination,
+ nextPage
+ }
+ expect(actions.goToPreviousPage(dispatch, pagination)).toEqual(expectedAction)
+ })
+})
+describe('when next navigation button is clicked', () => {
+ it('should create an action to go to next page', () => {
+ const nextPage = true
+ const pagination = {
+ totalCount: 25,
+ perPage: 12,
+ page:1
+ }
+ const expectedAction = {
+ type: 'GO_TO_NEXT_PAGE',
+ dispatch,
+ pagination,
+ nextPage
+ }
+ expect(actions.goToNextPage(dispatch, pagination)).toEqual(expectedAction)
+ })
+})
describe('when toggling arrivals', () => {
it('should create an action to toggleArrivals', () => {
const expectedAction = {
diff --git a/spec/javascripts/vehicle_journeys/reducers/modal_spec.js b/spec/javascripts/vehicle_journeys/reducers/modal_spec.js
index 8da8e6c65..8e854be40 100644
--- a/spec/javascripts/vehicle_journeys/reducers/modal_spec.js
+++ b/spec/javascripts/vehicle_journeys/reducers/modal_spec.js
@@ -34,6 +34,14 @@ describe('modal reducer', () => {
).toEqual(newState)
})
+ it('should handle CREATE_VEHICLEJOURNEY_MODAL', () => {
+ expect(
+ modalReducer(state, {
+ type: 'CREATE_VEHICLEJOURNEY_MODAL'
+ })
+ ).toEqual(Object.assign({}, state, { type: 'create' }))
+ })
+
it('should handle CLOSE_MODAL', () => {
expect(
modalReducer(state, {
diff --git a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
index 5540caf02..bb40add3a 100644
--- a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
+++ b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
@@ -55,6 +55,27 @@ describe('vehicleJourneys reducer', () => {
})
+ it('should handle ADD_VEHICLEJOURNEY', () => {
+ let fakeData = {
+ journey_pattern_id: {value : '1'},
+ comment: {value: 'test'}
+ }
+ expect(
+ vjReducer(state, {
+ type: 'ADD_VEHICLEJOURNEY',
+ data: fakeData
+ })
+ ).toEqual([{
+ journey_pattern_id: 1,
+ comment: 'test',
+ objectid: '',
+ footnotes: [],
+ time_tables: [],
+ vehicle_journey_at_stops: [],
+ deletable: false
+ }, ...state])
+ })
+
it('should handle RECEIVE_VEHICLE_JOURNEYS', () => {
expect(
vjReducer(state, {