aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Donnet2016-11-14 21:15:31 +0100
committerLuc Donnet2016-11-14 21:15:31 +0100
commit9cfa2309d53fa45342776f7cd2972080b3b85582 (patch)
treeaa435ae46f61fd25eee29a9e8a6c9beaf620a1d2
parent552611c5a96134eff8515bbfe32870e900225bfb (diff)
parent3960264693d8ea79907b7c5619af678c69aef234 (diff)
downloadchouette-core-9cfa2309d53fa45342776f7cd2972080b3b85582.tar.bz2
Merge branch 'master' of github.com:AF83/stif-boiv
-rw-r--r--.gitignore5
-rw-r--r--Gemfile7
-rw-r--r--Gemfile.lock15
-rw-r--r--app/assets/javascripts/es6_browserified/actions/index.js32
-rw-r--r--app/assets/javascripts/es6_browserified/components/App.js12
-rw-r--r--app/assets/javascripts/es6_browserified/components/BSelect2.js127
-rw-r--r--app/assets/javascripts/es6_browserified/components/Todo.js59
-rw-r--r--app/assets/javascripts/es6_browserified/components/TodoList.js34
-rw-r--r--app/assets/javascripts/es6_browserified/containers/AddTodo.js21
-rw-r--r--app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js37
-rw-r--r--app/assets/javascripts/es6_browserified/form_helper.js10
-rw-r--r--app/assets/javascripts/es6_browserified/reducers/index.js8
-rw-r--r--app/assets/javascripts/es6_browserified/reducers/todos.js73
-rw-r--r--app/assets/javascripts/es6_browserified/stop_points.js58
-rw-r--r--app/assets/stylesheets/application.sass.erb6
-rw-r--r--app/assets/stylesheets/components/_form.sass13
-rw-r--r--app/assets/stylesheets/vendor/bootstrap_changes.sass16
-rw-r--r--app/assets/stylesheets/vendor/select2-bootstrap.css720
-rw-r--r--app/assets/stylesheets/vendor/select2.css498
-rw-r--r--app/controllers/api/v1/routes_controller.rb4
-rw-r--r--app/controllers/clean_ups_controller.rb20
-rw-r--r--app/controllers/referential_companies_controller.rb2
-rw-r--r--app/controllers/referential_group_of_lines_controller.rb2
-rw-r--r--app/controllers/referential_networks_controller.rb2
-rw-r--r--app/controllers/referentials_controller.rb6
-rw-r--r--app/controllers/routes_controller.rb2
-rw-r--r--app/controllers/stop_areas_controller.rb1
-rw-r--r--app/helpers/routes_helper.rb10
-rw-r--r--app/inputs/search_stop_area_input.rb18
-rw-r--r--app/models/chouette/for_alighting_enumerations.rb2
-rw-r--r--app/models/chouette/route.rb64
-rw-r--r--app/models/clean_up.rb214
-rw-r--r--app/models/concerns/route_restrictions.rb2
-rw-r--r--app/models/line_referential.rb6
-rw-r--r--app/models/line_referential_sync_message.rb2
-rw-r--r--app/models/organisation.rb30
-rw-r--r--app/models/referential.rb23
-rw-r--r--app/models/stop_area_referential_sync_message.rb2
-rw-r--r--app/models/user.rb41
-rw-r--r--app/models/workbench.rb6
-rw-r--r--app/views/api/kml/routes/show.kml.slim4
-rw-r--r--app/views/footnotes/_footnote_fields.html.slim2
-rw-r--r--app/views/line_referentials/show.html.slim24
-rw-r--r--app/views/lines/_form.html.slim10
-rw-r--r--app/views/lines/show.html.slim3
-rw-r--r--app/views/referential_companies/_company.html.slim12
-rw-r--r--app/views/referential_companies/index.html.slim7
-rw-r--r--app/views/referential_companies/show.html.slim21
-rw-r--r--app/views/referential_lines/_form.html.slim6
-rw-r--r--app/views/referential_lines/_line.html.slim8
-rw-r--r--app/views/referential_lines/_reflines_routes.html.slim30
-rw-r--r--app/views/referential_lines/index.html.slim28
-rw-r--r--app/views/referential_lines/show.html.slim118
-rw-r--r--app/views/referential_networks/_network.html.slim13
-rw-r--r--app/views/referential_networks/index.html.slim3
-rw-r--r--app/views/referential_networks/show.html.slim21
-rw-r--r--app/views/referential_stop_areas/_genealogical.html.slim6
-rw-r--r--app/views/referential_stop_areas/_stop_area.html.slim14
-rw-r--r--app/views/referential_stop_areas/index.html.slim7
-rw-r--r--app/views/referential_stop_areas/show.html.slim45
-rw-r--r--app/views/referentials/_counts.html.slim2
-rw-r--r--app/views/referentials/index.html.slim9
-rw-r--r--app/views/referentials/show.html.slim5
-rw-r--r--app/views/referentials/show.js.slim5
-rw-r--r--app/views/routes/_form.html.slim144
-rw-r--r--app/views/routes/_route.html.slim14
-rw-r--r--app/views/routes/_stop_point_fields.html.slim37
-rw-r--r--app/views/routes/_test.html.slim36
-rw-r--r--app/views/routes/edit.html.slim4
-rw-r--r--app/views/routes/new.html.slim4
-rw-r--r--app/views/routes/show.html.slim102
-rw-r--r--app/views/rule_parameter_sets/_form.html.slim5
-rw-r--r--app/views/rule_parameter_sets/show.html.slim18
-rw-r--r--app/views/shared/_header.html.slim8
-rw-r--r--app/views/stop_area_referentials/show.html.slim22
-rw-r--r--app/views/vehicle_journeys/_form.html.slim4
-rw-r--r--app/workers/clean_up_worker.rb16
-rw-r--r--config/application.rb3
-rw-r--r--config/deploy.rb12
-rw-r--r--config/initializers/apartment.rb4
-rw-r--r--config/initializers/assets.rb2
-rw-r--r--config/initializers/delayed_job_config.rb6
-rw-r--r--config/initializers/devise_async.rb2
-rw-r--r--config/initializers/simple_form.rb18
-rw-r--r--config/initializers/simple_form_bootstrap.rb67
-rw-r--r--config/locales/directions.en.yml2
-rw-r--r--config/locales/enumerize.en.yml17
-rw-r--r--config/locales/enumerize.fr.yml25
-rw-r--r--config/locales/referentials.en.yml3
-rw-r--r--config/locales/referentials.fr.yml1
-rw-r--r--config/locales/routes.en.yml22
-rw-r--r--config/locales/routes.fr.yml4
-rw-r--r--db/migrate/20120516172252_create_delayed_jobs.rb22
-rw-r--r--db/migrate/20161109160857_add_organisation_code_index.rb5
-rw-r--r--db/migrate/20161114134518_create_clean_ups.rb18
-rw-r--r--db/schema.rb23
-rw-r--r--lib/stif/my_workbench_scopes.rb23
-rw-r--r--lib/tasks/ci.rake1
-rw-r--r--package.json20
-rwxr-xr-xscript/delayed_job5
-rw-r--r--spec/factories/chouette_routes.rb14
-rw-r--r--spec/factories/clean_ups.rb15
-rw-r--r--spec/features/access_points_spec.rb37
-rw-r--r--spec/features/routes_spec.rb39
-rw-r--r--spec/features/stop_points_spec.rb4
-rw-r--r--spec/models/chouette/route_spec.rb78
-rw-r--r--spec/models/clean_up_spec.rb58
-rw-r--r--spec/models/line_referential_spec.rb6
-rw-r--r--spec/models/organisation_spec.rb17
-rw-r--r--spec/models/user_spec.rb9
-rw-r--r--spec/models/workbench_spec.rb23
-rw-r--r--spec/views/vehicle_journeys/_form.html.erb_spec.rb16
-rw-r--r--spec/workers/clean_up_worker_spec.rb4
113 files changed, 2737 insertions, 915 deletions
diff --git a/.gitignore b/.gitignore
index 31b5d928c..4bd57ce25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,3 +28,8 @@ coverage
# IDE
.idea
+
+bin/
+
+# Ignore node modules
+/node_modules
diff --git a/Gemfile b/Gemfile
index ed8cb52ff..68034d8a3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,6 +10,9 @@ gem 'uglifier', '~> 2.7.2'
# Use CoffeeScript for .js.coffee assets and views
gem 'coffee-rails', '~> 4.0.0'
+# ES6 powa
+gem 'browserify-rails'
+
# Use jquery as the JavaScript library
gem 'jquery-rails', '~> 3.1.4' # Update to v4 for Rails 4.2
# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks
@@ -53,7 +56,7 @@ gem 'polylines'
# Codifligne API
gem 'codifligne', git: 'git@github.com:AF83/stif-codifline-api.git'
# Reflex API
-gem 'reflex', git: 'git@github.com:AF83/stif-reflex-api.git', branch: 'sax_refactoring'
+gem 'reflex', git: 'git@github.com:AF83/stif-reflex-api.git'
# Authentication
gem 'devise', '~> 3.4.0'
@@ -112,7 +115,6 @@ gem 'rabl'
gem 'sidekiq'
gem 'sinatra'
-gem 'delayed_job_active_record'
gem 'whenever', github: 'af83/whenever', require: false # '~> 0.9'
gem 'rake'
gem 'devise-async'
@@ -125,6 +127,7 @@ gem 'letter_opener'
group :development do
gem 'capistrano', '2.13.5'
gem 'capistrano-ext'
+ gem 'capistrano-npm', require: false
gem 'guard'
gem 'guard-rspec'
gem 'rails-erd'
diff --git a/Gemfile.lock b/Gemfile.lock
index 631c0bfbe..4d9e94fbd 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -24,7 +24,6 @@ GIT
GIT
remote: git@github.com:AF83/stif-reflex-api.git
revision: 2c01010dce3a6cb39339995c373faf89ae00f3f3
- branch: sax_refactoring
specs:
reflex (0.0.1)
nokogiri (~> 1.6)
@@ -90,6 +89,8 @@ GEM
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
breadcrumbs_on_rails (2.3.0)
+ browserify-rails (1.1.0)
+ railties (>= 4.0.0, < 5.0)
builder (3.2.2)
calendar_helper (0.2.5)
open4
@@ -101,6 +102,8 @@ GEM
net-ssh-gateway (>= 1.1.0)
capistrano-ext (1.2.1)
capistrano (>= 1.0.0)
+ capistrano-npm (0.0.2)
+ capistrano (>= 2.5.5)
capybara (2.4.4)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
@@ -149,11 +152,6 @@ GEM
debug_inspector (0.0.2)
deep_cloneable (2.0.2)
activerecord (>= 3.1.0, < 5.0.0)
- delayed_job (4.0.6)
- activesupport (>= 3.0, < 5.0)
- delayed_job_active_record (4.0.3)
- activerecord (>= 3.0, < 5.0)
- delayed_job (>= 3.0, < 4.1)
devise (3.4.1)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
@@ -574,9 +572,11 @@ DEPENDENCIES
better_errors
binding_of_caller
breadcrumbs_on_rails
+ browserify-rails
calendar_helper (= 0.2.5)
capistrano (= 2.13.5)
capistrano-ext
+ capistrano-npm
capybara (~> 2.4.0)
cocoon
codifligne!
@@ -585,7 +585,6 @@ DEPENDENCIES
daemons
database_cleaner
deep_cloneable (~> 2.0.0)
- delayed_job_active_record
devise (~> 3.4.0)
devise-async
devise-encryptable
@@ -674,4 +673,4 @@ DEPENDENCIES
will_paginate-bootstrap (~> 1.0.1)
BUNDLED WITH
- 1.12.5
+ 1.13.6
diff --git a/app/assets/javascripts/es6_browserified/actions/index.js b/app/assets/javascripts/es6_browserified/actions/index.js
new file mode 100644
index 000000000..de3bfc113
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/actions/index.js
@@ -0,0 +1,32 @@
+module.exports = {
+ addStop : () => {
+ return {
+ type: 'ADD_STOP'
+ }
+ },
+ moveStopUp : (index) => {
+ return {
+ type: 'MOVE_STOP_UP',
+ index
+ }
+ },
+ moveStopDown : (index) => {
+ return {
+ type: 'MOVE_STOP_DOWN',
+ index
+ }
+ },
+ deleteStop: (index) => {
+ return {
+ type: 'DELETE_STOP',
+ index
+ }
+ },
+ updateInputValue: (index, text) => {
+ return {
+ type : "UPDATE_INPUT_VALUE",
+ index,
+ text
+ }
+ }
+}
diff --git a/app/assets/javascripts/es6_browserified/components/App.js b/app/assets/javascripts/es6_browserified/components/App.js
new file mode 100644
index 000000000..7488b0b39
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/App.js
@@ -0,0 +1,12 @@
+var React = require('react')
+var AddTodo = require('../containers/AddTodo')
+var VisibleTodoList = require('../containers/VisibleTodoList')
+
+const App = () => (
+ <div>
+ <AddTodo />
+ <VisibleTodoList />
+ </div>
+)
+
+module.exports = App
diff --git a/app/assets/javascripts/es6_browserified/components/BSelect2.js b/app/assets/javascripts/es6_browserified/components/BSelect2.js
new file mode 100644
index 000000000..a78dc625f
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/BSelect2.js
@@ -0,0 +1,127 @@
+var React = require('react')
+var PropTypes = require('react').PropTypes
+var Select2 = require('react-select2')
+
+
+// get JSON full path
+var origin = window.location.origin
+var path = window.location.pathname.split('/', 3).join('/')
+
+
+class BSelect3 extends React.Component{
+ constructor(props) {
+ super(props)
+ this.state = {
+ edit: false
+ }
+ }
+ onToggleEdit(e) {
+ e.preventDefault()
+ this.setState({edit: !this.state.edit})
+ }
+ onChange(e) {
+ this.props.onChange(this.props.index, {
+ text: e.currentTarget.textContent, stoparea_id: e.currentTarget.value
+ })
+ this.setState({edit: false})
+ }
+
+ render() {
+ if(this.state.edit)
+ return (
+ <div className='input-group select2-bootstrap-append'>
+ <BSelect2 {...this.props} onSelect={ this.onChange.bind(this) }/>
+
+ <span className='input-group-btn'>
+ <button type='button' className='btn btn-default' onClick={this.onToggleEdit.bind(this)}>
+ <span className='fa fa-undo'></span>
+ </button>
+ </span>
+ </div>
+ )
+ else
+ if(!this.props.value.stoparea_id)
+ return (
+ <div>
+ <BSelect2 {...this.props} onSelect={ this.onChange.bind(this) }/>
+ </div>
+ )
+ else
+ return (
+ <div className='input-group'>
+ <a
+ className='form-control form-control-link'
+ href={origin + path + '/stop_areas/' + this.props.value.stoparea_id}
+ title={"Voir l'arrêt '" + this.props.value.text + "'"}
+ >
+ {this.props.value.text}
+ </a>
+ <span className='input-group-btn'>
+ <button type='button' className='btn btn-default' onClick={this.onToggleEdit.bind(this)}>
+ <span className='fa fa-pencil'></span>
+ </button>
+ </span>
+ </div>
+ )
+ }
+}
+
+class BSelect2 extends React.Component{
+ componentDidMount() {
+ this.refs.newSelect.el.select2('open')
+ }
+
+ render() {
+ return (
+ <Select2
+ value={ this.props.value.stoparea_id }
+ onSelect={ this.props.onSelect }
+ ref='newSelect'
+ options={{
+ placeholder: 'Sélectionnez un arrêt existant...',
+ allowClear: true,
+ language: 'fr', /* Doesn't seem to work... :( */
+ theme: 'bootstrap',
+ width: '100%',
+ ajax: {
+ url: origin + path + '/autocomplete_stop_areas.json',
+ dataType: 'json',
+ delay: '500',
+ data: function(params) {
+ return {
+ q: params.term
+ };
+ },
+ processResults: function(data, params) {
+ return {
+ results: data.map(
+ item => Object.assign(
+ {},
+ item,
+ { text: item.name + ", " + item.zip_code + " " + item.short_city_name }
+ )
+ )
+ };
+ },
+ cache: true
+ },
+ minimumInputLength: 3,
+ templateResult: formatRepo
+ }}
+ />
+ )
+ }
+}
+
+const formatRepo = (props) => {
+ if(props.text) return props.text
+ // console.log(props)
+ // return (
+ // <div>
+ // {props.short_name}
+ // <small><em>{props.zip_code} {props.short_city_name}</em></small>
+ // </div>
+ // )
+}
+
+module.exports = BSelect3
diff --git a/app/assets/javascripts/es6_browserified/components/Todo.js b/app/assets/javascripts/es6_browserified/components/Todo.js
new file mode 100644
index 000000000..16e42eb3c
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/Todo.js
@@ -0,0 +1,59 @@
+var React = require('react')
+var PropTypes = require('react').PropTypes
+var BSelect2 = require('./BSelect2')
+
+const Container = {display: 'table', width: '100%'}
+const firstBlock = {display: 'table-cell', verticalAlign: 'middle'}
+const secondBlock = {display: 'table-cell', verticalAlign: 'middle', width: 150, textAlign: 'right'}
+
+const Todo = (props) => {
+ return (
+ <div className='list-group-item' style={Container}>
+ <div style={firstBlock}>
+ <div style={{display: 'inline-block', width: '10%', verticalAlign: 'middle', textAlign: 'right'}}>
+ <span className='label label-default' style={{marginRight: 10}}>{props.value.stoparea_id}</span>
+ </div>
+
+ <div style={{display: 'inline-block', width: '90%', verticalAlign: 'middle'}}>
+ <BSelect2 id={'route_stop_points_' + props.id} value={props.value} onChange={props.onChange} index={props.index} />
+ </div>
+ </div>
+
+ <div style={secondBlock}>
+ <div className='btn-group btn-group-sm'>
+ <div
+ className={'btn btn-primary' + (props.first ? ' disabled' : '')}
+ onClick={props.onMoveUpClick}
+ >
+ <span className='fa fa-arrow-up'></span>
+ </div>
+ <div
+ className={'btn btn-primary' + (props.last ? ' disabled' : '')}
+ onClick={props.onMoveDownClick}
+ >
+ <span className='fa fa-arrow-down'></span>
+ </div>
+ <div
+ className='btn btn-danger'
+ onClick={props.onDeleteClick}
+ >
+ <span className='fa fa-trash'></span>
+ </div>
+ </div>
+ </div>
+ </div>
+ )
+}
+
+Todo.propTypes = {
+ onDeleteClick: PropTypes.func.isRequired,
+ onMoveUpClick: PropTypes.func.isRequired,
+ onMoveDownClick: PropTypes.func.isRequired,
+ onChange: PropTypes.func.isRequired,
+ first: PropTypes.bool,
+ last: PropTypes.bool,
+ index: PropTypes.number,
+ value: PropTypes.object
+}
+
+module.exports = Todo
diff --git a/app/assets/javascripts/es6_browserified/components/TodoList.js b/app/assets/javascripts/es6_browserified/components/TodoList.js
new file mode 100644
index 000000000..e909f07bb
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/TodoList.js
@@ -0,0 +1,34 @@
+var React = require('react')
+var PropTypes = require('react').PropTypes
+var Todo = require('./Todo')
+
+const TodoList = ({ todos, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange }) => {
+ return (
+ <div className='list-group'>
+ {todos.map((todo, index) =>
+ <Todo
+ key={'item-' + index}
+ onDeleteClick={() => onDeleteClick(index)}
+ onMoveUpClick={() => {
+ onMoveUpClick(index)
+ }}
+ onMoveDownClick={() => onMoveDownClick(index)}
+ onChange={ onChange }
+ first={ index === 0 }
+ last={ index === (todos.length - 1) }
+ index={ index }
+ value={ todo }
+ />
+ )}
+ </div>
+ )
+}
+
+TodoList.propTypes = {
+ todos: PropTypes.array.isRequired,
+ onDeleteClick: PropTypes.func.isRequired,
+ onMoveUpClick: PropTypes.func.isRequired,
+ onMoveDownClick: PropTypes.func.isRequired
+}
+
+module.exports = TodoList
diff --git a/app/assets/javascripts/es6_browserified/containers/AddTodo.js b/app/assets/javascripts/es6_browserified/containers/AddTodo.js
new file mode 100644
index 000000000..539b6f78e
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/containers/AddTodo.js
@@ -0,0 +1,21 @@
+var React = require('react')
+var connect = require('react-redux').connect
+var addTodo = require('../actions').addStop
+
+let AddTodo = ({ dispatch }) => {
+ return (
+ <div className="clearfix" style={{marginBottom: 10}}>
+ <form onSubmit={e => {
+ e.preventDefault()
+ dispatch(addTodo())
+ }}>
+ <button type="submit" className="btn btn-primary btn-xs pull-right">
+ <span className="fa fa-plus"></span> Ajouter un arrêt
+ </button>
+ </form>
+ </div>
+ )
+}
+AddTodo = connect()(AddTodo)
+
+module.exports = AddTodo
diff --git a/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js b/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js
new file mode 100644
index 000000000..09da36060
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/containers/VisibleTodoList.js
@@ -0,0 +1,37 @@
+var connect = require('react-redux').connect
+var toggleTodo = require('../actions').toggleTodo
+var deleteStop = require('../actions').deleteStop
+var moveStopUp = require('../actions').moveStopUp
+var moveStopDown = require('../actions').moveStopDown
+var handleChange = require('../actions').updateInputValue
+var TodoList = require('../components/TodoList')
+
+const mapStateToProps = (state) => {
+ return {
+ todos: state.todos
+ }
+}
+
+const mapDispatchToProps = (dispatch) => {
+ return {
+ onDeleteClick: (index) =>{
+ dispatch(deleteStop(index))
+ },
+ onMoveUpClick: (index) =>{
+ dispatch(moveStopUp(index))
+ },
+ onMoveDownClick: (index) =>{
+ dispatch(moveStopDown(index))
+ },
+ onChange: (index, text) =>{
+ dispatch(handleChange(index, text))
+ }
+ }
+}
+
+const VisibleTodoList = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(TodoList)
+
+module.exports = VisibleTodoList
diff --git a/app/assets/javascripts/es6_browserified/form_helper.js b/app/assets/javascripts/es6_browserified/form_helper.js
new file mode 100644
index 000000000..5888f23b9
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/form_helper.js
@@ -0,0 +1,10 @@
+module.exports = {
+ addInput : (name, value, index) => {
+ let form = document.querySelector('form')
+ let input = document.createElement('input')
+ input.setAttribute('type', 'hidden')
+ input.setAttribute('name', `route[stop_points_attributes][${index}][${name}]`)
+ input.setAttribute('value', value)
+ form.appendChild(input)
+ }
+}
diff --git a/app/assets/javascripts/es6_browserified/reducers/index.js b/app/assets/javascripts/es6_browserified/reducers/index.js
new file mode 100644
index 000000000..ae8423673
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/reducers/index.js
@@ -0,0 +1,8 @@
+var combineReducers = require('redux').combineReducers
+var todos = require('./todos')
+
+const todoApp = combineReducers({
+ todos
+})
+
+module.exports = todoApp
diff --git a/app/assets/javascripts/es6_browserified/reducers/todos.js b/app/assets/javascripts/es6_browserified/reducers/todos.js
new file mode 100644
index 000000000..e46107efb
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/reducers/todos.js
@@ -0,0 +1,73 @@
+var addInput = require('../form_helper').addInput
+
+const todo = (state = {}, action, length) => {
+ switch (action.type) {
+ case 'ADD_STOP':
+ return {
+ text: '',
+ index: length
+ }
+ case 'UPDATE_INPUT_VALUE':
+ console.log('reducer', action)
+ if (state.index !== action.index) {
+ return state
+ }
+
+ return Object.assign(
+ {},
+ state,
+ {text: action.text.text, stoparea_id: action.text.stoparea_id}
+ )
+ default:
+ return state
+ }
+}
+const updateFormForDeletion = (stop) =>{
+ if (stop.stoppoint_id !== undefined){
+ let now = Date.now()
+ addInput('id', stop.stoppoint_id, now)
+ addInput('_destroy', 'true', now)
+ }
+}
+
+const todos = (state = [], action) => {
+ switch (action.type) {
+ case 'ADD_STOP':
+ return [
+ ...state,
+ todo(undefined, action, state.length)
+ ]
+ case 'MOVE_STOP_UP':
+ return [
+ ...state.slice(0, action.index - 1),
+ state[action.index],
+ state[action.index - 1],
+ ...state.slice(action.index + 1)
+ ]
+ case 'MOVE_STOP_DOWN':
+ return [
+ ...state.slice(0, action.index),
+ state[action.index + 1],
+ state[action.index],
+ ...state.slice(action.index + 2)
+ ]
+ case 'DELETE_STOP':
+ updateFormForDeletion(state[action.index])
+ return [
+ ...state.slice(0, action.index),
+ ...state.slice(action.index + 1).map((todo)=>{
+ todo.index--
+ return todo
+ })
+ ]
+ case 'UPDATE_INPUT_VALUE':
+ return state.map((t, i) => (i === action.index) ? action.text : t)
+ // return state.map(t =>
+ // todo(t, action)
+ // )
+ default:
+ return state
+ }
+}
+
+module.exports = todos
diff --git a/app/assets/javascripts/es6_browserified/stop_points.js b/app/assets/javascripts/es6_browserified/stop_points.js
new file mode 100644
index 000000000..7ecfd9253
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/stop_points.js
@@ -0,0 +1,58 @@
+var React = require('react')
+var render = require('react-dom').render
+var Provider = require('react-redux').Provider
+var createStore = require('redux').createStore
+// var applyMiddleware = require('redux').applyMiddleware
+var todoApp = require('./reducers')
+var App = require('./components/App')
+// var createLogger = require('redux-logger').default
+// var thunkMiddleware = require('redux-thunk').default
+// var promise = require('redux-promise')
+var addInput = require('./form_helper').addInput
+
+const getInitialState = () => {
+ let state = []
+ let datas = JSON.parse(decodeURIComponent(window.itinerary_stop))
+ for (let [index, value] of datas.entries()){
+
+ let fancyText = value.name
+ if(value.zip_code && value.city_name)
+ fancyText += ", " + value.zip_code + " " + value.city_name
+
+ state.push({
+ stoppoint_id: value.stoppoint_id,
+ stoparea_id: value.stoparea_id,
+ index: index,
+ city_name: value.city_name,
+ zip_code: value.zip_code,
+ text: fancyText
+ })
+ }
+ return state
+}
+
+var initialState = {todos: getInitialState()}
+// const loggerMiddleware = createLogger()
+let store = createStore(
+ todoApp,
+ initialState
+ // applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+)
+
+render(
+ <Provider store={store}>
+ <App />
+ </Provider>,
+ document.getElementById('stop_points')
+)
+
+document.querySelector('input[name=commit]').addEventListener('click', (event)=>{
+ let state = store.getState()
+ for (let [i, todo] of state.todos.entries()){
+ if (todo.stoppoint_id == undefined){
+ todo.stoppoint_id = ""
+ }
+ addInput('id',todo.stoppoint_id, i)
+ addInput('stop_area_id',todo.stoparea_id, i)
+ }
+})
diff --git a/app/assets/stylesheets/application.sass.erb b/app/assets/stylesheets/application.sass.erb
index 53b767384..5a0927b9d 100644
--- a/app/assets/stylesheets/application.sass.erb
+++ b/app/assets/stylesheets/application.sass.erb
@@ -42,10 +42,16 @@ $body-bg: #eee
@import 'vendor/typeahead'
@import 'vendor/bootstrap_changes'
@import 'vendor/simple_form'
+// Select2
+@import 'vendor/select2'
+@import 'vendor/select2-bootstrap'
// Main css
@import 'main/*'
+// Components
+@import 'components/*'
+
// Hack to make li simple
li
list-style: none
diff --git a/app/assets/stylesheets/components/_form.sass b/app/assets/stylesheets/components/_form.sass
new file mode 100644
index 000000000..d5f4a1eae
--- /dev/null
+++ b/app/assets/stylesheets/components/_form.sass
@@ -0,0 +1,13 @@
+//-------//
+// FORMS //
+//-------//
+
+.form-control
+ &.form-control-link
+ &:hover, &:focus
+ // Reset default link styles
+ text-decoration: none
+ color: inherit
+ // Add custom
+ color: #555
+ background-color: #f5f5f5
diff --git a/app/assets/stylesheets/vendor/bootstrap_changes.sass b/app/assets/stylesheets/vendor/bootstrap_changes.sass
index 900949492..085f860a8 100644
--- a/app/assets/stylesheets/vendor/bootstrap_changes.sass
+++ b/app/assets/stylesheets/vendor/bootstrap_changes.sass
@@ -18,10 +18,10 @@
.validity_out
color: $brand-danger
-
+
.validity_out_soon
color: $brand-warning
-
+
.validity_regular
color: $brand-success
@@ -42,6 +42,14 @@
> ul
margin: 0
padding: 0
-
+
> li
- list-style: none !important \ No newline at end of file
+ list-style: none !important
+
+
+//-----------------------//
+// Bootstrap-rails fixes //
+//-----------------------//
+
+.input-group-btn > .btn
+ height: 34px
diff --git a/app/assets/stylesheets/vendor/select2-bootstrap.css b/app/assets/stylesheets/vendor/select2-bootstrap.css
new file mode 100644
index 000000000..99437f434
--- /dev/null
+++ b/app/assets/stylesheets/vendor/select2-bootstrap.css
@@ -0,0 +1,720 @@
+/*!
+ * Select2 Bootstrap Theme v0.1.0-beta.9 (https://select2.github.io/select2-bootstrap-theme)
+ * Copyright 2015-2016 Florian Kissling and contributors (https://github.com/select2/select2-bootstrap-theme/graphs/contributors)
+ * Licensed under MIT (https://github.com/select2/select2-bootstrap-theme/blob/master/LICENSE)
+ */
+
+.select2-container--bootstrap {
+ display: block;
+ /*------------------------------------* #COMMON STYLES
+ \*------------------------------------*/
+ /**
+ * Search field in the Select2 dropdown.
+ */
+ /**
+ * No outline for all search fields - in the dropdown
+ * and inline in multi Select2s.
+ */
+ /**
+ * Adjust Select2's choices hover and selected styles to match
+ * Bootstrap 3's default dropdown styles.
+ *
+ * @see http://getbootstrap.com/components/#dropdowns
+ */
+ /**
+ * Clear the selection.
+ */
+ /**
+ * Address disabled Select2 styles.
+ *
+ * @see https://select2.github.io/examples.html#disabled
+ * @see http://getbootstrap.com/css/#forms-control-disabled
+ */
+ /*------------------------------------* #DROPDOWN
+ \*------------------------------------*/
+ /**
+ * Dropdown border color and box-shadow.
+ */
+ /**
+ * Limit the dropdown height.
+ */
+ /*------------------------------------* #SINGLE SELECT2
+ \*------------------------------------*/
+ /*------------------------------------* #MULTIPLE SELECT2
+ \*------------------------------------*/
+ /**
+ * Address Bootstrap control sizing classes
+ *
+ * 1. Reset Bootstrap defaults.
+ * 2. Adjust the dropdown arrow button icon position.
+ *
+ * @see http://getbootstrap.com/css/#forms-control-sizes
+ */
+ /* 1 */
+ /*------------------------------------* #RTL SUPPORT
+ \*------------------------------------*/
+}
+
+.select2-container--bootstrap .select2-selection {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ color: #555555;
+ font-size: 14px;
+ outline: 0;
+}
+
+.select2-container--bootstrap .select2-selection.form-control {
+ border-radius: 4px;
+}
+
+.select2-container--bootstrap .select2-search--dropdown .select2-search__field {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ color: #555555;
+ font-size: 14px;
+}
+
+.select2-container--bootstrap .select2-search__field {
+ outline: 0;
+ /* Firefox 18- */
+ /**
+ * Firefox 19+
+ *
+ * @see http://stackoverflow.com/questions/24236240/color-for-styled-placeholder-text-is-muted-in-firefox
+ */
+}
+
+.select2-container--bootstrap .select2-search__field::-webkit-input-placeholder {
+ color: #999;
+}
+
+.select2-container--bootstrap .select2-search__field:-moz-placeholder {
+ color: #999;
+}
+
+.select2-container--bootstrap .select2-search__field::-moz-placeholder {
+ color: #999;
+ opacity: 1;
+}
+
+.select2-container--bootstrap .select2-search__field:-ms-input-placeholder {
+ color: #999;
+}
+
+.select2-container--bootstrap .select2-results__option {
+ padding: 6px 12px;
+ /**
+ * Disabled results.
+ *
+ * @see https://select2.github.io/examples.html#disabled-results
+ */
+ /**
+ * Hover state.
+ */
+ /**
+ * Selected state.
+ */
+}
+
+.select2-container--bootstrap .select2-results__option[role=group] {
+ padding: 0;
+}
+
+.select2-container--bootstrap .select2-results__option[aria-disabled=true] {
+ color: #777777;
+ cursor: not-allowed;
+}
+
+.select2-container--bootstrap .select2-results__option[aria-selected=true] {
+ background-color: #f5f5f5;
+ color: #262626;
+}
+
+.select2-container--bootstrap .select2-results__option--highlighted[aria-selected] {
+ background-color: #337ab7;
+ color: #fff;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option {
+ padding: 6px 12px;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__group {
+ padding-left: 0;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -12px;
+ padding-left: 24px;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -24px;
+ padding-left: 36px;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -36px;
+ padding-left: 48px;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -48px;
+ padding-left: 60px;
+}
+
+.select2-container--bootstrap .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -60px;
+ padding-left: 72px;
+}
+
+.select2-container--bootstrap .select2-results__group {
+ color: #777777;
+ display: block;
+ padding: 6px 12px;
+ font-size: 12px;
+ line-height: 1.42857143;
+ white-space: nowrap;
+}
+
+.select2-container--bootstrap.select2-container--focus .select2-selection, .select2-container--bootstrap.select2-container--open .select2-selection {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);
+ -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ -webkit-transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
+ transition: border-color ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+ transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s, -webkit-box-shadow ease-in-out 0.15s;
+ border-color: #66afe9;
+}
+
+.select2-container--bootstrap.select2-container--open {
+ /**
+ * Make the dropdown arrow point up while the dropdown is visible.
+ */
+ /**
+ * Handle border radii of the container when the dropdown is showing.
+ */
+}
+
+.select2-container--bootstrap.select2-container--open .select2-selection .select2-selection__arrow b {
+ border-color: transparent transparent #999 transparent;
+ border-width: 0 4px 4px 4px;
+}
+
+.select2-container--bootstrap.select2-container--open.select2-container--below .select2-selection {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+ border-bottom-color: transparent;
+}
+
+.select2-container--bootstrap.select2-container--open.select2-container--above .select2-selection {
+ border-top-right-radius: 0;
+ border-top-left-radius: 0;
+ border-top-color: transparent;
+}
+
+.select2-container--bootstrap .select2-selection__clear {
+ color: #999;
+ cursor: pointer;
+ float: right;
+ font-weight: bold;
+ margin-right: 10px;
+}
+
+.select2-container--bootstrap .select2-selection__clear:hover {
+ color: #333;
+}
+
+.select2-container--bootstrap.select2-container--disabled .select2-selection {
+ border-color: #ccc;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+
+.select2-container--bootstrap.select2-container--disabled .select2-selection,
+.select2-container--bootstrap.select2-container--disabled .select2-search__field {
+ cursor: not-allowed;
+}
+
+.select2-container--bootstrap.select2-container--disabled .select2-selection,
+.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice {
+ background-color: #eeeeee;
+}
+
+.select2-container--bootstrap.select2-container--disabled .select2-selection__clear,
+.select2-container--bootstrap.select2-container--disabled .select2-selection--multiple .select2-selection__choice__remove {
+ display: none;
+}
+
+.select2-container--bootstrap .select2-dropdown {
+ -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
+ border-color: #66afe9;
+ overflow-x: hidden;
+ margin-top: -1px;
+}
+
+.select2-container--bootstrap .select2-dropdown--above {
+ -webkit-box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175);
+ box-shadow: 0px -6px 12px rgba(0, 0, 0, 0.175);
+ margin-top: 1px;
+}
+
+.select2-container--bootstrap .select2-results > .select2-results__options {
+ max-height: 200px;
+ overflow-y: auto;
+}
+
+.select2-container--bootstrap .select2-selection--single {
+ height: 34px;
+ line-height: 1.42857143;
+ padding: 6px 24px 6px 12px;
+ /**
+ * Adjust the single Select2's dropdown arrow button appearance.
+ */
+}
+
+.select2-container--bootstrap .select2-selection--single .select2-selection__arrow {
+ position: absolute;
+ bottom: 0;
+ right: 12px;
+ top: 0;
+ width: 4px;
+}
+
+.select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
+ border-color: #999 transparent transparent transparent;
+ border-style: solid;
+ border-width: 4px 4px 0 4px;
+ height: 0;
+ left: 0;
+ margin-left: -4px;
+ margin-top: -2px;
+ position: absolute;
+ top: 50%;
+ width: 0;
+}
+
+.select2-container--bootstrap .select2-selection--single .select2-selection__rendered {
+ color: #555555;
+ padding: 0;
+}
+
+.select2-container--bootstrap .select2-selection--single .select2-selection__placeholder {
+ color: #999;
+}
+
+.select2-container--bootstrap .select2-selection--multiple {
+ min-height: 34px;
+ padding: 0;
+ height: auto;
+ /**
+ * Make Multi Select2's choices match Bootstrap 3's default button styles.
+ */
+ /**
+ * Minus 2px borders.
+ */
+ /**
+ * Clear the selection.
+ */
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__rendered {
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: block;
+ line-height: 1.42857143;
+ list-style: none;
+ margin: 0;
+ overflow: hidden;
+ padding: 0;
+ width: 100%;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__placeholder {
+ color: #999;
+ float: left;
+ margin-top: 5px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
+ color: #555555;
+ background: #fff;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ cursor: default;
+ float: left;
+ margin: 5px 0 0 6px;
+ padding: 0 6px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
+ background: transparent;
+ padding: 0 12px;
+ height: 32px;
+ line-height: 1.42857143;
+ margin-top: 0;
+ min-width: 5em;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove {
+ color: #999;
+ cursor: pointer;
+ display: inline-block;
+ font-weight: bold;
+ margin-right: 3px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__choice__remove:hover {
+ color: #333;
+}
+
+.select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
+ margin-top: 6px;
+}
+
+.select2-container--bootstrap .select2-selection--single.input-sm,
+.input-group-sm .select2-container--bootstrap .select2-selection--single,
+.form-group-sm .select2-container--bootstrap .select2-selection--single {
+ border-radius: 3px;
+ font-size: 12px;
+ height: 30px;
+ line-height: 1.5;
+ padding: 5px 22px 5px 10px;
+ /* 2 */
+}
+
+.select2-container--bootstrap .select2-selection--single.input-sm .select2-selection__arrow b,
+.input-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b,
+.form-group-sm .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
+ margin-left: -5px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-sm,
+.input-group-sm .select2-container--bootstrap .select2-selection--multiple,
+.form-group-sm .select2-container--bootstrap .select2-selection--multiple {
+ min-height: 30px;
+ border-radius: 3px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__choice,
+.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice,
+.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
+ font-size: 12px;
+ line-height: 1.5;
+ margin: 4px 0 0 5px;
+ padding: 0 5px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-search--inline .select2-search__field,
+.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field,
+.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
+ padding: 0 10px;
+ font-size: 12px;
+ height: 28px;
+ line-height: 1.5;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-sm .select2-selection__clear,
+.input-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear,
+.form-group-sm .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
+ margin-top: 5px;
+}
+
+.select2-container--bootstrap .select2-selection--single.input-lg,
+.input-group-lg .select2-container--bootstrap .select2-selection--single,
+.form-group-lg .select2-container--bootstrap .select2-selection--single {
+ border-radius: 6px;
+ font-size: 18px;
+ height: 46px;
+ line-height: 1.3333333;
+ padding: 10px 31px 10px 16px;
+ /* 1 */
+}
+
+.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow,
+.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow,
+.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow {
+ width: 5px;
+}
+
+.select2-container--bootstrap .select2-selection--single.input-lg .select2-selection__arrow b,
+.input-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b,
+.form-group-lg .select2-container--bootstrap .select2-selection--single .select2-selection__arrow b {
+ border-width: 5px 5px 0 5px;
+ margin-left: -5px;
+ margin-left: -10px;
+ margin-top: -2.5px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-lg,
+.input-group-lg .select2-container--bootstrap .select2-selection--multiple,
+.form-group-lg .select2-container--bootstrap .select2-selection--multiple {
+ min-height: 46px;
+ border-radius: 6px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__choice,
+.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice,
+.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__choice {
+ font-size: 18px;
+ line-height: 1.3333333;
+ border-radius: 4px;
+ margin: 9px 0 0 8px;
+ padding: 0 10px;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-search--inline .select2-search__field,
+.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field,
+.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-search--inline .select2-search__field {
+ padding: 0 16px;
+ font-size: 18px;
+ height: 44px;
+ line-height: 1.3333333;
+}
+
+.select2-container--bootstrap .select2-selection--multiple.input-lg .select2-selection__clear,
+.input-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear,
+.form-group-lg .select2-container--bootstrap .select2-selection--multiple .select2-selection__clear {
+ margin-top: 10px;
+}
+
+.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single {
+ /**
+ * Make the dropdown arrow point up while the dropdown is visible.
+ */
+}
+
+.select2-container--bootstrap .select2-selection.input-lg.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #999 transparent;
+ border-width: 0 5px 5px 5px;
+}
+
+.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single {
+ /**
+ * Make the dropdown arrow point up while the dropdown is visible.
+ */
+}
+
+.input-group-lg .select2-container--bootstrap .select2-selection.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #999 transparent;
+ border-width: 0 5px 5px 5px;
+}
+
+.select2-container--bootstrap[dir="rtl"] {
+ /**
+ * Single Select2
+ *
+ * 1. Makes sure that .select2-selection__placeholder is positioned
+ * correctly.
+ */
+ /**
+ * Multiple Select2
+ */
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--single {
+ padding-left: 24px;
+ padding-right: 12px;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__rendered {
+ padding-right: 0;
+ padding-left: 0;
+ text-align: right;
+ /* 1 */
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__clear {
+ float: left;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow {
+ left: 12px;
+ right: auto;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--single .select2-selection__arrow b {
+ margin-left: 0;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice,
+.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder {
+ float: right;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ margin-left: 0;
+ margin-right: 6px;
+}
+
+.select2-container--bootstrap[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
+ margin-left: 2px;
+ margin-right: auto;
+}
+
+/*------------------------------------* #ADDITIONAL GOODIES
+\*------------------------------------*/
+/**
+ * Address Bootstrap's validation states
+ *
+ * If a Select2 widget parent has one of Bootstrap's validation state modifier
+ * classes, adjust Select2's border colors and focus states accordingly.
+ * You may apply said classes to the Select2 dropdown (body > .select2-container)
+ * via JavaScript match Bootstraps' to make its styles match.
+ *
+ * @see http://getbootstrap.com/css/#forms-control-validation
+ */
+.has-warning .select2-dropdown,
+.has-warning .select2-selection {
+ border-color: #8a6d3b;
+}
+
+.has-warning .select2-container--focus .select2-selection,
+.has-warning .select2-container--open .select2-selection {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;
+ border-color: #66512c;
+}
+
+.has-warning.select2-drop-active {
+ border-color: #66512c;
+}
+
+.has-warning.select2-drop-active.select2-drop.select2-drop-above {
+ border-top-color: #66512c;
+}
+
+.has-error .select2-dropdown,
+.has-error .select2-selection {
+ border-color: #a94442;
+}
+
+.has-error .select2-container--focus .select2-selection,
+.has-error .select2-container--open .select2-selection {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
+ border-color: #843534;
+}
+
+.has-error.select2-drop-active {
+ border-color: #843534;
+}
+
+.has-error.select2-drop-active.select2-drop.select2-drop-above {
+ border-top-color: #843534;
+}
+
+.has-success .select2-dropdown,
+.has-success .select2-selection {
+ border-color: #3c763d;
+}
+
+.has-success .select2-container--focus .select2-selection,
+.has-success .select2-container--open .select2-selection {
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;
+ border-color: #2b542c;
+}
+
+.has-success.select2-drop-active {
+ border-color: #2b542c;
+}
+
+.has-success.select2-drop-active.select2-drop.select2-drop-above {
+ border-top-color: #2b542c;
+}
+
+/**
+ * Select2 widgets in Bootstrap Input Groups
+ *
+ * When Select2 widgets are combined with other elements using Bootstraps
+ * "Input Group" component, we don't want specific edges of the Select2
+ * container to have a border-radius.
+ *
+ * Use .select2-bootstrap-prepend and .select2-bootstrap-append on
+ * a Bootstrap 3 .input-group to let the contained Select2 widget know which
+ * edges should not be rounded as they are directly followed by another element.
+ *
+ * @see http://getbootstrap.com/components/#input-groups
+ */
+/**
+ * Mimick Bootstraps .input-group .form-control styles.
+ *
+ * @see https://github.com/twbs/bootstrap/blob/master/less/input-groups.less
+ */
+.input-group .select2-container--bootstrap {
+ display: table;
+ table-layout: fixed;
+ position: relative;
+ z-index: 2;
+ float: left;
+ width: 100%;
+ margin-bottom: 0;
+ /**
+ * Adjust z-index like Bootstrap does to show the focus-box-shadow
+ * above appended buttons in .input-group and .form-group.
+ */
+}
+
+.input-group .select2-container--bootstrap.select2-container--open, .input-group .select2-container--bootstrap.select2-container--focus {
+ z-index: 3;
+}
+
+.input-group.select2-bootstrap-prepend .select2-container--bootstrap .select2-selection {
+ border-bottom-left-radius: 0;
+ border-top-left-radius: 0;
+}
+
+.input-group.select2-bootstrap-append .select2-container--bootstrap .select2-selection {
+ border-bottom-right-radius: 0;
+ border-top-right-radius: 0;
+}
+
+/**
+ * Adjust alignment of Bootstrap buttons in Bootstrap Input Groups to address
+ * Multi Select2's height which - depending on how many elements have been selected -
+ * may grow taller than its initial size.
+ *
+ * @see http://getbootstrap.com/components/#input-groups
+ */
+.select2-bootstrap-append .select2-container--bootstrap,
+.select2-bootstrap-append .input-group-btn,
+.select2-bootstrap-append .input-group-btn .btn,
+.select2-bootstrap-prepend .select2-container--bootstrap,
+.select2-bootstrap-prepend .input-group-btn,
+.select2-bootstrap-prepend .input-group-btn .btn {
+ vertical-align: top;
+}
+
+/**
+ * Temporary fix for https://github.com/select2/select2-bootstrap-theme/issues/9
+ *
+ * Provides `!important` for certain properties of the class applied to the
+ * original `<select>` element to hide it.
+ *
+ * @see https://github.com/select2/select2/pull/3301
+ * @see https://github.com/fk/select2/commit/31830c7b32cb3d8e1b12d5b434dee40a6e753ada
+ */
+.form-control.select2-hidden-accessible {
+ position: absolute !important;
+ width: 1px !important;
+}
+
+/**
+ * Display override for inline forms
+ */
+.form-inline .select2-container--bootstrap {
+ display: inline-block;
+}
diff --git a/app/assets/stylesheets/vendor/select2.css b/app/assets/stylesheets/vendor/select2.css
new file mode 100644
index 000000000..6f3cb138d
--- /dev/null
+++ b/app/assets/stylesheets/vendor/select2.css
@@ -0,0 +1,498 @@
+.select2-container {
+ box-sizing: border-box;
+ display: inline-block;
+ margin: 0;
+ position: relative;
+ vertical-align: middle; }
+ .select2-container .select2-selection--single {
+ box-sizing: border-box;
+ cursor: pointer;
+ display: block;
+ height: 28px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-container .select2-selection--single .select2-selection__rendered {
+ display: block;
+ padding-left: 8px;
+ padding-right: 20px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap; }
+ .select2-container .select2-selection--single .select2-selection__clear {
+ position: relative; }
+ .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered {
+ padding-right: 8px;
+ padding-left: 20px; }
+ .select2-container .select2-selection--multiple {
+ box-sizing: border-box;
+ cursor: pointer;
+ display: block;
+ min-height: 32px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-container .select2-selection--multiple .select2-selection__rendered {
+ display: inline-block;
+ overflow: hidden;
+ padding-left: 8px;
+ text-overflow: ellipsis;
+ white-space: nowrap; }
+ .select2-container .select2-search--inline {
+ float: left; }
+ .select2-container .select2-search--inline .select2-search__field {
+ box-sizing: border-box;
+ border: none;
+ font-size: 100%;
+ margin-top: 5px;
+ padding: 0; }
+ .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {
+ -webkit-appearance: none; }
+
+.select2-dropdown {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ box-sizing: border-box;
+ display: block;
+ position: absolute;
+ left: -100000px;
+ width: 100%;
+ z-index: 1051; }
+
+.select2-results {
+ display: block; }
+
+.select2-results__options {
+ list-style: none;
+ margin: 0;
+ padding: 0; }
+
+.select2-results__option {
+ padding: 6px;
+ user-select: none;
+ -webkit-user-select: none; }
+ .select2-results__option[aria-selected] {
+ cursor: pointer; }
+
+.select2-container--open .select2-dropdown {
+ left: 0; }
+
+.select2-container--open .select2-dropdown--above {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--open .select2-dropdown--below {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-search--dropdown {
+ display: block;
+ padding: 4px; }
+ .select2-search--dropdown .select2-search__field {
+ padding: 4px;
+ width: 100%;
+ box-sizing: border-box; }
+ .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {
+ -webkit-appearance: none; }
+ .select2-search--dropdown.select2-search--hide {
+ display: none; }
+
+.select2-close-mask {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ display: block;
+ position: fixed;
+ left: 0;
+ top: 0;
+ min-height: 100%;
+ min-width: 100%;
+ height: auto;
+ width: auto;
+ opacity: 0;
+ z-index: 99;
+ background-color: #fff;
+ filter: alpha(opacity=0); }
+
+.select2-hidden-accessible {
+ border: 0 !important;
+ clip: rect(0 0 0 0) !important;
+ height: 1px !important;
+ margin: -1px !important;
+ overflow: hidden !important;
+ padding: 0 !important;
+ position: absolute !important;
+ width: 1px !important; }
+
+.select2-container--default .select2-selection--single {
+ background-color: #fff;
+ border: 1px solid #aaa;
+ border-radius: 4px; }
+ .select2-container--default .select2-selection--single .select2-selection__rendered {
+ color: #444;
+ line-height: 28px; }
+ .select2-container--default .select2-selection--single .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold; }
+ .select2-container--default .select2-selection--single .select2-selection__placeholder {
+ color: #999; }
+ .select2-container--default .select2-selection--single .select2-selection__arrow {
+ height: 26px;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ width: 20px; }
+ .select2-container--default .select2-selection--single .select2-selection__arrow b {
+ border-color: #888 transparent transparent transparent;
+ border-style: solid;
+ border-width: 5px 4px 0 4px;
+ height: 0;
+ left: 50%;
+ margin-left: -4px;
+ margin-top: -2px;
+ position: absolute;
+ top: 50%;
+ width: 0; }
+
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear {
+ float: left; }
+
+.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow {
+ left: 1px;
+ right: auto; }
+
+.select2-container--default.select2-container--disabled .select2-selection--single {
+ background-color: #eee;
+ cursor: default; }
+ .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {
+ display: none; }
+
+.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #888 transparent;
+ border-width: 0 4px 5px 4px; }
+
+.select2-container--default .select2-selection--multiple {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ cursor: text; }
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered {
+ box-sizing: border-box;
+ list-style: none;
+ margin: 0;
+ padding: 0 5px;
+ width: 100%; }
+ .select2-container--default .select2-selection--multiple .select2-selection__rendered li {
+ list-style: none; }
+ .select2-container--default .select2-selection--multiple .select2-selection__placeholder {
+ color: #999;
+ margin-top: 5px;
+ float: left; }
+ .select2-container--default .select2-selection--multiple .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold;
+ margin-top: 5px;
+ margin-right: 10px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice {
+ background-color: #e4e4e4;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ cursor: default;
+ float: left;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 0 5px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {
+ color: #999;
+ cursor: pointer;
+ display: inline-block;
+ font-weight: bold;
+ margin-right: 2px; }
+ .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {
+ color: #333; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline {
+ float: right; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ margin-left: 5px;
+ margin-right: auto; }
+
+.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
+ margin-left: 2px;
+ margin-right: auto; }
+
+.select2-container--default.select2-container--focus .select2-selection--multiple {
+ border: solid black 1px;
+ outline: 0; }
+
+.select2-container--default.select2-container--disabled .select2-selection--multiple {
+ background-color: #eee;
+ cursor: default; }
+
+.select2-container--default.select2-container--disabled .select2-selection__choice__remove {
+ display: none; }
+
+.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--default .select2-search--dropdown .select2-search__field {
+ border: 1px solid #aaa; }
+
+.select2-container--default .select2-search--inline .select2-search__field {
+ background: transparent;
+ border: none;
+ outline: 0;
+ box-shadow: none;
+ -webkit-appearance: textfield; }
+
+.select2-container--default .select2-results > .select2-results__options {
+ max-height: 200px;
+ overflow-y: auto; }
+
+.select2-container--default .select2-results__option[role=group] {
+ padding: 0; }
+
+.select2-container--default .select2-results__option[aria-disabled=true] {
+ color: #999; }
+
+.select2-container--default .select2-results__option[aria-selected=true] {
+ background-color: #ddd; }
+
+.select2-container--default .select2-results__option .select2-results__option {
+ padding-left: 1em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__group {
+ padding-left: 0; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -1em;
+ padding-left: 2em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -2em;
+ padding-left: 3em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -3em;
+ padding-left: 4em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -4em;
+ padding-left: 5em; }
+ .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {
+ margin-left: -5em;
+ padding-left: 6em; }
+
+.select2-container--default .select2-results__option--highlighted[aria-selected] {
+ background-color: #5897fb;
+ color: white; }
+
+.select2-container--default .select2-results__group {
+ cursor: default;
+ display: block;
+ padding: 6px; }
+
+.select2-container--classic .select2-selection--single {
+ background-color: #f7f7f7;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ outline: 0;
+ background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);
+ background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);
+ background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
+ .select2-container--classic .select2-selection--single:focus {
+ border: 1px solid #5897fb; }
+ .select2-container--classic .select2-selection--single .select2-selection__rendered {
+ color: #444;
+ line-height: 28px; }
+ .select2-container--classic .select2-selection--single .select2-selection__clear {
+ cursor: pointer;
+ float: right;
+ font-weight: bold;
+ margin-right: 10px; }
+ .select2-container--classic .select2-selection--single .select2-selection__placeholder {
+ color: #999; }
+ .select2-container--classic .select2-selection--single .select2-selection__arrow {
+ background-color: #ddd;
+ border: none;
+ border-left: 1px solid #aaa;
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ height: 26px;
+ position: absolute;
+ top: 1px;
+ right: 1px;
+ width: 20px;
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
+ background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);
+ background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }
+ .select2-container--classic .select2-selection--single .select2-selection__arrow b {
+ border-color: #888 transparent transparent transparent;
+ border-style: solid;
+ border-width: 5px 4px 0 4px;
+ height: 0;
+ left: 50%;
+ margin-left: -4px;
+ margin-top: -2px;
+ position: absolute;
+ top: 50%;
+ width: 0; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear {
+ float: left; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow {
+ border: none;
+ border-right: 1px solid #aaa;
+ border-radius: 0;
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ left: 1px;
+ right: auto; }
+
+.select2-container--classic.select2-container--open .select2-selection--single {
+ border: 1px solid #5897fb; }
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {
+ background: transparent;
+ border: none; }
+ .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {
+ border-color: transparent transparent #888 transparent;
+ border-width: 0 4px 5px 4px; }
+
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);
+ background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);
+ background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }
+
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0;
+ background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);
+ background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);
+ background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }
+
+.select2-container--classic .select2-selection--multiple {
+ background-color: white;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ cursor: text;
+ outline: 0; }
+ .select2-container--classic .select2-selection--multiple:focus {
+ border: 1px solid #5897fb; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__rendered {
+ list-style: none;
+ margin: 0;
+ padding: 0 5px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__clear {
+ display: none; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice {
+ background-color: #e4e4e4;
+ border: 1px solid #aaa;
+ border-radius: 4px;
+ cursor: default;
+ float: left;
+ margin-right: 5px;
+ margin-top: 5px;
+ padding: 0 5px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {
+ color: #888;
+ cursor: pointer;
+ display: inline-block;
+ font-weight: bold;
+ margin-right: 2px; }
+ .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {
+ color: #555; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ float: right; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice {
+ margin-left: 5px;
+ margin-right: auto; }
+
+.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove {
+ margin-left: 2px;
+ margin-right: auto; }
+
+.select2-container--classic.select2-container--open .select2-selection--multiple {
+ border: 1px solid #5897fb; }
+
+.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {
+ border-top: none;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0; }
+
+.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {
+ border-bottom: none;
+ border-bottom-left-radius: 0;
+ border-bottom-right-radius: 0; }
+
+.select2-container--classic .select2-search--dropdown .select2-search__field {
+ border: 1px solid #aaa;
+ outline: 0; }
+
+.select2-container--classic .select2-search--inline .select2-search__field {
+ outline: 0;
+ box-shadow: none; }
+
+.select2-container--classic .select2-dropdown {
+ background-color: white;
+ border: 1px solid transparent; }
+
+.select2-container--classic .select2-dropdown--above {
+ border-bottom: none; }
+
+.select2-container--classic .select2-dropdown--below {
+ border-top: none; }
+
+.select2-container--classic .select2-results > .select2-results__options {
+ max-height: 200px;
+ overflow-y: auto; }
+
+.select2-container--classic .select2-results__option[role=group] {
+ padding: 0; }
+
+.select2-container--classic .select2-results__option[aria-disabled=true] {
+ color: grey; }
+
+.select2-container--classic .select2-results__option--highlighted[aria-selected] {
+ background-color: #3875d7;
+ color: white; }
+
+.select2-container--classic .select2-results__group {
+ cursor: default;
+ display: block;
+ padding: 6px; }
+
+.select2-container--classic.select2-container--open .select2-dropdown {
+ border-color: #5897fb; }
+
+/* Do the shit, dude */
+.select2-container .select2-results__options .select2-results__option.select2-results__message {
+ display: none;
+}
+.select2-container .select2-results__options .select2-results__option.loading-results {
+ font-size: 0;
+}
+.select2-container .select2-results__options .select2-results__option.loading-results::before {
+ content: "Recherche en cours...";
+ font-size: 14px;
+ font-style: italic;
+ display: inline;
+}
diff --git a/app/controllers/api/v1/routes_controller.rb b/app/controllers/api/v1/routes_controller.rb
index e3694725f..fbc589355 100644
--- a/app/controllers/api/v1/routes_controller.rb
+++ b/app/controllers/api/v1/routes_controller.rb
@@ -3,11 +3,11 @@ class Api::V1::RoutesController < Api::V1::ChouetteController
defaults :resource_class => Chouette::Route, :finder => :find_by_objectid!
belongs_to :line, :parent_class => Chouette::Line, :optional => true, :finder => :find_by_objectid!, :param => :line_id
-
+
protected
def collection
@routes ||= parent.routes
- end
+ end
end
diff --git a/app/controllers/clean_ups_controller.rb b/app/controllers/clean_ups_controller.rb
index 8718fc0dc..c6e4ecd44 100644
--- a/app/controllers/clean_ups_controller.rb
+++ b/app/controllers/clean_ups_controller.rb
@@ -1,23 +1,19 @@
class CleanUpsController < ChouetteController
respond_to :html, :only => [:create]
-
belongs_to :referential
def create
- clean_up = CleanUp.new(params[:clean_up])
-
- if clean_up.invalid?
- flash[:alert] = clean_up.errors.full_messages.join("<br/>")
+ clean_up = CleanUp.new(clean_up_params)
+ clean_up.referential = @referential
+ if clean_up.valid?
+ clean_up.save
else
- begin
- result = clean_up.clean
- flash[:notice] = result.notice.join("<br/>")
- rescue => e
- Rails.logger.error "CleanUp failed : #{e} #{e.backtrace}"
- flash[:alert] = t('clean_ups.failure', error_message: e.to_s)
- end
+ flash[:alert] = clean_up.errors.full_messages.join("<br/>")
end
redirect_to referential_path(@referential)
end
+ def clean_up_params
+ params.require(:clean_up).permit(:keep_lines, :keep_stops, :keep_companies, :keep_networks, :keep_group_of_lines, :expected_date)
+ end
end
diff --git a/app/controllers/referential_companies_controller.rb b/app/controllers/referential_companies_controller.rb
index 104deba9f..a369488ba 100644
--- a/app/controllers/referential_companies_controller.rb
+++ b/app/controllers/referential_companies_controller.rb
@@ -27,7 +27,7 @@ class ReferentialCompaniesController < ChouetteController
end
def collection
- @q = referential.companies.search(params[:q])
+ @q = referential.workbench.companies.search(params[:q])
@companies ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page])
end
diff --git a/app/controllers/referential_group_of_lines_controller.rb b/app/controllers/referential_group_of_lines_controller.rb
index d40fd6090..4decef558 100644
--- a/app/controllers/referential_group_of_lines_controller.rb
+++ b/app/controllers/referential_group_of_lines_controller.rb
@@ -55,7 +55,7 @@ class ReferentialGroupOfLinesController < ChouetteController
end
def collection
- @q = referential.group_of_lines.search(params[:q])
+ @q = referential.workbench.group_of_lines.search(params[:q])
@group_of_lines ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page])
end
diff --git a/app/controllers/referential_networks_controller.rb b/app/controllers/referential_networks_controller.rb
index 2d3f4ad6b..00c680c65 100644
--- a/app/controllers/referential_networks_controller.rb
+++ b/app/controllers/referential_networks_controller.rb
@@ -35,7 +35,7 @@ class ReferentialNetworksController < ChouetteController
end
def collection
- @q = referential.networks.search(params[:q])
+ @q = referential.workbench.networks.search(params[:q])
@networks ||= @q.result(:distinct => true).order(:name).paginate(:page => params[:page])
end
diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb
index 3ae59f975..003c85d3a 100644
--- a/app/controllers/referentials_controller.rb
+++ b/app/controllers/referentials_controller.rb
@@ -57,11 +57,7 @@ class ReferentialsController < BreadcrumbController
end
def create_resource(referential)
- if referential.created_from
- referential.clone_association referential.created_from
- else
- referential.organisation = current_organisation
- end
+ referential.organisation = current_organisation unless referential.created_from
super
end
diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb
index 59c129867..a7e8e32a6 100644
--- a/app/controllers/routes_controller.rb
+++ b/app/controllers/routes_controller.rb
@@ -77,7 +77,7 @@ class RoutesController < ChouetteController
private
def route_params
- params.require(:route).permit( :direction_code, :wayback_code, :line_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :opposite_route_id, :published_name, :number, :direction, :wayback, { stop_points_attributes: [ :id, :_destroy, :position, :stop_area_id, :for_boarding, :for_alighting ] } )
+ params.require(:route).permit( :line_id, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :opposite_route_id, :published_name, :number, :direction, :wayback, { stop_points_attributes: [ :id, :_destroy, :position, :stop_area_id, :for_boarding, :for_alighting ] } )
end
end
diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 8f6a1565a..1f55b1de8 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -26,6 +26,7 @@ class StopAreasController < BreadcrumbController
end
def add_children
+ authorize stop_area
@stop_area = stop_area
@children = stop_area.children
build_breadcrumb :edit
diff --git a/app/helpers/routes_helper.rb b/app/helpers/routes_helper.rb
index b3d79262e..71017fd13 100644
--- a/app/helpers/routes_helper.rb
+++ b/app/helpers/routes_helper.rb
@@ -6,11 +6,15 @@ module RoutesHelper
end
def fonticon_wayback(wayback)
- if wayback == "A"
+ if wayback == 'straight_forward'
return '<i class="fa fa-arrow-right"></i>'.html_safe
else
- return '<i class="fa fa-arrow-left"></i>'.html_safe
+ return '<i class="fa fa-arrow-left"></i>'.html_safe
end
end
-
+
+ def route_json_for_edit(route)
+ route.stop_points.includes(:stop_area).map { |s| s.stop_area.attributes.slice("name","city_name", "zip_code").merge(stoppoint_id: s.id, stoparea_id: s.stop_area.id) }.to_json
+ end
+
end
diff --git a/app/inputs/search_stop_area_input.rb b/app/inputs/search_stop_area_input.rb
index e5cfafc34..c7e21e921 100644
--- a/app/inputs/search_stop_area_input.rb
+++ b/app/inputs/search_stop_area_input.rb
@@ -1,5 +1,5 @@
class SearchStopAreaInput < Formtastic::Inputs::SearchInput
-
+
def search
if options[:json]
tokenLimit = options[:tokenLimit].present? ? options[:tokenLimit] : "null"
@@ -16,19 +16,19 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput
var item_localization = function( item){
var localization = item.zip_code + ' ' + item.short_city_name;
- return localization;
+ return localization;
};
- var item_format = function( item ){
- var name = item_name( item );
+ var item_format = function( item ){
+ var name = item_name( item );
var localization = item_localization( item );
-
+
html_result = '<li>';
html_result += '<span><image src=\"' + item.stop_area_path + '\" height=\"25px\" width=\"25px\"></span>'
if(name != '')
{
- html_result += '<span style=\"height:25px; line-height:25px; margin-left: 5px; \">' + name + '</span>' ;
- }
+ html_result += '<span style=\"height:25px; line-height:25px; margin-left: 5px; \">' + name + '</span>' ;
+ }
if(localization != '')
{
html_result += '<small style=\"height:25px; line-height:25px; margin-left: 10px; color: #555; \">' + localization + '</small>';
@@ -48,7 +48,7 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput
noResultsText: '#{options[:no_result_text]}',
searchingText: '#{options[:searching_text]}',
resultsFormatter: item_format,
- tokenFormatter: item_format,
+ tokenFormatter: item_format,
});
});").html_safe)
end
@@ -62,7 +62,7 @@ class SearchStopAreaInput < Formtastic::Inputs::SearchInput
end
end
- def input_html_options
+ def input_html_options
css_class = super[:class]
super.merge({
:required => nil,
diff --git a/app/models/chouette/for_alighting_enumerations.rb b/app/models/chouette/for_alighting_enumerations.rb
index 4f34927d3..ab07a670d 100644
--- a/app/models/chouette/for_alighting_enumerations.rb
+++ b/app/models/chouette/for_alighting_enumerations.rb
@@ -2,7 +2,7 @@ module Chouette
module ForAlightingEnumerations
extend Enumerize
extend ActiveModel::Naming
-
+
enumerize :for_alighting, in: %w[normal forbidden request_stop is_flexible]
end
end
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 8949a6bc2..446eb5f70 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -1,14 +1,17 @@
class Chouette::Route < Chouette::TridentActiveRecord
include RouteRestrictions
+ extend Enumerize
+ extend ActiveModel::Naming
+
+ enumerize :direction, in: %i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)
+ enumerize :wayback, in: %i(straight_forward backward)
+
# FIXME http://jira.codehaus.org/browse/JRUBY-6358
self.primary_key = "id"
- attr_accessor :wayback_code
- attr_accessor :direction_code
-
def self.nullable_attributes
- [:published_name, :comment, :number, :name]
+ [:published_name, :comment, :number, :name, :direction, :wayback]
end
belongs_to :line
@@ -61,8 +64,11 @@ class Chouette::Route < Chouette::TridentActiveRecord
# validates_presence_of :name
validates_presence_of :line
- # validates_presence_of :direction_code
- # validates_presence_of :wayback_code
+ # validates_presence_of :direction
+ # validates_presence_of :wayback
+
+ validates :direction, inclusion: { in: self.direction.values }
+ validates :wayback, inclusion: { in: self.wayback.values }
before_destroy :dereference_opposite_route
@@ -96,52 +102,6 @@ class Chouette::Route < Chouette::TridentActiveRecord
.order( "vehicle_journey_at_stops.departure_time")
end
- def self.direction_binding
- { "A" => "straight_forward",
- "R" => "backward",
- "ClockWise" => "clock_wise",
- "CounterClockWise" => "counter_clock_wise",
- "North" => "north",
- "NorthWest" => "north_west",
- "West" => "west",
- "SouthWest" => "south_west",
- "South" => "south",
- "SouthEast" => "south_east",
- "East" => "east",
- "NorthEast" => "north_east"}
- end
- def direction_code
- return nil if self.class.direction_binding[direction].nil?
- Chouette::Direction.new( self.class.direction_binding[direction])
- end
- def direction_code=(direction_code)
- self.direction = nil
- self.class.direction_binding.each do |k,v|
- self.direction = k if v==direction_code
- end
- end
- @@directions = nil
- def self.directions
- @@directions ||= Chouette::Direction.all
- end
- def self.wayback_binding
- { "A" => "straight_forward", "R" => "backward"}
- end
- def wayback_code
- return nil if self.class.wayback_binding[wayback].nil?
- Chouette::Wayback.new( self.class.wayback_binding[wayback])
- end
- def wayback_code=(wayback_code)
- self.wayback = nil
- self.class.wayback_binding.each do |k,v|
- self.wayback = k if v==wayback_code
- end
- end
- @@waybacks = nil
- def self.waybacks
- @@waybacks ||= Chouette::Wayback.all
- end
-
def stop_point_permutation?( stop_point_ids)
stop_points.map(&:id).map(&:to_s).sort == stop_point_ids.map(&:to_s).sort
end
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index 1a03b0fb1..986fbdd24 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -1,151 +1,121 @@
-class CleanUp
- include ActiveModel::Validations
- include ActiveModel::Conversion
- extend ActiveModel::Naming
+class CleanUp < ActiveRecord::Base
+ include AASM
+ belongs_to :referential
+ validates :expected_date, presence: true
+ after_commit :perform_cleanup, :on => :create
+
+ def perform_cleanup
+ CleanUpWorker.perform_async(self.id)
+ end
+
+ aasm column: :status do
+ state :new, :initial => true
+ state :pending
+ state :successful
+ state :failed
- attr_accessor :expected_date, :keep_lines, :keep_stops , :keep_companies
- attr_accessor :keep_networks, :keep_group_of_lines
+ event :run, after: :update_started_at do
+ transitions :from => [:new, :failed], :to => :pending
+ end
- validates_presence_of :expected_date
+ event :successful, after: :update_ended_at do
+ transitions :from => [:pending, :failed], :to => :successful
+ end
- def initialize(attributes = {})
- attributes.each do |name, value|
- send("#{name}=", value)
+ event :failed, after: :update_ended_at do
+ transitions :from => :pending, :to => :failed
end
end
- def persisted?
- false
+ def update_started_at
+ update_attribute(:started_at, Time.now)
end
- def vehicle_journeys
- Chouette::VehicleJourney.where "id not in (select distinct vehicle_journey_id from time_tables_vehicle_journeys)"
+ def update_ended_at
+ update_attribute(:ended_at, Time.now)
end
- def journey_patterns
- Chouette::JourneyPattern.where "id not in (select distinct journey_pattern_id from vehicle_journeys)"
+ def clean
+ # as foreign keys are presents , delete method can be used for faster performance
+ # find and remove time_tables
+ result = CleanUpResult.new
+ tms = Chouette::TimeTable.validity_out_from_on?(expected_date)
+ result.time_table_count = tms.size
+ tms.each.map(&:delete)
+
+ result.vehicle_journey_count = self.clean_vehicle_journeys
+ result.journey_pattern_count = self.clean_journey_patterns
+ result.route_count = self.clean_routes
+ result.line_count = self.clean_lines unless keep_lines
+
+ unless keep_stops
+ result.stop_count += self.clean_physical_stop_areas
+ result.stop_count += self.clean_commercial_stop_areas
+ result.stop_count += self.clean_stop_place_stop_areas
+ result.stop_count += self.clean_itl_stop_areas
+ end
+
+ # If asked remove companies without lines or vehicle journeys
+ result.company_count = self.clean_companies unless keep_companies
+ # If asked remove networks without lines
+ result.network_count = self.clean_networks unless keep_networks
+ # If asked remove group_of_lines without lines
+ result.group_of_line_count = self.clean_group_of_lines unless keep_group_of_lines
+ result
end
- def routes
- Chouette::Route.where "id not in (select distinct route_id from journey_patterns)"
+ def clean_physical_stop_areas
+ ids = Chouette::StopArea.physical.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id)
+ Chouette::StopArea.physical.where(id: ids).delete_all
end
- def lines
- Chouette::Line.where "id not in (select distinct line_id from routes)"
+ def clean_commercial_stop_areas
+ ids = Chouette::StopArea.commercial.where.not(parent_id: nil).pluck(:parent_id)
+ Chouette::StopArea.commercial.where.not(id: ids).delete_all
end
- def physical_stop_areas
- Chouette::StopArea.physical
+ def clean_stop_place_stop_areas
+ ids = Chouette::StopArea.stop_place.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id)
+ Chouette::StopArea.stop_place.where(id: ids).delete_all
end
- def commercial_stop_areas
- Chouette::StopArea.commercial
+ def clean_itl_stop_areas
+ ids = Chouette::StopArea.itl.includes(:stop_points).where(:stop_points => {id: nil}).pluck(:id)
+ Chouette::StopArea.itl.where(id: ids).delete_all
end
- def stop_place_stop_areas
- Chouette::StopArea.stop_place
+ def clean_vehicle_journeys
+ ids = Chouette::VehicleJourney.includes(:time_tables).where(:time_tables => {id: nil}).pluck(:id)
+ Chouette::VehicleJourney.where(id: ids).delete_all
end
- def itl_stop_areas
- Chouette::StopArea.itl
+ def clean_lines
+ ids = Chouette::Line.includes(:routes).where(:routes => {id: nil}).pluck(:id)
+ Chouette::Line.where(id: ids).delete_all
end
- def clean
- # as foreign keys are presents , delete method can be used for faster performance
- result = CleanUpResult.new
- # find and remove time_tables
- tms = Chouette::TimeTable.validity_out_from_on?(Date.parse(expected_date))
- result.time_table_count = tms.size
- tms.each do |tm|
- tm.delete
- end
- # remove vehiclejourneys without timetables
- vehicle_journeys.find_each do |vj|
- if vj.time_tables.size == 0
- result.vehicle_journey_count += 1
- vj.delete
- end
- end
- # remove journeypatterns without vehicle journeys
- journey_patterns.find_each do |jp|
- if jp.vehicle_journeys.size == 0
- result.journey_pattern_count += 1
- jp.delete
- end
- end
- # remove routes without journeypatterns
- routes.find_each do |r|
- if r.journey_patterns.size == 0
- result.route_count += 1
- r.delete
- end
- end
- # if asked remove lines without routes
- if keep_lines == "0"
- lines.find_each do |l|
- if l.routes.size == 0
- result.line_count += 1
- l.delete
- end
- end
- end
- # if asked remove stops without children (recurse)
- if keep_stops == "0"
- physical_stop_areas.find_each do |bp|
- if bp.stop_points.size == 0
- result.stop_count += 1
- bp.delete
- end
- end
- commercial_stop_areas.find_each do |csp|
- if csp.children.size == 0
- result.stop_count += 1
- csp.delete
- end
- end
- stop_place_stop_areas.find_each do |sp|
- if sp.children.size == 0
- result.stop_count += 1
- sp.delete
- end
- end
- itl_stop_areas.find_each do |itl|
- if itl.routing_stops.size == 0
- result.stop_count += 1
- itl.delete
- end
- end
- end
- # if asked remove companies without lines or vehicle journeys
- if keep_companies == "0"
- Chouette::Company.find_each do |c|
- if c.lines.size == 0
- result.company_count += 1
- c.delete
- end
- end
- end
+ def clean_routes
+ ids = Chouette::Route.includes(:journey_patterns).where(:journey_patterns => {id: nil}).pluck(:id)
+ Chouette::Route.where(id: ids).delete_all
+ end
- # if asked remove networks without lines
- if keep_networks == "0"
- Chouette::Network.find_each do |n|
- if n.lines.size == 0
- result.network_count += 1
- n.delete
- end
- end
- end
+ def clean_journey_patterns
+ ids = Chouette::JourneyPattern.includes(:vehicle_journeys).where(:vehicle_journeys => {id: nil}).pluck(:id)
+ Chouette::JourneyPattern.where(id: ids).delete_all
+ end
- # if asked remove group_of_lines without lines
- if keep_group_of_lines == "0"
- Chouette::GroupOfLine.find_each do |n|
- if n.lines.size == 0
- result.group_of_line_count += 1
- n.delete
- end
- end
- end
- result
+ def clean_companies
+ ids = Chouette::Company.includes(:lines).where(:lines => {id: nil}).pluck(:id)
+ Chouette::Company.where(id: ids).delete_all
+ end
+
+ def clean_networks
+ ids = Chouette::Network.includes(:lines).where(:lines => {id: nil}).pluck(:id)
+ Chouette::Network.where(id: ids).delete_all
end
+ def clean_group_of_lines
+ ids = Chouette::GroupOfLine.includes(:lines).where(:lines => {id: nil}).pluck(:id)
+ Chouette::GroupOfLine.where(id: ids).delete_all
+ end
end
diff --git a/app/models/concerns/route_restrictions.rb b/app/models/concerns/route_restrictions.rb
index 5a098d86f..4a21cbccf 100644
--- a/app/models/concerns/route_restrictions.rb
+++ b/app/models/concerns/route_restrictions.rb
@@ -8,7 +8,7 @@ module RouteRestrictions
# HUB-37
def wayback_code_limitation
return unless hub_restricted?
- errors.add( :wayback_code, I18n.t('hub.routes.wayback_code_exclusive')) if line.routes.reject {|r| r.id==id}.map(&:wayback_code).include?( wayback_code)
+ errors.add( :wayback, I18n.t('hub.routes.wayback_code_exclusive')) if line.routes.reject {|r| r.id==id}.map(&:wayback).include?( wayback)
end
# HUB-37
diff --git a/app/models/line_referential.rb b/app/models/line_referential.rb
index 7d3b638cb..7096fd6ff 100644
--- a/app/models/line_referential.rb
+++ b/app/models/line_referential.rb
@@ -6,7 +6,7 @@ class LineReferential < ActiveRecord::Base
has_many :group_of_lines, class_name: 'Chouette::GroupOfLine'
has_many :companies, class_name: 'Chouette::Company'
has_many :networks, class_name: 'Chouette::Network'
- has_many :line_referential_syncs, -> { order created_at: :desc}
+ has_many :line_referential_syncs, -> { order created_at: :desc }
has_many :workbenches
def add_member(organisation, options = {})
@@ -26,4 +26,8 @@ class LineReferential < ActiveRecord::Base
def last_sync
line_referential_syncs.last
end
+
+ def transport_modes
+ Chouette::TransportMode.all.select { |tm| tm.positive? }
+ end
end
diff --git a/app/models/line_referential_sync_message.rb b/app/models/line_referential_sync_message.rb
index c62b77689..da9db4095 100644
--- a/app/models/line_referential_sync_message.rb
+++ b/app/models/line_referential_sync_message.rb
@@ -1,6 +1,6 @@
class LineReferentialSyncMessage < ActiveRecord::Base
belongs_to :line_referential_sync
- enum criticity: [:info, :warn, :error]
+ enum criticity: [:info, :warning, :danger]
validates :criticity, presence: true
end
diff --git a/app/models/organisation.rb b/app/models/organisation.rb
index 86386772c..4d93b0ba6 100644
--- a/app/models/organisation.rb
+++ b/app/models/organisation.rb
@@ -14,7 +14,8 @@ class Organisation < ActiveRecord::Base
has_many :workbenches
- validates :name, :presence => true, :uniqueness => true
+ validates_presence_of :name
+ validates_uniqueness_of :code
after_create :add_rule_parameter_set
@@ -39,20 +40,23 @@ class Organisation < ActiveRecord::Base
end
end
+ def self.sync_update code, name, scope
+ org = Organisation.find_or_initialize_by(code: code)
+ if scope
+ org.sso_attributes ||= {}
+ org.sso_attributes['functional_scope'] = scope
+ org.sso_attributes_will_change!
+ end
+ org.name = name
+ org.synced_at = Time.now
+ org.save
+ org
+ end
+
def self.portail_sync
self.portail_api_request.each do |el|
- Organisation.find_or_create_by(code: el['code']).tap do |org|
- org.name = el['name']
- if el['functional_scope']
- org.sso_attributes ||= {}
- org.sso_attributes[:functional_scope] = el['functional_scope'].delete('\\"')
- end
- if org.changed?
- org.synced_at = Time.now
- org.save
- puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test?
- end
- end
+ org = self.sync_update el['code'], el['name'], el['functional_scope']
+ puts "✓ Organisation #{org.name} has been updated" unless Rails.env.test?
end
end
end
diff --git a/app/models/referential.rb b/app/models/referential.rb
index afadf5edd..8b8df3294 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -30,7 +30,7 @@ class Referential < ActiveRecord::Base
validates_presence_of :line_referential
belongs_to :created_from, class_name: 'Referential'
- has_many :lines, through: :line_referential
+ has_many :associated_lines, through: :line_referential, source: :lines
has_many :companies, through: :line_referential
has_many :group_of_lines, through: :line_referential
has_many :networks, through: :line_referential
@@ -43,6 +43,10 @@ class Referential < ActiveRecord::Base
has_many :stop_areas, through: :stop_area_referential
belongs_to :workbench
+ def lines
+ workbench ? workbench.lines : associated_lines
+ end
+
def slug_excluded_values
if ! slug.nil?
if slug.start_with? "pg_"
@@ -128,13 +132,6 @@ class Referential < ActiveRecord::Base
})
end
- def clone_association from
- self.organisation = from.organisation
- self.line_referential = from.line_referential
- self.stop_area_referential = from.stop_area_referential
- self.workbench = from.workbench
- end
-
def self.available_srids
[
[ "RGF 93 Lambert 93 (2154)", 2154 ],
@@ -171,7 +168,8 @@ class Referential < ActiveRecord::Base
projection_type || ""
end
- before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench
+ before_validation :assign_line_and_stop_area_referential, :on => :create, if: :workbench, unless: :created_from
+ before_validation :clone_associations, :on => :create, if: :created_from
before_create :create_schema
after_create :create_referential_metadata, if: :workbench, unless: :created_from
@@ -185,6 +183,13 @@ class Referential < ActiveRecord::Base
self.referential_metadatas.create
end
+ def clone_associations
+ self.organisation = created_from.organisation
+ self.line_referential = created_from.line_referential
+ self.stop_area_referential = created_from.stop_area_referential
+ self.workbench = created_from.workbench
+ end
+
def clone_referential_metadatas
self.created_from.referential_metadatas.each do |meta|
self.referential_metadatas << ReferentialMetadata.new_from(meta)
diff --git a/app/models/stop_area_referential_sync_message.rb b/app/models/stop_area_referential_sync_message.rb
index e965297da..d75c25ebb 100644
--- a/app/models/stop_area_referential_sync_message.rb
+++ b/app/models/stop_area_referential_sync_message.rb
@@ -1,6 +1,6 @@
class StopAreaReferentialSyncMessage < ActiveRecord::Base
belongs_to :stop_area_referential_sync
- enum criticity: [:info, :warn, :error]
+ enum criticity: [:info, :warning, :danger]
validates :criticity, presence: true
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 8f0c32c54..5cfdf0605 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -29,16 +29,10 @@ class User < ActiveRecord::Base
after_destroy :check_destroy_organisation
def cas_extra_attributes=(extra_attributes)
- extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
- self.name = extra[:full_name]
- self.email = extra[:email]
-
- self.organisation = Organisation.find_or_create_by(code: extra[:organisation_code]).tap do |org|
- org.name = extra[:organisation_name]
- org.sso_attributes ||= {}
- org.sso_attributes[:functional_scope] = extra[:functional_scope].delete('\\"') if extra[:functional_scope]
- org.synced_at = Time.now
- end
+ extra = extra_attributes.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
+ self.name = extra[:full_name]
+ self.email = extra[:email]
+ self.organisation = Organisation.sync_update extra[:organisation_code], extra[:organisation_name], extra[:functional_scope]
end
def self.portail_api_request
@@ -60,25 +54,14 @@ class User < ActiveRecord::Base
def self.portail_sync
self.portail_api_request.each do |el|
- User.find_or_create_by(username: el['username']).tap do |user|
- user.name = "#{el['firstname']} #{el['lastname']}"
- user.email = el['email']
- user.locked_at = el['locked_at']
-
- # Set organisation
- user.organisation = Organisation.find_or_create_by(code: el['organization_code']).tap do |org|
- org.name = el['organization_name']
- org.sso_attributes ||= {}
- org.sso_attributes[:functional_scope] = el['functional_scope'].delete('\\"') if el['functional_scope']
- org.synced_at = Time.now
- end
-
- if user.changed?
- user.synced_at = Time.now
- user.save
- puts "✓ user #{user.username} has been updated" unless Rails.env.test?
- end
- end
+ user = User.find_or_initialize_by(username: el['username'])
+ user.name = "#{el['firstname']} #{el['lastname']}"
+ user.email = el['email']
+ user.locked_at = el['locked_at']
+ user.organisation = Organisation.sync_update el['organization_code'], el['organization_name'], el['functional_scope']
+ user.synced_at = Time.now
+ user.save
+ puts "✓ user #{user.username} has been updated" unless Rails.env.test?
end
end
diff --git a/app/models/workbench.rb b/app/models/workbench.rb
index 3525fe55e..a83fea70d 100644
--- a/app/models/workbench.rb
+++ b/app/models/workbench.rb
@@ -3,6 +3,12 @@ class Workbench < ActiveRecord::Base
belongs_to :line_referential
belongs_to :stop_area_referential
+ has_many :lines, -> (workbench) { Stif::MyWorkbenchScopes.new(workbench).line_scope(self) }, through: :line_referential
+ has_many :networks, through: :line_referential
+ has_many :companies, through: :line_referential
+ has_many :group_of_lines, through: :line_referential
+ has_many :stop_areas, through: :stop_area_referential
+
validates :name, presence: true
validates :organisation, presence: true
diff --git a/app/views/api/kml/routes/show.kml.slim b/app/views/api/kml/routes/show.kml.slim
index 3b08d81ce..51d2817c8 100644
--- a/app/views/api/kml/routes/show.kml.slim
+++ b/app/views/api/kml/routes/show.kml.slim
@@ -6,11 +6,11 @@ kml xmlns="http://www.opengis.net/kml/2.2"
placemark id="#{@route.objectid}"
name = h(@route.name)
extendeddata
- - [:direction_code, :wayback_code, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :published_name, :number, :direction, :wayback].each do |prop|
+ - [:direction, :wayback, :objectid, :object_version, :creation_time, :creator_id, :name, :comment, :published_name, :number, :direction_text, :wayback_text].each do |prop|
data name="#{prop.to_s}"
value = h(@route.send( prop))
data name="line_objectid"
value = h(@route.line.objectid)
- = @route.geometry_presenter.geometry.kml_representation.html_safe \ No newline at end of file
+ = @route.geometry_presenter.geometry.kml_representation.html_safe
diff --git a/app/views/footnotes/_footnote_fields.html.slim b/app/views/footnotes/_footnote_fields.html.slim
index ab006cfa9..c1944ed2d 100644
--- a/app/views/footnotes/_footnote_fields.html.slim
+++ b/app/views/footnotes/_footnote_fields.html.slim
@@ -1,4 +1,4 @@
= f.inputs :class => 'nested-fields footnote' do
= f.input :code, :wrapper_html => { class: 'col-md-3' }
= f.input :label, :wrapper_html => { class: 'col-md-7' }
- = link_to_remove_association t('actions.destroy'), f, class: 'col-md-2 remove' \ No newline at end of file
+ = link_to_remove_association t('actions.destroy'), f, class: 'col-md-2 remove'
diff --git a/app/views/line_referentials/show.html.slim b/app/views/line_referentials/show.html.slim
index 406da8fee..95f097fc8 100644
--- a/app/views/line_referentials/show.html.slim
+++ b/app/views/line_referentials/show.html.slim
@@ -25,17 +25,19 @@
h3 Historique des synchronisations
ul.list-group width="75%"
- - @line_referential.line_referential_syncs.each do |sync|
- - unless sync.line_referential_sync_messages.empty?
- - sync.line_referential_sync_messages.last.tap do |log|
- - if log.criticity = log.criticity
- li.alert class="alert-#{log.criticity}"
- strong = l(log.created_at, format: :short) + " : "
- / [:processing_time] unit conversion
- - data = log.message_attributs.symbolize_keys!
- - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i)
-
- = t("line_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!)
+ - @line_referential.line_referential_syncs.each_with_index do |sync, i|
+ / Display only 10 msgs
+ - if i < 10
+ - unless sync.line_referential_sync_messages.empty?
+ - sync.line_referential_sync_messages.last.tap do |log|
+ - if log.criticity = log.criticity
+ li.alert class="alert-#{log.criticity}"
+ strong = l(log.created_at, format: :short) + " : "
+ / [:processing_time] unit conversion
+ - data = log.message_attributs.symbolize_keys!
+ - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i)
+
+ = t("line_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!)
- content_for :sidebar do
ul.actions
diff --git a/app/views/lines/_form.html.slim b/app/views/lines/_form.html.slim
index 113a5c46c..6c847b275 100644
--- a/app/views/lines/_form.html.slim
+++ b/app/views/lines/_form.html.slim
@@ -6,7 +6,7 @@
= form.input :published_name
= form.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.line.registration_number")}
= form.input :number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@line_referential)}.line.number") }
- = form.input :transport_mode, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
+ = form.input :transport_mode, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
= form.input :color, as: :string
= form.input :text_color
= form.input :stable_id
@@ -19,11 +19,11 @@
.footnotes_block
h3 = t("footnotes.index.title")
-
+
#footnotes
= form.semantic_fields_for :footnotes do |f|
= render "footnotes/footnote_fields", :f => f
-
+
.add_footnote
= link_to_add_association t("footnotes.actions.add_footnote"), form, :footnotes , :partial => "footnotes/footnote_fields", :"data-association-insertion-method" => "append", :"data-association-insertion-node" => "div#footnotes", class: 'add'
@@ -32,7 +32,7 @@
= form.action :cancel, as: :link
javascript:
- $(function() {
+ $(function() {
$("#line_group_of_line_tokens").tokenInput("#{name_filter_referential_group_of_lines_path(@line_referential, format: :json)}", {
crossDomain: false,
prePopulate: $('#group_of_line_tokens').data('pre'),
@@ -42,4 +42,4 @@ javascript:
noResultsText: "#{I18n.t('no_result_text')}",
searchingText: "#{I18n.t('searching_term')}"
});
- }); \ No newline at end of file
+ });
diff --git a/app/views/lines/show.html.slim b/app/views/lines/show.html.slim
index cca0e395c..b314dee82 100644
--- a/app/views/lines/show.html.slim
+++ b/app/views/lines/show.html.slim
@@ -118,7 +118,8 @@
p.after_map
-h3.routes = t('.itineraries')
+h3.routes
+ = t('.itineraries')
.routes.paginated_content
/ FIXME #825
diff --git a/app/views/referential_companies/_company.html.slim b/app/views/referential_companies/_company.html.slim
index 06e13764e..e6090540d 100644
--- a/app/views/referential_companies/_company.html.slim
+++ b/app/views/referential_companies/_company.html.slim
@@ -2,10 +2,12 @@
.panel-heading
.panel-title.clearfix
span.pull-right
- = link_to edit_referential_company_path(@referential, company), class: 'btn btn-default btn-sm' do
- span.fa.fa-pencil
- = link_to referential_company_path(@referential, company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
- span.fa.fa-trash-o
+ - if policy(company).update?
+ = link_to edit_referential_company_path(@referential, company), class: 'btn btn-default btn-sm' do
+ span.fa.fa-pencil
+ - if policy(company).destroy?
+ = link_to referential_company_path(@referential, company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
+ span.fa.fa-trash-o
h5
= link_to [@referential, company], class: 'preview', title: "#{Chouette::Company.model_name.human.capitalize} #{company.name}" do
span.name
@@ -13,4 +15,4 @@
.panel-body
p
= company.human_attribute_name('code')
- = company.code \ No newline at end of file
+ = company.code
diff --git a/app/views/referential_companies/index.html.slim b/app/views/referential_companies/index.html.slim
index b32f206ca..6af6d7fc8 100644
--- a/app/views/referential_companies/index.html.slim
+++ b/app/views/referential_companies/index.html.slim
@@ -19,6 +19,7 @@
- content_for :sidebar do
ul.actions
- li
- = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add'
- br \ No newline at end of file
+ - if policy(Chouette::Company).create?
+ li
+ = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add'
+ br
diff --git a/app/views/referential_companies/show.html.slim b/app/views/referential_companies/show.html.slim
index a445dad61..a1a767bbd 100644
--- a/app/views/referential_companies/show.html.slim
+++ b/app/views/referential_companies/show.html.slim
@@ -44,12 +44,15 @@
- content_for :sidebar do
ul.actions
- li
- = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add'
- li
- = link_to t('companies.actions.edit'), edit_referential_company_path(@referential, @company), class: 'edit'
- li
- = link_to t('companies.actions.destroy'), referential_company_path(@referential, @company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'remove'
- br
-
- = creation_tag(@company) \ No newline at end of file
+ - if policy(Chouette::Company).create?
+ li
+ = link_to t('companies.actions.new'), new_referential_company_path(@referential), class: 'add'
+ - if policy(@company).update?
+ li
+ = link_to t('companies.actions.edit'), edit_referential_company_path(@referential, @company), class: 'edit'
+ - if policy(@company).destroy?
+ li
+ = link_to t('companies.actions.destroy'), referential_company_path(@referential, @company), :method => :delete, :data => {:confirm => t('companies.actions.destroy_confirm')}, class: 'remove'
+ br
+
+ = creation_tag(@company)
diff --git a/app/views/referential_lines/_form.html.slim b/app/views/referential_lines/_form.html.slim
index f4e49b3a3..08a011017 100644
--- a/app/views/referential_lines/_form.html.slim
+++ b/app/views/referential_lines/_form.html.slim
@@ -6,7 +6,7 @@
= form.input :published_name
= form.input :registration_number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.line.registration_number") }
= form.input :number, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.line.number") }
- = form.input :transport_mode, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
+ = form.input :transport_mode, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => false, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
= form.input :color, as: :string
= form.input :text_color
= form.input :stable_id
@@ -19,7 +19,7 @@
.footnotes_block
h3 = t("footnotes.index.title")
-
+
#footnotes
= form.semantic_fields_for :footnotes do |f|
= render "footnotes/footnote_fields", f: f
@@ -42,4 +42,4 @@ javascript:
noResultsText: "#{I18n.t('no_result_text')}",
searchingText: "#{I18n.t('searching_term')}"
});
- }); \ No newline at end of file
+ });
diff --git a/app/views/referential_lines/_line.html.slim b/app/views/referential_lines/_line.html.slim
index 0dffb50aa..1c8b8eaa8 100644
--- a/app/views/referential_lines/_line.html.slim
+++ b/app/views/referential_lines/_line.html.slim
@@ -3,7 +3,7 @@
ul.ce-LineBlock-header-list
li
= check_box_tag "ids[]", line.id, false, class: "multiple_selection", style: "display: none;"
-
+
- if line.number && line.number.length <= 3
span.label.label-default.line_number style="#{number_style(line)}"
= line.number
@@ -13,11 +13,11 @@
h5.ce-LineBlock-header-title = truncate(line.name, length: 24)
li
- - if edit
+ - if edit && policy(Chouette::Line).update?
= link_to edit_referential_line_path(@referential, line), class: 'btn btn-default btn-sm' do
span.fa.fa-pencil
- - if delete
+ - if delete && policy(Chouette::Line).destroy?
= link_to referential_line_path(@referential, line), method: :delete, data: { confirm: t('lines.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do
span.fa.fa-trash-o
@@ -46,4 +46,4 @@
= line.human_attribute_name('group_of_line')
= link_to_if( line.group_of_lines.first, line.group_of_lines.first.name, referential_group_of_line_path(@referential, line.group_of_lines.first), :title => "#{line.human_attribute_name('group_of_line')} #{line.group_of_lines.first.name}")
- else
- = t('lines.form.several_group_of_lines', :count => line.group_of_lines.count) \ No newline at end of file
+ = t('lines.form.several_group_of_lines', :count => line.group_of_lines.count)
diff --git a/app/views/referential_lines/_reflines_routes.html.slim b/app/views/referential_lines/_reflines_routes.html.slim
new file mode 100644
index 000000000..43cc908b4
--- /dev/null
+++ b/app/views/referential_lines/_reflines_routes.html.slim
@@ -0,0 +1,30 @@
+table.table.table-bordered.table-hover
+ thead
+ tr
+ th.text-center = @routes.human_attribute_name(:name)
+ th.text-center = @routes.human_attribute_name(:published_name)
+ th.text-center = @routes.human_attribute_name(:wayback)
+ th.text-center = @routes.human_attribute_name(:opposite_route)
+ th.text-center = "Actions"
+
+ - @routes.each do |route|
+ tr
+ td = truncate(route.name, length: 20)
+ td = route.published_name
+ td = route.wayback_text
+ td
+ - if route.opposite_route
+ = route.opposite_route.name
+ - else
+ = "Aucune séquence d'arrêts associée en sens opposé"
+
+ td.text-center
+ .btn.btn-group.btn-group-sm
+ = link_to [@referential, @line, route], class: 'btn btn-default preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do
+ span.fa.fa-eye
+
+ = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do
+ span.fa.fa-pencil
+
+ = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do
+ span.fa.fa-trash-o
diff --git a/app/views/referential_lines/index.html.slim b/app/views/referential_lines/index.html.slim
index 4922cde85..5647bde0c 100644
--- a/app/views/referential_lines/index.html.slim
+++ b/app/views/referential_lines/index.html.slim
@@ -24,25 +24,27 @@
- content_for :sidebar do
ul.actions
- li
- = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add'
+ - if policy(Chouette::Line).create?
+ li
+ = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add'
- #multiple_selection_menu
- h4> = t(".multi_selection")
+ - if policy(Chouette::Line).destroy?
+ #multiple_selection_menu
+ h4> = t(".multi_selection")
- .disabled
- a.enable href="#"
- = t(".multi_selection_enable")
+ .disabled
+ a.enable href="#"
+ = t(".multi_selection_enable")
- .enabled style="display: none;"
- a.disable href="#"
- = t(".multi_selection_disable")
+ .enabled style="display: none;"
+ a.disable href="#"
+ = t(".multi_selection_disable")
- ul.actions
- = link_to t(".delete_selected"), referential_lines_path(@referential), "data-multiple-method" => "delete", :class => "remove", "confirmation-text" => t("lines.actions.destroy_selection_confirm")
+ ul.actions
+ = link_to t(".delete_selected"), referential_lines_path(@referential), "data-multiple-method" => "delete", :class => "remove", "confirmation-text" => t("lines.actions.destroy_selection_confirm")
a.select_all href="#"
= t(".select_all")
= " | "
a.deselect_all href="#"
- = t(".deselect_all") \ No newline at end of file
+ = t(".deselect_all")
diff --git a/app/views/referential_lines/show.html.slim b/app/views/referential_lines/show.html.slim
index ae8314a14..4c439d08a 100644
--- a/app/views/referential_lines/show.html.slim
+++ b/app/views/referential_lines/show.html.slim
@@ -54,51 +54,51 @@
label = "#{@line.human_attribute_name('url')} : "
= @line.url
- p
- label = "#{@line.human_attribute_name('mobility_restricted_suitability')} : "
-
- - if @line.mobility_restricted_suitability.nil?
- = @line.human_attribute_name("unspecified_mrs")
- - elsif @line.mobility_restricted_suitability?
- = @line.human_attribute_name("accessible")
- - else
- = @line.human_attribute_name("not_accessible")
-
- br
- = "#{@line.human_attribute_name('number_of_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', true).count}"
- br
- = "#{@line.human_attribute_name('number_of_non_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', false).count}"
- br
- = "#{@line.human_attribute_name('number_of_null_mrs_vj')} : "
- = @line.vehicle_journeys.count - (@line.vehicle_journeys.where("mobility_restricted_suitability = ?", true).count + @line.vehicle_journeys.where("mobility_restricted_suitability = ?", false).count)
-
- p
- label = "#{@line.human_attribute_name('flexible_service')} : "
-
- - if @line.flexible_service.nil?
- = @line.human_attribute_name("unspecified_fs")
- - elsif @line.flexible_service?
- = @line.human_attribute_name("on_demaond_fs")
- - else
- = @line.human_attribute_name("regular_fs")
-
- br
- = "#{@line.human_attribute_name('number_of_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', true).count}"
- br
- = "#{@line.human_attribute_name('number_of_non_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', false).count}"
- br
- = @line.human_attribute_name("number_of_null_fs_vj")
-
- - if @line.flexible_service.nil?
- = "(#{@line.human_attribute_name('default_fs_msg')})"
-
- = ": #{@line.vehicle_journeys.count - (@line.vehicle_journeys.where('flexible_service = ?', true).count + @line.vehicle_journeys.where('flexible_service = ?', false).count)}"
-
- p
- label = "#{@line.human_attribute_name('footnotes')} : "
- ul
- - @line.footnotes.each do |footnote|
- li = "#{footnote.code} : #{footnote.label}"
+ / p
+ / label = "#{@line.human_attribute_name('mobility_restricted_suitability')} : "
+ /
+ / - if @line.mobility_restricted_suitability.nil?
+ / = @line.human_attribute_name("unspecified_mrs")
+ / - elsif @line.mobility_restricted_suitability?
+ / = @line.human_attribute_name("accessible")
+ / - else
+ / = @line.human_attribute_name("not_accessible")
+ /
+ / br
+ / = "#{@line.human_attribute_name('number_of_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', true).count}"
+ / br
+ / = "#{@line.human_attribute_name('number_of_non_mrs_vj')} : #{@line.vehicle_journeys.where('mobility_restricted_suitability = ?', false).count}"
+ / br
+ / = "#{@line.human_attribute_name('number_of_null_mrs_vj')} : "
+ / = @line.vehicle_journeys.count - (@line.vehicle_journeys.where("mobility_restricted_suitability = ?", true).count + @line.vehicle_journeys.where("mobility_restricted_suitability = ?", false).count)
+ /
+ / p
+ / label = "#{@line.human_attribute_name('flexible_service')} : "
+ /
+ / - if @line.flexible_service.nil?
+ / = @line.human_attribute_name("unspecified_fs")
+ / - elsif @line.flexible_service?
+ / = @line.human_attribute_name("on_demaond_fs")
+ / - else
+ / = @line.human_attribute_name("regular_fs")
+ /
+ / br
+ / = "#{@line.human_attribute_name('number_of_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', true).count}"
+ / br
+ / = "#{@line.human_attribute_name('number_of_non_fs_vj')} : #{@line.vehicle_journeys.where('flexible_service = ?', false).count}"
+ / br
+ / = @line.human_attribute_name("number_of_null_fs_vj")
+ /
+ / - if @line.flexible_service.nil?
+ / = "(#{@line.human_attribute_name('default_fs_msg')})"
+ /
+ / = ": #{@line.vehicle_journeys.count - (@line.vehicle_journeys.where('flexible_service = ?', true).count + @line.vehicle_journeys.where('flexible_service = ?', false).count)}"
+ /
+ / p
+ / label = "#{@line.human_attribute_name('footnotes')} : "
+ / ul
+ / - @line.footnotes.each do |footnote|
+ / li = "#{footnote.code} : #{footnote.label}"
p
label = "#{@line.human_attribute_name('comment')} : "
@@ -109,27 +109,33 @@
#flexible_service.col-md-6
p.after_map
-h3.routes = t('.itineraries')
+h3.routes
+ = t('.itineraries')
.routes.paginated_content
- = paginated_content @routes, "routes/route"
+ / = paginated_content @routes, "routes/route"
+ = render 'reflines_routes'
- if @line.group_of_lines.any?
h3.line_group_of_lines = t('.group_of_lines')
.group_of_lines.paginated_content
- = paginated_content @group_of_lines, "group_of_lines/group_of_line", :delete => false
+ = paginated_content @group_of_lines, "referential_group_of_lines/group_of_line", :delete => false
- content_for :sidebar do
ul.actions
- li
- = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add'
- li
- = link_to t('lines.actions.edit'), edit_referential_line_path(@referential, @line), class: 'edit'
- li
- = link_to t('lines.actions.destroy'), referential_line_path(@referential, @line), method: :delete, :data => {:confirm => t('lines.actions.destroy_confirm')}, class: 'remove'
+ - if policy(Chouette::Line).create?
+ li
+ = link_to t('lines.actions.new'), new_referential_line_path(@referential), class: 'add'
+ - if policy(@line).update?
+ li
+ = link_to t('lines.actions.edit'), edit_referential_line_path(@referential, @line), class: 'edit'
+ - if policy(@line).destroy?
+ li
+ = link_to t('lines.actions.destroy'), referential_line_path(@referential, @line), method: :delete, :data => {:confirm => t('lines.actions.destroy_confirm')}, class: 'remove'
- if !@line.hub_restricted? || (@line.hub_restricted? && @line.routes.size < 2)
- li
+ / FIXME #825
+ li
= link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add'
- = creation_tag(@line) \ No newline at end of file
+ = creation_tag(@line)
diff --git a/app/views/referential_networks/_network.html.slim b/app/views/referential_networks/_network.html.slim
index dc1aa6b5c..f7c7b66eb 100644
--- a/app/views/referential_networks/_network.html.slim
+++ b/app/views/referential_networks/_network.html.slim
@@ -2,13 +2,14 @@
.panel-heading
.panel-title.clearfix
span.pull-right
- = link_to edit_referential_network_path(@referential, network), class: 'btn btn-default btn-sm' do
- span.fa.fa-pencil
-
- = link_to referential_network_path(@referential, network), method: :delete, :data => { :confirm => t('networks.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do
- span.fa.fa-trash-o
+ - if policy(network).update?
+ = link_to edit_referential_network_path(@referential, network), class: 'btn btn-default btn-sm' do
+ span.fa.fa-pencil
+ - if policy(network).destroy?
+ = link_to referential_network_path(@referential, network), method: :delete, :data => { :confirm => t('networks.actions.destroy_confirm') }, class: 'btn btn-danger btn-sm' do
+ span.fa.fa-trash-o
h5
= link_to [@referential, network], class: 'preview', title: "#{Chouette::Network.model_name.human.capitalize} #{network.name}" do
span.name
- = truncate(network.name, :length => 20) \ No newline at end of file
+ = truncate(network.name, :length => 20)
diff --git a/app/views/referential_networks/index.html.slim b/app/views/referential_networks/index.html.slim
index f3ead931e..e3e9f2a07 100644
--- a/app/views/referential_networks/index.html.slim
+++ b/app/views/referential_networks/index.html.slim
@@ -19,5 +19,6 @@
- content_for :sidebar do
ul.actions
li
+ - if policy(Chouette::Network).create?
= link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add'
- br \ No newline at end of file
+ br
diff --git a/app/views/referential_networks/show.html.slim b/app/views/referential_networks/show.html.slim
index 936f6a4a8..d579d311b 100644
--- a/app/views/referential_networks/show.html.slim
+++ b/app/views/referential_networks/show.html.slim
@@ -36,12 +36,15 @@
- content_for :sidebar do
ul.actions
- li
- = link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add'
- li
- = link_to t('networks.actions.edit'), edit_referential_network_path(@referential, @network), class: 'edit'
- li
- = link_to t('networks.actions.destroy'), referential_network_path(@referential, @network), method: :delete, data: { :confirm => t('networks.actions.destroy_confirm')}, class: 'remove'
- br
-
- = creation_tag(@network) \ No newline at end of file
+ - if policy(Chouette::Network).create?
+ li
+ = link_to t('networks.actions.new'), new_referential_network_path(@referential), class: 'add'
+ - if policy(@network).update?
+ li
+ = link_to t('networks.actions.edit'), edit_referential_network_path(@referential, @network), class: 'edit'
+ - if policy(@network).destroy?
+ li
+ = link_to t('networks.actions.destroy'), referential_network_path(@referential, @network), method: :delete, data: { :confirm => t('networks.actions.destroy_confirm')}, class: 'remove'
+ br
+
+ = creation_tag(@network)
diff --git a/app/views/referential_stop_areas/_genealogical.html.slim b/app/views/referential_stop_areas/_genealogical.html.slim
index a44884c92..162c24d9b 100644
--- a/app/views/referential_stop_areas/_genealogical.html.slim
+++ b/app/views/referential_stop_areas/_genealogical.html.slim
@@ -5,7 +5,7 @@ h3 = genealogical_title
= link_to([@referential, @stop_area.parent], :title => t("area_types.label.#{@stop_area.parent.stop_area_type}") + "#{@stop_area.parent.name}") do
= image_tag "map/" + @stop_area.parent.stop_area_type + ".png"
= @stop_area.parent.name
-
+
.link
= image_tag "icons/link.png"
@@ -18,7 +18,7 @@ h3 = genealogical_title
.link = image_tag "icons/link.png"
- else
- .no_parent = &nbsp;
+ .no_parent
.target
= image_tag "map/" + @stop_area.stop_area_type + ".png"
@@ -51,4 +51,4 @@ h3 = genealogical_title
span = route.line.number
= link_to([@referential, route.line , route]) do
- span = route.name \ No newline at end of file
+ span = route.name
diff --git a/app/views/referential_stop_areas/_stop_area.html.slim b/app/views/referential_stop_areas/_stop_area.html.slim
index f94bd319e..bb9ed7ce3 100644
--- a/app/views/referential_stop_areas/_stop_area.html.slim
+++ b/app/views/referential_stop_areas/_stop_area.html.slim
@@ -2,11 +2,13 @@
.panel-heading
.panel-title.clearfix
span.pull-right
- = link_to edit_referential_stop_area_path(@referential, stop_area), class: 'btn btn-default btn-sm' do
- span.fa.fa-pencil
+ - if policy(stop_area).update?
+ = link_to edit_referential_stop_area_path(@referential, stop_area), class: 'btn btn-default btn-sm' do
+ span.fa.fa-pencil
- = link_to referential_stop_area_path(@referential, stop_area), method: :delete, :data => {:confirm => t('stop_areas.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
- span.fa.fa-trash-o
+ - if policy(stop_area).destroy?
+ = link_to referential_stop_area_path(@referential, stop_area), method: :delete, :data => {:confirm => t('stop_areas.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
+ span.fa.fa-trash-o
h5
= link_to([@referential, stop_area], class: "preview", :title => t("area_types.label.#{stop_area.stop_area_type}") + " #{stop_area.name}") do
@@ -34,11 +36,11 @@
- else
- stop_area.routing_lines.each do |line|
span.label.label-default.line = line.number
-
+
- else
= "#{t('.lines')} : "
- if stop_area.lines.blank?
= t(".no_object")
- else
- stop_area.lines.each do |line|
- span.label.label-default.line = line.number || truncate( line.name, length: 4 ) \ No newline at end of file
+ span.label.label-default.line = line.number || truncate( line.name, length: 4 )
diff --git a/app/views/referential_stop_areas/index.html.slim b/app/views/referential_stop_areas/index.html.slim
index 85bd15d20..1b634b09c 100644
--- a/app/views/referential_stop_areas/index.html.slim
+++ b/app/views/referential_stop_areas/index.html.slim
@@ -26,7 +26,8 @@
- content_for :sidebar do
ul.actions
+ - if policy(Chouette::StopArea).create?
+ li
+ = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add'
li
- = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add'
- li
- / = link_to t('stop_areas.actions.default_geometry'), default_geometry_referential_stop_areas_path(@referential), :method => :put, :class => "calculator" \ No newline at end of file
+ / = link_to t('stop_areas.actions.default_geometry'), default_geometry_referential_stop_areas_path(@referential), :method => :put, :class => "calculator"
diff --git a/app/views/referential_stop_areas/show.html.slim b/app/views/referential_stop_areas/show.html.slim
index 76414edf0..2278c4812 100644
--- a/app/views/referential_stop_areas/show.html.slim
+++ b/app/views/referential_stop_areas/show.html.slim
@@ -109,7 +109,7 @@
p.after_map
.genealogical.clearfix
- = render "stop_areas/genealogical"
+ = render "referential_stop_areas/genealogical"
- if manage_access_points
div
@@ -122,22 +122,25 @@ p.after_map
tr
td
ul.actions
- li
- = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add'
- li
- = link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), class: 'edit'
- li
- = link_to t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), method: :delete, data: { :confirm => t('stop_areas.actions.destroy_confirm') }, class: 'remove'
+ - if policy(Chouette::StopArea).new?
+ li
+ = link_to t('stop_areas.actions.new'), new_referential_stop_area_path(@referential), class: 'add'
+ - if policy(@stop_area).update?
+ li
+ = link_to t('stop_areas.actions.edit'), edit_referential_stop_area_path(@referential, @stop_area), class: 'edit'
+ - if policy(@stop_area).destroy?
+ li
+ = link_to t('stop_areas.actions.destroy'), referential_stop_area_path(@referential, @stop_area), method: :delete, data: { :confirm => t('stop_areas.actions.destroy_confirm') }, class: 'remove'
- if manage_itl
- tr
- td
- h4 = t('.itl_managment')
- ul.actions
- li
- = link_to t('stop_areas.actions.add_routing_lines'), add_routing_lines_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_lines'
- li
- = link_to t('stop_areas.actions.add_routing_stops'), add_routing_stops_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_stops'
+ / tr
+ / td
+ / h4 = t('.itl_managment')
+ / ul.actions
+ / li
+ / = link_to t('stop_areas.actions.add_routing_lines'), add_routing_lines_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_lines'
+ / li
+ / = link_to t('stop_areas.actions.add_routing_stops'), add_routing_stops_referential_stop_area_path(@referential, @stop_area), class: 'add_routing_stops'
- else
tr
@@ -145,17 +148,17 @@ p.after_map
h4 = t('.stop_managment')
ul.actions
li
- = link_to t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), class: 'parent'
+ / = link_to t('stop_areas.actions.select_parent'), select_parent_referential_stop_area_path(@referential, @stop_area), class: 'parent'
- if @stop_area.parent == nil
li
- = link_to t('stop_areas.actions.clone_as_parent'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'parent'), class: 'clone'
+ / = link_to t('stop_areas.actions.clone_as_parent'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'parent'), class: 'clone'
- if manage_children
li
- = link_to t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), class: 'children'
+ / = link_to t('stop_areas.actions.add_children'), add_children_referential_stop_area_path(@referential, @stop_area), class: 'children'
li
- = link_to t('stop_areas.actions.clone_as_child'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'child'), class: 'clone'
+ / = link_to t('stop_areas.actions.clone_as_child'), new_referential_stop_area_stop_area_copy_path(@referential, @stop_area, hierarchy: 'child'), class: 'clone'
- if manage_access_points
tr
@@ -163,9 +166,9 @@ p.after_map
h4 = t(".access_managment")
ul.actions
li
- = link_to t('access_points.actions.new'), new_referential_stop_area_access_point_path(@referential,@stop_area), class: 'add'
+ / = link_to t('access_points.actions.new'), new_referential_stop_area_access_point_path(@referential,@stop_area), class: 'add'
li
- = link_to t('stop_areas.actions.manage_access_links'), access_links_referential_stop_area_path(@referential,@stop_area), class: 'access_link'
+ / = link_to t('stop_areas.actions.manage_access_links'), access_links_referential_stop_area_path(@referential,@stop_area), class: 'access_link'
br
diff --git a/app/views/referentials/_counts.html.slim b/app/views/referentials/_counts.html.slim
index fc3ad251e..9754ebc99 100644
--- a/app/views/referentials/_counts.html.slim
+++ b/app/views/referentials/_counts.html.slim
@@ -67,4 +67,4 @@
li.list-group-item
span.badge = @referential.access_points.size
= image_tag "map/access_in_out.png"
- = Referential.human_attribute_name("access_points") \ No newline at end of file
+ = Referential.human_attribute_name("access_points")
diff --git a/app/views/referentials/index.html.slim b/app/views/referentials/index.html.slim
index e37f157de..c03943ac7 100644
--- a/app/views/referentials/index.html.slim
+++ b/app/views/referentials/index.html.slim
@@ -14,12 +14,3 @@
/ FIXME #823
- if false
li = link_to t('referentials.actions.new'), new_referential_path, class: 'add'
-
- ul
- / FIXME #820
- / Don't blame me. See #820
- li = link_to 'Données Reflex', stop_area_referential_path(1)
-
- / FIXME #824
- / Don't blame me. See #824
- li = link_to 'Données CodifLigne', line_referential_path(1)
diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim
index d5fed0344..1fc8f108f 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -44,7 +44,7 @@ h2
- if @referential.api_keys.present?
h3.api_keys = t('.api_keys')
-
+
.api_keys.paginated_content
= paginated_content(@referential.api_keys, "api_keys/api_key")
@@ -66,8 +66,9 @@ h2
li = link_to t('referentials.actions.destroy'), referential_path(@referential), method: :delete, data: {:confirm => t('referentials.actions.destroy_confirm')}, class: "remove"
li = link_to t('api_keys.actions.new'), new_referential_api_key_path(@referential), class: 'add'
+ li = link_to t('referentials.actions.clone'), new_referential_path(from: @referential.id), class: 'add'
br
h4 = t('.clean_up')
- == render 'clean' \ No newline at end of file
+ == render 'clean'
diff --git a/app/views/referentials/show.js.slim b/app/views/referentials/show.js.slim
index f1d01ce6c..5e47bf935 100644
--- a/app/views/referentials/show.js.slim
+++ b/app/views/referentials/show.js.slim
@@ -3,7 +3,6 @@
| update_infos = function(json) {
| var info, update_info;
| info = $('#referential_' + json.referential_id);
-| console.log(info)
| update_info = function(key, value) {
| if (key.match(/_count$/)) {
| return $(info.find('.' + key)[0]).text(value);
@@ -16,5 +15,5 @@
| };
| _results = [];
| _results.push(update_referential_details());
-| return _results;
-| }); \ No newline at end of file
+| return _results;
+| });
diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim
index 329862955..3dd813fc2 100644
--- a/app/views/routes/_form.html.slim
+++ b/app/views/routes/_form.html.slim
@@ -1,91 +1,53 @@
-= semantic_form_for [@referential, @line, @route] do |form|
- = form.inputs do
- = form.input :name
- = form.input :published_name
- = form.input :number
- = form.input :comment
- = form.input :opposite_route, as: :select, :collection => @line.routes.select { |r| r.id != @route.id }
- = form.input :direction_code, as: :select, :collection => Chouette::Route.directions, :include_blank => false, :member_label => Proc.new { |mode| t("directions.label.#{mode}") }
- = form.input :wayback_code, as: :select, :collection => Chouette::Route.waybacks, :include_blank => false, :member_label => Proc.new { |mode| t("waybacks.label.#{mode}") }
- = form.input :objectid, :required => !@route.new_record?, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.route.objectid")}
-
- #stop_points
- = form.semantic_fields_for :stop_points, :include_id => false do |p|
- == render "stop_point_fields", f: p
-
- .links
- = link_to_add_association t("routes.actions.add_stop_point"), form, :stop_points, class: 'add_stop_point add'
- br
- = link_to t('routes.actions.new_stop_point'), new_referential_stop_area_path(@referential), { class: 'add', target: '_blank' }
-
- = form.actions do
- = form.action :submit, as: :button
- = form.action :cancel, as: :link
-
-javascript:
- $(document).ready(function() {
- var stop_point_ids = [];
-
- var order_position = function() {
- $('#stop_points input[type="hidden"][id$="position"]').each(function(index) {
- $(this).val(index);
- });
- };
-
- var write_stop_point_ids = function(){
- $('#stop_points input[type="hidden"][class~="stop_point_id"]').each(function(index,element) {
- // soit le parent a la classe added_stop_point
- if ( $(element).hasClass("added_stop_point") ){
- $(this).attr("value", "");
- } else {
- $(this).attr("value", stop_point_ids.shift());
- }
- });
- }
-
- var empty_stop_point_ids = function() {
- stop_point_ids = $.map($('#stop_points input[type="hidden"][class="stop_point_id"]'), function(element, index) {
- return $(element).val();
- });
- // console.log( "before-remove");
- // console.log( stop_point_ids);
- };
-
- $('#stop_points').sortable({
- axis: 'y',
- dropOnEmpty: false,
- handle: '.handle',
- cursor: 'crosshair',
- items: '.stop_point',
- opacity: 0.4,
- scroll: true,
- start: function( event, ui ) {
- empty_stop_point_ids();
- },
- update: function( event, ui ) {
- write_stop_point_ids();
- order_position();
- }
- });
-
- $('#stop_points').bind("cocoon:after-insert", function(event, insertedItem) {
- var new_stop_count = $('div.nested-fields.stop_point').size();
- var cocoonId = insertedItem.find("input.new_stop_point").attr("id").match( /route_stop_points_attributes_(\d+)_stop_area_id/)[1];
- insertedItem.find('input').each( function(index,e){
- var old = $(e).attr("name");
- if (old!=undefined) {
- $(e).attr("name", old.replace( cocoonId, new_stop_count - 1));
- }
- });
-
- //console.log( "cocoonId="+cocoonId+", new_stop_count="+new_stop_count);
- order_position();
- });
-
- $('#stop_points').on("cocoon:before-remove", empty_stop_point_ids);
-
- $('#stop_points').on("cocoon:after-remove", function() {
- write_stop_point_ids();
- order_position();
- });
- }); \ No newline at end of file
+= simple_form_for [@referential, @line, @route] do |f|
+ .row
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :name
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :published_name
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :number
+
+ .row
+ .col-lg-6.col-md-6.col-sm-5.col-xs-5
+ = f.input :comment
+ .col-lg-6.col-md-6.col-sm-7.col-xs-7
+ = f.input :opposite_route, collection: @line.routes.select { |r| r.id != @route.id }
+
+ .row
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :direction, include_blank: false
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :wayback, include_blank: false
+ .col-lg-4.col-md-4.col-sm-4.col-xs-4
+ = f.input :objectid, required: !@route.new_record?, input_html: { title: t("formtastic.titles#{format_restriction_for_locales(@referential)}.route.objectid") }
+
+ .row style="margin-top:20px"
+ .col-lg-12.col-md-12.col-sm-12.col-xs-12
+ #stop_points
+ / div.clearfix style="margin-bottom:5px"
+ / label style="margin:0" Arrêts
+ / .btn.btn-primary.btn-xs.pull-right data-event="add_stop_point"
+ / span.fa.fa-plus
+ / = " #{t('routes.actions.add_stop_point')}"
+ /
+ / = link_to_add_association f, :stop_points, class: 'btn btn-primary btn-xs pull-right' do
+ / span.fa.fa-plus
+ / = " #{t('routes.actions.add_stop_point')}"
+ / THIS IS BROKEN
+ / = link_to t('routes.actions.new_stop_point'), new_referential_stop_area_path(@referential), target: '_blank'
+ /
+ / .list-group
+ / = f.simple_fields_for :stop_points do |point|
+ / = render 'stop_point_fields', f: point
+
+ .row
+ .col-lg-12.col-md-12.col-sm-12.col-xs-12.text-right
+ = link_to 'Annuler', :back, class: 'btn btn-link'
+ = f.button :submit, class: 'btn btn-danger'
+
+// Get JSON data for route stop points
+= javascript_tag do
+ | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}"
+
+/ StopPoints Reactux component
+= javascript_include_tag 'es6_browserified/stop_points.js'
diff --git a/app/views/routes/_route.html.slim b/app/views/routes/_route.html.slim
index fd740fa9b..251c92000 100644
--- a/app/views/routes/_route.html.slim
+++ b/app/views/routes/_route.html.slim
@@ -1,19 +1,19 @@
#index_item.panel.panel-default.route
.panel-heading
.panel-title.clearfix
- span.pull-right
- = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default btn-sm' do
+ .btn-group.btn-group-sm.pull-right
+ = link_to edit_referential_line_route_path(@referential, @line, route), class: 'btn btn-default' do
span.fa.fa-pencil
- = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger btn-sm' do
+ = link_to referential_line_route_path(@referential, @line, route), method: :delete, :data => {:confirm => t('routes.actions.destroy_confirm')}, class: 'btn btn-danger' do
span.fa.fa-trash-o
h5
= link_to [@referential, @line, route], class: 'preview', title: "#{Chouette::Route.model_name.human.capitalize} #{route.name}" do
span.name
- - if route.wayback_code
+ - if route.wayback
= fonticon_wayback(route.wayback)
-
+
= truncate(route.name, length: 20)
.panel-body
@@ -38,6 +38,6 @@
p
- if !route.direction.blank?
- = "#{route.human_attribute_name('direction_code')} : #{t('directions.label.'+route.direction_code)}"
+ => "#{route.human_attribute_name('direction')} : #{route.direction_text}"
- else
- br \ No newline at end of file
+ br
diff --git a/app/views/routes/_stop_point_fields.html.slim b/app/views/routes/_stop_point_fields.html.slim
index 814e882c2..3b51e5e0d 100644
--- a/app/views/routes/_stop_point_fields.html.slim
+++ b/app/views/routes/_stop_point_fields.html.slim
@@ -1,16 +1,23 @@
-.nested-fields.stop_point.row
- = f.inputs do
- .col-md-1.resize
- = link_to_remove_association "<i class='fa fa-trash-o'></i>".html_safe, f
- span.handle alt="#{t('stop_points.index.move')}" title="#{t('stop_points.index.move')}" >
- i.fa.fa-arrows
-
- .col-md-11
- - if f.object.stop_area.nil? || f.object.new_record?
- = f.input :id, as: :hidden, :input_html => { :class => "stop_point_id added_stop_point", :value => "" }
- = f.input :position, as: :hidden, :input_html => { :class => "position" }
+.list-group-item
+ div style="display:inline-block;vertical-align:middle;width:75%;"
+ - if f.object.stop_area.nil? || f.object.new_record?
+ / = f.input :stop_area_id, label: false
= f.input :stop_area_id, :label => false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "new_stop_point stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render }
- - else
- = f.input :id, as: :hidden, :input_html => { class: 'stop_point_id' }
- = f.input :position, as: :hidden, :input_html => { class: 'position' }
- = f.input :stop_area_id, label: false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render } \ No newline at end of file
+
+ - else
+ = "#{@route.stop_areas.find(f.object.stop_area_id).name} "
+ em.small
+ = "#{@route.stop_areas.find(f.object.stop_area_id).zip_code} #{@route.stop_areas.find(f.object.stop_area_id).city_name}"
+
+ div.text-right style="display:inline-block;vertical-align:middle;width:25%;"
+ .btn-group.btn-group-sm style="padding:0;"
+ .btn.btn-default
+ span.fa.fa-times
+ .btn.btn-primary
+ span.fa.fa-arrow-up
+ .btn.btn-primary
+ span.fa.fa-arrow-down
+ .btn.btn-danger
+ span.fa.fa-trash
+ / = link_to_remove_association f, class: 'btn btn-danger', data: {confirm: 'Are you sure?'} do
+ / span.fa.fa-trash
diff --git a/app/views/routes/_test.html.slim b/app/views/routes/_test.html.slim
new file mode 100644
index 000000000..deb525d32
--- /dev/null
+++ b/app/views/routes/_test.html.slim
@@ -0,0 +1,36 @@
+.list-group-item
+ = f.inputs do
+ - if f.object.stop_area.nil? || f.object.new_record?
+ div style="display:inline-block;vertical-align:middle;width:75%;"
+ span
+ span.text-danger = "[#{@route.stop_areas.find(f.object.stop_area_id).position.inspect}] "
+ = @route.stop_areas.find(f.object.stop_area_id).name
+
+ / = f.input :stop_area_id, :label => false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "new_stop_point stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render }
+
+ = f.input :stop_area_id, :label => false, as: :search_stop_area
+
+ = f.input :id, as: :hidden, :input_html => { :class => "stop_point_id added_stop_point", :value => "" }
+ = f.input :position, as: :hidden, :input_html => { :class => "position" }
+
+ - else
+ div style="display:inline-block;vertical-align:middle;width:75%;"
+ span
+ span.text-danger = "[#{@route.stop_areas.find(f.object.stop_area_id).position.inspect}] "
+ = @route.stop_areas.find(f.object.stop_area_id).name
+
+ / = f.input :stop_area_id, label: false, as: :search_stop_area, :json => referential_autocomplete_stop_areas_path(@referential, :format => :json)+"?filter=physical", :hint_text => t('search_hint'), :no_result_text => t('no_result_text'),:searching_text => t('searching_term'), :tokenLimit => 1, :input_html => { :class => "stop_area_id", :"data-pre" => Rabl::Renderer.new('autocomplete_stop_areas/index', [f.object.stop_area].compact, :view_path => 'app/views', :format => :json, :scope => self ).render }
+
+ = f.input :id, as: :hidden, :input_html => { class: 'stop_point_id' }
+ = f.input :position, as: :hidden, :input_html => { class: 'position' }
+
+ div.text-right style="display:inline-block;;vertical-align:middle;width:25%;"
+ .btn-group.btn-group-sm style="padding:0;"
+ .btn.btn-default
+ span.fa.fa-times
+ .btn.btn-primary
+ span.fa.fa-arrow-up
+ .btn.btn-primary
+ span.fa.fa-arrow-down
+ = link_to_remove_association f, class: 'btn btn-danger' do
+ span.fa.fa-trash
diff --git a/app/views/routes/edit.html.slim b/app/views/routes/edit.html.slim
index 7e2c1f982..a0431dc32 100644
--- a/app/views/routes/edit.html.slim
+++ b/app/views/routes/edit.html.slim
@@ -1,3 +1,5 @@
= title_tag t('routes.edit.title', route: @route.name )
-== render 'form' \ No newline at end of file
+.row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2
+ == render 'form'
diff --git a/app/views/routes/new.html.slim b/app/views/routes/new.html.slim
index e91ebf362..51410a2e5 100644
--- a/app/views/routes/new.html.slim
+++ b/app/views/routes/new.html.slim
@@ -1,3 +1,5 @@
= title_tag t('routes.new.title')
-== render 'form' \ No newline at end of file
+.row
+ .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-8.col-sm-offset-2
+ == render 'form'
diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim
index a4e1aa90f..968fc5795 100644
--- a/app/views/routes/show.html.slim
+++ b/app/views/routes/show.html.slim
@@ -6,66 +6,72 @@
.summary
p
label = "#{@route.human_attribute_name(:name)} : "
- = @route.name
+ = " #{@route.name}"
p
label = "#{@route.human_attribute_name(:published_name)} : "
- = @route.published_name
+ = " #{@route.published_name}"
+
+ / p
+ / label = "#{@route.human_attribute_name(:number)} : "
+ / = " #{@route.number}"
+ /
+ / p
+ / label = "#{@route.human_attribute_name(:comment)} : "
+ / = " #{@route.comment}"
+ /
+ / p
+ / label = "#{@route.human_attribute_name(:direction)} : "
+ / - if @route.direction
+ / = " #{@route.direction_text}"
+ / - else
+ / = " #{t('.undefined')}"
p
- label = "#{@route.human_attribute_name(:number)} : "
- = @route.number
-
- p
- label = "#{@route.human_attribute_name(:comment)} : "
- = @route.comment
-
- p
- label = "#{@route.human_attribute_name(:direction_code)} : "
- - if @route.direction_code
- = t("directions.label.#{@route.direction_code}").capitalize
- - else
- = t(".undefined")
-
- p
- label = "#{@route.human_attribute_name(:wayback_code)} : "
- - if @route.wayback_code
- = t("waybacks.label.#{@route.wayback_code}").capitalize
+ label = "#{@route.human_attribute_name(:wayback)} : "
+ - if @route.wayback
+ = " #{@route.wayback_text}"
- else
- = t(".undefined")
+ = " #{t('.undefined')}"
p
label = "#{@route.human_attribute_name(:opposite_route)} : "
- if @route.opposite_route
= link_to @route.opposite_route.name, [@referential, @line, @route.opposite_route]
- else
- = t(".no_opposite_route")
+ = " #{t('.no_opposite_route')}"
p.after_map
-#accordion.panel-group
- .panel.panel-default
- .panel-heading
- h4.panel-title
- a data-toggle="collapse" data-parent="#accordion" href="#stop_points"
- = t('.stop_points')
-
- #stop_points.panel-collapse.collapse
- .panel-body
- .stop_points.paginated_content
- = paginated_content(@route.stop_points, "stop_points/stop_point")
-
-#accordion.panel-group
- .panel.panel-default
- .panel-heading
- h4.panel-title
- a data-toggle="collapse" data-parent="#accordion" href="#journey_patterns"
- = t('.journey_patterns')
-
- #journey_patterns.panel-collapse.collapse
- .panel-body
- .journey_patterns.paginated_content
- = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern")
+#stop_points.panel.panel-default
+ .panel-heading
+ h4.panel-title
+ strong = t('.stop_points')
+
+ .list-group
+ - @route.stop_points.each do |point|
+ - if point.stop_area.zip_code && point.stop_area.city_name
+ - linktxt = "#{point.stop_area.name}, #{point.stop_area.zip_code} #{point.stop_area.city_name}"
+ - else
+ - linktxt = "#{point.stop_area.name}"
+
+ = link_to [@referential, point.stop_area], { style: 'display: table;width: 100%;', class: 'list-group-item', title: "Voir l'arrêt '#{linktxt}'" } do
+ div style='display: table-cell;vertical-align: middle;'
+ div style='display: inline-block;width: 10%;vertical-align: middle;text-align: right;'
+ span.label.label-default style='margin-right: 10px;'
+ = "#{point.stop_area.id}"
+ div style='display: inline-block;width: 90%;vertical-align: middle;'
+ = linktxt
+
+
+/ .panel.panel-default
+/ .panel-heading
+/ h4.panel-title
+/ strong = t('.journey_patterns')
+/
+/ .panel-body
+/ .journey_patterns.paginated_content
+/ = paginated_content( @route.journey_patterns, "journey_patterns/journey_pattern")
- content_for :sidebar do
ul.actions
@@ -76,10 +82,10 @@ p.after_map
ul.actions
- if @route.stop_points.size >= 2
li = link_to t('journey_patterns.actions.new'), new_referential_line_route_journey_pattern_path(@referential, @line, @route), class: 'add'
-
+
- if @route.stop_points.present?
li = link_to t('routes.actions.edit_boarding_alighting'), edit_boarding_alighting_referential_line_route_path(@referential, @line, @route), class: 'edit'
-
+
- if @route.journey_patterns.size > 0
li = link_to t('vehicle_journeys.actions.index'), [@referential, @line, @route, :vehicle_journeys], class: 'clock'
@@ -87,4 +93,4 @@ p.after_map
li = link_to t('vehicle_journey_imports.new.title'), new_referential_line_route_vehicle_journey_import_path( @referential, @line, @route ), class: 'import'
li = link_to t('vehicle_journey_exports.new.title'), referential_line_route_vehicle_journey_exports_path(@referential, @line, @route, format: :zip), class: 'export'
- = creation_tag(@route) \ No newline at end of file
+ = creation_tag(@route)
diff --git a/app/views/rule_parameter_sets/_form.html.slim b/app/views/rule_parameter_sets/_form.html.slim
index 74ad9ae3b..de3368a1b 100644
--- a/app/views/rule_parameter_sets/_form.html.slim
+++ b/app/views/rule_parameter_sets/_form.html.slim
@@ -25,7 +25,7 @@
thead
tr
th = t("transport_modes.name")
-
+
- RuleParameterSet.mode_attribute_prefixes.each do |prefix|
- if prefix == "allowed_transport"
- hidden = (@rule_parameter_set.check_allowed_transport_modes == "1") ? "" : 'display:none;'
@@ -35,6 +35,7 @@
th = RuleParameterSet.human_attribute_name(prefix)
tbody
+ / To be removed, see #1936
- Chouette::Line.transport_modes.map(&:to_s).each do |mode|
tr
== render partial: "mode_fields", :locals => { f: form, mode: mode }
@@ -69,4 +70,4 @@ javascript:
$( "#rule_parameter_set_check_allowed_transport_modes").change( function() {
$(".allowed").toggle();
});
- }); \ No newline at end of file
+ });
diff --git a/app/views/rule_parameter_sets/show.html.slim b/app/views/rule_parameter_sets/show.html.slim
index 2d54f4572..72a8fa99c 100644
--- a/app/views/rule_parameter_sets/show.html.slim
+++ b/app/views/rule_parameter_sets/show.html.slim
@@ -5,10 +5,10 @@
p
label = "#{RuleParameterSet.human_attribute_name('stop_areas_area')} : "
= @rule_parameter_set.stop_areas_area
-
+
.attributes_group
span.title = t(".min_distance")
-
+
.columns
.two_columns
label = "#{t('.inter_stop_area_distance_min')} : "
@@ -20,7 +20,7 @@
.attributes_group
span.title = t(".max_distance")
-
+
.columns
.two_columns
label = "#{t('.parent_stop_area_distance_max')} : "
@@ -91,23 +91,23 @@
table.table.table-striped.table-condensed
tr
th = t("transport_modes.name")
-
+
- RuleParameterSet.mode_attribute_prefixes.each do |prefix|
- unless prefix == "allowed_transport"
th = RuleParameterSet.human_attribute_name(prefix)
-
+ / To be removed, see #1936
- Chouette::Line.transport_modes.map(&:to_s).each do |mode|
- if @rule_parameter_set.allowed(mode)
tr
td = t("transport_modes.label.#{mode}")
-
+
- RuleParameterSet.mode_attribute_prefixes.each do |prefix|
- unless prefix == "allowed_transport"
td = @rule_parameter_set.send "#{prefix}_mode_#{mode}"
.rule_parameter_by_object
label = t("rule_parameter_sets.labels.columns_restrictions")
-
+
table.table.table-bordered.table-condensed
- RuleParameterSet.validable_object_names.each do |object_name|
- if @rule_parameter_set.selected(object_name)
@@ -119,7 +119,7 @@
th = RuleParameterSet.human_attribute_name("string_type")
th = RuleParameterSet.human_attribute_name("min_size")
th = RuleParameterSet.human_attribute_name("max_size")
-
+
tbody
- RuleParameterSet.validable_columns[object_name].each do |col|
- if @rule_parameter_set.selected_column(object_name,col)
@@ -140,4 +140,4 @@
li = link_to t('rule_parameter_sets.actions.edit'), edit_organisation_rule_parameter_set_path( @rule_parameter_set), class: 'edit'
- if current_organisation.rule_parameter_sets.size > 1
- li = link_to t('rule_parameter_sets.actions.destroy'), organisation_rule_parameter_set_path( @rule_parameter_set), method: :delete, data: { confirm: t('rule_parameter_sets.actions.destroy_confirm') }, class: 'remove' \ No newline at end of file
+ li = link_to t('rule_parameter_sets.actions.destroy'), organisation_rule_parameter_set_path( @rule_parameter_set), method: :delete, data: { confirm: t('rule_parameter_sets.actions.destroy_confirm') }, class: 'remove'
diff --git a/app/views/shared/_header.html.slim b/app/views/shared/_header.html.slim
index 27b0139c2..73e705e35 100644
--- a/app/views/shared/_header.html.slim
+++ b/app/views/shared/_header.html.slim
@@ -7,7 +7,7 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation"
span.icon-bar
span.icon-bar
span.icon-bar
- span.icon-bar.version = APP_VERSION
+ / span.icon-bar.version = APP_VERSION
= link_to referentials_path, class: 'navbar-brand' do
/ = image_tag("logo_chouette.png")
@@ -85,12 +85,12 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation"
= link_to referential_route_sections_path(@referential) do
span.badge.pull-right = @referential.route_sections.size
= Referential.human_attribute_name("route_sections")
-
+
li
= link_to referential_timebands_path(@referential) do
span.badge.pull-right = @referential.timebands.size
= Referential.human_attribute_name("timebands")
-
+
li
= link_to Referential.human_attribute_name("imports"), referential_imports_path(@referential)
li
@@ -128,4 +128,4 @@ nav.navbar.navbar-default.navbar-fixed-top role="navigation"
li = link_to t('layouts.user.sign_out'), destroy_user_session_path, method: :delete
li.divider
li
- = tab_link_to Organisation.model_name.human, organisation_path \ No newline at end of file
+ = tab_link_to Organisation.model_name.human, organisation_path
diff --git a/app/views/stop_area_referentials/show.html.slim b/app/views/stop_area_referentials/show.html.slim
index 9cceed5e5..907cdb168 100644
--- a/app/views/stop_area_referentials/show.html.slim
+++ b/app/views/stop_area_referentials/show.html.slim
@@ -13,17 +13,19 @@
h3 Historique des synchronisations
ul.list-group width="75%"
- - @stop_area_referential.stop_area_referential_syncs.each do |sync|
- - unless sync.stop_area_referential_sync_messages.empty?
- - sync.stop_area_referential_sync_messages.last.tap do |log|
- - if log.criticity = log.criticity
- li.alert class="alert-#{log.criticity}"
- strong = l(log.created_at, format: :short) + " : "
- / [:processing_time] unit conversion
- - data = log.message_attributs.symbolize_keys!
- - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i)
+ - @stop_area_referential.stop_area_referential_syncs.each_with_index do |sync, i|
+ / Display only 10 msgs
+ - if i < 10
+ - unless sync.stop_area_referential_sync_messages.empty?
+ - sync.stop_area_referential_sync_messages.last.tap do |log|
+ - if log.criticity = log.criticity
+ li.alert class="alert-#{log.criticity}"
+ strong = l(log.created_at, format: :short) + " : "
+ / [:processing_time] unit conversion
+ - data = log.message_attributs.symbolize_keys!
+ - data[:processing_time] = distance_of_time_in_words(data[:processing_time].to_i)
- = t("stop_area_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!)
+ = t("stop_area_referential_sync.message.#{log.message_key}", log.message_attributs.symbolize_keys!)
- content_for :sidebar do
ul.actions
diff --git a/app/views/vehicle_journeys/_form.html.slim b/app/views/vehicle_journeys/_form.html.slim
index bc26e1ac5..61d6b0e06 100644
--- a/app/views/vehicle_journeys/_form.html.slim
+++ b/app/views/vehicle_journeys/_form.html.slim
@@ -7,7 +7,7 @@
= form.input :published_journey_name
= form.input :published_journey_identifier
= form.input :comment
- = form.input :transport_mode_name, as: :select, :collection => Chouette::Line.transport_modes, :include_blank => true, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
+ = form.input :transport_mode_name, as: :select, :collection => @line.line_referential.transport_modes, :include_blank => true, :member_label => Proc.new { |mode| t("transport_modes.label.#{mode}") }
= form.input :mobility_restricted_suitability, as: :select, :collection => [[vehicle_journey.human_attribute_name("accessible"), true], [vehicle_journey.human_attribute_name("not_accessible"), false]], :include_blank => true
= form.input :flexible_service, as: :select, :collection => [[vehicle_journey.human_attribute_name("on_demand_fs"), true], [vehicle_journey.human_attribute_name("regular_fs"), false]], :include_blank => true
= form.input :status_value
@@ -23,4 +23,4 @@
= form.action :submit, as: :button, label: t(".submit_#{vehicle_journey.journey_category}#{'_edit' unless form.object.new_record?}"), button_html: { class: 'btn btn-primary' }
= form.action :cancel, as: :link
-== render 'form_footer', vehicle_journey: vehicle_journey \ No newline at end of file
+== render 'form_footer', vehicle_journey: vehicle_journey
diff --git a/app/workers/clean_up_worker.rb b/app/workers/clean_up_worker.rb
new file mode 100644
index 000000000..f758b900b
--- /dev/null
+++ b/app/workers/clean_up_worker.rb
@@ -0,0 +1,16 @@
+class CleanUpWorker
+ include Sidekiq::Worker
+
+ def perform(id)
+ cleaner = CleanUp.find id
+ cleaner.run!
+ begin
+ cleaner.referential.switch
+ result = cleaner.clean
+ cleaner.successful!
+ rescue Exception => e
+ Rails.logger.error "CleanUpWorker : #{e}"
+ cleaner.failed!
+ end
+ end
+end
diff --git a/config/application.rb b/config/application.rb
index 52da477a5..93a4cc8fd 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -26,5 +26,8 @@ module ChouetteIhm
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
config.i18n.default_locale = :fr
+
+ # Configure Browserify to use babelify to compile ES6
+ config.browserify_rails.commandline_options = "-t [ babelify --presets [ es2015 react ] ]"
end
end
diff --git a/config/deploy.rb b/config/deploy.rb
index cd6391ec3..bfbcabb4e 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -23,6 +23,11 @@ ssh_options[:forward_agent] = true
require "bundler/capistrano"
require 'whenever/capistrano'
+require 'capistrano/npm'
+set :npm_options, '--production --silent --no-progress'
+
+after 'deploy:finalize_update', 'npm:install'
+
# Whenever
set :whenever_variables, ->{ "'environment=#{fetch :whenever_environment}&bundle_command=bin/bundle exec&additionnal_path=/var/lib/gems/2.2.0/bin'" } # invoke bin/bundle to use 'correct' ruby environment
@@ -73,10 +78,3 @@ namespace :deploy do
run "cd #{current_path} && #{bundle_cmd} exec /var/lib/gems/2.2.0/bin/rake db:seed RAILS_ENV=#{rails_env}"
end
end
-
-namespace :delayed_job do
- task :restart do
- run "sudo /etc/init.d/stif-boiv restart"
- end
- # after "deploy:restart", "delayed_job:restart"
-end
diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb
index 7a3549c02..445e32b78 100644
--- a/config/initializers/apartment.rb
+++ b/config/initializers/apartment.rb
@@ -21,7 +21,6 @@ Apartment.configure do |config|
"Referential",
"Organisation",
"User",
- "Delayed::Backend::ActiveRecord::Job",
"Api::V1::ApiKey",
"RuleParameterSet",
"StopAreaReferential",
@@ -36,7 +35,8 @@ Apartment.configure do |config|
"Chouette::Company",
"Chouette::Network",
"ReferentialCloning",
- "Workbench"
+ "Workbench",
+ "CleanUp"
]
# use postgres schemas?
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb
index d2f4ec33a..928236c4a 100644
--- a/config/initializers/assets.rb
+++ b/config/initializers/assets.rb
@@ -5,4 +5,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
-# Rails.application.config.assets.precompile += %w( search.js )
+Rails.application.config.assets.precompile += %w( es6_browserified/*.js )
diff --git a/config/initializers/delayed_job_config.rb b/config/initializers/delayed_job_config.rb
deleted file mode 100644
index 147b2550e..000000000
--- a/config/initializers/delayed_job_config.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-# config/initializers/delayed_job_config.rb
-#Delayed::Job.destroy_failed_jobs = false
-silence_warnings do
- Delayed::Job.const_set("MAX_ATTEMPTS", 1)
- Delayed::Job.const_set("MAX_RUN_TIME", 12.hours)
-end \ No newline at end of file
diff --git a/config/initializers/devise_async.rb b/config/initializers/devise_async.rb
index 3ee0a7858..10f4d98b6 100644
--- a/config/initializers/devise_async.rb
+++ b/config/initializers/devise_async.rb
@@ -1,2 +1,2 @@
-Devise::Async.backend = :delayed_job
+Devise::Async.backend = :sidekiq
Devise::Async.enabled = false # Set to true to use Delayed Job for asynchronous mail
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index d5492e529..472863fa8 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -5,8 +5,9 @@ SimpleForm.setup do |config|
# wrapper, change the order or even add your own to the
# stack. The options given below are used to wrap the
# whole input.
- config.wrappers :default, class: :input,
- hint_class: :field_with_hint, error_class: :field_with_errors do |b|
+ config.wrappers :default, class: 'form-group',
+ error_class: 'has-error' do |b|
+ # hint_class: :field_with_hint, error_class: :field_with_errors do |b|
## Extensions enabled by default
# Any of these extensions can be disabled for a
# given input by passing: `f.input EXTENSION_NAME => false`.
@@ -41,8 +42,8 @@ SimpleForm.setup do |config|
## Inputs
b.use :label_input
- b.use :hint, wrap_with: { tag: :span, class: :hint }
b.use :error, wrap_with: { tag: :span, class: :error }
+ b.use :hint, wrap_with: { tag: :span, class: :hint }
## full_messages_for
# If you want to display the full error message for the attribute, you can
@@ -72,7 +73,7 @@ SimpleForm.setup do |config|
config.error_notification_tag = :div
# CSS class to add for error notification helper.
- config.error_notification_class = 'error_notification'
+ config.error_notification_class = 'alert alert-error'
# ID to add for error notification helper.
# config.error_notification_id = nil
@@ -90,25 +91,24 @@ SimpleForm.setup do |config|
# config.collection_wrapper_class = nil
# You can wrap each item in a collection of radio/check boxes with a tag,
- # defaulting to :span. Please note that when using :boolean_style = :nested,
- # SimpleForm will force this option to be a label.
+ # defaulting to :span.
# config.item_wrapper_tag = :span
# You can define a class to use in all item wrappers. Defaulting to none.
# config.item_wrapper_class = nil
# How the label text should be generated altogether with the required text.
- # config.label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
+ config.label_text = lambda { |label, required, explicit_label| "#{label} #{required}" }
# You can define the class to use on all labels. Default is nil.
# config.label_class = nil
# You can define the default class to be used on forms. Can be overriden
# with `html: { :class }`. Defaulting to none.
- # config.default_form_class = nil
+ config.default_form_class = 'form'
# You can define which elements should obtain additional classes
- # config.generate_additional_classes_for = [:wrapper, :label, :input]
+ config.generate_additional_classes_for = [:label, :input]
# Whether attributes are required by default (or not). Default is true.
# config.required_by_default = true
diff --git a/config/initializers/simple_form_bootstrap.rb b/config/initializers/simple_form_bootstrap.rb
index 4f4dc23b3..be0f4bf55 100644
--- a/config/initializers/simple_form_bootstrap.rb
+++ b/config/initializers/simple_form_bootstrap.rb
@@ -14,8 +14,8 @@ SimpleForm.setup do |config|
b.use :label, class: 'control-label'
b.use :input, class: 'form-control'
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
config.wrappers :vertical_file_input, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
@@ -26,8 +26,8 @@ SimpleForm.setup do |config|
b.use :label, class: 'control-label'
b.use :input
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
config.wrappers :vertical_boolean, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
@@ -38,8 +38,8 @@ SimpleForm.setup do |config|
ba.use :label_input
end
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
config.wrappers :vertical_radio_and_checkboxes, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
@@ -47,8 +47,8 @@ SimpleForm.setup do |config|
b.optional :readonly
b.use :label, class: 'control-label'
b.use :input
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
config.wrappers :horizontal_form, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
@@ -62,8 +62,8 @@ SimpleForm.setup do |config|
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input, class: 'form-control'
- ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
end
@@ -76,8 +76,8 @@ SimpleForm.setup do |config|
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input
- ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
end
@@ -90,8 +90,8 @@ SimpleForm.setup do |config|
ba.use :label_input
end
- wr.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- wr.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ wr.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ wr.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
end
@@ -103,8 +103,8 @@ SimpleForm.setup do |config|
b.wrapper tag: 'div', class: 'col-sm-9' do |ba|
ba.use :input
- ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
end
@@ -118,45 +118,32 @@ SimpleForm.setup do |config|
b.use :label, class: 'sr-only'
b.use :input, class: 'form-control'
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ b.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ b.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
- config.wrappers :form_without_label, :tag => 'div', :class => 'form-group', :error_class => 'error' do |b|
-
+ config.wrappers :multi_select, tag: 'div', class: 'form-group', error_class: 'has-error' do |b|
b.use :html5
- b.use :placeholder
- b.optional :maxlength
- b.optional :pattern
- b.optional :min_max
b.optional :readonly
-
- b.wrapper tag: 'div', class: 'col-sm-12' do |ba|
+ b.use :label, class: 'control-label'
+ b.wrapper tag: 'div', class: 'form-inline' do |ba|
ba.use :input, class: 'form-control'
- ba.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- ba.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
+ ba.use :error, wrap_with: { tag: 'span', class: 'help-block small' }
+ ba.use :hint, wrap_with: { tag: 'p', class: 'help-block small' }
end
- end
-
- config.wrappers :nested, :tag => 'span', :error_class => 'has-error' do |b|
- b.use :html5
- b.use :placeholder
- b.optional :readonly
- b.use :input
- b.use :error, wrap_with: { tag: 'span', class: 'help-block' }
- b.use :hint, wrap_with: { tag: 'p', class: 'help-block' }
end
-
# Wrappers for forms and inputs using the Bootstrap toolkit.
# Check the Bootstrap docs (http://getbootstrap.com)
# to learn about the different styles for forms and inputs,
# buttons and other elements.
- config.default_wrapper = :horizontal_form
+ config.default_wrapper = :vertical_form
config.wrapper_mappings = {
check_boxes: :vertical_radio_and_checkboxes,
radio_buttons: :vertical_radio_and_checkboxes,
file: :vertical_file_input,
boolean: :vertical_boolean,
+ datetime: :multi_select,
+ date: :multi_select,
+ time: :multi_select
}
end
-
diff --git a/config/locales/directions.en.yml b/config/locales/directions.en.yml
index 575ffe90d..05bc29da3 100644
--- a/config/locales/directions.en.yml
+++ b/config/locales/directions.en.yml
@@ -3,7 +3,7 @@ en:
label:
straight_forward: "straight forward"
backward: "backward"
- clock_wise: "clockwise"
+ clockwise: "clockwise"
counter_clock_wise: "counterclockwise"
north: "north"
north_west: "north west"
diff --git a/config/locales/enumerize.en.yml b/config/locales/enumerize.en.yml
index 99e2edb75..aab0bcf32 100644
--- a/config/locales/enumerize.en.yml
+++ b/config/locales/enumerize.en.yml
@@ -33,3 +33,20 @@ en:
netex: "Experimental"
hub: "Specific Transdev Format"
kml: "line, route, ... drawings on Keyhole Markup Language format"
+ route:
+ direction:
+ straight_forward: 'Straight Forward'
+ backward: 'Backward'
+ clockwise: 'ClockWise'
+ counter_clockwise: 'Counter Clockwise'
+ north: 'North'
+ north_west: 'North West'
+ west: 'West'
+ south_west: 'South West'
+ south: 'South'
+ south_east: 'South East'
+ east: 'East'
+ north_east: 'North East'
+ wayback:
+ straight_forward: 'Straight Forward'
+ backward: 'Backward'
diff --git a/config/locales/enumerize.fr.yml b/config/locales/enumerize.fr.yml
index 4bfd71d28..b800521e3 100644
--- a/config/locales/enumerize.fr.yml
+++ b/config/locales/enumerize.fr.yml
@@ -1,6 +1,6 @@
fr:
- simple_form:
- include_blanks:
+ simple_form:
+ include_blanks:
defaults:
for_boarding: "Non défini"
for_alighting: "Non défini"
@@ -9,7 +9,7 @@ fr:
normal: "Montée autorisée"
forbidden: "Montée interdite"
request_stop: "Montée sur demande au conducteur"
- is_flexible: "Montée sur réservation"
+ is_flexible: "Montée sur réservation"
for_alighting:
normal: "Descente autorisée"
forbidden: "Descente interdite"
@@ -32,4 +32,21 @@ fr:
gtfs: "General Transit Feed Specification défini par Google"
netex: "Expérimental"
hub: "Format spécifique Transdev"
- kml: "Tracés de lignes, séquences d'arrêts, ... en 'Keyhole Markup Language'"
+ kml: "Tracés de lignes, séquences d'arrêts, ... en 'Keyhole Markup Language'"
+ route:
+ direction:
+ straight_forward: 'Aller'
+ backward: 'Retour'
+ clockwise: 'Sens horaire'
+ counter_clockwise: 'Sens anti horaire'
+ north: 'Nord'
+ north_west: 'Nord Ouest'
+ west: 'Ouest'
+ south_west: 'Sud Ouest'
+ south: 'Sud'
+ south_east: 'Sud Est'
+ east: 'Est'
+ north_east: 'Nord Est'
+ wayback:
+ straight_forward: 'Aller'
+ backward: 'Retour'
diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml
index 3691a8227..4609069c7 100644
--- a/config/locales/referentials.en.yml
+++ b/config/locales/referentials.en.yml
@@ -24,6 +24,7 @@ en:
destroy_confirm: "Do you confirm to destroy this data space ?"
destroy: "Destroy this data space"
edit: "Edit this data space"
+ clone: "Clone this data space"
errors:
pg_excluded: "can't begins with pg_"
public_excluded: "public is a reserved value"
@@ -81,4 +82,4 @@ en:
notice:
referential:
archived: "The data space has been successfully archived"
- unarchived: "The data space has been successfully unarchived" \ No newline at end of file
+ unarchived: "The data space has been successfully unarchived"
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index cada9c3a0..18ef4e8da 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -24,6 +24,7 @@ fr:
destroy_confirm: "Etes vous sûr de vouloir supprimer cet espace de données ?"
destroy: "Supprimer cet espace de données"
edit: "Modifier cet espace de données"
+ clone: "Cloner cet espace de données"
errors:
pg_excluded: "ne peut pas commencer par pg_ (valeurs réservées)"
public_excluded: "public est une valeur réservée"
diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml
index a3a26cb8c..b78feff0f 100644
--- a/config/locales/routes.en.yml
+++ b/config/locales/routes.en.yml
@@ -18,8 +18,8 @@ en:
title: "Update route %{route}"
show:
title: "Route %{route}"
- stop_points: "Stop point on route list"
- journey_patterns: "Route journey patterns list"
+ stop_points: "Stop point on route list"
+ journey_patterns: "Route journey patterns list"
no_opposite_route: "No reversed route associated"
undefined: "Undefined"
index:
@@ -33,37 +33,37 @@ en:
for_alighting: "Alighting"
route:
no_journey_pattern: "No Journey pattern"
- wayback:
+ wayback:
positive: "forward"
negative: "backward"
opposite: "Opposite route"
no_opposite: "No opposite route"
- activerecord:
- models:
- route:
+ activerecord:
+ models:
+ route:
zero: "route"
one: "route"
other: "routes"
attributes:
route:
- wayback:
+ wayback:
positive: "forward"
negative: "backward"
line: "Line"
vehicle_journeys: "Vehicle journeys"
journey_patterns: "Journey patterns"
name: "Name"
- published_name: "Published name"
+ published_name: "Published name"
comment: "Comments"
number: "Number"
- direction_code: "Direction"
- wayback_code: "Wayback"
+ direction: "Direction"
+ wayback: "Wayback"
opposite_route: "Reversed route"
objectid: "Neptune identifier"
object_version: "Version"
creation_time: "Created on"
creator_id: "Created by"
- no_journey_pattern: "No journey pattern"
+ no_journey_pattern: "No journey pattern"
formtastic:
titles:
route:
diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml
index ea190e6e2..f80693b8b 100644
--- a/config/locales/routes.fr.yml
+++ b/config/locales/routes.fr.yml
@@ -56,8 +56,8 @@ fr:
published_name: "Nom public"
number: "Indice"
comment: "Commentaire"
- direction_code: "Direction"
- wayback_code: "Sens"
+ direction: "Direction"
+ wayback: "Sens"
opposite_route: "Séquence d'arrêts associée en sens opposé"
objectid: "Identifiant Neptune"
object_version: "Version"
diff --git a/db/migrate/20120516172252_create_delayed_jobs.rb b/db/migrate/20120516172252_create_delayed_jobs.rb
deleted file mode 100644
index e7841608c..000000000
--- a/db/migrate/20120516172252_create_delayed_jobs.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-class CreateDelayedJobs < ActiveRecord::Migration
- def self.up
- create_table :delayed_jobs, :force => true do |table|
- table.integer :priority, :default => 0 # Allows some jobs to jump to the front of the queue
- table.integer :attempts, :default => 0 # Provides for retries, but still fail eventually.
- table.text :handler # YAML-encoded string of the object that will do work
- table.text :last_error # reason for last failure (See Note below)
- table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future.
- table.datetime :locked_at # Set when a client is working on this object
- table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead)
- table.string :locked_by # Who is working on this object (if locked)
- table.string :queue # The name of the queue this job is in
- table.timestamps
- end
-
- add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
- end
-
- def self.down
- drop_table :delayed_jobs
- end
-end
diff --git a/db/migrate/20161109160857_add_organisation_code_index.rb b/db/migrate/20161109160857_add_organisation_code_index.rb
new file mode 100644
index 000000000..89d9e67c2
--- /dev/null
+++ b/db/migrate/20161109160857_add_organisation_code_index.rb
@@ -0,0 +1,5 @@
+class AddOrganisationCodeIndex < ActiveRecord::Migration
+ def change
+ add_index :organisations, :code, unique: true
+ end
+end
diff --git a/db/migrate/20161114134518_create_clean_ups.rb b/db/migrate/20161114134518_create_clean_ups.rb
new file mode 100644
index 000000000..3fa60d484
--- /dev/null
+++ b/db/migrate/20161114134518_create_clean_ups.rb
@@ -0,0 +1,18 @@
+class CreateCleanUps < ActiveRecord::Migration
+ def change
+ create_table :clean_ups do |t|
+ t.string :status
+ t.datetime :started_at
+ t.datetime :ended_at
+ t.references :referential, index: true
+ t.boolean :keep_lines
+ t.boolean :keep_stops
+ t.boolean :keep_companies
+ t.boolean :keep_networks
+ t.boolean :keep_group_of_lines
+ t.datetime :expected_date
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 3e877de49..2b682eb19 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: 20161024135931) do
+ActiveRecord::Schema.define(version: 20161114134518) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -77,6 +77,23 @@ ActiveRecord::Schema.define(version: 20161024135931) do
t.datetime "updated_at"
end
+ create_table "clean_ups", force: true do |t|
+ t.string "status"
+ t.datetime "started_at"
+ t.datetime "ended_at"
+ t.integer "referential_id"
+ t.boolean "keep_lines"
+ t.boolean "keep_stops"
+ t.boolean "keep_companies"
+ t.boolean "keep_networks"
+ t.boolean "keep_group_of_lines"
+ t.datetime "expected_date"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
+ add_index "clean_ups", ["referential_id"], :name => "index_clean_ups_on_referential_id"
+
create_table "companies", force: true do |t|
t.string "objectid", null: false
t.integer "object_version"
@@ -362,6 +379,8 @@ ActiveRecord::Schema.define(version: 20161024135931) do
t.hstore "sso_attributes"
end
+ add_index "organisations", ["code"], :name => "index_organisations_on_code", :unique => true
+
create_table "pt_links", force: true do |t|
t.integer "start_of_link_id", limit: 8
t.integer "end_of_link_id", limit: 8
@@ -721,8 +740,6 @@ ActiveRecord::Schema.define(version: 20161024135931) do
add_index "workbenches", ["stop_area_referential_id"], :name => "index_workbenches_on_stop_area_referential_id"
Foreigner.load
- add_foreign_key "access_links", "access_points", name: "aclk_acpt_fkey", dependent: :delete
-
add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", dependent: :delete
add_foreign_key "journey_frequencies", "timebands", name: "journey_frequencies_timeband_id_fk", dependent: :nullify
diff --git a/lib/stif/my_workbench_scopes.rb b/lib/stif/my_workbench_scopes.rb
new file mode 100644
index 000000000..89c4e659c
--- /dev/null
+++ b/lib/stif/my_workbench_scopes.rb
@@ -0,0 +1,23 @@
+module Stif
+ class MyWorkbenchScopes
+ attr_accessor :workbench
+
+ def initialize(workbench)
+ @workbench = workbench
+ end
+
+ def line_scope(initial_scope)
+ ids = self.parse_functional_scope
+ ids ? initial_scope.where(objectid: ids) : initial_scope
+ end
+
+ def parse_functional_scope
+ return false unless @workbench.organisation.sso_attributes
+ begin
+ JSON.parse @workbench.organisation.sso_attributes['functional_scope']
+ rescue Exception => e
+ Rails.logger.error "MyWorkbenchScopes : #{e}"
+ end
+ end
+ end
+end
diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake
index 7fca878b6..2b584c08b 100644
--- a/lib/tasks/ci.rake
+++ b/lib/tasks/ci.rake
@@ -3,6 +3,7 @@ namespace :ci do
task :setup do
cp "config/database/jenkins.yml", "config/database.yml"
sh "RAILS_ENV=test rake db:migrate"
+ sh "npm install"
end
def git_branch
diff --git a/package.json b/package.json
new file mode 100644
index 000000000..99c7916c1
--- /dev/null
+++ b/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "something",
+ "dependencies": {
+ "babel-polyfill": "^6.16.0",
+ "babel-preset-es2015": "^6.18.0",
+ "babel-preset-react": "^6.16.0",
+ "babelify": "^7.3.0",
+ "browserify": "^13.1.1",
+ "browserify-incremental": "^3.1.1",
+ "react": "^15.3.2",
+ "react-dom": "^15.3.2",
+ "react-redux": "^4.4.5",
+ "react-select2": "^4.0.2",
+ "redux": "^3.6.0"
+ },
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+}
diff --git a/script/delayed_job b/script/delayed_job
deleted file mode 100755
index edf195985..000000000
--- a/script/delayed_job
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env ruby
-
-require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
-require 'delayed/command'
-Delayed::Command.new(ARGV).daemonize
diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb
index 047c35912..e872d24f5 100644
--- a/spec/factories/chouette_routes.rb
+++ b/spec/factories/chouette_routes.rb
@@ -4,23 +4,23 @@ FactoryGirl.define do
sequence(:name) { |n| "Route #{n}" }
sequence(:published_name) { |n| "Long route #{n}" }
sequence(:number) { |n| "#{n}" }
- sequence(:wayback_code) { |n| Chouette::Wayback.new( n % 2) }
- sequence(:direction_code) { |n| Chouette::Direction.new( n % 12) }
+ sequence(:wayback) { |n| Chouette::Route.wayback.values[n % 2] }
+ sequence(:direction) { |n| Chouette::Route.direction.values[n % 12] }
sequence(:objectid) { |n| "test:Route:#{n}" }
-
+
association :line, :factory => :line
-
+
factory :route do
transient do
stop_points_count 5
end
-
+
after(:create) do |route, evaluator|
create_list(:stop_point, evaluator.stop_points_count, route: route)
end
-
+
end
end
-
+
end
diff --git a/spec/factories/clean_ups.rb b/spec/factories/clean_ups.rb
new file mode 100644
index 000000000..41165ac16
--- /dev/null
+++ b/spec/factories/clean_ups.rb
@@ -0,0 +1,15 @@
+FactoryGirl.define do
+ factory :clean_up do
+ status "MyString"
+started_at "2016-11-14 14:45:18"
+ended_at "2016-11-14 14:45:18"
+referential nil
+keep_lines false
+keep_stops false
+keep_companies false
+keep_networks false
+keep_group_of_lines false
+expected_date "2016-11-14 14:45:18"
+ end
+
+end
diff --git a/spec/features/access_points_spec.rb b/spec/features/access_points_spec.rb
index a78545ee4..327c5879a 100644
--- a/spec/features/access_points_spec.rb
+++ b/spec/features/access_points_spec.rb
@@ -40,24 +40,25 @@ describe "Access points", :type => :feature do
end
- describe "new" do
- it "creates an access point" do
- visit referential_stop_area_path(referential, stop_area)
- click_link I18n.t("access_points.actions.new")
- fill_in "access_point[name]", :with => "My Access Point Name"
- click_button(I18n.t('formtastic.create',model: I18n.t('activerecord.models.access_point.one')))
- expect(page).to have_content("My Access Point Name")
- end
- end
+ # Fixme #1780
+ # describe "new" do
+ # it "creates an access point" do
+ # visit referential_stop_area_path(referential, stop_area)
+ # click_link I18n.t("access_points.actions.new")
+ # fill_in "access_point[name]", :with => "My Access Point Name"
+ # click_button(I18n.t('formtastic.create',model: I18n.t('activerecord.models.access_point.one')))
+ # expect(page).to have_content("My Access Point Name")
+ # end
+ # end
- describe "edit" do
- it "edits an acess point" do
- visit referential_stop_area_access_point_path(referential, stop_area, subject)
- click_link I18n.t("access_points.actions.edit")
- fill_in "access_point[name]", :with => "My New Access Point Name"
- click_button(I18n.t('formtastic.update',model: I18n.t('activerecord.models.access_point.one')))
- expect(page).to have_content("My New Access Point Name")
- end
- end
+ # describe "edit" do
+ # it "edits an acess point" do
+ # visit referential_stop_area_access_point_path(referential, stop_area, subject)
+ # click_link I18n.t("access_points.actions.edit")
+ # fill_in "access_point[name]", :with => "My New Access Point Name"
+ # click_button(I18n.t('formtastic.update',model: I18n.t('activerecord.models.access_point.one')))
+ # expect(page).to have_content("My New Access Point Name")
+ # end
+ # end
end
diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb
index c50ff50bc..e76665b31 100644
--- a/spec/features/routes_spec.rb
+++ b/spec/features/routes_spec.rb
@@ -34,46 +34,13 @@ describe "Routes", :type => :feature do
click_link "Ajouter une séquence d'arrêts"
fill_in "route_name", :with => "A to B"
fill_in "Indice", :with => "AB"
- select 'aller', :from => "route_direction_code"
- select 'aller', :from => "route_wayback_code"
- click_button("Créer séquence d'arrêts")
+ select 'Aller', :from => "route_direction"
+ select 'Aller', :from => "route_wayback"
+ click_button("Créer un(e) séquence d'arrêts")
expect(page).to have_content("A to B")
end
end
- describe "from line's page, select a route and edit it" do
- it "return to line's page with changed name" do
- visit referential_line_path(referential,line)
- click_link "#{route.name}"
- click_link "Modifier cette séquence d'arrêts"
- fill_in "route_name", :with => "#{route.name}-changed"
- click_button("Modifier séquence d'arrêts")
- expect(page).to have_content("#{route.name}-changed")
- end
- end
-
- describe "from line's page, select a route and delete it" do
- it "return to line's page without route name" do
- visit referential_line_path(referential,line)
- click_link "#{route.name}"
- click_link "Supprimer cette séquence d'arrêts"
- expect(page).not_to have_content(route.name)
- end
- end
-
- describe "from route's page, select edit boarding/alighting and update it" do
- it "Edits boarding/alighting properties on route stops" do
- visit referential_line_route_path(referential, line, route)
- click_link I18n.t('routes.actions.edit_boarding_alighting')
- expect(page).to have_content(I18n.t('routes.edit_boarding_alighting.title'))
- stop_points.each do |sp|
- expect(page).to have_content(sp.stop_area.name)
- expect(page).to have_content(sp.for_boarding)
- expect(page).to have_content(sp.for_alighting)
- end
- end
- end
-
describe "Modifies boarding/alighting properties on route stops" do
it "Puts (http) an update request" do
#visit edit_boarding_alighting_referential_line_route_path(referential, line, route)
diff --git a/spec/features/stop_points_spec.rb b/spec/features/stop_points_spec.rb
index 34548f3dc..18cd97709 100644
--- a/spec/features/stop_points_spec.rb
+++ b/spec/features/stop_points_spec.rb
@@ -11,13 +11,13 @@ describe "StopPoints", :type => :feature do
describe "from route's page to a stop points page" do
it "display route's stop points" do
visit referential_line_route_path(referential,line,route)
- click_link "Liste des arrêts de la séquence d'arrêts"
+ #click_link "Liste des arrêts de la séquence d'arrêts"
route.stop_areas.each do |sa|
expect(page).to have_content(sa.name)
end
end
end
-
+
describe "from route's page, go to new stop point page" do
it "display route's stop points" do
visit referential_line_route_path(referential,line,route)
diff --git a/spec/models/chouette/route_spec.rb b/spec/models/chouette/route_spec.rb
index 1acc5a0f7..0392485d8 100644
--- a/spec/models/chouette/route_spec.rb
+++ b/spec/models/chouette/route_spec.rb
@@ -3,17 +3,21 @@ require 'spec_helper'
describe Chouette::Route, :type => :model do
subject { create(:route) }
- it { is_expected.to validate_uniqueness_of :objectid }
-
describe '#objectid' do
subject { super().objectid }
it { is_expected.to be_kind_of(Chouette::ObjectId) }
end
+ it { is_expected.to enumerize(:direction).in(:straight_forward, :backward, :clockwise, :counter_clockwise, :north, :north_west, :west, :south_west, :south, :south_east, :east, :north_east) }
+ it { is_expected.to enumerize(:wayback).in(:straight_forward, :backward) }
+
#it { is_expected.to validate_presence_of :name }
it { is_expected.to validate_presence_of :line }
+ it { is_expected.to validate_uniqueness_of :objectid }
#it { is_expected.to validate_presence_of :wayback_code }
#it { is_expected.to validate_presence_of :direction_code }
+ it { is_expected.to validate_inclusion_of(:direction).in_array(%i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)) }
+ it { is_expected.to validate_inclusion_of(:wayback).in_array(%i(straight_forward backward)) }
context "reordering methods" do
let( :bad_stop_point_ids){subject.stop_points.map { |sp| sp.id + 1}}
@@ -165,74 +169,4 @@ describe Chouette::Route, :type => :model do
end
end
end
-
- describe "#direction_code" do
- def self.legacy_directions
- %w{A R ClockWise CounterClockWise North NorthWest West SouthWest
- South SouthEast East NorthEast}
- end
- legacy_directions.each do |direction|
- context "when direction is #{direction}" do
- direction_code = Chouette::Direction.new( Chouette::Route.direction_binding[ direction])
- it "should be #{direction_code}" do
- subject.direction = direction
- expect(subject.direction_code).to eq(direction_code)
- end
- end
- end
- context "when direction is nil" do
- it "should be nil" do
- subject.direction = nil
- expect(subject.direction_code).to be_nil
- end
- end
- end
- describe "#direction_code=" do
- context "when unknown direction is provided" do
- it "should change direction to nil" do
- subject.direction_code = "dummy"
- expect(subject.direction).to be_nil
- end
- end
- context "when an existing direction (west) is provided" do
- it "should change direction Direction.west" do
- subject.direction_code = "west"
- expect(subject.direction).to eq("West")
- end
- end
- end
- describe "#wayback_code" do
- def self.legacy_waybacks
- %w{A R}
- end
- legacy_waybacks.each do |wayback|
- context "when wayback is #{wayback}" do
- wayback_code = Chouette::Wayback.new( Chouette::Route.wayback_binding[ wayback])
- it "should be #{wayback_code}" do
- subject.wayback = wayback
- expect(subject.wayback_code).to eq(wayback_code)
- end
- end
- end
- context "when wayback is nil" do
- it "should be nil" do
- subject.wayback = nil
- expect(subject.wayback_code).to be_nil
- end
- end
- end
- describe "#wayback_code=" do
- context "when unknown wayback is provided" do
- it "should change wayback to nil" do
- subject.wayback_code = "dummy"
- expect(subject.wayback).to be_nil
- end
- end
- context "when an existing wayback (straight_forward) is provided" do
- it "should change wayback Wayback.straight_forward" do
- subject.wayback_code = "straight_forward"
- expect(subject.wayback).to eq("A")
- end
- end
- end
end
diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb
new file mode 100644
index 000000000..e603b09b0
--- /dev/null
+++ b/spec/models/clean_up_spec.rb
@@ -0,0 +1,58 @@
+require 'rails_helper'
+
+RSpec.describe CleanUp, :type => :model do
+ let(:cleaner) { CleanUp.new }
+
+ it { should validate_presence_of(:expected_date) }
+ it { should belong_to(:referential) }
+
+ it 'should convert initialize attribute to boolean' do
+ params = { keep_lines: "0", keep_stops: "1" }
+ cleaner = CleanUp.new(params)
+ expect(cleaner.keep_lines).to eq false
+ expect(cleaner.keep_stops).to eq true
+ end
+
+ it 'should delete group of line without lines' do
+ create_list(:group_of_line, 2)
+ create_list(:line, 2, group_of_lines: [create(:group_of_line)])
+ expect(cleaner.clean_group_of_lines).to eq 2
+ end
+
+ it 'should delete company without lines' do
+ create_list(:company, 2)
+ create_list(:line, 2)
+ expect(cleaner.clean_companies).to eq 2
+ end
+
+ it 'should delete physical stop_areas without stop_points' do
+ create_list(:stop_area, 2)
+ create_list(:stop_point, 2)
+ Chouette::StopArea.update_all(area_type: "Quay")
+ expect(cleaner.clean_physical_stop_areas).to eq 2
+ end
+
+ it 'should delete vehiclejourneys without timetables' do
+ create_list(:vehicle_journey, 2)
+ create_list(:vehicle_journey, 2, time_tables:[create(:time_table)])
+ expect(cleaner.clean_vehicle_journeys).to eq 2
+ end
+
+ it 'should delete lines without routes' do
+ create_list(:line, 2)
+ create_list(:route, 2, line: create(:line))
+ expect(cleaner.clean_lines).to eq 2
+ end
+
+ it 'should delete routes without journeypatterns' do
+ create_list(:route, 2)
+ create_list(:journey_pattern, 2, route: create(:route))
+ expect(cleaner.clean_routes).to eq 2
+ end
+
+ it 'should delete journeypatterns without vehicle journeys' do
+ create_list(:journey_pattern, 2)
+ create_list(:vehicle_journey, 2, journey_pattern: create(:journey_pattern))
+ expect(cleaner.clean_journey_patterns).to eq 2
+ end
+end
diff --git a/spec/models/line_referential_spec.rb b/spec/models/line_referential_spec.rb
index 02838a4a7..942795076 100644
--- a/spec/models/line_referential_spec.rb
+++ b/spec/models/line_referential_spec.rb
@@ -9,4 +9,10 @@ RSpec.describe LineReferential, :type => :model do
it { is_expected.to have_many(:line_referential_syncs) }
it { is_expected.to have_many(:workbenches) }
it { should validate_presence_of(:sync_interval) }
+
+ describe "#transport_modes" do
+ it 'returns a list of all transport modes' do
+ expect(FactoryGirl.create(:line_referential).transport_modes).to eq( Chouette::TransportMode.all.select { |tm| tm.positive? } )
+ end
+ end
end
diff --git a/spec/models/organisation_spec.rb b/spec/models/organisation_spec.rb
index c0aba2eb8..9b4235755 100644
--- a/spec/models/organisation_spec.rb
+++ b/spec/models/organisation_spec.rb
@@ -1,9 +1,8 @@
require 'spec_helper'
describe Organisation, :type => :model do
-
it { should validate_presence_of(:name) }
- it { should validate_uniqueness_of(:name) }
+ it { should validate_uniqueness_of(:code) }
it 'should have a valid factory' do
expect(FactoryGirl.build(:organisation)).to be_valid
@@ -36,17 +35,17 @@ describe Organisation, :type => :model do
it 'should retrieve functional scope' do
Organisation.portail_sync
org = Organisation.find_by(code: 'RATP')
- expect(org.sso_attributes['functional_scope']).to eq "[STIF:CODIFLIGNE:Line:C00840, STIF:CODIFLIGNE:Line:C00086]"
+ expect(org.sso_attributes['functional_scope']).to eq "[\"STIF:CODIFLIGNE:Line:C00840\", \"STIF:CODIFLIGNE:Line:C00086\"]"
end
it 'should update existing organisations' do
- create :organisation, name: 'dummy_name', code:'RATP', updated_at: 10.days.ago
+ create :organisation, name: 'dummy_name', code:'RATP', updated_at: 10.days.ago, sso_attributes: {functional_scope: "[\"STIF:CODIFLIGNE:Line:C00840\"]"}
Organisation.portail_sync
- Organisation.find_by(code: 'RATP').tap do |org|
- expect(org.name).to eq('RATP')
- expect(org.updated_at.utc).to be_within(1.second).of Time.now
- expect(org.synced_at.utc).to be_within(1.second).of Time.now
- end
+ org = Organisation.find_by(code: 'RATP')
+ expect(org.name).to eq('RATP')
+ expect(org.updated_at.utc).to be_within(1.second).of Time.now
+ expect(org.synced_at.utc).to be_within(1.second).of Time.now
+ expect(org.sso_attributes['functional_scope']).to eq "[\"STIF:CODIFLIGNE:Line:C00840\", \"STIF:CODIFLIGNE:Line:C00086\"]"
end
it 'should not create organisation if code is already present' do
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index c20e80ca1..7d0a548c1 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -36,7 +36,14 @@ describe User, :type => :model do
it 'should store organisation functional_scope' do
User.authenticate_with_cas_ticket(ticket)
org = Organisation.find_by(code: ticket.extra_attributes[:organisation_code])
- expect(org.sso_attributes['functional_scope']).to eq "[STIF:CODIFLIGNE:Line:C00840, STIF:CODIFLIGNE:Line:C00086]"
+ expect(org.sso_attributes['functional_scope']).to eq "[\"STIF:CODIFLIGNE:Line:C00840\", \"STIF:CODIFLIGNE:Line:C00086\"]"
+ end
+
+ it 'should update organisation functional_scope' do
+ create :organisation, code: ticket.extra_attributes[:organisation_code], sso_attributes: {functional_scope: "[\"STIF:CODIFLIGNE:Line:C00840\"]"}
+ User.authenticate_with_cas_ticket(ticket)
+ org = Organisation.find_by(code: ticket.extra_attributes[:organisation_code])
+ expect(org.sso_attributes['functional_scope']).to eq "[\"STIF:CODIFLIGNE:Line:C00840\", \"STIF:CODIFLIGNE:Line:C00086\"]"
end
it 'should not create a new organisation if organisation is already present' do
diff --git a/spec/models/workbench_spec.rb b/spec/models/workbench_spec.rb
index 023a65ea2..84149ddb0 100644
--- a/spec/models/workbench_spec.rb
+++ b/spec/models/workbench_spec.rb
@@ -1,7 +1,6 @@
require 'rails_helper'
RSpec.describe Workbench, :type => :model do
-
it 'should have a valid factory' do
expect(FactoryGirl.build(:workbench)).to be_valid
end
@@ -12,4 +11,26 @@ RSpec.describe Workbench, :type => :model do
it { should belong_to(:organisation) }
it { should belong_to(:line_referential) }
it { should belong_to(:stop_area_referential) }
+
+ it { should have_many(:lines).through(:line_referential) }
+ it { should have_many(:networks).through(:line_referential) }
+ it { should have_many(:companies).through(:line_referential) }
+ it { should have_many(:group_of_lines).through(:line_referential) }
+
+ it { should have_many(:stop_areas).through(:stop_area_referential) }
+
+ context '.lines' do
+ let!(:ids) { ['STIF:CODIFLIGNE:Line:C00840', 'STIF:CODIFLIGNE:Line:C00086'] }
+ let!(:organisation) { create :organisation, sso_attributes: { functional_scope: ids.to_json } }
+ let(:workbench) { create :workbench, organisation: organisation }
+
+ it 'should filter lines based on my organisation functional_scope' do
+ ids.insert('STIF:CODIFLIGNE:Line:0000').each do |id|
+ create :line, objectid: id, line_referential: workbench.line_referential
+ end
+ lines = workbench.lines
+ expect(lines.count).to eq 2
+ expect(lines.map(&:objectid)).to include(*ids)
+ end
+ end
end
diff --git a/spec/views/vehicle_journeys/_form.html.erb_spec.rb b/spec/views/vehicle_journeys/_form.html.erb_spec.rb
index 05fa068d9..af32406b8 100644
--- a/spec/views/vehicle_journeys/_form.html.erb_spec.rb
+++ b/spec/views/vehicle_journeys/_form.html.erb_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe "/vehicle_journeys/_form", :type => :view do
-
+
assign_referential
let!(:line) { assign :line, create(:line) }
let!(:route) { assign :route, create(:route, :line => line) }
@@ -14,7 +14,7 @@ describe "/vehicle_journeys/_form", :type => :view do
route,
vehicle_journey) }
expect(rendered).to have_selector( "select#vehicle_journey_transport_mode_name") do |node|
- Chouette::Line.transport_modes.each do |mode|
+ line.transport_modes.each do |mode|
expect(node).to have_selector("option", :text => mode.text_code)
end
end
@@ -26,7 +26,7 @@ describe "/vehicle_journeys/_form", :type => :view do
line,
route,
vehicle_journey) }
- expect(rendered).to have_selector("form") do
+ expect(rendered).to have_selector("form") do
with_selector "input[type=text][comment=]", vehicle_journey.comment
end
end
@@ -37,7 +37,7 @@ describe "/vehicle_journeys/_form", :type => :view do
line,
route,
vehicle_journey) }
- expect(rendered).to have_selector("form") do |form_node|
+ expect(rendered).to have_selector("form") do |form_node|
vehicle_journey.stop_points.each do |sp|
form_node.with_selector "label", :text => sp.stop_area.name
end
@@ -51,14 +51,14 @@ describe "/vehicle_journeys/_form", :type => :view do
vehicle_journey) }
expect(view).to render_template(:partial => "_vehicle_journey_at_stop_fields", :count => vehicle_journey.vehicle_journey_at_stops.count)
end
-
+
it "should render vehicle_journey_at_stop's departure time" do
render partial: 'vehicle_journeys/form',
locals: { vehicle_journey: vehicle_journey, form_url: referential_line_route_vehicle_journeys_path(referential,
line,
route,
vehicle_journey) }
- expect(rendered).to have_selector("form") do |form_node|
+ expect(rendered).to have_selector("form") do |form_node|
vehicle_journey.stop_points.each_with_index do |sp, index|
form_node.with_selector "select", :name => "vehicle_journey[vehicle_journey_at_stops_attributes][#{index}][departure_time(4i)]"
form_node.with_selector "select", :name => "vehicle_journey[vehicle_journey_at_stops_attributes][#{index}][departure_time(5i)]"
@@ -73,7 +73,7 @@ describe "/vehicle_journeys/_form", :type => :view do
line,
route,
vehicle_journey) }
- expect(rendered).to have_selector("form") do
+ expect(rendered).to have_selector("form") do
with_selector "input[type=text][objectid=][disabled=true]", vehicle_journey.objectid
end
end
@@ -86,7 +86,7 @@ describe "/vehicle_journeys/_form", :type => :view do
line,
route,
vehicle_journey) }
- expect(rendered).to have_selector("form") do
+ expect(rendered).to have_selector("form") do
with_selector "input[type=text][objectid=][disabled=false]", vehicle_journey.objectid
end
end
diff --git a/spec/workers/clean_up_worker_spec.rb b/spec/workers/clean_up_worker_spec.rb
new file mode 100644
index 000000000..e85768fa3
--- /dev/null
+++ b/spec/workers/clean_up_worker_spec.rb
@@ -0,0 +1,4 @@
+require 'rails_helper'
+RSpec.describe CleanUpWorker, type: :worker do
+ pending "add some examples to (or delete) #{__FILE__}"
+end