diff options
| author | Thomas Haddad | 2017-02-16 17:14:45 +0100 | 
|---|---|---|
| committer | Thomas Haddad | 2017-02-16 17:15:49 +0100 | 
| commit | bb693070b8f06bc9cb4845d27d58dfed9ce3411e (patch) | |
| tree | 0c0e2f155e98daa609ca04ab09fd4fd63bae7e21 | |
| parent | 051b25a06ae9cb5fd19791688eac6ba40ab56396 (diff) | |
| download | chouette-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>
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, {  | 
