aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Gemfile4
-rw-r--r--Gemfile.lock8
-rw-r--r--app/assets/javascripts/es6_browserified/actions/index.js33
-rw-r--r--app/assets/javascripts/es6_browserified/components/App.js12
-rw-r--r--app/assets/javascripts/es6_browserified/components/BSelect2.js96
-rw-r--r--app/assets/javascripts/es6_browserified/components/Todo.js62
-rw-r--r--app/assets/javascripts/es6_browserified/components/TodoList.js37
-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/reducers/index.js8
-rw-r--r--app/assets/javascripts/es6_browserified/reducers/todos.js63
-rw-r--r--app/assets/javascripts/es6_browserified/stop_points.js48
-rw-r--r--app/assets/stylesheets/application.sass.erb3
-rw-r--r--app/assets/stylesheets/vendor/select2-bootstrap.css721
-rw-r--r--app/assets/stylesheets/vendor/select2.css484
-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/stop_areas_controller.rb1
-rw-r--r--app/models/organisation.rb26
-rw-r--r--app/models/referential.rb23
-rw-r--r--app/models/user.rb41
-rw-r--r--app/models/workbench.rb6
-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/_line.html.slim8
-rw-r--r--app/views/referential_lines/index.html.slim28
-rw-r--r--app/views/referential_lines/show.html.slim22
-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.slim1
-rw-r--r--app/views/routes/_form.html.slim53
-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/shared/_header.html.slim8
-rw-r--r--config/application.rb3
-rw-r--r--config/deploy.rb5
-rw-r--r--config/initializers/assets.rb2
-rw-r--r--config/initializers/simple_form.rb18
-rw-r--r--config/initializers/simple_form_bootstrap.rb67
-rw-r--r--config/locales/referentials.en.yml3
-rw-r--r--config/locales/referentials.fr.yml1
-rw-r--r--lib/stif/my_workbench_scopes.rb23
-rw-r--r--lib/tasks/ci.rake1
-rw-r--r--package.json20
-rw-r--r--spec/features/access_points_spec.rb37
-rw-r--r--spec/features/routes_spec.rb33
-rw-r--r--spec/models/organisation_spec.rb2
-rw-r--r--spec/models/user_spec.rb2
-rw-r--r--spec/models/workbench_spec.rb23
62 files changed, 2062 insertions, 287 deletions
diff --git a/.gitignore b/.gitignore
index b6a61fd27..762c156eb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,3 +30,5 @@ coverage
.idea
bin/
+# Ignore node modules
+/node_modules
diff --git a/Gemfile b/Gemfile
index ed8cb52ff..aab237513 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
@@ -125,6 +128,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..a3ede77d1 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -90,6 +90,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 +103,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)
@@ -574,9 +578,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!
@@ -674,4 +680,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..8967c0322
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/actions/index.js
@@ -0,0 +1,33 @@
+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) => {
+ console.log('action',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..7e4782563
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/BSelect2.js
@@ -0,0 +1,96 @@
+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) {
+ console.log(e.currentTarget.value, e.currentTarget.textContent)
+ this.props.onChange(this.props.index, {text: e.currentTarget.textContent, id: e.currentTarget.value})
+ this.setState({edit: false})
+ }
+ render() {
+ if(this.state.edit)
+ return (
+ <div>
+ <BSelect2 {...this.props} onSelect={ this.onChange.bind(this) }/>
+ </div>
+ )
+ else
+ return (
+ <div>
+ <span
+ title="Cliquez pour changer l'arrêt"
+ style={{cursor: 'pointer', display: 'block'}}
+ onClick={this.onToggleEdit.bind(this)}
+ >
+ {this.props.value.text}
+ </span>
+ </div>
+ )
+ }
+}
+
+const BSelect2 = (props) => {
+ return (
+ <Select2
+ value={props.value.id}
+ onSelect={ props.onSelect }
+ options={{
+ placeholder: 'Sélectionnez un arrêt existant...',
+ theme: 'bootstrap',
+ 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
+ }}
+ />
+ )
+}
+
+// to fix: this is for custom results return
+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..0e74e728f
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/Todo.js
@@ -0,0 +1,62 @@
+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: '150px', textAlign: 'right'}
+
+const Todo = (props) => {
+ return (
+ <div className='list-group-item' style={Container}>
+ <div style={firstBlock}>
+ <div style={{display: 'inline-block', width: '9%', verticalAlign: 'middle'}}>
+ <span className='strong'>#{props.index}</span>
+ </div>
+
+ <div style={{display: 'inline-block', width: '91%', verticalAlign: 'middle'}}>
+ <BSelect2 id={'route_stop_points_' + props.id} value={props.value} onChange={props.onChange} index={props.index} defaultData={props.defaultData}/>
+ </div>
+ </div>
+
+ <div style={secondBlock}>
+ <div className='btn-group btn-group-sm'>
+ <div className='btn btn-default'>
+ <span className='fa fa-times'></span>
+ </div>
+ <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,
+ defaultData: PropTypes.array
+}
+
+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..367cfc256
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/components/TodoList.js
@@ -0,0 +1,37 @@
+var React = require('react')
+var PropTypes = require('react').PropTypes
+var Todo = require('./Todo')
+
+const TodoList = ({ todos, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange }) => {
+ console.log(todos)
+ return (
+ <div className='list-group'>
+ {todos.map((todo, index) =>
+ <Todo
+ key={'item-' + index}
+ onDeleteClick={() => onDeleteClick(index)}
+ onMoveUpClick={() => {
+ console.log(index, todos)
+ onMoveUpClick(index)}
+ }
+ onMoveDownClick={() => onMoveDownClick(index)}
+ onChange={ onChange }
+ first={ index === 0 }
+ last={ index === (todos.length - 1) }
+ index={ index }
+ defaultData={ todos }
+ 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/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..bf64632bd
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/reducers/todos.js
@@ -0,0 +1,63 @@
+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, id: action.text.id}
+ )
+ default:
+ return state
+ }
+}
+
+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':
+ 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..9c0195f2b
--- /dev/null
+++ b/app/assets/javascripts/es6_browserified/stop_points.js
@@ -0,0 +1,48 @@
+var React = require('react')
+var render = require('react-dom').render
+var Provider = require('react-redux').Provider
+var createStore = require('redux').createStore
+// var 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')
+
+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({
+ id: value.id,
+ name: value.name,
+ city_name: value.city_name,
+ zip_code: value.zip_code,
+ text: fancyText
+ })
+ }
+ // console.log(state)
+ return state
+}
+
+var initialState = {todos: getInitialState()}
+// const loggerMiddleware = createLogger()
+let store = createStore(
+ todoApp,
+ initialState
+ // applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+)
+
+// console.log(store.getState())
+
+render(
+ <Provider store={store}>
+ <App />
+ </Provider>,
+ document.getElementById('stop_points')
+)
diff --git a/app/assets/stylesheets/application.sass.erb b/app/assets/stylesheets/application.sass.erb
index 53b767384..c59a07d94 100644
--- a/app/assets/stylesheets/application.sass.erb
+++ b/app/assets/stylesheets/application.sass.erb
@@ -42,6 +42,9 @@ $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/*'
diff --git a/app/assets/stylesheets/vendor/select2-bootstrap.css b/app/assets/stylesheets/vendor/select2-bootstrap.css
new file mode 100644
index 000000000..65f772696
--- /dev/null
+++ b/app/assets/stylesheets/vendor/select2-bootstrap.css
@@ -0,0 +1,721 @@
+/*!
+ * 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;
+ width: 100% !important
+ /*------------------------------------* #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..447b2b86c
--- /dev/null
+++ b/app/assets/stylesheets/vendor/select2.css
@@ -0,0 +1,484 @@
+.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; }
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/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/models/organisation.rb b/app/models/organisation.rb
index 86386772c..31443d1c7 100644
--- a/app/models/organisation.rb
+++ b/app/models/organisation.rb
@@ -39,20 +39,22 @@ 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
+ 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/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/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/_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/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..495f0bda7 100644
--- a/app/views/referential_lines/show.html.slim
+++ b/app/views/referential_lines/show.html.slim
@@ -121,15 +121,19 @@ h3.routes = t('.itineraries')
- 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
- = link_to t('routes.actions.new'), new_referential_line_route_path(@referential, @line), class: 'add'
+ / 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 044a745ec..1fc8f108f 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -66,6 +66,7 @@ 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')
diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim
index d23188fa1..32d738de1 100644
--- a/app/views/routes/_form.html.slim
+++ b/app/views/routes/_form.html.slim
@@ -1,3 +1,56 @@
+= 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.stop_areas.all.to_json)}"
+
+/ StopPoints Reactux component
+= javascript_include_tag 'es6_browserified/stop_points.js'
= semantic_form_for [@referential, @line, @route] do |form|
= form.inputs do
= form.input :name
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/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/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..34d1b6e4d 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
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/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/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/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/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 bb4b8ae3b..70f3448ab 100644
--- a/spec/features/routes_spec.rb
+++ b/spec/features/routes_spec.rb
@@ -41,39 +41,6 @@ describe "Routes", :type => :feature do
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/models/organisation_spec.rb b/spec/models/organisation_spec.rb
index c0aba2eb8..823ee7ea6 100644
--- a/spec/models/organisation_spec.rb
+++ b/spec/models/organisation_spec.rb
@@ -36,7 +36,7 @@ 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
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index c20e80ca1..bb43be63e 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -36,7 +36,7 @@ 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 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