aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js6
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js2
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js4
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/actions/index.js33
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/containers/App.js29
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/index.js48
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/current_month.js10
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/index.js18
-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.js8
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/periode_range.js10
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/status.js16
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/time_table_periods.js10
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js67
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/Filters.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/Navigate.js4
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js47
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js3
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/index.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js5
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js6
-rw-r--r--app/assets/javascripts/forms.coffee12
-rw-r--r--app/assets/javascripts/main_menu.coffee3
-rw-r--r--app/assets/stylesheets/base/_config.sass1
-rw-r--r--app/assets/stylesheets/components/_buttons.sass2
-rw-r--r--app/assets/stylesheets/components/_calendar.sass73
-rw-r--r--app/assets/stylesheets/components/_forms.sass33
-rw-r--r--app/assets/stylesheets/components/_labels.sass12
-rw-r--r--app/assets/stylesheets/components/_select2.sass16
-rw-r--r--app/assets/stylesheets/main/time_tables.sass6
-rw-r--r--app/controllers/referential_companies_controller.rb7
-rw-r--r--app/controllers/time_tables_controller.rb26
-rw-r--r--app/controllers/vehicle_journeys_controller.rb4
-rw-r--r--app/helpers/newapplication_helper.rb8
-rw-r--r--app/helpers/time_tables_helper.rb177
-rw-r--r--app/models/chouette/line.rb5
-rw-r--r--app/models/chouette/time_table.rb13
-rw-r--r--app/views/time_tables/_excluded_date_fields.html.slim20
-rw-r--r--app/views/time_tables/_form.html.slim41
-rw-r--r--app/views/time_tables/_periods.html.slim5
-rw-r--r--app/views/time_tables/_show_time_table.html.slim119
-rw-r--r--app/views/time_tables/index.html.slim88
-rw-r--r--app/views/time_tables/index.js.slim1
-rw-r--r--app/views/time_tables/month.rabl4
-rw-r--r--app/views/time_tables/show.html.slim62
-rw-r--r--app/views/time_tables/show.rabl18
-rw-r--r--app/views/vehicle_journeys/show.rabl6
-rw-r--r--config/locales/actions.en.yml2
-rw-r--r--config/locales/actions.fr.yml2
-rw-r--r--config/locales/calendars.en.yml8
-rw-r--r--config/locales/calendars.fr.yml21
-rw-r--r--config/locales/en.yml1
-rw-r--r--config/locales/fr.yml1
-rw-r--r--config/locales/time_tables.en.yml2
-rw-r--r--config/locales/time_tables.fr.yml2
-rw-r--r--config/routes.rb1
-rw-r--r--db/migrate/20170410134931_add_color_to_timetables.rb5
-rw-r--r--db/schema.rb3
-rw-r--r--spec/features/time_tables_spec.rb46
-rw-r--r--spec/javascripts/vehicle_journeys/reducers/filters_spec.js6
-rw-r--r--spec/views/time_tables/index.html.erb_spec.rb22
-rw-r--r--spec/views/time_tables/show.html.erb_spec.rb7
64 files changed, 953 insertions, 280 deletions
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
index 709686f21..54d62f999 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
@@ -130,9 +130,10 @@ const actions = {
if(next) {
dispatch(next)
} else {
- if(json.length != window.journeyPatternsPerPage){
- dispatch(actions.updateTotalCount(window.journeyPatternsPerPage - json.length))
+ if(json.length != window.currentItemsLength){
+ dispatch(actions.updateTotalCount(window.currentItemsLength - json.length))
}
+ window.currentItemsLength = json.length
dispatch(actions.receiveJourneyPatterns(json))
}
}
@@ -196,6 +197,7 @@ const actions = {
})
}
}
+ window.currentItemsLength = journeyPatterns.length
dispatch(actions.receiveJourneyPatterns(journeyPatterns))
}
})
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
index a37b9f1d8..d9f6d5550 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
@@ -14,7 +14,7 @@ class JourneyPattern extends Component{
let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid
return (
- <a href={vjURL}>Horaires des courses</a>
+ <a data-no-turbolink="true" href={vjURL}>Horaires des courses</a>
)
}
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js
index 3ca860e2e..5747aa5ce 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/Navigate.js
@@ -31,7 +31,7 @@ let Navigate = ({ dispatch, journeyPatterns, pagination, status }) => {
data-toggle=''
data-target='#ConfirmModal'
className={'previous_page' + (pagination.page == firstPage ? ' disabled' : '')}
- disabled={'previous_page' + (pagination.page == firstPage ? ' disabled' : '')}
+ disabled={(pagination.page == firstPage ? ' disabled' : '')}
>
</button>
<button
@@ -43,7 +43,7 @@ let Navigate = ({ dispatch, journeyPatterns, pagination, status }) => {
data-toggle=''
data-target='#ConfirmModal'
className={'next_page' + (pagination.page == lastPage ? ' disabled' : '')}
- disabled={'next_page' + (pagination.page == lastPage ? ' disabled' : '')}
+ disabled={(pagination.page == lastPage ? 'disabled' : '')}
>
</button>
</form>
diff --git a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
new file mode 100644
index 000000000..7c9a5be08
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
@@ -0,0 +1,33 @@
+const actions = {
+ fetchingApi: () =>({
+ type: 'FETCH_API'
+ }),
+ unavailableServer : () => ({
+ type: 'UNAVAILABLE_SERVER'
+ }),
+ receiveTimeTables : (json) => ({
+ type: "RECEIVE_TIME_TABLES",
+ json
+ }),
+
+ fetchTimeTables : (dispatch, currentPage, nextPage) => {
+ let urlJSON = window.location.pathname.split('/', 5).join('/') + '.json'
+ let hasError = false
+ fetch(urlJSON, {
+ credentials: 'same-origin',
+ }).then(response => {
+ if(response.status == 500) {
+ hasError = true
+ }
+ return response.json()
+ }).then((json) => {
+ if(hasError == true) {
+ dispatch(actions.unavailableServer())
+ } else {
+ dispatch(actions.receiveTimeTables(json))
+ }
+ })
+ },
+}
+
+module.exports = actions
diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js
new file mode 100644
index 000000000..ab8c3bf06
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js
@@ -0,0 +1,29 @@
+var React = require('react')
+var connect = require('react-redux').connect
+var Component = require('react').Component
+var actions = require('../actions')
+
+class App extends Component {
+ componentDidMount(){
+ this.props.onLoadFirstPage()
+ }
+
+ render(){
+ return(
+ <div></div>
+ )
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onLoadFirstPage: () =>{
+ dispatch(actions.fetchingApi())
+ actions.fetchTimeTables(dispatch)
+ }
+ }
+}
+
+const timeTableApp = connect(null, mapDispatchToProps)(App)
+
+module.exports = timeTableApp
diff --git a/app/assets/javascripts/es6_browserified/time_tables/index.js b/app/assets/javascripts/es6_browserified/time_tables/index.js
new file mode 100644
index 000000000..4e44e49ba
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/index.js
@@ -0,0 +1,48 @@
+var React = require('react')
+var render = require('react-dom').render
+var Provider = require('react-redux').Provider
+var createStore = require('redux').createStore
+var timeTablesApp = require('./reducers')
+var App = require('./containers/App')
+
+// logger, DO NOT REMOVE
+// var applyMiddleware = require('redux').applyMiddleware
+// var createLogger = require('redux-logger')
+// var thunkMiddleware = require('redux-thunk').default
+// var promise = require('redux-promise')
+
+var initialState = {
+ status: {
+ policy: window.perms,
+ fetchSuccess: true,
+ isFetching: false
+ },
+ current_month: [],
+ time_table_periods: [],
+ periode_range: [],
+ pagination: {
+ page : 1,
+ totalCount: window.journeyPatternLength,
+ perPage: window.journeyPatternsPerPage,
+ stateChanged: false
+ },
+ modal: {
+ type: '',
+ modalProps: {},
+ confirmModal: {}
+ }
+}
+// const loggerMiddleware = createLogger()
+
+let store = createStore(
+ timeTablesApp,
+ initialState
+ // applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+)
+
+render(
+ <Provider store={store}>
+ <App />
+ </Provider>,
+ document.getElementById('time_tables')
+)
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/current_month.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/current_month.js
new file mode 100644
index 000000000..425e897d1
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/current_month.js
@@ -0,0 +1,10 @@
+const currentMonth = (state = [], action) => {
+ switch (action.type) {
+ case 'RECEIVE_TIME_TABLES':
+ return action.json.current_month
+ default:
+ return state
+ }
+}
+
+module.exports = currentMonth
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/index.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/index.js
new file mode 100644
index 000000000..4308c0104
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/index.js
@@ -0,0 +1,18 @@
+var combineReducers = require('redux').combineReducers
+var status = require('./status')
+var pagination = require('./pagination')
+var modal = require('./modal')
+var current_month = require('./current_month')
+var periode_range = require('./periode_range')
+var time_table_periods = require('./time_table_periods')
+
+const timeTablesApp = combineReducers({
+ current_month,
+ periode_range,
+ time_table_periods,
+ status,
+ pagination,
+ modal
+})
+
+module.exports = timeTablesApp
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js
new file mode 100644
index 000000000..e011164c5
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/modal.js
@@ -0,0 +1,8 @@
+const modal = (state = {}, action) => {
+ switch (action.type) {
+ default:
+ return state
+ }
+}
+
+module.exports = modal
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js
new file mode 100644
index 000000000..5ea7300dc
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js
@@ -0,0 +1,8 @@
+const pagination = (state = {}, action) => {
+ switch (action.type) {
+ default:
+ return state
+ }
+}
+
+module.exports = pagination
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/periode_range.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/periode_range.js
new file mode 100644
index 000000000..095069f8a
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/periode_range.js
@@ -0,0 +1,10 @@
+const periodeRange = (state = [], action) => {
+ switch (action.type) {
+ case 'RECEIVE_TIME_TABLES':
+ return action.json.periode_range
+ default:
+ return state
+ }
+}
+
+module.exports = periodeRange
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/status.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/status.js
new file mode 100644
index 000000000..aaedff4c1
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/status.js
@@ -0,0 +1,16 @@
+var _ = require('lodash')
+
+const status = (state = {}, action) => {
+ switch (action.type) {
+ case 'UNAVAILABLE_SERVER':
+ return _.assign({}, state, {fetchSuccess: false})
+ case 'FETCH_API':
+ return _.assign({}, state, {isFetching: true})
+ case 'RECEIVE_JOURNEY_PATTERNS':
+ return _.assign({}, state, {fetchSuccess: true, isFetching: false})
+ default:
+ return state
+ }
+}
+
+module.exports = status
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/time_table_periods.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/time_table_periods.js
new file mode 100644
index 000000000..614e63894
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/time_table_periods.js
@@ -0,0 +1,10 @@
+const timeTablePeriods = (state = [], action) => {
+ switch (action.type) {
+ case 'RECEIVE_TIME_TABLES':
+ return action.json.time_table_periods
+ default:
+ return state
+ }
+}
+
+module.exports = timeTablePeriods
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 9b6eca720..81bbcdbb0 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
@@ -315,9 +315,12 @@ const actions = {
selected: false,
published_journey_name: val.published_journey_name || 'non renseigné',
published_journey_identifier: val.published_journey_name || 'non renseigné',
- company_id: val.published_journey_name || 'non renseigné'
+ company_id: val.published_journey_name || 'non renseigné',
+ transport_mode: val.route.line.transport_mode || 'non renseigné',
+ transport_mode: val.route.line.transport_submode || 'non renseigné'
})
}
+ window.currentItemsLength = vehicleJourneys.length
dispatch(actions.receiveVehicleJourneys(vehicleJourneys))
dispatch(actions.receiveTotalCount(json.total))
}
@@ -348,9 +351,10 @@ const actions = {
if(next) {
dispatch(next)
} else {
- if(json.length != window.vehicleJourneysPerPage){
- dispatch(actions.updateTotalCount(window.vehicleJourneysPerPage - json.length))
+ if(json.length != window.currentItemsLength){
+ dispatch(actions.updateTotalCount(window.currentItemsLength - json.length))
}
+ window.currentItemsLength = json.length
dispatch(actions.receiveVehicleJourneys(json))
}
}
@@ -406,20 +410,61 @@ const actions = {
return vjas
},
checkSchedules: (schedule) => {
+ let hours = 0
+ let minutes = 0
if (parseInt(schedule.departure_time.minute) > 59){
- schedule.departure_time.minute = actions.pad(parseInt(schedule.departure_time.minute) - 60, 'minute')
- schedule.departure_time.hour = actions.pad(parseInt(schedule.departure_time.hour) + 1, 'hour')
+ hours = Math.floor(parseInt(schedule.departure_time.minute) / 60)
+ minutes = parseInt(schedule.departure_time.minute) % 60
+ schedule.departure_time.minute = actions.simplePad(minutes, 'minute')
+ schedule.departure_time.hour = parseInt(schedule.departure_time.hour) + hours
}
if (parseInt(schedule.arrival_time.minute) > 59){
- schedule.arrival_time.minute = actions.pad(parseInt(schedule.arrival_time.minute) - 60, 'minute')
- schedule.arrival_time.hour = actions.pad(parseInt(schedule.arrival_time.hour) + 1, 'hour')
+ hours = Math.floor(parseInt(schedule.arrival_time.minute) / 60)
+ minutes = parseInt(schedule.arrival_time.minute) % 60
+ schedule.arrival_time.minute = actions.simplePad(minutes, 'minute')
+ schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) + hours
}
- if (parseInt(schedule.departure_time.hour) > 23){
- schedule.departure_time.hour = actions.pad(parseInt(schedule.departure_time.hour) - 24, 'hour')
+ if (parseInt(schedule.departure_time.minute) < 0){
+ hours = Math.floor(parseInt(schedule.departure_time.minute) / 60)
+ minutes = (parseInt(schedule.departure_time.minute) % 60) + 60
+ schedule.departure_time.minute = actions.simplePad(minutes, 'minute')
+ schedule.departure_time.hour = parseInt(schedule.departure_time.hour) + hours
}
- if (parseInt(schedule.arrival_time.hour) > 23){
- schedule.arrival_time.hour = actions.pad(parseInt(schedule.arrival_time.hour) - 24, 'hour')
+ if (parseInt(schedule.arrival_time.minute) < 0){
+ hours = Math.floor(parseInt(schedule.arrival_time.minute) / 60)
+ minutes = (parseInt(schedule.arrival_time.minute) % 60) + 60
+ schedule.arrival_time.minute = actions.simplePad(minutes, 'minute')
+ schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) + hours
}
+
+ if(schedule.departure_time.hour > 23){
+ schedule.departure_time.hour = '23'
+ schedule.departure_time.minute = '59'
+ }
+ if(schedule.arrival_time.hour > 23){
+ schedule.arrival_time.hour = '23'
+ schedule.arrival_time.minute = '59'
+ }
+
+ if(schedule.departure_time.hour < 0){
+ schedule.departure_time.hour = '00'
+ schedule.departure_time.minute = '00'
+ }
+ if(schedule.arrival_time.hour > 23){
+ schedule.arrival_time.hour = '00'
+ schedule.arrival_time.minute = '00'
+ }
+
+ schedule.departure_time.hour = actions.simplePad(parseInt(schedule.departure_time.hour), 'hour')
+ schedule.arrival_time.hour = actions.simplePad(parseInt(schedule.arrival_time.hour), 'hour')
+ // if (parseInt(schedule.departure_time.hour) > 23){
+ // schedule.departure_time.hour = parseInt(schedule.departure_time.hour) - 24
+ // }
+ // if (parseInt(schedule.arrival_time.hour) > 23){
+ // schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) - 24
+ // }
+ // schedule.departure_time.hour = actions.pad(schedule.departure_time.hour, 'hour')
+ // schedule.arrival_time.hour = actions.pad(schedule.arrival_time.hour, 'hour')
}
}
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Filters.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Filters.js
index bddb29434..6f07dd880 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Filters.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Filters.js
@@ -97,7 +97,7 @@ const Filters = ({filters, pagination, onFilter, onResetFilters, onUpdateStartTi
onChange={onToggleWithoutSchedule}
checked={filters.query.withoutSchedule}
></input>
- <span className='switch-label' data-checkedvalue='Oui' data-uncheckedvalue='Non'></span>
+ <span className='switch-label' data-checkedvalue='Non' data-uncheckedvalue='Oui'></span>
</label>
</div>
</div>
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Navigate.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Navigate.js
index 2d5923a4d..a62e034ae 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Navigate.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/Navigate.js
@@ -29,7 +29,7 @@ let Navigate = ({ dispatch, vehicleJourneys, pagination, status, filters}) => {
type='button'
data-target='#ConfirmModal'
className={(pagination.page == firstPage ? 'disabled ' : '') + 'previous_page'}
- disabled={(pagination.page == firstPage ? true : false)}
+ disabled={(pagination.page == firstPage ? 'disabled' : '')}
></button>
<button
onClick={e => {
@@ -39,7 +39,7 @@ let Navigate = ({ dispatch, vehicleJourneys, pagination, status, filters}) => {
type='button'
data-target='#ConfirmModal'
className={(pagination.page == lastPage ? 'disabled ' : '') + 'next_page'}
- disabled={(pagination.page == lastPage ? true : false)}
+ disabled={(pagination.page == lastPage ? 'disabled' : '')}
></button>
</form>
</div>
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
index 7fc625f6a..7448aa06e 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/DuplicateVehicleJourney.js
@@ -68,7 +68,7 @@ class DuplicateVehicleJourney extends Component {
<input
type='number'
ref='additional_time'
- min='0'
+ min='-59'
max='59'
className='form-control'
onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js
index 12814bad1..9a4790051 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/EditVehicleJourney.js
@@ -74,22 +74,51 @@ class EditVehicleJourney extends Component {
<div className='row'>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
- <label className='control-label is-required'>Numéro de train</label>
- <input
- type='text'
- ref='published_journey_identifier'
- className='form-control'
- defaultValue={this.props.modal.modalProps.vehicleJourney.published_journey_identifier}
- onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
- required
+ <div className='form-group'>
+ <label className='control-label is-required'>Numéro de train</label>
+ <input
+ type='text'
+ ref='published_journey_identifier'
+ className='form-control'
+ defaultValue={this.props.modal.modalProps.vehicleJourney.published_journey_identifier}
+ onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ required
/>
+ </div>
</div>
<div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
- <label className='control-label'>Transporteur</label>
+ <div className='form-group'>
+ <label className='control-label'>Transporteur</label>
<CompanySelect2
company = {this.props.modal.modalProps.vehicleJourney.company}
onSelect2Company = {(e) => this.props.onSelect2Company(e)}
/>
+ </div>
+ </div>
+ </div>
+
+ <div className='row'>
+ <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
+ <div className='form-group'>
+ <label className='control-label'>Mode de transport</label>
+ <input
+ type='text'
+ className='form-control'
+ value={(this.props.modal.modalProps.vehicleJourney.transport_mode || 'non renseigné')}
+ disabled={true}
+ />
+ </div>
+ </div>
+ <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
+ <div className='form-group'>
+ <label className='control-label'>Sous mode de transport</label>
+ <input
+ type='text'
+ className='form-control'
+ value={(this.props.modal.modalProps.vehicleJourney.transport_submode || 'non renseigné')}
+ disabled={true}
+ />
+ </div>
</div>
</div>
</div>
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js
index af1b29de1..ee7d01cf5 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/ShiftVehicleJourney.js
@@ -54,7 +54,7 @@ class ShiftVehicleJourney extends Component {
<input
type='number'
ref='additional_time'
- min='0'
+ min='-59'
max='59'
className='form-control'
onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js
index 7837cdbff..1f5e5e98f 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/select2s/CompanySelect2.js
@@ -6,6 +6,7 @@ var Select2 = require('react-select2')
// get JSON full path
var origin = window.location.origin
var path = window.location.pathname.split('/', 3).join('/')
+var line = window.location.pathname.split('/')[4]
class BSelect4 extends React.Component{
@@ -27,7 +28,7 @@ class BSelect4 extends React.Component{
width: '100%',
placeholder: 'Filtrer par transporteur...',
ajax: {
- url: origin + path + '/companies.json',
+ url: origin + path + '/companies.json' + '?line_id=' + line,
dataType: 'json',
delay: '500',
data: function(params) {
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
index bf6930215..4c9423c1f 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
@@ -44,7 +44,7 @@ var initialState = {
timetable: {
comment: ''
},
- withoutSchedule: false
+ withoutSchedule: true
}
},
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js
index e7d5baafc..cd065e362 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/filters.js
@@ -15,7 +15,7 @@ const filters = (state = {}, action) => {
minute: '59'
}
}
- newQuery = _.assign({}, state.query, {interval: interval, journeyPattern: {}, timetable: {}, withoutSchedule: false })
+ newQuery = _.assign({}, state.query, {interval: interval, journeyPattern: {}, timetable: {}, withoutSchedule: true })
return _.assign({}, state, {query: newQuery, queryString: ''})
case 'TOGGLE_WITHOUT_SCHEDULE':
newQuery = _.assign({}, state.query, {withoutSchedule: !state.query.withoutSchedule})
@@ -54,7 +54,8 @@ const filters = (state = {}, action) => {
'q[journey_pattern_id_eq]': state.query.journeyPattern.id || undefined,
'q[time_tables_id_eq]': state.query.timetable.id || undefined,
'q[vehicle_journey_at_stops_departure_time_gteq]': (state.query.interval.start.hour + ':' + state.query.interval.start.minute),
- 'q[vehicle_journey_at_stops_departure_time_lteq]': (state.query.interval.end.hour + ':' + state.query.interval.end.minute)
+ 'q[vehicle_journey_at_stops_departure_time_lteq]': (state.query.interval.end.hour + ':' + state.query.interval.end.minute),
+ 'q[vehicle_journey_without_departure_time]' : state.query.withoutSchedule
}
let queryString = actions.encodeParams(params)
return _.assign({}, state, {queryString: queryString})
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 ba3d58c22..2db76deae 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
@@ -60,9 +60,11 @@ const vehicleJourney= (state = {}, action) => {
}
actions.checkSchedules(shiftedSchedule)
shiftedVjas = _.assign({}, state.vehicle_journey_at_stops[i], shiftedSchedule)
- delete shiftedVjas['id']
- return _.assign({}, state.vehicle_journey_at_stops[i], shiftedVjas)
+ vjas = _.assign({}, state.vehicle_journey_at_stops[i], shiftedVjas)
+ delete vjas['id']
+ return vjas
}else {
+ delete vjas['id']
return vjas
}
})
diff --git a/app/assets/javascripts/forms.coffee b/app/assets/javascripts/forms.coffee
index 9d884edcd..679f92a54 100644
--- a/app/assets/javascripts/forms.coffee
+++ b/app/assets/javascripts/forms.coffee
@@ -30,9 +30,21 @@ isEdge = !isIE && !!window.StyleMedia
if isIE || isEdge
$('.formSubmitr').off()
+@colorSelector = ->
+ $('.form-group .dropdown.color_selector').each ->
+ selectedStatus = $(this).children('.dropdown-toggle').children('.fa-circle')
+
+ $(this).on 'click', "input[type='radio']", (e) ->
+ selectedValue = e.currentTarget.value
+ if selectedValue == ''
+ $(selectedStatus).css('color', 'transparent')
+ else
+ $(selectedStatus).css('color', selectedValue)
+
$(document).on 'ready page:load', togglableFilter
$(document).on 'ready page:load', submitMover
$(document).on 'ready page:load', switchInput
+$(document).on 'ready page:load', colorSelector
if isIE || isEdge
$(document).on 'click', '.formSubmitr', (e)->
diff --git a/app/assets/javascripts/main_menu.coffee b/app/assets/javascripts/main_menu.coffee
index 9357cff34..67e2f437e 100644
--- a/app/assets/javascripts/main_menu.coffee
+++ b/app/assets/javascripts/main_menu.coffee
@@ -49,5 +49,6 @@ $(document).on 'ready page:load', ->
$('#main_nav').removeClass 'sticky'
if $('#menu_top').find('.sticky-content').length > 0
- $('.page-action .small').after(link)
+ if !$('.page-action').find('.formSubmitr').length
+ $('.page-action .small').after(link)
$('.sticky-content').remove()
diff --git a/app/assets/stylesheets/base/_config.sass b/app/assets/stylesheets/base/_config.sass
index ae8b386e6..65444479f 100644
--- a/app/assets/stylesheets/base/_config.sass
+++ b/app/assets/stylesheets/base/_config.sass
@@ -21,3 +21,4 @@ $green: #70b12b
$red: #da2f36
$orange: #ed7f00
+$gold: #ffcc00
diff --git a/app/assets/stylesheets/components/_buttons.sass b/app/assets/stylesheets/components/_buttons.sass
index f128512f5..07758d56c 100644
--- a/app/assets/stylesheets/components/_buttons.sass
+++ b/app/assets/stylesheets/components/_buttons.sass
@@ -5,7 +5,7 @@
.btn
font-weight: 700
- .fa + span
+ .fa + span:not(.caret)
padding-left: 0.5em
span + .fa
padding-left: 0.5em
diff --git a/app/assets/stylesheets/components/_calendar.sass b/app/assets/stylesheets/components/_calendar.sass
new file mode 100644
index 000000000..64f2eda77
--- /dev/null
+++ b/app/assets/stylesheets/components/_calendar.sass
@@ -0,0 +1,73 @@
+//-----------//
+// CALENDARS //
+//-----------//
+
+table.calendar
+ display: table
+ width: 100%
+ table-layout: fixed
+ margin-bottom: 20px
+
+ th, td
+ border: 1px solid $darkgrey
+ text-align: center
+ padding: 0.35em 0.5em
+
+ th
+ padding: 0.5em
+
+ thead
+ tr
+ > th
+ border: none
+
+ &:first-child
+ text-transform: uppercase
+
+ tbody
+ tr > td
+ &.weekNumber
+ border: none
+ padding: 0.5em 0.5em 0.5em 0
+
+ &.outsideMonth
+ color: rgba($darkgrey, 0.35)
+
+ &.weekend
+ font-weight: bold
+
+ &.selected_period, &.selected_date, &.overlaped_date
+ > a
+ display: block
+ margin: 0 auto
+ width: 24px
+ height: 24px
+ line-height: 24px
+ color: $darkgrey
+ background-color: $gold
+ border-radius: 50%
+
+ &:hover, &:focus
+ color: $darkgrey
+ text-decoration: none
+
+.col-xs-6
+ &:nth-child(2n +1)
+ clear: both
+
+.col-sm-4
+ @media (min-width: 768px)
+ &:nth-child(2n +1)
+ clear: none
+ &:nth-child(3n+1)
+ clear: both
+
+// .col-md-4
+// @media (min-width: 992px)
+
+.col-lg-3
+ @media (min-width: 1200px)
+ &:nth-child(2n +1), &:nth-child(3n+1)
+ clear: none
+ &:nth-child(4n+1)
+ clear: both
diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass
index f2c76c9c1..6d841d5d4 100644
--- a/app/assets/stylesheets/components/_forms.sass
+++ b/app/assets/stylesheets/components/_forms.sass
@@ -95,6 +95,39 @@ input
+ [class*='col-sm-']
float: right
+// Colors dropdown
+.dropdown.color_selector
+ .btn.btn-default
+ &, &:hover, &:focus
+ border: 1px solid #cccccc
+ background-color: #fff
+ font-weight: normal
+ color: $darkgrey
+
+ .dropdown-menu
+ position: absolute
+ margin: 2px 0 0 0
+ min-width: 56px
+
+ > .radio
+ position: relative
+ padding: 3px 20px
+ // cursor: pointer
+
+ &:hover, &:focus
+ background-color: #f5f5f5
+
+ > label
+ padding: 0
+
+ input.color_selector, input[type='radio']
+ position: absolute
+ cursor: pointer
+ z-index: 1
+ width: 100%
+ margin: 0
+ opacity: 0
+
// Search bar
.search_bar
position: relative
diff --git a/app/assets/stylesheets/components/_labels.sass b/app/assets/stylesheets/components/_labels.sass
index 3514bce81..9607a97b8 100644
--- a/app/assets/stylesheets/components/_labels.sass
+++ b/app/assets/stylesheets/components/_labels.sass
@@ -8,7 +8,15 @@
font-weight: inherit
padding: 0.35em 0.4em
border-radius: 2px
+ border: 1px solid
+
+ + .label
+ margin-left: 0.5em
&.label-default
- background-color: rgba(#fff, 0.3)
- color: #fff
+ background-color: #fff
+ color: $darkgrey
+ border-color: rgba($grey, 0.5)
+
+ &.disabled
+ color: rgba($grey, 0.5)
diff --git a/app/assets/stylesheets/components/_select2.sass b/app/assets/stylesheets/components/_select2.sass
index 5e3741bf0..cbb3a80da 100644
--- a/app/assets/stylesheets/components/_select2.sass
+++ b/app/assets/stylesheets/components/_select2.sass
@@ -50,9 +50,19 @@
.form-filter
.form-group.select2ed
- .select2-container--bootstrap .select2-selection--single
- height: 31px
- padding: 4px 24px 5px 12px
+ .select2-container--bootstrap
+ .select2-selection--single, .select2-selection--multiple
+ height: 31px
+ padding: 0px 3px 4px 6px
+
+ .select2-selection--single
+ line-height: 31px
+
+ .select2-selection--multiple
+ min-height: 31px
+
+ .select2-search--inline .select2-search__field
+ height: 28px
.select2-container--bootstrap .select2-selection
border-color: rgba($grey, 0.3)
diff --git a/app/assets/stylesheets/main/time_tables.sass b/app/assets/stylesheets/main/time_tables.sass
index de2ae8253..6918bec1e 100644
--- a/app/assets/stylesheets/main/time_tables.sass
+++ b/app/assets/stylesheets/main/time_tables.sass
@@ -28,13 +28,13 @@
z-index: 100001
.validity_out
- color: $brand-danger
+ color: red
.validity_out_soon
- color: $brand-warning
+ color: orange
.validity_regular
- color: $brand-success
+ color: green
span.included_day_type
font-weight: bolder
diff --git a/app/controllers/referential_companies_controller.rb b/app/controllers/referential_companies_controller.rb
index 0966389b4..e8b104d14 100644
--- a/app/controllers/referential_companies_controller.rb
+++ b/app/controllers/referential_companies_controller.rb
@@ -27,7 +27,12 @@ class ReferentialCompaniesController < ChouetteController
end
def collection
- @q = referential.workbench.companies.search(params[:q])
+ scope = referential.line_referential.companies
+ if params[:line_id]
+ scope = referential.line_referential.lines.find(params[:line_id]).companies
+ end
+
+ @q = scope.search(params[:q])
if sort_column && sort_direction
@companies ||= @q.result(:distinct => true).order(sort_column + ' ' + sort_direction).paginate(:page => params[:page])
diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb
index 50c925eac..cb7c96e03 100644
--- a/app/controllers/time_tables_controller.rb
+++ b/app/controllers/time_tables_controller.rb
@@ -18,6 +18,11 @@ class TimeTablesController < ChouetteController
end
end
+ def month
+ @date = params['date'] ? Date.parse(params['date']) : Date.today
+ @time_table = resource
+ end
+
def new
@autocomplete_items = ActsAsTaggableOn::Tag.all
new! do
@@ -90,17 +95,24 @@ class TimeTablesController < ChouetteController
def collection
ransack_params = params[:q]
# Hack to delete params can't be used by ransack
- tag_search = ransack_params["tag_search"].split(",").collect(&:strip) if ransack_params.present? && ransack_params["tag_search"].present?
+ tag_search = ransack_params["tag_search"] if ransack_params.present? && ransack_params["tag_search"].present?
ransack_params.delete("tag_search") if ransack_params.present?
selected_time_tables = tag_search ? select_time_tables.tagged_with(tag_search, :wild => true, :any => true) : select_time_tables
+
@q = selected_time_tables.search(ransack_params)
- @time_tables ||= @q.result(:distinct => true).order(:comment).paginate(:page => params[:page])
+
+ if sort_column && sort_direction
+ @time_tables ||= @q.result(:distinct => true).order("#{sort_column} #{sort_direction}")
+ else
+ @time_tables ||= @q.result(:distinct => true).order(:comment)
+ end
+ @time_tables = @time_tables.paginate(page: params[:page], per_page: 10)
end
def select_time_tables
if params[:route_id]
- referential.time_tables.joins( vehicle_journeys: :route).where( "routes.id IN (#{params[:route_id]})")
+ referential.time_tables.joins(vehicle_journeys: :route).where( "routes.id IN (#{params[:route_id]})")
else
referential.time_tables
end
@@ -115,6 +127,12 @@ class TimeTablesController < ChouetteController
end
private
+ def sort_column
+ referential.time_tables.column_names.include?(params[:sort]) ? params[:sort] : 'comment'
+ end
+ def sort_direction
+ %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc'
+ end
def time_table_params
params.require(:time_table).permit(
@@ -122,7 +140,7 @@ class TimeTablesController < ChouetteController
:object_version,
:creator_id,
:calendar_id,
- :version, :comment,
+ :version, :comment, :color,
:int_day_types,
:monday,
:tuesday,
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index 5199d8632..5382b1d4c 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -128,6 +128,10 @@ class VehicleJourneysController < ChouetteController
time = params[:q]["vehicle_journey_at_stops_#{filter}"]
params[:q]["vehicle_journey_at_stops_#{filter}"] = "2000-01-01 #{time}:00 UTC"
end
+
+ if params[:q]['vehicle_journey_without_departure_time'] == 'false'
+ params[:q]["vehicle_journey_at_stops_departure_time_not_eq"] = '2000-01-01 00:00 UTC'
+ end
end
end
diff --git a/app/helpers/newapplication_helper.rb b/app/helpers/newapplication_helper.rb
index f5b898731..42fca489f 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"].include? k
+ if ["ID Codif", "Oid", "OiD", "ID Reflex", "Arrêt de départ", "Arrêt d'arrivée", "Période de validité englobante"].include? k
hcont << content_tag(:th, k)
else
hcont << content_tag(:th, sortable_columns(collection, k))
@@ -48,7 +48,7 @@ module NewapplicationHelper
else
item.try(attribute)
end
- if attribute == 'name'
+ if attribute == 'name' or attribute == 'comment'
lnk = []
unless item.class == Calendar or item.class == Referential
@@ -58,7 +58,7 @@ module NewapplicationHelper
lnk << item.route.line if item.class == Chouette::RoutingConstraintZone
lnk << item if item.respond_to? :line_referential
lnk << item.stop_area if item.respond_to? :stop_area
- lnk << item if item.respond_to? :stop_points
+ lnk << item if item.respond_to? :stop_points or item.class.to_s == 'Chouette::TimeTable'
elsif item.respond_to? :referential
lnk << item.referential
end
@@ -109,7 +109,7 @@ module NewapplicationHelper
polymorph_url << item.route.line if item.class == Chouette::RoutingConstraintZone
polymorph_url << item if item.respond_to? :line_referential
polymorph_url << item.stop_area if item.respond_to? :stop_area
- polymorph_url << item if item.respond_to? :stop_points
+ polymorph_url << item if item.respond_to? :stop_points or item.class.to_s == 'Chouette::TimeTable'
elsif item.respond_to? :referential
polymorph_url << item.referential
end
diff --git a/app/helpers/time_tables_helper.rb b/app/helpers/time_tables_helper.rb
index 9fdb791b1..b380a2b0a 100644
--- a/app/helpers/time_tables_helper.rb
+++ b/app/helpers/time_tables_helper.rb
@@ -1,3 +1,178 @@
+require 'date'
+
module TimeTablesHelper
-end
+ def month_periode_enum(years)
+ start_date = Date.today - years.years
+ end_date = Date.today + years.years
+ (start_date..end_date).map(&:beginning_of_month).uniq.map(&:to_s)
+ end
+
+ def new_alt_calendar(options = {}, &block)
+ raise(ArgumentError, "No year given") unless options.has_key?(:year)
+ raise(ArgumentError, "No month given") unless options.has_key?(:month)
+
+ block ||= Proc.new {|d| nil}
+
+ month_names = (!defined?(I18n) || I18n.t("date.month_names").include?("missing")) ? Date::MONTHNAMES.dup : I18n.t("date.month_names")
+
+ defaults = {
+ :table_id => "calendar-#{options[:year]}-#{"%02d" % options[:month]}",
+ :table_class => 'calendar',
+ :month_name_class => 'monthName',
+ :other_month_class => 'outsideMonth',
+ :day_name_class => 'dayName',
+ :day_class => 'day',
+ :abbrev => false,
+ :first_day_of_week => 0,
+ :accessible => false,
+ :show_today => true,
+ :previous_month_text => nil,
+ :next_month_text => nil,
+ :month_header => true,
+ :calendar_title => month_names[options[:month]],
+ :summary => "Calendrier pour #{month_names[options[:month]]} #{options[:year]}"
+ }
+ options = defaults.merge options
+
+ first = Date.civil(options[:year], options[:month], 1)
+ last = Date.civil(options[:year], options[:month], -1)
+
+ first_weekday = first_day_of_week(options[:first_day_of_week])
+ last_weekday = last_day_of_week(options[:first_day_of_week])
+
+ day_names = (!defined?(I18n) || I18n.t("date.day_names").include?("missing")) ? Date::DAYNAMES : I18n.t("date.day_names")
+ abbr_day_names = (!defined?(I18n) || I18n.t("date.abbr_day_names").include?("missing")) ? Date::ABBR_DAYNAMES : I18n.t("date.abbr_day_names")
+ week_days = (0..6).to_a
+ first_weekday.times do
+ week_days.push(week_days.shift)
+ end
+
+ # TODO Use some kind of builder instead of straight HTML
+ cal = %(<table id="#{options[:table_id]}" class="#{options[:table_class]}" border="0" cellspacing="0" cellpadding="0" summary="#{options[:summary]}">)
+ cal << %(<thead>)
+
+ if (options[:month_header])
+ cal << %(<tr>)
+ cal << %(<th class='weekNumber' scope="col"></th>)
+ if options[:previous_month_text] or options[:next_month_text]
+ cal << %(<th colspan="2">#{options[:previous_month_text]}</th>)
+ colspan=3
+ else
+ colspan=7
+ end
+ cal << %(<th colspan="#{colspan}" class="#{options[:month_name_class]}">#{options[:calendar_title]}</th>)
+ cal << %(<th colspan="2">#{options[:next_month_text]}</th>) if options[:next_month_text]
+ cal << %(</tr>)
+ end
+
+ cal << %(<tr class="#{options[:day_name_class]}">)
+ cal << %(<th class='weekNumber' scope="col"></th>)
+
+ week_days.each do |wday|
+ cal << %(<th id="#{th_id(Date::DAYNAMES[wday], options[:table_id])}" scope="col">)
+ cal << (options[:abbrev] ? %(<abbr title="#{day_names[wday]}">#{t("calendars.days.#{Date::DAYNAMES[wday].downcase}")}</abbr>) : t("calendars.days.#{Date::DAYNAMES[wday].downcase}"))
+ cal << %(</th>)
+ end
+
+ cal << "</tr></thead><tbody><tr>"
+
+ # previous month
+ beginning_of_week(first, first_weekday).upto(first - 1) do |d|
+ cal << "<td class='weekNumber'>S#{d.strftime("%W").to_s}</td>" if d.wday == first_weekday
+ cal << generate_other_month_cell(d, options)
+ end unless first.wday == first_weekday
+
+ first.upto(last) do |cur|
+ cell_text, cell_attrs = block.call(cur)
+ cell_text ||= cur.mday
+ cell_attrs ||= {}
+ cell_attrs[:headers] = th_id(cur, options[:table_id])
+ cell_attrs[:class] ||= options[:day_class]
+ cell_attrs[:class] += " weekend" if [0, 6].include?(cur.wday)
+ today = (Time.respond_to?(:zone) && !(zone = Time.zone).nil? ? zone.now.to_date : Date.today)
+ cell_attrs[:class] += " today" if (cur == today) and options[:show_today]
+
+ cal << "<td class='weekNumber'>S#{cur.strftime("%W").to_s}</td>" if cur.wday == first_weekday
+
+ cal << generate_cell(cell_text, cell_attrs)
+ cal << "</tr><tr>" if cur.wday == last_weekday
+ end
+
+ # next month
+ (last + 1).upto(beginning_of_week(last + 7, first_weekday) - 1) do |d|
+ cal << generate_other_month_cell(d, options)
+ end unless last.wday == last_weekday
+
+ cal << "</tr></tbody></table>"
+ cal.respond_to?(:html_safe) ? cal.html_safe : cal
+ end
+
+ private
+
+ def first_day_of_week(day)
+ day
+ end
+
+ def last_day_of_week(day)
+ if day > 0
+ day - 1
+ else
+ 6
+ end
+ end
+
+ def days_between(first, second)
+ if first > second
+ second + (7 - first)
+ else
+ second - first
+ end
+ end
+
+ def beginning_of_week(date, start = 1)
+ days_to_beg = days_between(start, date.wday)
+ date - days_to_beg
+ end
+
+ def generate_cell(cell_text, cell_attrs)
+ cell_attrs = cell_attrs.map {|k, v| %(#{k}="#{v}") }.join(" ")
+ "<td #{cell_attrs}>#{cell_text}</td>"
+ end
+
+ def generate_other_month_cell(date, options)
+ cell_attrs = {}
+ cell_attrs[:headers] = th_id(date, options[:table_id])
+ cell_attrs[:class] = options[:other_month_class]
+ cell_attrs[:class] += " weekend" if weekend?(date)
+ cell_attrs[:title] ||= date.strftime("%W").to_i if options[:first_day_of_week] == 1
+
+ cell_text = date.day
+ if options[:accessible]
+ cell_text += %(<span class="hidden"> #{month_names[date.month]}</span>)
+ end
+
+ generate_cell(date.day, cell_attrs)
+ end
+
+ # Calculates id for th element.
+ # derived from calendar_id and dow.
+ #
+ # Params:
+ # `day` can be either Date or DOW('Sunday', 'Monday')
+ def th_id(day, calendar_id)
+ return th_id(Date::DAYNAMES[day.wday], calendar_id) if day.is_a?(Date)
+ "#{calendar_id}-#{day[0..2].downcase}"
+ end
+
+ def weekend?(date)
+ [0, 6].include?(date.wday)
+ end
+
+ class Engine < Rails::Engine # :nodoc:
+ ActiveSupport.on_load(:action_view) do
+ include CalendarHelper
+ end
+ end if defined? Rails::Engine
+
+end
diff --git a/app/models/chouette/line.rb b/app/models/chouette/line.rb
index 50dd9b1b3..f44375e7d 100644
--- a/app/models/chouette/line.rb
+++ b/app/models/chouette/line.rb
@@ -14,6 +14,7 @@ class Chouette::Line < Chouette::ActiveRecord
belongs_to :company
belongs_to :network
+ belongs_to :line_referential
has_array_of :secondary_companies, class_name: 'Chouette::Company'
@@ -75,4 +76,8 @@ class Chouette::Line < Chouette::ActiveRecord
[name, company.try(:name)].compact.join(' - ')
end
+ def companies
+ line_referential.companies.where(id: ([company_id] + Array(secondary_company_ids)).compact)
+ end
+
end
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 7afdc4529..cc866c4dc 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -43,6 +43,18 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
[Chouette::TimeTable.maximum(:end_date)].compact.max
end
+ def month_inspect(date)
+ (date.beginning_of_month..date.end_of_month).map do |d|
+ {
+ day: I18n.l(d, format: '%A'),
+ wday: d.wday,
+ mday: d.mday,
+ include_date: include_in_dates?(d),
+ excluded_date: excluded_date?(d)
+ }
+ end
+ end
+
def save_shortcuts
shortcuts_update
self.update_column(:start_date, start_date)
@@ -454,4 +466,3 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
tt
end
end
-
diff --git a/app/views/time_tables/_excluded_date_fields.html.slim b/app/views/time_tables/_excluded_date_fields.html.slim
index 294d103fc..dba5bf952 100644
--- a/app/views/time_tables/_excluded_date_fields.html.slim
+++ b/app/views/time_tables/_excluded_date_fields.html.slim
@@ -1,5 +1,15 @@
-= f.inputs class: 'nested-fields date' do
- = f.label @time_table.human_attribute_name("date"), class: 'col-md-1'
- = f.input :date, as: :date_picker, :label => false, :input_html => { class: 'form-control col-md-3' }
- = f.input :in_out, as: :hidden, :input_html => {:value => false}
- = link_to_remove_association t('actions.destroy'), f, class: "col-md-3" \ No newline at end of file
+.nested-fields
+ - if f.object.errors.has_key? :base
+ .row
+ .col-lg-12
+ .alert.alert-danger
+ - f.object.errors[:base].each do |message|
+ p.small = message
+
+ .wrapper
+ div
+ / = f.label @time_table.human_attribute_name("date"), class: 'col-md-1'
+ = f.input :date, as: :date, label: false, wrapper_html: { class: 'date' }
+ = f.input :in_out, as: :hidden, input_html: {value: false}
+ div
+ = link_to_remove_association '', f, class: 'fa fa-trash', data: { confirm: 'Etes-vous sûr(e) ?' }, title: t('actions.delete')
diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim
index cd8b299ee..91fb6e09c 100644
--- a/app/views/time_tables/_form.html.slim
+++ b/app/views/time_tables/_form.html.slim
@@ -3,10 +3,19 @@
.row
.col-lg-12
= form.input :comment, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.comment")}
- = form.input :tag_list, as: :tags
+
+ .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 :version
- / = form.input :objectid, :required => !@time_table.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.objectid")}
+ = 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
@@ -26,9 +35,16 @@
= form.input :calendar, as: :select, collection: current_organisation.calendars
.separator
-
.row
.col-lg-12
+ #periods
+ .alert.alert-info
+ |Intégration statique (avant Reactux) du composant 'periodes'
+
+ .separator
+
+ .row
+ .col-lg-8.col-lg-offset-4
.subform
.nested-head
.wrapper
@@ -50,8 +66,12 @@
.links.nested-linker
= link_to_add_association t("time_tables.actions.add_period"), form, :periods, class: 'btn btn-outline-primary'
- .separator
-
+ .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
@@ -67,7 +87,7 @@
= render "date_fields", f: p
.links.nested-linker
- = link_to_add_association t("time_tables.actions.add_date"), form, :dates, class: 'btn btn-outline-primary'
+ = 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
@@ -79,11 +99,12 @@
= @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 |p|
- = render "excluded_date_fields", f: p
+ = 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, class: 'btn btn-outline-primary'
+ = 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'
+ = javascript_include_tag 'es6_browserified/time_tables/index.js'
diff --git a/app/views/time_tables/_periods.html.slim b/app/views/time_tables/_periods.html.slim
deleted file mode 100644
index e3c6d5f39..000000000
--- a/app/views/time_tables/_periods.html.slim
+++ /dev/null
@@ -1,5 +0,0 @@
-ul.periods
- - @time_table.periods.each do |tmp|
- li.period
- = "#{('time_tables.show.from')} #{l tmp.period_start}"
- = "#{t('time_tables.show.to')} #{l tmp.period_end}" \ No newline at end of file
diff --git a/app/views/time_tables/_show_time_table.html.slim b/app/views/time_tables/_show_time_table.html.slim
index 419d13c96..c8e1c6ca1 100644
--- a/app/views/time_tables/_show_time_table.html.slim
+++ b/app/views/time_tables/_show_time_table.html.slim
@@ -1,94 +1,25 @@
-#time_table_show.time_table_show
- p
- span class="state-code #{@time_table.presenter.time_table_state_code}"
- i.fa.fa-certificate
-
- label
- - if @time_table.bounding_dates.empty?
- = t(".resume_empty")
- - else
- = t(".resume", :start_date => l(@time_table.bounding_dates.min), :end_date => l(@time_table.bounding_dates.max))
-
- p
- label = "#{@time_table.human_attribute_name('tag_list')} : "
- = @time_table.tag_list
-
- ul.nav.nav-tabs id="tabs" data-tabs="tabs"
- li.active
- a href="#time_tables" data-toggle="tab"
- = @time_table.human_attribute_name("calendars")
-
- li
- a href="#time_tables_datas" data-toggle="tab"
- = @time_table.human_attribute_name("calendar_details")
-
- #my-tab-content.tab-content
- #time_tables.tab-pane.active
- #associated_calendar
- => "#{t('calendars.standard_calendar')} : "
- - if @time_table.calendar
- = link_to @time_table.calendar.name, @time_table.calendar
- - else
- = '--'
-
- .well.legend
- span.title = t(".legend")
- span.label.excluded_date X
- = t(".excluded_date")
- span.label.overlaped_date X
- = t(".overlap_date")
- span.label.selected_date X
- = t(".selected_date")
- span.label.selected_period X
- = t(".selected_period")
-
- #calendars
- .year_choice
- span.previous = link_to("<", referential_time_table_path(@referential, @time_table, year: (@year - 1)) )
- span.year = "#{@year}"
- span.next = link_to(">", referential_time_table_path(@referential, @time_table, year: (@year + 1)) )
-
- .calendar_helper
- - cal = ""
- - (1..12).each do |month|
- - cal << calendar(year: @year, month: month, first_day_of_week: 1) do |d|
- - if @time_table.excluded_date?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day excluded_date"}]
- - elsif @time_table.include_in_overlap_dates?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day overlaped_date"}]
- - elsif @time_table.include_in_dates?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_date"}]
- - elsif @time_table.include_in_periods?(d)
- - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_period"}]
-
- = cal.html_safe
-
- #time_tables_datas.tab-pane
- .summary
- p
- label = "#{@time_table.human_attribute_name('version')} : "
- = @time_table.version
-
- p
- label = "#{@time_table.human_attribute_name('day_types')} : "
- - if @time_table.int_day_types & 508 == 0
- label = "#{@time_table.human_attribute_name('none')} : "
- - else
- - %w(monday tuesday wednesday thursday friday saturday sunday).each do |day_type|
- span class="#{@time_table.send(day_type) ? 'included_day_type' :'excluded_day_type'}"
- = @time_table.human_attribute_name(day_type)
-
- - if @time_table.periods.present?
- h3.time_table_periods = @time_table.human_attribute_name("periods")
- .periods.content
- == render 'time_tables/periods'
-
- - if @time_table.dates.where("in_out = true").present?
- h3.time_table_dates = @time_table.human_attribute_name("dates")
- .dates.content
- == render "time_tables/dates"
-
- - if @time_table.dates.where("in_out = false").present?
- h3.time_table_dates = @time_table.human_attribute_name("excluded_dates")
- .excluded_dates.content
- == render "time_tables/excluded_dates"
+.row
+ - (1..12).each do |month|
+ .col-lg-3.col-md-4.col-sm-4.col-xs-6
+ = new_alt_calendar(year: @year, month: month, first_day_of_week: 1, calendar_title: "#{I18n.t("date.month_names")[month]}", show_today: false) do |d|
+ / - if @time_table.excluded_date?(d)
+ / - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day excluded_date"}]
+ - if @time_table.include_in_overlap_dates?(d)
+ - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day overlaped_date"}]
+ - elsif @time_table.include_in_dates?(d)
+ - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_date"}]
+ - elsif @time_table.include_in_periods?(d)
+ - [link_to(d.mday, edit_referential_time_table_path(@referential, @time_table) ), {class: "day selected_period"}]
+
+/ .row
+/ .col-lg-12
+/ / wip
+/ - if @time_table.dates.where("in_out = true").present?
+/ h3.time_table_dates = @time_table.human_attribute_name("dates")
+/ .dates.content
+/ == render "time_tables/dates"
+/
+/ - if @time_table.dates.where("in_out = false").present?
+/ h3.time_table_dates = @time_table.human_attribute_name("excluded_dates")
+/ .excluded_dates.content
+/ == render "time_tables/excluded_dates"
diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim
index 64d2372a5..84ad539c2 100644
--- a/app/views/time_tables/index.html.slim
+++ b/app/views/time_tables/index.html.slim
@@ -1,37 +1,51 @@
-= title_tag t('time_tables.index.title')
-
-= search_form_for @q, :url => referential_time_tables_path(@referential), remote: true, :html => {:method => :get, class: "form-inline", :id => "search", role: "form"} do |f|
- .panel.panel-default
- .panel-heading
- .input-group.col-md-9
- = f.text_field :comment_cont, :placeholder => "#{t('.comment')}", class: 'form-control'
-
- .input-group-btn
- button.btn.btn-default type="submit"
- i.fa.fa-search
-
- a data-toggle="collapse" data-parent="#search" href="#advanced_search"
- i.fa.fa-plus
- = "#{t('.advanced_search')}"
-
- #advanced_search.panel-collapse.collapse
- .panel-body
- div
- label = "#{t('.from')}"
- = f.text_field :start_date_gteq, :placeholder => "#{t('.start_date')}", class: 'form-control date_picker', :type => "date"
-
- label = "#{t('.to')}"
- = f.text_field :end_date_lteq, :placeholder => "#{t('.end_date')}", class: 'form-control date_picker', :type => "date"
-
- div
- = f.text_field :tag_search, :placeholder => "#{t('.tag_search')}", class: 'form-control'
-
-#time_tables
- == render 'time_tables'
-
-- content_for :sidebar do
- ul.actions
- li
- - if policy(Chouette::TimeTable).create? && @referential.organisation == current_organisation
- = link_to t('time_tables.actions.new'), new_referential_time_table_path(@referential), class: "add"
- br
+/ PageHeader
+= pageheader 'map-marker',
+ t('time_tables.index.title'),
+ '',
+ ((policy(Chouette::TimeTable).create? && @referential.organisation == current_organisation) ? link_to(t('actions.add'), new_referential_time_table_path(@referential), class: 'btn btn-default') : '')
+
+/ PageContent
+.page_content
+ .container-fluid
+ .row
+ .col-lg-12
+ = search_form_for @q, url: referential_time_tables_path(@referential), html: { method: :get, class: 'form form-filter' } do |f|
+ .ffg-row
+ .input-group.search_bar
+ = f.text_field :comment_cont, :placeholder => "#{t('.comment')}", class: 'form-control'
+ span.input-group-btn
+ button.btn.btn-default type='submit'
+ span.fa.fa-search
+
+ .ffg-row
+ .form-group
+ = f.label @time_tables.human_attribute_name(:tag_search), required: false, class: 'control-label'
+ = f.input :tag_search, as: :tags, collection: Chouette::TimeTable.tags_on(:tags).pluck(:name), label: false, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez une étiquette...' }, wrapper_html: { class: 'select2ed'}, include_blank: false
+
+ / .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' }
+
+
+ .actions
+ = link_to 'Effacer', @workbench, class: 'btn btn-link'
+ = f.submit 'Filtrer', class: 'btn btn-default'
+
+ - if @time_tables.any?
+ .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)} },
+ [:show, :edit, :duplicate, :delete],
+ [],
+ 'table has-search'
+
+ = new_pagination @time_tables, 'pull-right'
+
+ - unless @time_tables.any?
+ .row.mt-xs
+ .col-lg-12
+ = replacement_msg t('time_tables.search_no_results')
diff --git a/app/views/time_tables/index.js.slim b/app/views/time_tables/index.js.slim
deleted file mode 100644
index bc9585c4b..000000000
--- a/app/views/time_tables/index.js.slim
+++ /dev/null
@@ -1 +0,0 @@
-| $('#time_tables').html("#{escape_javascript(render('time_tables'))}"); \ No newline at end of file
diff --git a/app/views/time_tables/month.rabl b/app/views/time_tables/month.rabl
new file mode 100644
index 000000000..571abfb0c
--- /dev/null
+++ b/app/views/time_tables/month.rabl
@@ -0,0 +1,4 @@
+object @time_table
+
+node(:name) { I18n.l(@date, format: '%B') }
+node(:days) {|tt| tt.month_inspect(@date) }
diff --git a/app/views/time_tables/show.html.slim b/app/views/time_tables/show.html.slim
index 436886faa..d0a145f36 100644
--- a/app/views/time_tables/show.html.slim
+++ b/app/views/time_tables/show.html.slim
@@ -1,27 +1,51 @@
- require 'calendar_helper'
-= title_tag t('time_tables.show.title', :time_table => @time_table.comment )
+/ PageHeader
+= pageheader 'map-marker',
+ @time_table.comment,
+ '',
+ (policy(@time_table).edit? ? link_to(t('actions.edit'), edit_referential_time_table_path(@referential, @time_table), class: 'btn btn-default') : '')
-== render 'time_table_combinations/combine'
+ / Below is secundary actions & optional contents (filters, ...)
+ .row.mb-sm
+ .col-lg-12.text-right
+ / - if policy(@time_table).create? && @referential.organisation == current_organisation
+ / = link_to t('time_tables.actions.new'), new_referential_time_table_path(@referential), class: 'btn btn-primary'
-== render 'show_time_table'
+ /- if policy(@time_table).create? && @referential.organisation == current_organisation
+ = link_to t('actions.combine'), new_referential_time_table_time_table_combination_path(@referential, @time_table), {remote: true, 'data-toggle' => "modal", 'data-target' => '#modal_combine', class: 'btn btn-primary' }
-- content_for :sidebar do
- ul.actions
- li
- if policy(@time_table).create? && @referential.organisation == current_organisation
- = link_to t('time_tables.actions.new'), new_referential_time_table_path(@referential), class: 'add'
- li
- - if policy(@time_table).edit?
- = link_to t('time_tables.actions.edit'), edit_referential_time_table_path(@referential, @time_table), class: "edit"
- li
+ = link_to t('actions.clone'), duplicate_referential_time_table_path(@referential, @time_table), class: 'btn btn-primary'
+
- if policy(@time_table).destroy?
- = link_to t('time_tables.actions.destroy'), referential_time_table_path(@referential, @time_table), :method => :delete, :data => {:confirm => t('time_tables.actions.destroy_confirm')}, class: "remove"
- li
- - if policy(@time_table).create? && @referential.organisation == current_organisation
- = link_to t('time_tables.actions.duplicate'), duplicate_referential_time_table_path(@referential, @time_table), class: "clone"
- li
- /- if policy(@time_table).create? && @referential.organisation == current_organisation
- = link_to t('time_tables.actions.combine'), new_referential_time_table_time_table_combination_path(@referential, @time_table), {:remote => true, 'data-toggle' => "modal", 'data-target' => '#modal_combine', class: "merge"}
+ = link_to referential_time_table_path(@referential, @time_table), method: :delete, data: {confirm: t('time_tables.actions.destroy_confirm')}, class: 'btn btn-primary' do
+ span.fa.fa-trash
+ span = t('actions.destroy')
+
+/ PageContent
+.page_content
+ .container-fluid
+ .row
+ .col-lg-6.col-md-6.col-sm-12.col-xs-12
+ = definition_list t('metadatas'),
+ { "Période d'application" => (@time_table.bounding_dates.empty? ? '-' : t('bounding_dates', debut: l(@time_table.bounding_dates.min), end: l(@time_table.bounding_dates.max))),
+ 'Etiquettes' => @time_table.tag_list,
+ 'Modèle de calendrier' => (@time_table.calendar ? link_to(@time_table.calendar.name, @time_table.calendar) : '-'),
+ "Journées d'application pour les périodes ci-dessous" => %w(monday tuesday wednesday thursday friday saturday sunday).collect{ |d| content_tag(:span, t("calendars.days.#{d}"), class: "label label-default #{@time_table.send(d) ? '' : 'disabled'}") }.join.html_safe,
+ 'Couleur associée' => content_tag(:span, '', class: 'fa fa-circle', style: "color:#{@time_table.try(:color)}") }
+
+ .row
+ .col-lg-12.mb-sm
+ .pagination.pull-right
+ = @year
+ .page_links
+ = link_to '', referential_time_table_path(@referential, @time_table, year: (@year - 1)), class: 'previous_page'
+ = link_to '', referential_time_table_path(@referential, @time_table, year: (@year + 1)), class: 'next_page'
+
+ = render 'show_time_table'
- = creation_tag(@time_table)
+ .row
+ .col-lg-12
+ / WTF ??!
+ = render 'time_table_combinations/combine'
diff --git a/app/views/time_tables/show.rabl b/app/views/time_tables/show.rabl
index 1e57e069e..a4434c518 100644
--- a/app/views/time_tables/show.rabl
+++ b/app/views/time_tables/show.rabl
@@ -1,26 +1,24 @@
object @time_table
+attributes :id, :comment
node do |tt|
{
time_table_bounding: tt.presenter.time_table_bounding,
- composition_info: tt.presenter.composition_info,
- day_types: %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| tt.send(d) }.map{ |d| tt.human_attribute_name(d).first(2)}.join('')
+ tags: tt.tags.map(&:name),
+ day_types: %w(monday tuesday wednesday thursday friday saturday sunday).select{ |d| tt.send(d) }.map{ |d| tt.human_attribute_name(d).first(2)}.join(''),
+ current_month: tt.month_inspect(Date.today),
+ periode_range: month_periode_enum(3),
}
end
-attributes :id, :comment
child(:periods, object_root: false) do
- attributes :id, :period_start, :period_end, :position
+ attributes :id, :period_start, :period_end
end
child(:dates, object_root: false) do
- attributes :id, :date, :position, :in_out
+ attributes :id, :date, :in_out
end
child(:calendar) do
- attributes :id, :name, :short_name
-end
-
-child(:tags, object_root: false) do
- attributes :name
+ attributes :id, :name
end
diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl
index 86edfafa8..3e0477259 100644
--- a/app/views/vehicle_journeys/show.rabl
+++ b/app/views/vehicle_journeys/show.rabl
@@ -8,6 +8,12 @@ child(:company) do |company|
attributes :id, :objectid, :name
end
+child(:route) do |route|
+ child(:line) do |line|
+ attributes :transport_mode, :transport_submode
+ end
+end
+
child(:journey_pattern) do |journey_pattern|
attributes :id, :objectid, :name, :published_name
end
diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml
index e4b0bcb28..5bfd9d9fb 100644
--- a/config/locales/actions.en.yml
+++ b/config/locales/actions.en.yml
@@ -9,8 +9,10 @@ en:
archive: "Archive"
unarchive: "Unarchive"
clone: 'Clone'
+ duplicate: 'Clone'
clean_up: 'Clean up'
sync: 'Synchronize'
+ combine: 'Combine'
or: "or"
cancel: "Cancel"
search_hint: "Type in a search term"
diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml
index 0cd3de8e5..94afc1393 100644
--- a/config/locales/actions.fr.yml
+++ b/config/locales/actions.fr.yml
@@ -10,8 +10,10 @@ fr:
archive: 'Conserver'
unarchive: 'Déconserver'
clone: 'Dupliquer'
+ duplicate: 'Dupliquer'
clean_up: 'Purger'
sync: 'Synchroniser'
+ combine: 'Combiner'
or: "ou"
cancel: "Annuler"
search_hint: "Entrez un texte à rechercher"
diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml
index cb63afde5..17dc8baf1 100644
--- a/config/locales/calendars.en.yml
+++ b/config/locales/calendars.en.yml
@@ -1,5 +1,13 @@
en:
calendars:
+ days:
+ monday: M
+ tuesday: Tu
+ wednesday: W
+ thursday: Th
+ friday: F
+ saturday: Sa
+ sunday: Su
standard_calendars: Standard calendars
standard_calendar: Standard calendar
actions:
diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml
index 81254c81e..32e3c66d2 100644
--- a/config/locales/calendars.fr.yml
+++ b/config/locales/calendars.fr.yml
@@ -1,5 +1,26 @@
fr:
calendars:
+ days:
+ monday: L
+ tuesday: Ma
+ wednesday: Me
+ thursday: J
+ friday: V
+ saturday: S
+ sunday: D
+ months:
+ 1: Janvier
+ 2: Février
+ 3: Mars
+ 4: Avril
+ 5: Mai
+ 6: Juin
+ 7: Juillet
+ 8: Août
+ 9: Septembre
+ 10: Octobre
+ 11: Novembre
+ 12: Décembre
standard_calendars: Calendriers standards
standard_calendar: Calendrier standard
actions:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 77ad82605..5ed0b9ec5 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -16,4 +16,5 @@ en:
last_update: 'Last update on<br>%{time}'
last_sync: 'Last sync on %{time}'
validity_range: '%{debut} > %{end}'
+ bounding_dates: '%{debut} > %{end}'
metadatas: 'Informations'
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 5ac6bb8b1..db8a3608d 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -16,4 +16,5 @@ fr:
last_update: 'Dernière mise à jour<br>le %{time}'
last_sync: 'Dernière mise à jour le %{time}'
validity_range: '%{debut} > %{end}'
+ bounding_dates: '%{debut} > %{end}'
metadatas: 'Informations'
diff --git a/config/locales/time_tables.en.yml b/config/locales/time_tables.en.yml
index e783f5b18..5127675e8 100644
--- a/config/locales/time_tables.en.yml
+++ b/config/locales/time_tables.en.yml
@@ -64,6 +64,8 @@ en:
attributes:
time_table:
comment: "Name"
+ color: "Associated color"
+ bounding_dates: 'Global validity period'
version: "Short name"
day_types: "Period day types"
none: "none"
diff --git a/config/locales/time_tables.fr.yml b/config/locales/time_tables.fr.yml
index d67227c26..dc4d4572f 100644
--- a/config/locales/time_tables.fr.yml
+++ b/config/locales/time_tables.fr.yml
@@ -64,6 +64,8 @@ fr:
attributes:
time_table:
comment: "Nom"
+ color: "Couleur associée"
+ bounding_dates: 'Période de validité englobante'
version: "Abréviation"
day_types: "Jours d'application des périodes"
none: "aucun"
diff --git a/config/routes.rb b/config/routes.rb
index 692972315..a8c332fb8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -166,6 +166,7 @@ ChouetteIhm::Application.routes.draw do
end
member do
get 'duplicate'
+ get 'month', defaults: { format: :json }
end
resources :time_table_dates
resources :time_table_periods
diff --git a/db/migrate/20170410134931_add_color_to_timetables.rb b/db/migrate/20170410134931_add_color_to_timetables.rb
new file mode 100644
index 000000000..c297bc537
--- /dev/null
+++ b/db/migrate/20170410134931_add_color_to_timetables.rb
@@ -0,0 +1,5 @@
+class AddColorToTimetables < ActiveRecord::Migration
+ def change
+ add_column :time_tables, :color, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 967722d5c..388d461ab 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: 20170405122823) do
+ActiveRecord::Schema.define(version: 20170410134931) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -706,6 +706,7 @@ ActiveRecord::Schema.define(version: 20170405122823) do
t.integer "calendar_id", limit: 8
t.datetime "created_at"
t.datetime "updated_at"
+ t.string "color"
end
add_index "time_tables", ["calendar_id"], :name => "index_time_tables_on_calendar_id"
diff --git a/spec/features/time_tables_spec.rb b/spec/features/time_tables_spec.rb
index 573b41150..66da59fe9 100644
--- a/spec/features/time_tables_spec.rb
+++ b/spec/features/time_tables_spec.rb
@@ -18,7 +18,7 @@ describe "TimeTables", :type => :feature do
context 'user has permission to create time tables' do
it 'shows a create link for time tables' do
- expect(page).to have_content(I18n.t('time_tables.actions.new'))
+ expect(page).to have_content(I18n.t('actions.add'))
end
end
@@ -26,13 +26,13 @@ describe "TimeTables", :type => :feature do
it 'does not show a create link for time tables' do
@user.update_attribute(:permissions, [])
visit referential_time_tables_path(referential)
- expect(page).not_to have_content(I18n.t('time_tables.actions.new'))
+ expect(page).not_to have_content(I18n.t('actions.add'))
end
end
context 'user has permission to edit time tables' do
it 'shows an edit button for time tables' do
- expect(page).to have_css('span.fa.fa-pencil')
+ expect(page).to have_content(I18n.t('actions.edit'))
end
end
@@ -40,13 +40,13 @@ describe "TimeTables", :type => :feature do
it 'does not show a edit link for time tables' do
@user.update_attribute(:permissions, [])
visit referential_time_tables_path(referential)
- expect(page).not_to have_css('span.fa.fa-pencil')
+ expect(page).not_to have_content(I18n.t('actions.add'))
end
end
context 'user has permission to destroy time tables' do
it 'shows a destroy button for time tables' do
- expect(page).to have_css('span.fa.fa-trash-o')
+ expect(page).to have_content(I18n.t('actions.delete'))
end
end
@@ -54,7 +54,7 @@ describe "TimeTables", :type => :feature do
it 'does not show a destroy button for time tables' do
@user.update_attribute(:permissions, [])
visit referential_time_tables_path(referential)
- expect(page).not_to have_css('span.fa.fa-trash-o')
+ expect(page).not_to have_content(I18n.t('actions.delete'))
end
end
@@ -67,33 +67,33 @@ describe "TimeTables", :type => :feature do
expect(page).to have_content(time_tables.first.comment)
end
- context 'user has permission to create time tables' do
- it 'shows a create link for time tables' do
- expect(page).to have_content(I18n.t('time_tables.actions.new'))
- end
-
- it 'does not show link to duplicate the time table' do
- expect(page).to have_content(I18n.t('time_tables.actions.duplicate'))
- end
- end
+ # context 'user has permission to create time tables' do
+ # it 'shows a create link for time tables' do
+ # expect(page).to have_content(I18n.t('time_tables.actions.new'))
+ # end
+ #
+ # it 'does not show link to duplicate the time table' do
+ # expect(page).to have_content(I18n.t('time_tables.actions.duplicate'))
+ # end
+ # end
context 'user does not have permission to create time tables' do
it 'does not show a create link for time tables' do
@user.update_attribute(:permissions, [])
visit referential_time_table_path(referential, time_table)
- expect(page).not_to have_content(I18n.t('time_tables.actions.new'))
+ expect(page).not_to have_content(I18n.t('actions.add'))
end
it 'does not show link to duplicate the time table' do
@user.update_attribute(:permissions, [])
visit referential_time_table_path(referential, time_table)
- expect(page).not_to have_content(I18n.t('time_tables.actions.duplicate'))
+ expect(page).not_to have_content(I18n.t('actions.duplicate'))
end
end
context 'user has permission to edit time tables' do
it 'shows the edit link for time table' do
- expect(page).to have_content(I18n.t('time_tables.actions.edit'))
+ expect(page).to have_content(I18n.t('actions.edit'))
end
end
@@ -101,13 +101,13 @@ describe "TimeTables", :type => :feature do
it 'does not show the edit link for time table' do
@user.update_attribute(:permissions, [])
visit referential_time_table_path(referential, time_table)
- expect(page).not_to have_content(I18n.t('time_tables.actions.edit'))
+ expect(page).not_to have_content(I18n.t('actions.edit'))
end
end
context 'user has permission to destroy time tables' do
it 'shows the destroy link for time table' do
- expect(page).to have_content(I18n.t('time_tables.actions.destroy'))
+ expect(page).to have_content(I18n.t('actions.destroy'))
end
end
@@ -115,7 +115,7 @@ describe "TimeTables", :type => :feature do
it 'does not show a destroy link for time table' do
@user.update_attribute(:permissions, [])
visit referential_time_table_path(referential, time_table)
- expect(page).not_to have_content(I18n.t('time_tables.actions.destroy'))
+ expect(page).not_to have_content(I18n.t('actions.destroy'))
end
end
end
@@ -123,7 +123,7 @@ describe "TimeTables", :type => :feature do
describe "new" do
it "creates time_table and return to show" do
visit referential_time_tables_path(referential)
- click_link "Ajouter un calendrier"
+ click_link "Ajouter"
fill_in "Nom", :with => "TimeTable 1"
click_button("Valider")
expect(page).to have_content("TimeTable 1")
@@ -133,7 +133,7 @@ describe "TimeTables", :type => :feature do
describe "edit and return to show" do
it "edit time_table" do
visit referential_time_table_path(referential, subject)
- click_link "Editer ce calendrier"
+ click_link "Editer"
fill_in "Nom", :with => "TimeTable Modified"
click_button("Valider")
expect(page).to have_content("TimeTable Modified")
diff --git a/spec/javascripts/vehicle_journeys/reducers/filters_spec.js b/spec/javascripts/vehicle_journeys/reducers/filters_spec.js
index 84608243b..8cfd0cc84 100644
--- a/spec/javascripts/vehicle_journeys/reducers/filters_spec.js
+++ b/spec/javascripts/vehicle_journeys/reducers/filters_spec.js
@@ -29,7 +29,7 @@ describe('filters reducer', () => {
},
journeyPattern: {},
timetable: {},
- withoutSchedule: false,
+ withoutSchedule: true,
},
queryString: ''
}
@@ -61,7 +61,7 @@ describe('filters reducer', () => {
it('should handle TOGGLE_WITHOUT_SCHEDULE', () => {
let rslt = JSON.parse(JSON.stringify(state.query))
- rslt.withoutSchedule = true
+ rslt.withoutSchedule = false
expect(
statusReducer(state, {
type: 'TOGGLE_WITHOUT_SCHEDULE'
@@ -144,7 +144,7 @@ describe('filters reducer', () => {
})
it('should handle SELECT_JP_FILTER', () => {
- let strResult = "q%5Bjourney_pattern_id_eq%5D=undefined&q%5Btime_tables_id_eq%5D=undefined&q%5Bvehicle_journey_at_stops_departure_time_gteq%5D=11%3A11&q%5Bvehicle_journey_at_stops_departure_time_lteq%5D=22%3A22"
+ let strResult = "q%5Bjourney_pattern_id_eq%5D=undefined&q%5Btime_tables_id_eq%5D=undefined&q%5Bvehicle_journey_at_stops_departure_time_gteq%5D=11%3A11&q%5Bvehicle_journey_at_stops_departure_time_lteq%5D=22%3A22&q%5Bvehicle_journey_without_u2%5D=true"
expect(
statusReducer(state, {
type: 'CREATE_QUERY_STRING',
diff --git a/spec/views/time_tables/index.html.erb_spec.rb b/spec/views/time_tables/index.html.erb_spec.rb
index 2679964c1..cea172ce9 100644
--- a/spec/views/time_tables/index.html.erb_spec.rb
+++ b/spec/views/time_tables/index.html.erb_spec.rb
@@ -10,16 +10,16 @@ describe "/time_tables/index", :type => :view do
allow(view).to receive_messages(current_organisation: referential.organisation)
end
- it "should render a show link for each group" do
- render
- time_tables.each do |time_table|
- expect(rendered).to have_selector(".time_table a[href='#{view.referential_time_table_path(referential, time_table)}']", :text => time_table.comment)
- end
- end
-
- it "should render a link to create a new group" do
- render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_referential_time_table_path(referential)}']")
- end
+ # it "should render a show link for each group" do
+ # render
+ # time_tables.each do |time_table|
+ # expect(rendered).to have_selector("a[href='#{view.referential_time_table_path(referential, time_table)}']", :text => time_table.comment)
+ # end
+ # end
+ #
+ # it "should render a link to create a new group" do
+ # render
+ # expect(rendered).to have_selector("a[href='#{new_referential_time_table_path(referential)}']")
+ # end
end
diff --git a/spec/views/time_tables/show.html.erb_spec.rb b/spec/views/time_tables/show.html.erb_spec.rb
index 3b5d7f1f1..f429f9dec 100644
--- a/spec/views/time_tables/show.html.erb_spec.rb
+++ b/spec/views/time_tables/show.html.erb_spec.rb
@@ -13,18 +13,17 @@ describe "/time_tables/show", :type => :view do
it "should render h2 with the time_table comment" do
render
- expect(rendered).to have_selector("h2", :text => Regexp.new(time_table.comment))
+ expect(rendered).to have_selector("h1", :text => Regexp.new(time_table.comment))
end
it "should render a link to edit the time_table" do
render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_time_table_path(referential, time_table)}']")
+ expect(rendered).to have_selector(" a[href='#{view.edit_referential_time_table_path(referential, time_table)}']")
end
it "should render a link to remove the time_table" do
render
- expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_time_table_path(referential, time_table)}'][class='remove']")
+ expect(rendered).to have_selector(" a[href='#{view.referential_time_table_path(referential, time_table)}']")
end
end
-