diff options
| author | cedricnjanga | 2017-09-26 00:29:18 +0200 | 
|---|---|---|
| committer | cedricnjanga | 2017-09-26 00:29:18 +0200 | 
| commit | b611a84ed724036c4929bd4c3eaa7e23ea314f45 (patch) | |
| tree | 957eaecb346a480a6fce3cfbb1d902552edb962f | |
| parent | f59f05bbf073f90edd2ae0006f028d802b6ed675 (diff) | |
| parent | 733548a996d5e66c740f59d313eb031ddfcc9116 (diff) | |
| download | chouette-core-b611a84ed724036c4929bd4c3eaa7e23ea314f45.tar.bz2 | |
Merge branch 'master' into staging
31 files changed, 334 insertions, 125 deletions
| diff --git a/INSTALL.md b/INSTALL.md index 330230a40..82f9f5779 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -139,8 +139,22 @@ To create `Referential` objects with some data (`Route`, `JourneyPattern`, `Vehi  # Troubleshooting +## Postgres +  If Postgres complains about illegal type `hstore` in your tests that is probably because the shared extension is not installed, here is what to do:        bundle exec rake db:test:purge  Thanks to `lib/tasks/extensions.rake`. + +## macOS + +### Nokogiri + +http://www.nokogiri.org/tutorials/installing_nokogiri.html tells us that `xz` can cause troubles, here is what to do  + +``` +brew unlink xz +gem install nokogiri # or bundle install +brew link xz +``` diff --git a/app/assets/javascripts/es6_browserified/itineraries/form_helper.js b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js index 0baba27ef..f682e39c0 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/form_helper.js +++ b/app/assets/javascripts/es6_browserified/itineraries/form_helper.js @@ -1,11 +1,55 @@ -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', formatedName) -  input.setAttribute('value', value) -  form.appendChild(input) +const formHelper = { +  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', formatedName) +    input.setAttribute('value', value) +    form.appendChild(input) +  },  +  addError: (ids) => { +    ids.forEach((id) => { +      if (!$(id).parents('.form-group').hasClass('has-error')) { +        $(id).parents('.form-group').addClass('has-error') +        $(id).parent().append(`<span class='help-block small'>${'doit être rempli(e)'}</span>`) +      } +    })  +  }, +  cleanInputs: (ids) => { +    ids.forEach((id) =>{ +      $(id).parents('.form-group').removeClass('has-error') +      $(id).siblings('span').remove() +    }) +  }, +  handleForm: (...ids) => { +    let filledInputs = [] +    let blankInputs = [] +    ids.forEach(id => { +      $(id).val() == "" ? blankInputs.push(id) : filledInputs.push(id) +    }) +     +    if (filledInputs.length > 0) formHelper.cleanInputs(filledInputs) +    if (blankInputs.length > 0) formHelper.addError(blankInputs)   +  }, +  handleStopPoints: (event, state) => { +    if (state.stopPoints.length >= 2) { +      state.stopPoints.map((stopPoint, i) => { +        formHelper.addInput('id', stopPoint.stoppoint_id ? stopPoint.stoppoint_id : '', i) +        formHelper.addInput('stop_area_id', stopPoint.stoparea_id, i) +        formHelper.addInput('position', i, i) +        formHelper.addInput('for_boarding', stopPoint.for_boarding, i) +        formHelper.addInput('for_alighting', stopPoint.for_alighting, i) +      }) +    if ($('.alert.alert-danger').length > 0) $('.alert.alert-danger').remove() +    } else { +      event.preventDefault() +      let msg = "L'itinéraire doit comporter au moins deux arrêts" +      if ($('.alert.alert-danger').length == 0) { +        $('#stop_points').find('.subform').after(`<div class='alert alert-danger'><span class='fa fa-lg fa-exclamation-circle'></span><span>" ${msg} "</span></div>`) +      } +    } +  }  } -module.exports = addInput +module.exports = formHelper
\ No newline at end of file diff --git a/app/assets/javascripts/es6_browserified/itineraries/index.js b/app/assets/javascripts/es6_browserified/itineraries/index.js index ad32b9519..bb06126f7 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/index.js @@ -4,7 +4,7 @@ var Provider = require('react-redux').Provider  var createStore = require('redux').createStore  var reducers = require('./reducers')  var App = require('./components/App') -var addInput = require('./form_helper') +var { handleForm, handleStopPoints } = require('./form_helper')  let datas = JSON.parse(decodeURIComponent(window.itinerary_stop))  // logger, DO NOT REMOVE @@ -67,17 +67,12 @@ render(  document.querySelector('input[name=commit]').addEventListener('click', (event)=>{    let state = store.getState() -  if(state.stopPoints.length >= 2) { -    state.stopPoints.map((stopPoint, i) => { -      addInput('id', stopPoint.stoppoint_id ? stopPoint.stoppoint_id : '', i) -      addInput('stop_area_id',stopPoint.stoparea_id, i) -      addInput('position',i, i) -      addInput('for_boarding',stopPoint.for_boarding, i) -      addInput('for_alighting',stopPoint.for_alighting, i) -    }) -  } else { +  let name = $("#route_name").val() +  let publicName = $("#route_published_name").val() +  if (name == "" || publicName == "") {      event.preventDefault() -    let msg = "L'itinéraire doit comporter au moins deux arrêts" -    $('#stop_points').find('.subform').after("<div class='alert alert-danger'><span class='fa fa-lg fa-exclamation-circle'></span><span>" + msg + "</span></div>") +    handleForm("#route_name", "#route_published_name")    } +     +  handleStopPoints(event, state)  }) diff --git a/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js b/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js index a3b8accb3..f3a26b8d7 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js +++ b/app/assets/javascripts/es6_browserified/itineraries/reducers/stopPoints.js @@ -1,5 +1,5 @@  var _ = require('lodash') -var addInput = require('../form_helper') +var { addInput } = require('../form_helper')  const stopPoint = (state = {}, action, length) => {    switch (action.type) { 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 ba5d91568..361e89c36 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js +++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js @@ -1,19 +1,20 @@  const _ = require('lodash') +const { I18n } = window  const actions = { +  weekDays: (index) => { +    return _.range(1, 8).map(n => I18n.time_tables.edit.metas.days[n]) +  },    strToArrayDayTypes: (str) =>{ -    let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'] -    return weekDays.map((day, i) => str.indexOf(day) !== -1) +    return actions.weekDays().map(day => str.indexOf(day) !== -1)    }, -  arrayToStrDayTypes: (arr) => { -    let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'] -    let str = [] -    arr.map((dayActive, i) => { -      if(dayActive){ -        str.push(weekDays[i]) -      } -    }) -    return str.join(',') +  arrayToStrDayTypes: (dayTypes) => { +    let newDayTypes = dayTypes.reduce((arr, dayActive, i) => { +      if (dayActive) arr.push(actions.weekDays()[i]) +      return arr +    }, []) + +    return newDayTypes.join(',')    },    fetchingApi: () =>({      type: 'FETCH_API' @@ -149,8 +150,8 @@ const actions = {      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) +    let monthList = _.range(1,13).map(n => I18n.calendars.months[n]) +    let date = new Date(strDate)      return monthList[date.getMonth()]    },    getHumanDate(strDate, mLimit) { @@ -219,7 +220,7 @@ const actions = {        let period = periods[i]        if (index !== i && !period.deleted) {          if (new Date(period.period_start) <= end && new Date(period.period_end) >= start)  { -          error = 'Les périodes ne peuvent pas se chevaucher' +          error = I18n.time_tables.edit.error_submit.periods_overlaps            break          }        } @@ -233,7 +234,7 @@ const actions = {      for (let day of in_days) {        if (start <= new Date(day.date) && end >= new Date(day.date)) { -        error = 'Une période ne peut chevaucher une date dans un calendrier' +        error = I18n.time_tables.edit.error_submit.dates_overlaps          break        }      } @@ -241,7 +242,6 @@ const actions = {    },    fetchTimeTables: (dispatch, nextPage) => {      let urlJSON = window.location.pathname.split('/', 5).join('/') -    // console.log(nextPage)      if(nextPage) {        urlJSON += "/month.json?date=" + nextPage      }else{ @@ -310,9 +310,9 @@ const actions = {    errorModalMessage: (errorKey) => {      switch (errorKey) {        case "withoutPeriodsWithDaysTypes": -        return window.I18n.fr.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes +        return I18n.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes        case "withPeriodsWithoutDayTypes": -        return window.I18n.fr.time_tables.edit.error_modal.withPeriodsWithoutDayTypes +        return I18n.time_tables.edit.error_modal.withPeriodsWithoutDayTypes        default:          return errorKey diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js index 40ae0eccf..674a03296 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js @@ -1,18 +1,17 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { PropTypes } = require('react') -const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}) => ( +const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}, {I18n}) => (    <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> +            <h4 className='modal-title'>{I18n.time_tables.edit.confirm_modal.title}</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> +              <p>{I18n.time_tables.edit.confirm_modal.message}</p>              </div>            </div>            <div className='modal-footer'> @@ -22,7 +21,7 @@ const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable,                type='button'                onClick= {() => {onModalCancel(modal.confirmModal.callback)}}                > -              Ne pas valider +              {I18n.cancel}              </button>              <button                className='btn btn-primary' @@ -30,7 +29,7 @@ const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable,                type='button'                onClick = {() => {onModalAccept(modal.confirmModal.callback, timetable, metas)}}                > -              Valider +              {I18n.actions.submit}              </button>            </div>          </div> @@ -45,4 +44,8 @@ ConfirmModal.propTypes = {    onModalCancel: PropTypes.func.isRequired  } +ConfirmModal.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = ConfirmModal diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js b/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js index 4e8f7e363..2597a4870 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js @@ -1,15 +1,14 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes -var errorModalMessage = require('../actions').errorModalMessage +var { PropTypes } = require('react') +var { errorModalMessage } = require('../actions') -const ErrorModal = ({dispatch, modal, I18n, onModalClose}) => ( +const ErrorModal = ({dispatch, modal, onModalClose}, {I18n}) => (    <div className={ 'modal fade ' + ((modal.type == 'error') ? 'in' : '') } id='ErrorModal'>      <div className='modal-container'>        <div className='modal-dialog'>          <div className='modal-content'>            <div className='modal-header'> -            <h4 className='modal-title'>{window.I18n.fr.time_tables.edit.error_modal.title}</h4> +            <h4 className='modal-title'>{I18n.time_tables.edit.error_modal.title}</h4>            </div>            <div className='modal-body'>              <div className='mt-md mb-md'> @@ -23,7 +22,7 @@ const ErrorModal = ({dispatch, modal, I18n, onModalClose}) => (                type='button'                onClick= {() => {onModalClose()}}                > -              Retour +              {I18n.back}              </button>            </div>          </div> @@ -37,4 +36,8 @@ ErrorModal.propTypes = {    onModalClose: PropTypes.func.isRequired  } +ErrorModal.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = ErrorModal 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 a0fac84f3..26a96e4a6 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js @@ -1,9 +1,9 @@  var React = require('react') -var PropTypes = require('react').PropTypes -let weekDays = ['D', 'L', 'Ma', 'Me', 'J', 'V', 'S'] +var  { PropTypes }  = require('react') +const { weekDays } = require('../actions')  var TagsSelect2 = require('./TagsSelect2') -const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}) => { +const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}, {I18n}) => {    let colorList = ["", "#9B9B9B", "#FFA070", "#C67300", "#7F551B", "#41CCE3", "#09B09C", "#3655D7",   "#6321A0", "#E796C6", "#DD2DAA"]    return (      <div className='form-horizontal'> @@ -12,7 +12,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* comment (name) */}            <div className="form-group">              <label htmlFor="" className="control-label col-sm-4 required"> -              Nom <abbr title="Champ requis">*</abbr> +              {I18n.time_tables.edit.metas.name} <abbr title="">*</abbr>              </label>              <div className="col-sm-8">                <input @@ -27,7 +27,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* color */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Couleur associée</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.color}</label>              <div className="col-sm-8">                <div className="dropdown color_selector">                  <button @@ -72,7 +72,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* tags */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Etiquettes</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.tag_list}</label>              <div className="col-sm-8">                <TagsSelect2                  initialTags={metas.initial_tags} @@ -85,16 +85,16 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* calendar */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Modèle de calendrier associé</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.calendar}</label>              <div className="col-sm-8"> -              <span>{metas.calendar ? metas.calendar.name : 'Aucun'}</span> +              <span>{metas.calendar ? metas.calendar.name : I18n.time_tables.edit.metas.no_calendar}</span>              </div>            </div>            {/* day_types */}            <div className="form-group">              <label htmlFor="" className="control-label col-sm-4"> -              Journées d'applications pour les périodes ci-dessous +              {I18n.time_tables.edit.metas.day_types}              </label>              <div className="col-sm-8">                <div className="form-group labelled-checkbox-group"> @@ -112,7 +112,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec                            type="checkbox"                            checked={day ? 'checked' : ''}                            /> -                        <span className='lcbx-group-item-label'>{weekDays[i]}</span> +                        <span className='lcbx-group-item-label'>{weekDays()[i]}</span>                        </label>                      </div>                    </div> @@ -135,4 +135,8 @@ Metas.propTypes = {    onUnselect2Tags: PropTypes.func.isRequired  } +Metas.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = Metas 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 3234a3fd7..d494109cc 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js @@ -1,5 +1,5 @@  var React = require('react') -var PropTypes = require('react').PropTypes +var { PropTypes } = require('react')  var _ = require('lodash')  let monthsArray = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'] @@ -32,7 +32,7 @@ const makeYearsOptions = (yearSelected) => {    return arr  } -const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}) => ( +const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}, {I18n}) => (    <div className="container-fluid">      <div className="row">        <div className="col lg-6 col-lg-offset-3"> @@ -44,7 +44,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    <div>                      <div className="form-group">                        <label htmlFor="" className="control-label required"> -                        Début de période +                        {I18n.time_tables.edit.period_form.begin}                          <abbr title="requis">*</abbr>                        </label>                      </div> @@ -52,7 +52,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    <div>                      <div className="form-group">                        <label htmlFor="" className="control-label required"> -                        Fin de période +                      {I18n.time_tables.edit.period_form.end}                          <abbr title="requis">*</abbr>                        </label>                      </div> @@ -103,14 +103,14 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    className='btn btn-link'                    onClick={onClosePeriodForm}                  > -                  Annuler +                  {I18n.cancel}                  </button>                  <button                    type='button'                    className='btn btn-outline-primary mr-sm'                    onClick={() => onValidatePeriodForm(modal.modalProps, timetable.time_table_periods, metas, _.filter(timetable.time_table_dates, ['in_out', true]))}                  > -                  Valider +                  {I18n.actions.submit}                  </button>                </div>              </div> @@ -122,7 +122,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                  className='btn btn-outline-primary'                  onClick={onOpenAddPeriodForm}                  > -                Ajouter une période +                {I18n.time_tables.actions.add_period}                </button>              </div>            } @@ -142,4 +142,8 @@ PeriodForm.propTypes = {    timetable: PropTypes.object.isRequired  } +PeriodForm.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = PeriodForm diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js index cf4cbfb32..704e21331 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js @@ -1,11 +1,10 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  var actions = require('../actions')  class PeriodManager extends Component { -  constructor(props) { -    super(props) +  constructor(props, context) { +    super(props, context)    }    toEndPeriod(curr, end) { @@ -82,4 +81,8 @@ PeriodManager.propTypes = {    onOpenEditPeriodForm: PropTypes.func.isRequired  } +PeriodManager.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = PeriodManager diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js b/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js index a1f41a693..46188cdd1 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js @@ -9,8 +9,8 @@ var path = window.location.pathname.split('/', 4).join('/')  var _ = require('lodash')  class TagsSelect2 extends React.Component{ -  constructor(props) { -    super(props) +  constructor(props, context) { +    super(props, context)    }    mapKeys(array){ @@ -38,7 +38,7 @@ class TagsSelect2 extends React.Component{            allowClear: true,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Ajoutez ou cherchez une étiquette...', +          placeholder: this.context.I18n.time_tables.edit.select2.tag.placeholder,            ajax: {              url: origin + path + '/tags.json',              dataType: 'json', @@ -74,4 +74,8 @@ const formatRepo = (props) => {    if(props.name) return props.name  } +TagsSelect2.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = TagsSelect2 diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js b/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js index 71621c874..93a0a90fe 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js @@ -1,6 +1,5 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  class TimeTableDay extends Component {    constructor(props) { diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js b/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js index a613549c3..22e971c6b 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js @@ -1,14 +1,13 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes}  = require('react')  var TimeTableDay = require('./TimeTableDay')  var PeriodsInDay = require('./PeriodsInDay')  var ExceptionsInDay = require('./ExceptionsInDay')  var actions = require('../actions')  class Timetable extends Component{ -  constructor(props){ -    super(props) +  constructor(props, context){ +    super(props, context)    }    currentDate(mFirstday, day) { @@ -31,11 +30,11 @@ class Timetable extends Component{          <div className="table table-2entries mb-sm">            <div className="t2e-head w20">              <div className="th"> -              <div className="strong">Synthèse</div> +              <div className="strong">{this.context.I18n.time_tables.synthesis}</div>              </div> -            <div className="td"><span>Journées d'application</span></div> -            <div className="td"><span>Périodes</span></div> -            <div className="td"><span>Exceptions</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.day_types}</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.periods}</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.exceptions}</span></div>            </div>            <div className="t2e-item-list w80">              <div> @@ -111,4 +110,8 @@ Timetable.propTypes = {    onIncludeDateInPeriod: PropTypes.func.isRequired  } +Timetable.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = Timetable 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 02f0ddbd8..772747104 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js +++ b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js @@ -1,6 +1,6 @@  var React = require('react')  var connect = require('react-redux').connect -var Component = require('react').Component +var { Component, PropTypes} = require('react')  var actions = require('../actions')  var Metas = require('./Metas')  var Timetable = require('./Timetable') @@ -9,12 +9,17 @@ var PeriodForm = require('./PeriodForm')  var SaveTimetable = require('./SaveTimetable')  var ConfirmModal = require('./ConfirmModal')  var ErrorModal = require('./ErrorModal') +const { I18n } = window  class App extends Component {    componentDidMount(){      this.props.onLoadFirstPage()    } +  getChildContext() { +    return { I18n } +  } +    render(){      return(        <div className='row'> @@ -41,6 +46,10 @@ const mapDispatchToProps = (dispatch) => {    }  } +App.childContextTypes = { +  I18n: PropTypes.object +} +  const timeTableApp = connect(null, mapDispatchToProps)(App)  module.exports = timeTableApp diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js index edb965065..712808abd 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js @@ -96,9 +96,9 @@ const timetable = (state = {}, action) => {        let newPeriods = JSON.parse(JSON.stringify(action.timeTablePeriods))        if (action.modalProps.index !== false){ -        updatePeriod = newPeriods[action.modalProps.index] -        updatePeriod.period_start = period_start -        updatePeriod.period_end = period_end +        let updatedPeriod = newPeriods[action.modalProps.index] +        updatedPeriod.period_start = period_start +        updatedPeriod.period_end = period_end          newDates = _.reject(state.time_table_dates, d => actions.isInPeriod(newPeriods, d.date) && !d.in_out)        }else{          let newPeriod = { diff --git a/app/models/referential.rb b/app/models/referential.rb index af08aa868..c7b52ddf8 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -45,6 +45,8 @@ class Referential < ActiveRecord::Base    has_many :stop_areas, through: :stop_area_referential    belongs_to :workbench +  belongs_to :referential_suite +    scope :ready, -> { where(ready: true) }    scope :in_periode, ->(periode) { where(id: referential_ids_in_periode(periode)) }    scope :include_metadatas_lines, ->(line_ids) { where('referential_metadata.line_ids && ARRAY[?]::bigint[]', line_ids) } diff --git a/app/models/referential_suite.rb b/app/models/referential_suite.rb new file mode 100644 index 000000000..9fd25ef3f --- /dev/null +++ b/app/models/referential_suite.rb @@ -0,0 +1,6 @@ +class ReferentialSuite < ActiveRecord::Base +  belongs_to :new, class_name: 'Referential' +  belongs_to :current, class_name: 'Referential' + +  has_many :referentials +end diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim index ed55dc4e3..cc6f31489 100644 --- a/app/views/time_tables/edit.html.slim +++ b/app/views/time_tables/edit.html.slim @@ -11,6 +11,6 @@  = javascript_tag do    | window.actionType = "#{raw params[:action]}"; -  | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; +  | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};  = javascript_include_tag 'es6_browserified/time_tables/index.js' diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml index 8dea51ca3..44e55067d 100644 --- a/config/locales/actions.en.yml +++ b/config/locales/actions.en.yml @@ -22,6 +22,7 @@ en:      create_api_key: "Create an API key"    or: "or"    cancel: "Cancel" +  back: "Go Back"    search_hint: "Type in a search term"    no_result_text: "No Results"    searching_term: "Searching..." diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml index 01fc06326..ee35fbb31 100644 --- a/config/locales/actions.fr.yml +++ b/config/locales/actions.fr.yml @@ -22,6 +22,7 @@ fr:      create_api_key: "Créer une clé d'API"    or: "ou"    cancel: "Annuler" +  back: "Retour"    search_hint: "Entrez un texte à rechercher"    no_result_text: "Aucun résultat"    searching_term: "Recherche en cours..." diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml new file mode 100644 index 000000000..497ca50c3 --- /dev/null +++ b/config/locales/compliance_control_sets.en.yml @@ -0,0 +1,24 @@ +fr: +  compliance_control_sets: +    index: +      title: Control games +      new: Creating a control set +      edit: Editing a Control Game +    actions: +          new: Add +          edit: Edit +          destroy: Delete +          destroy_confirm: Are you sure to remove the control games ? +    filters: +          name: Specify a control game name... +    search_no_results: No control game matches your search +  activerecord: +          models: +            compliance_control_set: Calendar +          attributes: +            compliance_control_set: +              name: Name +              assignment: Affectation +              owner_jdc: Owner of the control game +              control_numbers: Nb contrôle +              updated_at: Update
\ No newline at end of file diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index fedfeede7..f5bb7c67b 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -10,8 +10,8 @@ fr:            destroy: Supprimer            destroy_confirm: Etes vous sûr de supprimer ce jeux de contrôle ?      filters: -          name: 'Indiquez un nom de jeux de contrôle...' -    search_no_results: 'Aucun jeu de contrôle ne correspond à votre recherche' +          name: Indiquez un nom de jeux de contrôle... +    search_no_results: Aucun jeu de contrôle ne correspond à votre recherche    activerecord:            models:              compliance_control_set: Calendrier diff --git a/config/locales/time_tables.en.yml b/config/locales/time_tables.en.yml index d67e30edb..e68836f99 100644 --- a/config/locales/time_tables.en.yml +++ b/config/locales/time_tables.en.yml @@ -29,10 +29,39 @@ en:        title: "Duplicate timetable"      edit:        title: "Update timetable %{time_table}" +      day_types: Day types +      periods: Periods +      exceptions: Exceptions +      synthesis: Synthesis        error_modal:          title: "Error"          withoutPeriodsWithDaysTypes: "A timetable can't have day type(s) without period(s)." -        withPeriodsWithoutDayTypes: "A tiemetable can't have period(s) swithout day type(s)."   +        withPeriodsWithoutDayTypes: "A tiemetable can't have period(s) swithout day type(s)."  +      error_submit: +        periods_overlaps: "Periods cannot overlap in a timetable" +        dates_overlaps: "A period cannot overlap a date in a timetable" +      confirm_modal: +        title: "Confirm" +        message: "You are about to change pages. Do you want to validate your changes before this?" +      metas: +        name: Name +        calendar: Associated calendar +        no_calendar: None +        day_types: Periods day tpes +        days: +          1: Su +          2: Mo +          3: Tu +          4: We +          5: Th +          6: Fr +          7: Sa +      select2: +        tag: +          placeholder: Add or search a tag... +      period_form: +        begin: Period start +        end: Period end      show:        title: "Timetable %{time_table}"        dates: "Application dates" diff --git a/config/locales/time_tables.fr.yml b/config/locales/time_tables.fr.yml index 06d1d59e8..b85f7ca33 100644 --- a/config/locales/time_tables.fr.yml +++ b/config/locales/time_tables.fr.yml @@ -29,10 +29,39 @@ fr:        title: "Dupliquer un calendrier"      edit:        title: "Editer le calendrier %{time_table}" +      day_types: Journées d'application +      periods: Périodes +      exceptions: Exceptions +      synthesis: Synthèse        error_modal:          title: "Erreur"          withoutPeriodsWithDaysTypes: "Un calendrier d'application ne peut pas avoir de journée(s) d'application sans période(s)." -        withPeriodsWithoutDayTypes: "Un calendrier d'application ne peut pas avoir de période(s) sans journée(s) d'application."   +        withPeriodsWithoutDayTypes: "Un calendrier d'application ne peut pas avoir de période(s) sans journée(s) d'application." +      error_submit: +        periods_overlaps: "Les périodes ne peuvent pas se chevaucher" +        dates_overlaps: "Une période ne peut chevaucher une date dans un calendrier" +      confirm_modal: +        title: "Confirmation" +        message: "Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?" +      metas: +        name: Nom +        calendar: Modèle de calendrier associée +        no_calendar: Aucun +        day_types: Journées d'applications pour les périodes ci-dessous +        days: +          1: Di +          2: Lu +          3: Ma +          4: Me +          5: Je +          6: Ve +          7: Sa +      select2: +        tag: +          placeholder: Ajoutez ou cherchez une étiquette... +      period_form: +        begin: Début de période +        end: Fin de période      show:        title: Calendrier %{time_table}        dates: "Dates d'application" diff --git a/db/migrate/20170922161352_create_referential_suites.rb b/db/migrate/20170922161352_create_referential_suites.rb new file mode 100644 index 000000000..5a8693d01 --- /dev/null +++ b/db/migrate/20170922161352_create_referential_suites.rb @@ -0,0 +1,10 @@ +class CreateReferentialSuites < ActiveRecord::Migration +  def change +    create_table :referential_suites do |t| +      t.bigint :new_id, index: true +      t.bigint :current_id, index: true + +      t.timestamps null: false +    end +  end +end diff --git a/db/migrate/20170922165315_add_referential_suite_to_referentials.rb b/db/migrate/20170922165315_add_referential_suite_to_referentials.rb new file mode 100644 index 000000000..a01ba4d40 --- /dev/null +++ b/db/migrate/20170922165315_add_referential_suite_to_referentials.rb @@ -0,0 +1,8 @@ +class AddReferentialSuiteToReferentials < ActiveRecord::Migration +  def change +    add_reference :referentials, :referential_suite, +      index: true, +      foreign_key: true, +      type: :bigint +  end +end diff --git a/db/schema.rb b/db/schema.rb index 2b62fa7f1..89f002aee 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: 20170918103913) do +ActiveRecord::Schema.define(version: 20170922165315) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" @@ -602,6 +602,16 @@ ActiveRecord::Schema.define(version: 20170918103913) do    add_index "referential_metadata", ["referential_id"], name: "index_referential_metadata_on_referential_id", using: :btree    add_index "referential_metadata", ["referential_source_id"], name: "index_referential_metadata_on_referential_source_id", using: :btree +  create_table "referential_suites", id: :bigserial, force: :cascade do |t| +    t.integer  "new_id",     limit: 8 +    t.integer  "current_id", limit: 8 +    t.datetime "created_at",           null: false +    t.datetime "updated_at",           null: false +  end + +  add_index "referential_suites", ["current_id"], name: "index_referential_suites_on_current_id", using: :btree +  add_index "referential_suites", ["new_id"], name: "index_referential_suites_on_new_id", using: :btree +    create_table "referentials", id: :bigserial, force: :cascade do |t|      t.string   "name"      t.string   "slug" @@ -622,9 +632,11 @@ ActiveRecord::Schema.define(version: 20170918103913) do      t.datetime "archived_at"      t.integer  "created_from_id",          limit: 8      t.boolean  "ready",                              default: false +    t.integer  "referential_suite_id",     limit: 8    end    add_index "referentials", ["created_from_id"], name: "index_referentials_on_created_from_id", using: :btree +  add_index "referentials", ["referential_suite_id"], name: "index_referentials_on_referential_suite_id", using: :btree    create_table "route_sections", id: :bigserial, force: :cascade do |t|      t.integer  "departure_id",       limit: 8 @@ -987,6 +999,7 @@ ActiveRecord::Schema.define(version: 20170918103913) do    add_foreign_key "journey_patterns", "stop_points", column: "departure_stop_point_id", name: "departure_point_fkey", on_delete: :nullify    add_foreign_key "journey_patterns_stop_points", "journey_patterns", name: "jpsp_jp_fkey", on_delete: :cascade    add_foreign_key "journey_patterns_stop_points", "stop_points", name: "jpsp_stoppoint_fkey", on_delete: :cascade +  add_foreign_key "referentials", "referential_suites"    add_foreign_key "route_sections", "stop_areas", column: "arrival_id"    add_foreign_key "route_sections", "stop_areas", column: "departure_id"    add_foreign_key "routes", "routes", column: "opposite_route_id", name: "route_opposite_route_fkey" diff --git a/lib/model_attribute.rb b/lib/model_attribute.rb index 60580e306..4d246853a 100644 --- a/lib/model_attribute.rb +++ b/lib/model_attribute.rb @@ -12,9 +12,9 @@ class ModelAttribute    def self.classes      all        .map(&:klass) +      .uniq        .map(&:to_s)        .map(&:camelize) -      .uniq    end    def self.group_by_class @@ -93,7 +93,8 @@ class ModelAttribute    end    def ==(other) -    klass == other.klass && +    self.class === other && +      klass == other.klass &&        name == other.name &&        data_type == other.data_type    end diff --git a/spec/lib/model_attribute_spec.rb b/spec/lib/model_attribute_spec.rb index 427e01490..cdba87a90 100644 --- a/spec/lib/model_attribute_spec.rb +++ b/spec/lib/model_attribute_spec.rb @@ -1,4 +1,8 @@  RSpec.describe ModelAttribute do +  before(:each) do +    ModelAttribute.instance_variable_set(:@__all__, []) +  end +    describe ".define" do      it "adds a new instance of ModelAttribute to .all" do        expect do @@ -16,11 +20,9 @@ RSpec.describe ModelAttribute do    describe ".classes" do      it "returns the list of classes of ModelAttributes in .all" do -      ModelAttribute.instance_variable_set(:@__all__, [ -        ModelAttribute.new(:route, :name, :string), -        ModelAttribute.new(:journey_pattern, :name, :string), -        ModelAttribute.new(:time_table, :start_date, :date) -      ]) +      ModelAttribute.define(:route, :name, :string) +      ModelAttribute.define(:journey_pattern, :name, :string) +      ModelAttribute.define(:time_table, :start_date, :date)        expect(ModelAttribute.classes).to match_array([          'Route', @@ -32,9 +34,7 @@ RSpec.describe ModelAttribute do    describe ".from_code" do      it "returns a ModelAttribute from a given code" do -      ModelAttribute.instance_variable_set(:@__all__, [ -        ModelAttribute.new(:journey_pattern, :name, :string) -      ]) +      ModelAttribute.define(:journey_pattern, :name, :string)        expect(ModelAttribute.from_code('journey_pattern#name')).to eq(          ModelAttribute.new(:journey_pattern, :name, :string) @@ -44,12 +44,10 @@ RSpec.describe ModelAttribute do    describe ".group_by_class" do      it "returns all ModelAttributes grouped by klass" do -      ModelAttribute.instance_variable_set(:@__all__, [ -        ModelAttribute.new(:route, :name, :string), -        ModelAttribute.new(:route, :published_name, :string), -        ModelAttribute.new(:journey_pattern, :name, :string), -        ModelAttribute.new(:vehicle_journey, :number, :integer) -      ]) +      ModelAttribute.define(:route, :name, :string) +      ModelAttribute.define(:route, :published_name, :string) +      ModelAttribute.define(:journey_pattern, :name, :string) +      ModelAttribute.define(:vehicle_journey, :number, :integer)        expect(ModelAttribute.group_by_class).to eq({          route: [ @@ -68,12 +66,10 @@ RSpec.describe ModelAttribute do    describe ".methods_by_class" do      it "returns all ModelAttributes for a given class" do -      ModelAttribute.instance_variable_set(:@__all__, [ -        ModelAttribute.new(:route, :name, :string), -        ModelAttribute.new(:route, :published_name, :string), -        ModelAttribute.new(:route, :direction, :string), -        ModelAttribute.new(:journey_pattern, :name, :string) -      ]) +      ModelAttribute.define(:route, :name, :string) +      ModelAttribute.define(:route, :published_name, :string) +      ModelAttribute.define(:route, :direction, :string) +      ModelAttribute.define(:journey_pattern, :name, :string)        expect(ModelAttribute.methods_by_class(:route)).to match_array([          ModelAttribute.new(:route, :name, :string), @@ -85,12 +81,10 @@ RSpec.describe ModelAttribute do    describe ".methods_by_class_and_type" do      it "returns ModelAttributes of a certain class and type" do -      ModelAttribute.instance_variable_set(:@__all__, [ -        ModelAttribute.new(:route, :name, :string), -        ModelAttribute.new(:route, :checked_at, :date), -        ModelAttribute.new(:journey_pattern, :name, :string), -        ModelAttribute.new(:journey_pattern, :section_status, :integer) -      ]) +      ModelAttribute.define(:route, :name, :string) +      ModelAttribute.define(:route, :checked_at, :date) +      ModelAttribute.define(:journey_pattern, :name, :string) +      ModelAttribute.define(:journey_pattern, :section_status, :integer)        expect(ModelAttribute.methods_by_class_and_type(:route, :string)).to match_array([          ModelAttribute.new(:route, :name, :string) diff --git a/spec/models/referential_spec.rb b/spec/models/referential_spec.rb index f9ace08cc..bb8fabb2e 100644 --- a/spec/models/referential_spec.rb +++ b/spec/models/referential_spec.rb @@ -10,6 +10,7 @@ describe Referential, :type => :model do    it { should have_many(:metadatas) }    it { should belong_to(:workbench) } +  it { should belong_to(:referential_suite) }    context ".referential_ids_in_periode" do      it 'should retrieve referential id in periode range' do diff --git a/spec/models/referential_suite_spec.rb b/spec/models/referential_suite_spec.rb new file mode 100644 index 000000000..771187b55 --- /dev/null +++ b/spec/models/referential_suite_spec.rb @@ -0,0 +1,5 @@ +RSpec.describe ReferentialSuite, type: :model do +  it { should belong_to(:new).class_name('Referential') } +  it { should belong_to(:current).class_name('Referential') } +  it { should have_many(:referentials) } +end | 
