diff options
| author | Thomas Haddad | 2017-02-24 14:59:30 +0100 |
|---|---|---|
| committer | Thomas Haddad | 2017-02-24 14:59:30 +0100 |
| commit | 72c004af1cc964433019aa0fea54e81cc9d0918d (patch) | |
| tree | a9bfbefb4e00639002e5bfdb6a25da48dec7b8e5 | |
| parent | bb257ba1838c009c5efb7a1ada4aaf0e5cdb5fef (diff) | |
| download | chouette-core-72c004af1cc964433019aa0fea54e81cc9d0918d.tar.bz2 | |
Refs #2521: Add footnote edition for one vj
Signed-off-by: Thomas Shawarma Haddad <thomas.haddad@af83.com>
9 files changed, 276 insertions, 1 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 027092e21..6af35aa04 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js @@ -40,6 +40,15 @@ const actions = { type : 'EDIT_VEHICLEJOURNEY_MODAL', vehicleJourney }), + openNotesEditModal : (vehicleJourney) => ({ + type : 'EDIT_NOTES_VEHICLEJOURNEY_MODAL', + vehicleJourney + }), + toggleFootnoteModal : (footnote, isShown) => ({ + type: 'TOGGLE_FOOTNOTE_MODAL', + footnote, + isShown + }), openShiftModal : () => ({ type : 'SHIFT_VEHICLEJOURNEY_MODAL' }), @@ -58,6 +67,10 @@ const actions = { type: 'EDIT_VEHICLEJOURNEY', data }), + editVehicleJourneyNotes : (footnotes) => ({ + type: 'EDIT_VEHICLEJOURNEY_NOTES', + footnotes + }), shiftVehicleJourney : (data) => ({ type: 'SHIFT_VEHICLEJOURNEY', data 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 f8021e235..ecc0f0c51 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/App.js @@ -9,6 +9,7 @@ var DeleteVehicleJourneys = require('../containers/tools/DeleteVehicleJourneys') var ShiftVehicleJourney = require('../containers/tools/ShiftVehicleJourney') var DuplicateVehicleJourney = require('../containers/tools/DuplicateVehicleJourney') var EditVehicleJourney = require('../containers/tools/EditVehicleJourney') +var NotesEditVehicleJourney = require('../containers/tools/NotesEditVehicleJourney') const App = () => ( <div> @@ -21,6 +22,7 @@ const App = () => ( <ShiftVehicleJourney /> <DuplicateVehicleJourney /> <EditVehicleJourney /> + <NotesEditVehicleJourney /> </div> </div> <VehicleJourneysList /> 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 new file mode 100644 index 000000000..a0002152f --- /dev/null +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/NotesEditVehicleJourney.js @@ -0,0 +1,117 @@ +var React = require('react') +var Component = require('react').Component +var PropTypes = require('react').PropTypes +var actions = require('../../actions') + +class NotesEditVehicleJourney extends Component { + constructor(props) { + super(props) + } + + handleSubmit() { + this.props.onNotesEditVehicleJourney(this.props.modal.modalProps.vehicleJourney.footnotes) + this.props.onModalClose() + $('#NotesEditVehicleJourneyModal').modal('hide') + } + + renderFootnoteButton(lf, vjArray){ + let footnote_id = undefined + vjArray.forEach((f) => { + if(f.id == lf.id){ + footnote_id = f.id + } + }) + + if(footnote_id){ + return <button + type='button' + className='btn btn-primary btn-sm' + onClick={() => this.props.onToggleFootnoteModal(lf, false)} + >Retirer</button> + }else{ + return <button + type='button' + className='btn btn-primary btn-sm' + onClick={() => this.props.onToggleFootnoteModal(lf, true)} + >Ajouter</button> + } + } + + render() { + if(this.props.status.isFetching == true) { + return false + } + if(this.props.status.fetchSuccess == true) { + return ( + <div className='pull-left'> + <button + disabled= {(actions.getSelected(this.props.vehicleJourneys).length == 1) ? false : true} + type='button' + className='btn btn-primary btn-sm' + data-toggle='modal' + data-target='#NotesEditVehicleJourneyModal' + onClick={() => this.props.onOpenNotesEditModal(actions.getSelected(this.props.vehicleJourneys)[0])} + > + <span className='fa fa-paw'></span> + </button> + + <div className={ 'modal fade ' + ((this.props.modal.type == 'duplicate') ? 'in' : '') } id='NotesEditVehicleJourneyModal'> + <div className='modal-dialog'> + <div className='modal-content'> + <div className='modal-header clearfix'> + <h4>Notes</h4> + </div> + + {(this.props.modal.type == 'notes_edit') && ( + <form> + <div className='modal-body'> + {window.line_footnotes.map((lf, i) => + <div + key = {i} + > + <span>Titre: {lf.label} </span> + <span>Contenu: {lf.code}</span> + {this.renderFootnoteButton(lf, this.props.modal.modalProps.vehicleJourney.footnotes)} + </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 + } + } +} + +NotesEditVehicleJourney.propTypes = { + onOpenNotesEditModal: PropTypes.func.isRequired, + onModalClose: PropTypes.func.isRequired, + onToggleFootnoteModal: PropTypes.func.isRequired, + onNotesEditVehicleJourney: PropTypes.func.isRequired +} + +module.exports = NotesEditVehicleJourney diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/NotesEditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/NotesEditVehicleJourney.js new file mode 100644 index 000000000..edd70af17 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/NotesEditVehicleJourney.js @@ -0,0 +1,32 @@ +var connect = require('react-redux').connect +var NotesEditComponent = require('../../components/tools/NotesEditVehicleJourney') +var actions = require('../../actions') + +const mapStateToProps = (state) => { + return { + modal: state.modal, + vehicleJourneys: state.vehicleJourneys, + status: state.status + } +} + +const mapDispatchToProps = (dispatch) => { + return { + onModalClose: () =>{ + dispatch(actions.closeModal()) + }, + onOpenNotesEditModal: (vj) =>{ + dispatch(actions.openNotesEditModal(vj)) + }, + onToggleFootnoteModal: (footnote, isShown) => { + dispatch(actions.toggleFootnoteModal(footnote, isShown)) + }, + onNotesEditVehicleJourney: (footnotes) =>{ + dispatch(actions.editVehicleJourneyNotes(footnotes)) + } + } +} + +const NotesEditVehicleJourney = connect(mapStateToProps, mapDispatchToProps)(NotesEditComponent) + +module.exports = NotesEditVehicleJourney 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 8f0ca57b2..c925e56fd 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js @@ -8,8 +8,24 @@ const modal = (state = {}, action) => { callback: action.callback, } }) + case 'EDIT_NOTES_VEHICLEJOURNEY_MODAL': + let vehicleJourneyModal = Object.assign({}, action.vehicleJourney) + return { + type: 'notes_edit', + modalProps: { + vehicleJourney: vehicleJourneyModal + }, + confirmModal: {} + } + case 'TOGGLE_FOOTNOTE_MODAL': + let newModalProps = JSON.parse(JSON.stringify(state.modalProps)) + if (action.isShown){ + newModalProps.vehicleJourney.footnotes.push(action.footnote) + }else{ + newModalProps.vehicleJourney.footnotes = newModalProps.vehicleJourney.footnotes.filter((f) => {return f.id != action.footnote.id }) + } + return Object.assign({}, state, {modalProps: newModalProps}) case 'EDIT_VEHICLEJOURNEY_MODAL': - console.log(action.vj) return { type: 'edit', modalProps: { 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 008f14605..9639f8686 100644 --- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js +++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js @@ -103,6 +103,16 @@ const vehicleJourneys = (state = [], action) => { return vj } }) + case 'EDIT_VEHICLEJOURNEY_NOTES': + return state.map((vj, i) => { + if (vj.selected){ + return Object.assign({}, vj, { + footnotes: action.footnotes + }) + }else{ + return vj + } + }) case 'SHIFT_VEHICLEJOURNEY': return state.map((vj, i) => { if (vj.selected){ diff --git a/spec/javascripts/vehicle_journeys/actions_spec.js b/spec/javascripts/vehicle_journeys/actions_spec.js index 5d01ac284..d2c95d4a1 100644 --- a/spec/javascripts/vehicle_journeys/actions_spec.js +++ b/spec/javascripts/vehicle_journeys/actions_spec.js @@ -152,3 +152,34 @@ describe('when clicking on validate button inside duplicating modal', () => { expect(actions.duplicateVehicleJourney(data)).toEqual(expectedAction) }) }) +describe('when clicking on edit notes modal', () => { + it('should create an action to open footnotes modal', () => { + const vehicleJourney = {} + const expectedAction = { + type: 'EDIT_NOTES_VEHICLEJOURNEY_MODAL', + vehicleJourney + } + expect(actions.openNotesEditModal(vehicleJourney)).toEqual(expectedAction) + }) +}) +describe('when clicking on a footnote button inside footnote modal', () => { + it('should create an action to toggle this footnote', () => { + const footnote = {}, isShown = true + const expectedAction = { + type: 'TOGGLE_FOOTNOTE_MODAL', + footnote, + isShown + } + expect(actions.toggleFootnoteModal(footnote, isShown)).toEqual(expectedAction) + }) +}) +describe('when clicking on validate button inside footnote modal', () => { + it('should create an action to update vj footnotes', () => { + const footnotes = [] + const expectedAction = { + type: 'EDIT_VEHICLEJOURNEY_NOTES', + footnotes + } + expect(actions.editVehicleJourneyNotes(footnotes)).toEqual(expectedAction) + }) +}) diff --git a/spec/javascripts/vehicle_journeys/reducers/modal_spec.js b/spec/javascripts/vehicle_journeys/reducers/modal_spec.js index 8e854be40..b41f0818f 100644 --- a/spec/javascripts/vehicle_journeys/reducers/modal_spec.js +++ b/spec/javascripts/vehicle_journeys/reducers/modal_spec.js @@ -49,4 +49,35 @@ describe('modal reducer', () => { }) ).toEqual(state) }) + + it('should handle EDIT_NOTES_VEHICLEJOURNEY_MODAL', () => { + let vehicleJourney = {} + let modalPropsResult = { + vehicleJourney: {} + } + expect( + modalReducer(state, { + type: 'EDIT_NOTES_VEHICLEJOURNEY_MODAL', + vehicleJourney + }) + ).toEqual(Object.assign({}, state, {type: 'notes_edit', modalProps: modalPropsResult})) + }) + + it('should handle TOGGLE_FOOTNOTE_MODAL', () => { + state.modalProps = {vehicleJourney : {footnotes: [{}, {}]}} + let footnote = {} + let newState = { + // for the sake of the test, no need to specify the type + type: '', + modalProps:{vehicleJourney: {footnotes: [{},{},{}]}}, + confirmModal: {} + } + expect( + modalReducer(state, { + type: 'TOGGLE_FOOTNOTE_MODAL', + footnote, + isShown: true + }) + ).toEqual(newState) + }) }) diff --git a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js index 35d53a1fd..f0665a023 100644 --- a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js +++ b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js @@ -1,6 +1,11 @@ var vjReducer = require('es6_browserified/vehicle_journeys/reducers/vehicleJourneys') let state = [] +let stateModal = { + type: '', + modalProps: {}, + confirmModal: {} +} let fakeFootnotes = [{ id: 1, code: 1, @@ -214,4 +219,22 @@ describe('vehicleJourneys reducer', () => { }) ).toEqual([newVJ, state[1]]) }) + + + it('should handle EDIT_VEHICLEJOURNEY_NOTES', () => { + let fakeFootnote = { + id: 3, + code: 3, + label: "3" + } + fakeFootnotes.push(fakeFootnote) + let fakeFootnotesResult = fakeFootnotes.slice(0) + let newVJ = Object.assign({}, state[0], {footnotes: fakeFootnotesResult}) + expect( + vjReducer(state, { + type: 'EDIT_VEHICLEJOURNEY_NOTES', + footnotes: fakeFootnotesResult + }) + ).toEqual([newVJ, state[1]]) + }) }) |
